diff -ur --new-file old/linux/CREDITS new/linux/CREDITS --- old/linux/CREDITS Mon Jan 31 16:04:07 2000 +++ new/linux/CREDITS Mon Jan 31 16:05:40 2000 @@ -24,6 +24,12 @@ S: Iasi 6600 S: Romania +N: Monalisa Agrawal +E: magrawal@nortelnetworks.com +D: Basic Interphase 5575 driver with UBR and ABR support. +S: 75 Donald St, Apt 42 +S: Weymouth, MA 02188 + N: Dave Airlie E: airlied@linux.ie W: http://www.csn.ul.ie/~airlied @@ -862,12 +868,12 @@ S: USA N: Jochen Hein -E: jochen.hein@delphi.central.de +E: jochen@jochen.org P: 1024/4A27F015 25 72 FB E3 85 9F DE 3B CB 0A DA DA 40 77 05 6C D: National Language Support D: Linux Internationalization Project D: German Localization for Linux and GNU software -S: Frankenstraße +S: Frankenstraße 33 S: 34131 Kassel S: Germany @@ -945,7 +951,7 @@ S: United Kingdom N: Ron Holt -E: ron@holt.org +E: ron@sovereign.org W: http://www.holt.org/ W: http://www.ronholt.com/ D: Kernel development @@ -1006,6 +1012,14 @@ S: CB3 0DS S: United Kingdom +N: Andreas Jaeger +E: aj@suse.de +D: Various smaller kernel fixes +D: glibc developer +S: Gottfried-Kinkel-Str. 18 +S: D 67659 Kaiserslautern +S: Germany + N: Mike Jagdis E: jaggy@purplet.demon.co.uk E: Mike.Jagdis@purplet.demon.co.uk @@ -1116,6 +1130,13 @@ S: TW9 1AE S: United Kingdom +N: Marko Kiiskila +E: marko@iprg.nokia.com +D: Author of ATM Lan Emulation +S: 660 Harvard Ave. #7 +S: Santa Clara, CA 95051 +S: USA + N: Russell King E: rmk@arm.uk.linux.org D: Linux/arm integrator, maintainer & hacker @@ -1306,6 +1327,15 @@ S: North Little Rock, Arkansas 72115 S: USA +N: Christophe Lizzi +E: lizzi@cnam.fr +W: http://cedric.cnam.fr/personne/lizzi +D: FORE Systems 200E-series ATM network driver, sparc64 port of ATM +S: CNAM, Laboratoire CEDRIC +S: 292, rue St-Martin +S: 75141 Paris Cedex 03 +S: France + N: Siegfried "Frieder" Loeffler (dg1sek) E: floeff@tunix.mathematik.uni-stuttgart.de, fl@LF.net W: http://www.mathematik.uni-stuttgart.de/~floeff @@ -1669,7 +1699,7 @@ D: Joystick driver D: arcnet-hardware readme D: Minor ARCnet hacking -D: USB hacking +D: USB (HID, ACM, Printer ...) S: Ucitelska 1576 S: Prague 8 S: 182 00 Czech Republic @@ -2315,6 +2345,13 @@ S: UC Berkeley S: Berkeley, CA 94720-1776 S: USA + +N: Mike Westall +D: IBM Turboways 25 ATM Device Driver +E: westall@cs.clemson.edu +S: Department of Computer Science +S: Clemson University +S: Clemson SC 29634 USA N: Greg Wettstein E: greg@wind.rmcc.com diff -ur --new-file old/linux/Documentation/Configure.help new/linux/Documentation/Configure.help --- old/linux/Documentation/Configure.help Mon Jan 31 16:04:07 2000 +++ new/linux/Documentation/Configure.help Mon Jan 31 16:05:40 2000 @@ -4472,15 +4472,6 @@ does not work correctly without modification please contact the author by email at ipslinux@us.ibm.com. -IBM ServeRAID Support -CONFIG_SCSI_IPS - This is support for the IBM ServeRAID hardware RAID controllers. - Consult the SCSI-HOWTO, available via anonymous FTP from - ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, and the file - README.ips in drivers/scsi for more information. If this driver - does not work correctly without modification please contact the - author by email at ipslinux@us.ibm.com. - BusLogic SCSI support CONFIG_SCSI_BUSLOGIC This is support for BusLogic MultiMaster and FlashPoint SCSI Host @@ -8059,8 +8050,8 @@ The module will be called usb-uhci.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. -OHCI-HCD (Compaq, iMacs, OPTi, SiS, ALi, ...) support? -CONFIG_USB_OHCI_HCD +OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support? +CONFIG_USB_OHCI The Open Host Controller Interface is a standard by Compaq/Microsoft/National for accessing the USB PC hardware (also called USB host controller). If your USB host controller conforms @@ -8069,11 +8060,11 @@ chipsets - like SiS (actual 610, 610 and so on) or ALi (ALi IV, ALi V, Aladdin Pro..) - conform to this standard. - You may want to read the file Documentation/usb/ohci-hcd.txt. + You may want to read the file Documentation/usb/ohci.txt. This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called usb-ohci-hcd.o. If you want to compile it + The module will be called usb-ohci.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. USB Human Interface Device (HID) support @@ -8123,6 +8114,21 @@ into one misc device. If you say N, you'll have a separate device for each your USB mouse. +Support for digitizers +CONFIG_INPUT_MOUSEDEV_DIGITIZER + Use this if you have a digitizer that doesn't emulate a mouse + itself, and want to use it as a mouse. + +Horizontal screen resolution +CONFIG_INPUT_MOUSEDEV_SCREEN_X + For the mouse emulation to be correct, the mousedev driver needs + to know the screen resolution you are using (in X). + +Vertical screen resolution +CONFIG_INPUT_MOUSEDEV_SCREEN_Y + For the mouse emulation to be correct, the mousedev driver needs + to know the screen resolution you are using (in X). + Joystick support CONFIG_INPUT_JOYDEV Say Y here if you want your USB HID joystick or gamepad to be @@ -8220,17 +8226,47 @@ Say Y here if you want to connect this type of camera to your computer's USB port. + This driver uses the Video For Linux API. You must enable + (Y or M in config) Video For Linux (under Character Devices) + to use this driver. Information on this API and pointers to + "v4l" programs may be found on the WWW at + http://roadrunner.swansea.uk.linux.org/v4l.shtml . + This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). The module will be called cpia.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. +USB IBM (Xirlink) C-It Camera support +CONFIG_USB_IBMCAM + Say Y here if you want to connect this type of camera to your + computer's USB port. + + This driver uses the Video For Linux API. You must enable + (Y or M in config) Video For Linux (under Character Devices) + to use this driver. Information on this API and pointers to + "v4l" programs may be found on the WWW at + http://roadrunner.swansea.uk.linux.org/v4l.shtml . + + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called ibmcam.o. If you want to compile it as a + module, say M here and read Documentation/modules.txt. This camera + has several configuration options which can be specified when you + load the module. Read Documentation/usb/ibmcam.txt to learn more. + USB OV511 Camera support CONFIG_USB_OV511 Say Y here if you want to connect this type of camera to your computer's USB port. See Documentation/usb/ov511.txt for more information and for a list of supported cameras. + This driver uses the Video For Linux API. You must enable + (Y or M in config) Video For Linux (under Character Devices) + to use this driver. Information on this API and pointers to + "v4l" programs may be found on the WWW at + http://roadrunner.swansea.uk.linux.org/v4l.shtml . + This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). The module will be called ov511.o. If you want to compile it as a @@ -8248,20 +8284,20 @@ The module will be called dc2xx.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. -USB SCSI (mass storage) support -CONFIG_USB_SCSI +USB Mass Storage support +CONFIG_USB_STORAGE Say Y here if you want to connect USB mass storage devices to your computer's USB port. This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called usb-scsi.o. If you want to compile it as a - module, say M here and read Documentation/modules.txt. + The module will be called usb-storage.o. If you want to compile it + as a module, say M here and read Documentation/modules.txt. -USB SCSI verbose debug -CONFIG_USB_SCSI_DEBUG - Say Y here in order to have the USB SCSI code generate verbose - debugging messages. +USB Mass Storage verbose debug +CONFIG_USB_STORAGE_DEBUG + Say Y here in order to have the USB Mass Storage code generate + verbose debugging messages. USS720 parport driver CONFIG_USB_USS720 @@ -10635,9 +10671,10 @@ major number 10 and minor number 135 using mknod ("man mknod"), you will get access to the real time clock built into your computer. Every PC has such a clock built in. It can be used to generate - signals from as low as 1Hz up to 8192Hz, and can also be used as a - 24 hour alarm. It reports status information via the file /proc/rtc - and its behaviour is set by various ioctls on /dev/rtc. + signals from as low as 1Hz up to 8192Hz, and can also be used + as a 24 hour alarm. It reports status information via the file + /proc/driver/rtc and its behaviour is set by various ioctls on + /dev/rtc. If you run Linux on a multiprocessor machine and said Y to "Symmetric Multi Processing" above, you should say Y here to read @@ -11937,6 +11974,11 @@ Say Y here unless you are building a special purpose kernel. +JavaStation OS Flash SIMM (EXPERIMENTAL) +CONFIG_SUN_JSFLASH + This option enables a driver for JavaStation OS Flash driver. + Say N unless you want to boot from your Flash SIMM. + #Siemens SAB82532 serial support #CONFIG_SAB82532 ### @@ -12316,13 +12358,11 @@ use a Toshiba CD-ROM drive; otherwise, the option is not needed and would impact performance a bit, so say N. -Hades SCSI DMA emulator (EXPERIMENTAL) +Hades SCSI DMA emulator CONFIG_TT_DMA_EMUL This option enables code which emulates the TT SCSI DMA chip on the Hades. This increases the SCSI transfer rates at least ten times - compared to PIO transfers. Note that this code is experimental and - has only been tested on a Hades with a 68060 processor. Before you - use this, make backups of your entire hard disk. + compared to PIO transfers. Ariadne support CONFIG_ARIADNE diff -ur --new-file old/linux/Documentation/DMA-mapping.txt new/linux/Documentation/DMA-mapping.txt --- old/linux/Documentation/DMA-mapping.txt Thu Jan 1 01:00:00 1970 +++ new/linux/Documentation/DMA-mapping.txt Thu Jan 27 17:58:15 2000 @@ -0,0 +1,143 @@ + Dynamic DMA mapping + =================== + + David S. Miller + Richard Henderson + Jakub Jelinek + +Most of the 64bit platforms have special hardware that translates bus +addresses (DMA addresses) to physical addresses similarly to how page +tables and/or TLB translate virtual addresses to physical addresses. +This is needed so that e.g. PCI devices can access with a Single Address +Cycle (32bit DMA address) any page in the 64bit physical address space. +Previously in Linux those 64bit platforms had to set artificial limits on +the maximum RAM size in the system, so that the virt_to_bus() static scheme +works (the DMA address translation tables were simply filled on bootup +to map each bus address to the physical page __pa(bus_to_virt())). + +So that Linux can use the dynamic DMA mapping, it needs some help from the +drivers, namely it has to take into account that DMA addresses should be +mapped only for the time they are actually used and unmapped after the DMA +transfer. + +The following API will work of course even on platforms where no such +hardware exists, see e.g. include/asm-i386/pci.h for how it is implemented on +top of the virt_to_bus interface. + +First of all, you should make sure + +#include + +is in your driver. This file defines a dma_addr_t type which should be +used everywhere you hold a DMA (bus) address returned from the DMA mapping +functions. + +There are two types of DMA mappings: +- static DMA mappings which are usually mapped at driver initialization, + unmapped at the end and for which the hardware should not assume + sequential accesses (from both the DMA engine in the card and CPU). +- streaming DMA mappings which are usually mapped for one DMA transfer, + unmapped right after it (unless you use pci_dma_sync below) and for which + hardware can optimize for sequential accesses. + +To allocate and map a static DMA region, you should do: + + dma_addr_t dma_handle; + + cpu_addr = pci_alloc_consistent(dev, size, &dma_handle); + +where dev is a struct pci_dev *. You should pass NULL for PCI like buses +where devices don't have struct pci_dev (like ISA, EISA). +This argument is needed because the DMA translations may be bus +specific (and often is private to the bus which the device is attached to). +Size is the length of the region you want to allocate. +This routine will allocate RAM for that region, so it acts similarly to +__get_free_pages (but takes size instead of page order). +It returns two values: the virtual address which you can use to access it +from the CPU and dma_handle which you pass to the card. +The return address is guaranteed to be page aligned. + +To unmap and free such DMA region, you call: + + pci_free_consistent(dev, size, cpu_addr, dma_handle); + +where dev, size are the same as in the above call and cpu_addr and +dma_handle are the values pci_alloc_consistent returned. + +The streaming DMA mapping routines can be called from interrupt context. +There are two versions of each map/unmap, one which map/unmap a single +memory region, one which map/unmap a scatterlist. + +To map a single region, you do: + + dma_addr_t dma_handle; + + dma_handle = pci_map_single(dev, addr, size); + +and to unmap it: + + pci_unmap_single(dev, dma_handle, size); + +You should call pci_unmap_single when the DMA activity is finished, e.g. +from interrupt which told you the DMA transfer is done. + +Similarly with scatterlists, you map a region gathered from several regions by: + + int i, count = pci_map_sg(dev, sglist, nents); + struct scatterlist *sg; + + for (i = 0, sg = sglist; i < count; i++, sg++) { + hw_address[i] = sg_dma_address(sg); + hw_len[i] = sg_dma_len(sg); + } + +where nents is the number of entries in the sglist. +The implementation is free to merge several consecutive sglist entries +into one (e.g. if DMA mapping is done with PAGE_SIZE granularity, any +consecutive sglist entries can be merged into one provided the first one +ends and the second one starts on a page boundary - in fact this is a huge +advantage for cards which either cannot do scatter-gather or have very +limited number of scatter-gather entries) and returns the actual number +of sg entries it mapped them too. +Then you should loop count times (note: this can be less than nents times) +and use sg_dma_address() and sg_dma_length() macros where you previously +accessed sg->address and sg->length as shown above. + +To unmap a scatterlist, just call: + + pci_unmap_sg(dev, sglist, nents); + +Again, make sure DMA activity finished. +Every pci_map_{single,sg} call should have its pci_unmap_{single,sg} +counterpart, because the bus address space is a shared resource (although +in some ports the mapping is per each BUS so less devices contend for the +same bus address space) and you could render the machine unusable by eating +all bus addresses. + +If you need to use the same streaming DMA region multiple times and touch +the data in between the DMA transfers, just map it +with pci_map_{single,sg}, after each DMA transfer call either: + + pci_dma_sync_single(dev, dma_handle, size); + +or: + + pci_dma_sync_sg(dev, sglist, nents); + +and after the last DMA transfer call one of the DMA unmap routines +pci_unmap_{single,sg}. If you don't touch the data from the first pci_map_* +call till pci_unmap_*, then you don't have to call pci_sync_* routines. + +Drivers converted fully to this interface should not use virt_to_bus any +longer, nor should they use bus_to_virt. Some drivers have to be changed a +little bit, because there is no longer an equivalent to bus_to_virt in the +dynamic DMA mapping scheme - you have to always store the DMA addresses +returned by the pci_alloc_consistent and pci_map_single calls (pci_map_sg +stores them in the scatterlist itself if the platform supports dynamic DMA +mapping in hardware) in your driver structures and/or in the card registers. + +For PCI cards which recognize fewer address lines than 32 in Single +Address Cycle, you should set corresponding pci_dev's dma_mask field to a +different mask. The dma mapping routines then should either honour your request +and allocate the DMA only with the bus address with bits set in your +dma_mask or should complain that the device is not supported on that platform. diff -ur --new-file old/linux/Documentation/filesystems/udf.txt new/linux/Documentation/filesystems/udf.txt --- old/linux/Documentation/filesystems/udf.txt Sat Sep 4 21:42:30 1999 +++ new/linux/Documentation/filesystems/udf.txt Tue Jan 25 20:19:04 2000 @@ -1,7 +1,7 @@ * * ./Documentation/filesystems/udf.txt * -UDF Filesystem version 0.8.9 +UDF Filesystem version 0.9.0 If you encounter problems with reading UDF discs using this driver, please report them to linux_udf@hootie.lvld.hp.com, which is the @@ -19,8 +19,6 @@ unhide Show otherwise hidden files. undelete Show deleted files in lists. strict Set strict conformance (unused) - utf8 (unused) - iocharset (unused) The remaining are for debugging and disaster recovery: diff -ur --new-file old/linux/Documentation/networking/ip-sysctl.txt new/linux/Documentation/networking/ip-sysctl.txt --- old/linux/Documentation/networking/ip-sysctl.txt Sun Jan 9 06:36:20 2000 +++ new/linux/Documentation/networking/ip-sysctl.txt Sat Jan 22 20:54:56 2000 @@ -64,8 +64,14 @@ TCP variables: tcp_syn_retries - INTEGER - Number of times initial SYNs for an TCP connection attempt will - be retransmitted. Should not be higher than 255. + Number of times initial SYNs for an active TCP connection attempt + will be retransmitted. Should not be higher than 255. Default value + is 5, which corresponds to ~180seconds. + +tcp_synack_retries - INTEGER + Number of times SYNACKs for a passive TCP connection attempt will + be retransmitted. Should not be higher than 255. Default value + is 5, which corresponds to ~180seconds. tcp_keepalive_time - INTEGER How often TCP sends out keepalive messages when keepalive is enabled. @@ -73,15 +79,76 @@ tcp_keepalive_probes - INTEGER How many keepalive probes TCP sends out, until it decides that the - connection is broken. + connection is broken. Default value: 9. + +tcp_keepalive_interval - INTEGER + How frequently the probes are send out. Multiplied by + tcp_keepalive_probes it is time to kill not responding connection, + after probes started. Default value: 75sec i.e. connection + will be aborted after ~11 minutes of retries. tcp_retries1 - INTEGER + How many times to retry before deciding that somethig is wrong + and it is necessary to report this suspection to network layer. + Minimal RFC value is 3, it is default, which corresponds + to ~3sec-8min depending on RTO. + tcp_retries2 - INTEGER -tcp_max_delay_acks - INTEGER + How may times to retry before killing alive TCP connection. + RFC1122 says that the limit should be longer than 100 sec. + It is too small number. Default value 15 corresponds to ~13-30min + depending on RTO. + +tcp_orphan_retries - INTEGER + How may times to retry before killing TCP connection, closed + by our side. Default value 7 corresponds to ~50sec-16min + depending on RTO. If you machine is loaded WEB server, + you should think about lowering this value, such sockets + may consume significant resources. Cf. tcp_max_orphans. + tcp_fin_timeout - INTEGER -tcp_max_ka_probes - INTEGER -tcp_hoe_retransmits - INTEGER - Undocumented for now. + Time to hold socket in state FIN-WAIT-2, if it was closed + by our side. Peer can be broken and never close its side, + or even died unexpectedly. Default value is 60sec. + Usual value used in 2.2 was 180 seconds, you may restore + it, but remember that if your machine is even underloaded WEB server, + you risk to overflow memory with kilotons of dead sockets, + FIN-WAIT-2 sockets are less dangerous than FIN-WAIT-1, + because they eat maximum 1.5K of memory, but they tend + to live longer. Cf. tcp_max_orphans. + +tcp_max_tw_buckets - INTEGER + Maximal number of timewait sockets held by system simultaneously. + If this number is exceeded time-wait socket is immediately destroyed + and warning is printed. This limit exists only to prevent + simple DoS attacks, you _must_ not lower the limit artificially, + but rather increase it (probably, after increasing installed memory), + if network conditions require more than default value. + +tcp_tw_recycle - BOOLEAN + Enable fast recycling TIME-WAIT sockets. Default value is 1. + It should not be changed without advice/request of technical + experts. + +tcp_max_orphans - INTEGER + Maximal number of TCP sockets not attached to any user file handle, + held by system. If this number is exceeded orphaned connections are + reset immediately and warning is printed. This limit exists + only to prevent simple DoS attacks, you _must_ not rely on this + or lower the limit artificially, but rather increase it + (probably, after increasing installed memory), + if network conditions require more than default value, + and tune network services to linger and kill such states + more aggressivley. Let me to remind again: each orphan eats + up to ~64K of unswappable memory. + +tcp_abort_on_overflow - BOOLEAN + If listening service is too slow to accept new connections, + reset them. Default state is FALSE. It means that if overflow + occured due to a burst, connection will recover. Enable this + option _only_ if you are really sure that listening daemon + cannot be tuned to accept connections faster. Enabling this + option can harm clients of your server. tcp_syncookies - BOOLEAN Only valid when the kernel was compiled with CONFIG_SYNCOOKIES @@ -89,15 +156,36 @@ overflows. This is to prevent against the common 'syn flood attack' Default: FALSE + Note, that syncookies is fallback facility. + It MUST NOT be used to help highly loaded servers to stand + against legal connection rate. If you see synflood warnings + in your logs, but investigation shows that they occur + because of overload with legal connections, you should tune + another parameters until this warning disappear. + See: tcp_max_syn_backlog, tcp_synack_retries, tcp_abort_on_overflow. + + syncookies seriously violate TCP protocol, do not allow + to use TCP extensions, can result in serious degradation + of some services (f.e. SMTP relaying), visible not by you, + but your clients and relays, contacting you. While you see + synflood warnings in logs not being really flooded, your server + is seriously misconfigured. + tcp_stdurg - BOOLEAN Use the Host requirements interpretation of the TCP urg pointer field. Most hosts use the older BSD interpretation, so if you turn this on Linux might not communicate correctly with them. Default: FALSE -tcp_syn_taildrop - BOOLEAN tcp_max_syn_backlog - INTEGER - Undocumented (work in progress) + Maximal number of remembered connection requests, which are + still did not receive an acknowldgement from connecting client. + Default value is 1024 for systems with more than 128Mb of memory, + and 128 for low memory machines. If server suffers of overload, + try to increase this number. Warning! If you make it greater + than 1024, it would be better to change TCP_SYNQ_HSIZE in + include/net/tcp.h to keep TCP_SYNQ_HSIZE*16<=tcp_max_syn_backlog + and to recompile kernel. tcp_window_scaling - BOOLEAN Enable window scaling as defined in RFC1323. @@ -116,8 +204,15 @@ ip_local_port_range - 2 INTEGERS Defines the local port range that is used by TCP and UDP to choose the local port. The first number is the first, the - second the last local port number. For high-usage systems - change this to 32768-61000. + second the last local port number. Default value depends on + amount of memory available on the system: + > 128Mb 32768-61000 + < 128Mb 1024-4999 or even less. + This number defines number of active connections, which this + system can issue simultaneously to systems not supporting + TCP extensions (timestamps). With tcp_tw_recycle enabled + (i.e. by default) range 1024-4999 is enough to issue up to + 2000 connections per second to systems supporting timestamps. icmp_echo_ignore_all - BOOLEAN icmp_echo_ignore_broadcasts - BOOLEAN @@ -201,7 +296,7 @@ 0 - No source validation. - Default value is 0. Note that some distribution enable it + Default value is 0. Note that some distributions enable it in startip scripts. Alexey Kuznetsov. @@ -210,4 +305,4 @@ Updated by: Andi Kleen ak@muc.de -$Id: ip-sysctl.txt,v 1.11 2000/01/08 20:32:41 davem Exp $ +$Id: ip-sysctl.txt,v 1.13 2000/01/18 08:24:09 davem Exp $ diff -ur --new-file old/linux/Documentation/networking/smctr.txt new/linux/Documentation/networking/smctr.txt --- old/linux/Documentation/networking/smctr.txt Thu Jan 6 23:47:29 2000 +++ new/linux/Documentation/networking/smctr.txt Wed Jan 26 22:15:02 2000 @@ -2,9 +2,7 @@ By Jay Schulist The Linux SMC Token Ring driver works with the SMC TokenCard Elite (8115T) -ISA adapters. Preliminary support for the SMC TokenCard Elite/A (8115T/A) -MCA adapter has been started but is not complete. (Contact me for information -if you have the proper setup to finish the MCA parts). +ISA and SMC TokenCard Elite/A (8115T/A) MCA adapters. Latest information on this driver can be obtained on the Linux-SNA WWW site. Please point your browser to: http://www.linux-sna.org diff -ur --new-file old/linux/Documentation/networking/wan-router.txt new/linux/Documentation/networking/wan-router.txt --- old/linux/Documentation/networking/wan-router.txt Thu May 21 03:54:34 1998 +++ new/linux/Documentation/networking/wan-router.txt Sat Jan 22 21:31:10 2000 @@ -1,19 +1,26 @@ ------------------------------------------------------------------------------ WAN Router for Linux Operating System ------------------------------------------------------------------------------ +Version 2.1.1 - Nov 08, 1999 +Version 2.0.8 - Nov 02, 1999 +Version 2.0.7 - Aug 26, 1999 +Version 2.0.6 - Aug 17, 1999 +Version 2.0.5 - Aug 12, 1999 +Version 2.0.4 - Nov 26, 1998 +Version 2.0.3 - Aug 25, 1998 +Version 2.0.2 - Dec 09, 1997 Version 2.0.1 - Nov 28, 1997 Version 2.0.0 - Nov 06, 1997 Version 1.0.3 - June 3, 1997 Version 1.0.1 - January 30, 1997 -Author: Jaspreet Singh - Gene Kozin -Copyright (c) 1995-1997 Sangoma Technologies Inc. +Author: Nenad Corbic +Copyright (c) 1995-1999 Sangoma Technologies Inc. ------------------------------------------------------------------------------ WARNING: This Version of WANPIPE supports only the S508 and S508/FT1 cards. IF YOU OWN A S502E OR A S508 CARD THEN PLEASE CONTACT SANGOMA TECHNOLOGIES FOR -AN UPGRADE. +AN UPGRADE. ONLY THE BiSYNC STREAMING CODE IS SUPPORTED ON S502E/S503 cards. INTRODUCTION @@ -129,11 +136,55 @@ REVISION HISTORY +2.1.1 Nov 09, 1999 - New code for S514PCI card + - Completely redesigned drivers + fully tested and optimized. + +2.0.8 Nov 02, 1999 - Fixed up the X25API code. + - Clear call bug fixed.i + - Eanbled driver for multi-card + operation. + +2.0.7 Aug 26, 1999 - Merged X25API code into WANPIPE. + - Fixed a memeory leak for X25API + - Updated the X25API code for 2.2.X kernels. + - Improved NEM handling. + +2.0.6 Aug 17, 1999 - Kernel patch works for both 2.2.10 and 2.2.11 kernels + - Fixed up 2.0.5 installation bugs + - No functional difference between 2.0.6 and 2.0.5 + +2.0.5 Aug 12, 1999 - NEW PPP, interrupt drive code + - NEW X25 Xpipmon debugger + - Comments added to setup scripts + - Numerous bug fixes + +2.0.4 Nov 26, 1998 - NEW Cisco Dual Port support. + - NEW support for BiSync Streaming API. + - NEW support for HDLC (LAPB) API. + - WANPIPE provides an API for application + development using the BSD socket interface. + +2.0.3 Aug 25, 1998 - NEW support for Cisco HDLC, with cpipemon + utility for monitoring + - CIR support for Frame-relay + - Support for PAP and CHAP for ppp has been + implemented + - Dynamic IP assignment for PPP + - Multiple channel IPX support for Frame-relay + and X25 + - Inverse Arp support for Frame-relay + - FT1 Configuration utility for linux + - Man Pages for router.conf, router, sdladump, + cfgft1, fpipemon, ppipemon and cpipemon + +2.0.2 Dev 09, 1997 - Implemented PAP and CHAP for ppp. + 2.0.1 Nov 28, 1997 - Protection of "enable_irq()" while "disable_irq()" has been enabled from any other routine (for Frame Relay, PPP and X25). - - Added additional Stats for Fpipemon and Ppipemon - Improved Load Sharing for multiple boards. - + - Added additional Stats for Fpipemon and Ppipemon + - Improved Load Sharing for multiple boards. 2.0.0 Nov 07, 1997 - Implemented protection of RACE conditions by critical flags for FRAME RELAY and PPP. @@ -173,7 +224,7 @@ 1.0.1 January 30, 1997 - Implemented user-readable status and statistics - via /proc file system + via /proc filesystem 1.0.0 December 31, 1996 diff -ur --new-file old/linux/Documentation/networking/wanpipe.txt new/linux/Documentation/networking/wanpipe.txt --- old/linux/Documentation/networking/wanpipe.txt Tue Apr 28 23:22:04 1998 +++ new/linux/Documentation/networking/wanpipe.txt Sat Jan 22 21:31:10 2000 @@ -1,36 +1,23 @@ ------------------------------------------------------------------------------ -WANPIPE(tm) Multiprotocol WAN Driver for Linux WAN Router +Linux WAN Router Utilities Package ------------------------------------------------------------------------------ -Release 4.1 -November 17, 1997 -Author: Jaspreet Singh -Copyright (c) 1995-1997 Sangoma Technologies Inc. +Version 2.1.1 +Nov 08, 1999 +Author: Nenad Corbic +Copyright (c) 1995-1999 Sangoma Technologies Inc. ------------------------------------------------------------------------------ INTRODUCTION -WANPIPE(tm) is a family of intelligent multiprotocol WAN communication adapters -for personal computers (ISA bus) designed to provide PC connectivity to -various communication links, such as leased lines and public data networks, at -speeds up to T1/E1 using a variety of synchronous communications protocols, -including frame relay, PPP, X.25, SDLC, etc. - -WANPIPE driver together with Linux WAN Router module allows you to build a -relatively inexpensive, yet high-performance multiprotocol WAN router. For -more information about the Linux WAN Router please read the file -Documentation/networking/wan-router.txt. You must also obtain the WAN Tools -package to be able to use the Linux WAN Router and WANPIPE driver. The package -is available via the Internet from Sangoma Technologies' anonymous FTP server: - - ftp.sangoma.com/pub/linux/wantools-X.Y.Z.tgz - or - ftp.sangoma.com/pub/linux/wanpipe-X.Y.Z.tgz - -The names of the packages differ only due to naming convention. The -functionality of wantools and wanpipe packages are the same. The latest -version of the WAN Drivers is wanpipe-2.0.0. +This is a set of utilities and shell scripts you need in order to be able to +use Linux kernel-level WAN Router. Please read WAN Router User's manual +(router.txt) and WANPIPE driver documentation found in /usr/lib/router/doc +directory for installation and configuration instructions. -For technical questions and/or comments please e-mail to jaspreet@sangoma.com. +You can find the latest version of this software in /pub/linux directory on +Sangoma Technologies' anonymous FTP server (ftp.sangoma.com). + +For technical questions and/or comments please e-mail to ncorbic@sangoma.com. For general inquiries please contact Sangoma Technologies Inc. by Hotline: 1-800-388-2475 (USA and Canada, toll free) @@ -57,117 +44,214 @@ -NEW IN THIS RELEASE - - o This Version of WANPIPE supports only the S508 and S508/FT1 cards. IF YOU - OWN A S502E OR A S508 CARD THEN PLEASE CONTACT SANGOMA TECHNOLOGIES FOR AN - UPGRADE. - o Protection of "enable_irq()" while "disable_irq()" has been enabled from - any other routine (for Frame Relay, PPP and X25). - o Added additional Stats for Fpipemon and Ppipemon. - o Improved Load Sharing for multiple boards - - -FILE LIST - -drivers/net: - README.wanpipe This file - sdladrv.c SDLA support module source code - sdla_fr.c SDLA Frame Relay source code - sdla_ppp.c SDLA PPP source code - sdla_x25.c SDLA X.25 source code - sdlamain.c SDLA support source code - -include/linux: - sdla_x25.h SDLA X.25 firmware API definitions - sdla_fr.h SDLA frame relay firmware API definitions - sdla_ppp.h SDLA PPP firmware API definitions - wanpipe.h WANPIPE API definitions - sdladrv.h SDLA support module API definitions - sdlasfm.h SDLA firmware module definitions - router.h - - -REVISION HISTORY - -4.1 November 28, 1997 - o Protection of "enable_irq()" while "disable_irq()" has been enabled - from any other routine (for Frame Relay, PPP and X25). - o Added additional Stats for Fpipemon and Ppipemon - o Improved Load Sharing for multiple boards - - -4.0 November 06, 1997 - o Implemented better protection of RACE conditions by critical flags for - FRAME RELAY, PPP and X25. - o DLCI List interrupt mode implemented for DLCI specific CIR. - o IPX support for FRAME RELAY, PPP and X25. - o IPX Server Support (MARS) for FRAME RELAY, PPP and X25. - o More driver specific stats included. - o MULTICAST for FRAME RELAY and PPP. - -3.1.0 January 30, 1997 - - o Implemented IOCTL for executing adapter commands. - o Fixed a bug in frame relay code causing driver configured as a FR - switch to be stuck in WAN_DISCONNECTED mode. - -3.0.0 December 31, 1996 - - o Uses Linux WAN Router interface - o Added support for X.25 routing - o Miscellaneous bug fixes and performance improvements - -2.4.1 December 18, 1996 +ACKNOWLEDGEMENTS - o Added support for LMI and Q.933 frame relay link management +This product is based on the WANPIPE(tm) Multiprotocol WAN Router developed +by Sangoma Technologies Inc. for Linux 2.2.x. Success of the WANPIPE +together with the next major release of Linux kernel in summer 1996 commanded +adequate changes to the WANPIPE code to take full advantage of new Linux +features. + +Instead of continuing developing proprietary interface tied to Sangoma WAN +cards, we decided to separate all hardware-independent code into a separate +module and defined two levels of interfaces - one for user-level applications +and another for kernel-level WAN drivers. WANPIPE is now implemented as a +WAN driver compliant with the WAN Link Driver interface. Also a general +purpose WAN configuration utility and a set of shell scripts was developed to +support WAN router at the user level. + +Many useful ideas concerning hardware-independent interface implementation +were given by Mike McLagan and his implementation +of the Frame Relay router and drivers for Sangoma cards (dlci/sdla). + +With the new implementation of the APIs being incorporated into the WANPIPE, +a special thank goes to Alan Cox in providing insight into BSD sockets. + +Special thanks to all the WANPIPE users who performed field-testing, reported +bugs and made valuable comments and suggestions that help us to improve this +product. -2.3.0 October 17, 1996 - o All shell scripts use meta-configuration file - o Miscellaneous bug fixes -2.2.0 July 16, 1996 +NEW IN THIS RELEASE - o Compatible with Linux 2.0 - o Added uninstall script - o User's Manual is available in HTML format +o Renamed startup script to wanrouter +o Option to turn off/on each router + separately +o New source directory /usr/lib/wanrouter +o New PPP driver +o X25 is not supported in this release + + +PRODUCT COMPONENTS AND RELATED FILES + +/etc: + wanpipe1.conf default router configuration file + wanrouter.rc meta-configuration file (used by the Setup script) + +/lib/modules/X.Y.Z/misc: + wanrouter.o router kernel loadable module + +/lib/modules/X.Y.Z/net: + sdladrv.o Sangoma SDLA support module + wanpipe.o Sangoma WANPIPE(tm) driver module + +/proc/net/wanrouter + Config reads current router configuration + Status reads current router status + {name} reads WAN driver statistics + +/usr/sbin: + wanrouter router start-up script + wanconfig router configuration utility + sdladump WANPIPE adapter memory dump utility + fpipemon Monitor for Frame Relay + cpipemon Monitor for Cisco HDLC + +/usr/lib/wanrouter: + README this file + COPYING GNU General Public License + Setup installation script + Configure configuration script + Filelist distribution definition file + +/usr/lib/wanrouter/doc: + WANPIPE_USER_MANUAL.txt WAN Router User's Manual + WANPIPE_CONFIG.txt WAN Configuration Manual + +/usr/lib/wanrouter/interfaces: + * interface configuration files (TCP/IP configuration) + +/usr/lib/wanrouter/patches: + wanrouter-22.gz patch for Linux kernel 2.2.10 and 2.2.11 + (compatible for all 2.2.X kernels) + wanrouter-20.gz patch for Linux kernel 2.0.36 + + Fix_2.2.11.gz patch to fix the 2.2.11 kernel so other patches + can be applied properly. + +/usr/lib/wanrouter/samples: + interface sample interface configuration file + wanpipe1.cpri CHDLC primary port + wanpipe2.csec CHDLC secondary port + wanpipe1.fr Frame Relay protocol + wanpipe1.ppp PPP protocol ) + wanrouter.rc sample meta-configuration file -2.1.0 June 20, 1996 +/usr/lib/wanrouter/src: + * wan-tools source code - o Added support for synchronous PPP - o Added support for S503 adapter - o Added API for executing adapter commands - o Fixed a re-entrancy problem in frame relay driver - o Changed interface between SDLA driver and protocol support modules - o Updated frame relay firmware +/usr/include/linux: + wanrouter.h router API definitions + wanpipe.h WANPIPE API definitions + sdladrv.h SDLA support module API definitions + sdlasfm.h SDLA firmware module definitions -2.0.0 May 1, 1996 +/usr/src/linux/net/router: + * router source code - o Added interactive installation and configuration scripts - o Added System V-style start-up script - o Added dynamic memory window address selection in SDLA driver - o Miscellaneous bug fixes in SDLA driver - o Updated S508 frame relay firmware - o Changed SFM file format +/var/log: + wanrouter router start-up log (created by the Setup script) -1.0.0 February 12, 1996 +/var/lock: + wanrouter router lock file (created by the Setup script) - o Final release - o Added support for Linux 1.3 - o Updated S508 frame relay firmware +/usr/lib/wanrouter/wanpipe: + fr514.sfm Frame relay firmware for Sangoma S508/S514 card + cdual514.sfm Dual Port Cisco HDLC firmware for Sangoma S508/S514 card + ppp514.sfm PPP Firmware for Sangoma S508 and S514 cards -0.9.0 December 21, 1995 - o Added SNAP encapsulation for routed frames - o Added support for the frame relay switch emulation mode - o Added support for S508 adapter - o Added capability to autodetect adapter type - o Miscellaneous bug fixes in SDLA and frame relay drivers +REVISION HISTORY -0.1.0 October 12, 1995 +1.0.0 December 31, 1996 Initial version - o Initial version +1.0.1 January 30, 1997 Status and statistics can be read via /proc + filesystem entries. ->>>>>>> END OF README <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +1.0.2 April 30, 1997 Added UDP management via monitors. +1.0.3 June 3, 1997 UDP management for multiple boards using Frame + Relay and PPP + Enabled continuous transmission of Configure + Request Packet for PPP (for 508 only) + Connection Timeout for PPP changed from 900 to 0 + Flow Control Problem fixed for Frame Relay + +1.0.4 July 10, 1997 S508/FT1 monitoring capability in fpipemon and + ppipemon utilities. + Configurable TTL for UDP packets. + Multicast and Broadcast IP source addresses are + silently discarded. + +1.0.5 July 28, 1997 Configurable T391,T392,N391,N392,N393 for Frame + Relay in router.conf. + Configurable Memory Address through router.conf + for Frame Relay, PPP and X.25. (commenting this + out enables auto-detection). + Fixed freeing up received buffers using kfree() + for Frame Relay and X.25. + Protect sdla_peek() by calling save_flags(), + cli() and restore_flags(). + Changed number of Trace elements from 32 to 20 + Added DLCI specific data monitoring in FPIPEMON. +2.0.0 Nov 07, 1997 Implemented protection of RACE conditions by + critical flags for FRAME RELAY and PPP. + DLCI List interrupt mode implemented. + IPX support in FRAME RELAY and PPP. + IPX Server Support (MARS) + More driver specific stats included in FPIPEMON + and PIPEMON. + +2.0.1 Nov 28, 1997 Bug Fixes for version 2.0.0. + Protection of "enable_irq()" while + "disable_irq()" has been enabled from any other + routine (for Frame Relay, PPP and X25). + Added additional Stats for Fpipemon and Ppipemon + Improved Load Sharing for multiple boards + +2.0.2 Dec 09, 1997 Support for PAP and CHAP for ppp has been + implemented. + +2.0.3 Aug 15, 1998 New release supporting Cisco HDLC, CIR for Frame + relay, Dynamic IP assignment for PPP and Inverse + Arp support for Frame-relay. Man Pages are + included for better support and a new utility + for configuring FT1 cards. + +2.0.4 Dec 09, 1998 Dual Port support for Cisco HDLC. + Support for HDLC (LAPB) API. + Supports BiSync Streaming code for S502E + and S503 cards. + Support for Streaming HDLC API. + Provides a BSD socket interface for + creating applications using BiSync + streaming. + +2.0.5 Aug 04, 1999 CHDLC initializatin bug fix. + PPP interrupt driven driver: + Fix to the PPP line hangup problem. + New PPP firmware + Added comments to the startup SYSTEM ERROR messages + Xpipemon debugging application for the X25 protocol + New USER_MANUAL.txt + Fixed the odd boundary 4byte writes to the board. + BiSync Streaming code has been taken out. + Available as a patch. + Streaming HDLC API has been taken out. + Available as a patch. + +2.0.6 Aug 17, 1999 Increased debugging in statup scripts + Fixed insallation bugs from 2.0.5 + Kernel patch works for both 2.2.10 and 2.2.11 kernels. + There is no functional difference between the two packages + +2.0.7 Aug 26, 1999 o Merged X25API code into WANPIPE. + o Fixed a memeory leak for X25API + o Updated the X25API code for 2.2.X kernels. + o Improved NEM handling. + +2.1.0 Oct 25, 1999 o New code for S514 PCI Card + o New CHDLC and Frame Relay drivers + o PPP and X25 are not supported in this release +>>>>>> END OF README <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< diff -ur --new-file old/linux/Documentation/rtc.txt new/linux/Documentation/rtc.txt --- old/linux/Documentation/rtc.txt Fri Jun 5 07:53:50 1998 +++ new/linux/Documentation/rtc.txt Tue Jan 25 23:13:47 2000 @@ -22,8 +22,8 @@ the type of interrupt (update-done, alarm-rang, or periodic) that was raised, and the remaining bytes contain the number of interrupts since the last read. Status information is reported through the pseudo-file -/proc/rtc if the /proc filesystem was enabled. The driver has built in -locking so that only one process is allowed to have the /dev/rtc +/proc/driver/rtc if the /proc filesystem was enabled. The driver has +built in locking so that only one process is allowed to have the /dev/rtc interface open at a time. A user process can monitor these interrupts by doing a read(2) or a diff -ur --new-file old/linux/Documentation/usb/CREDITS new/linux/Documentation/usb/CREDITS --- old/linux/Documentation/usb/CREDITS Tue Jan 18 07:19:12 2000 +++ new/linux/Documentation/usb/CREDITS Fri Jan 21 22:03:02 2000 @@ -12,6 +12,7 @@ ham Bradley M Keryan Greg Kroah-Hartman + Pavel Machek Paul Mackerras David E. Nelson Vojtech Pavlik diff -ur --new-file old/linux/Documentation/usb/ibmcam.txt new/linux/Documentation/usb/ibmcam.txt --- old/linux/Documentation/usb/ibmcam.txt Thu Jan 1 01:00:00 1970 +++ new/linux/Documentation/usb/ibmcam.txt Mon Jan 24 07:39:14 2000 @@ -0,0 +1,166 @@ +README for Linux device driver for the IBM "C-It" USB video camera + +INTRODUCTION: + +This driver does not use all features known to exist in +the IBM camera. However most of needed features work well. + +This driver was developed using logs of observed USB traffic +which was produced by standard Windows driver (c-it98.sys). +I did not have any input from Xirlink. Some people asked about +data sheets, but nothing came out of that. I didn't try. + +Video formats: 128x96, 176x144, 352x288 +Frame rate: 3 - 30 frames per second (FPS) +External interface: USB +Internal interface: Video For Linux (V4L) +Supported controls: +- by V4L: Contrast, Brightness, Color, Hue +- by driver options: frame rate, lighting conditions, video format, + default picture settings, sharpness. + +SUPPORTED CAMERAS: + +IBM "C-It" camera, also known as "Xirlink PC Camera" +The device uses proprietary ASIC (and compression method); +it is manufactured by Xirlink. See http://www.xirlink.com + +WHAT YOU NEED: + +- An IBM C-it camera + +- A Linux box with USB support (2.3/2.4 or 2.2 w/backport) + +- A Video4Linux compatible frame grabber program such as xawtv. + +HOW TO COMPILE THE DRIVER: + +You need to compile the driver only if you are a developer +or if you want to make changes to the code. Most distributions +precompile all modules, so you can go directly to the next +section "HOW TO USE THE DRIVER". + +The driver consists of two files in usb/ directory: +ibmcam.c and ibmcam.h These files are included into the +Linux kernel build process if you configure the kernel +for CONFIG_USB_IBMCAM. Run "make xconfig" and in USB section +you will find the IBM camera driver. Select it, save the +configuration and recompile. + +HOW TO USE THE DRIVER: + +I recommend to compile driver as a module. This gives you an +easier access to its configuration. The camera has many more +settings than V4L can operate, so some settings are done using +module options. + +Typically module is installed with command 'modprobe', like this: + +# modprobe ibmcam framerate=1 + +Alternatively you can use 'insmod' in similar fashion: + +# insmod /lib/modules/2.x.y/usb/ibmcam.o framerate=1 + +Module can be inserted with camera connected or disconnected. + +The driver can have options, though some defaults are provided. + +Driver options: + +Name Type Range [default] Example +-------------- -------------- -------------- ------------------ +debug Integer 0-9 [0] debug=1 +flags Integer 0-0xFF [0] flags=0x0d +framerate Integer 0-6 [2] framerate=1 +init_brightness Integer 0-255 [128] init_brightness=100 +init_contrast Integer 0-255 [192] init_contrast=200 +init_color Integer 0-255 [128] init_color=130 +init_hue Integer 0-255 [128] init_hue=115 +lighting Integer 0-2 [1] lighting=2 +sharpness Integer 0-6 [4] sharpness=3 +videosize Integer 0-2 [2] videosize=1 + +debug You don't need this option unless you are a developer. + If you are a developer then you will see in the code + what values do what. 0=off. + +flags This is a bit mask, and you can combine any number of + bits to produce what you want. Usually you don't want + any of extra features this option provides: + + FLAGS_RETRY_VIDIOCSYNC 1 This bit allows to retry failed + VIDIOCSYNC ioctls without failing. + Will work with xawtv, will not + with xrealproducer. Default is + not set. + FLAGS_MONOCHROME 2 Activates monochrome (b/w) mode. + FLAGS_DISPLAY_HINTS 4 Shows colored pixels which have + magic meaning to developers. + FLAGS_OVERLAY_STATS 8 Shows tiny numbers on screen, + useful only for debugging. + FLAGS_FORCE_TESTPATTERN 16 Shows blue screen with numbers. + +framerate This setting controls frame rate of the camera. This is + an approximate setting (in terms of "worst" ... "best") + because camera changes frame rate depending on amount + of light available. Setting 0 is slowest, 6 is fastest. + Beware - fast settings are very demanding and may not + work well with all video sizes. Be conservative. + +init_brightness These settings specify _initial_ values which will be +init_contrast used to set up the camera. If your V4L application has +init_color its own controls to adjust the picture then these +init_hue controls will be used too. These options allow you to + preconfigure the camera when it gets connected, before + any V4L application connects to it. Good for webcams. + +lighting This option selects one of three hardware-defined + photosensitivity settings of the camera. 0=bright light, + 1=Medium (default), 2=Low light. This setting affects + frame rate: the dimmer the lighting the lower the frame + rate (because longer exposition time is needed). + +sharpness This option controls smoothing (noise reduction) + made by camera. Setting 0 is most smooth, setting 6 + is most sharp. Be aware that CMOS sensor used in the + camera is pretty noisy, so if you choose 6 you will + be greeted with "snowy" image. Default is 4. + +videosize This setting chooses one if three image sizes that are + supported by this driver. Camera supports more, but + it's difficult to reverse-engineer all formats. + Following video sizes are supported: + + videosize=0 128x96 + videosize=1 176x144 + videosize=2 352x288 + + The last one (352x288) is the native size of the sensor + array, so it's the best resolution camera can yield. + Choose the image size you need. The smaller image can + support faster frame rate. Default is 352x288. + +WHAT NEEDS TO BE DONE: + +- The box freezes if working camera (with xawtv) is unplugged (OHCI). + Workaround: don't do that :) End the V4L application first. +- Some USB frames are lost on high frame rates, though they shouldn't +- ViCE compression (Xirlink proprietary) may improve frame rate +- On occasion camera does not start properly; xawtv reports errors. + Workaround: reload the driver module. Reason: [1]. +- On occasion camera produces negative image (funny colors.) + Workaround: reload the driver module. Reason: [1]. +- The button on the camera is not used. I don't know how to get to it. + +[1] +- Camera reports its status back to the driver; however I don't know + what returned data means. If camera fails at some initialization + stage then something should be done, and I don't do that because + I don't even know that some command failed. + +CREDITS: + +The code is based in no small part on the CPiA driver by Johannes Erdfelt, +Randy Dunlap, and others. Big thanks to them for their pioneering work on that +and the USB stack. diff -ur --new-file old/linux/Documentation/usb/ohci-hcd.txt new/linux/Documentation/usb/ohci-hcd.txt --- old/linux/Documentation/usb/ohci-hcd.txt Wed Jan 5 01:12:59 2000 +++ new/linux/Documentation/usb/ohci-hcd.txt Thu Jan 1 01:00:00 1970 @@ -1,98 +0,0 @@ - -The OHCI HCD layer is a simple but nearly complete implementation of what the -USB people would call a HCD for the OHCI. - (ISO comming soon, Bulk, INT u. CTRL transfers enabled) -It is based on Linus Torvalds UHCI code and Gregory Smith OHCI fragments (0.03 source tree). -The layer (functions) on top of it, is for interfacing to the alternate-usb device-drivers. - -- Roman Weissgaerber - - * v4.0 1999/08/18 removed all dummy eds, unlink unused eds, code cleanup, bulk transfers - * v2.1 1999/05/09 ep_addr correction, code cleanup - * v0.2.0 1999/05/04 - * everything has been moved into 2 files (ohci-hcd.c, ohci-hub-root.c and headers) - * virtual root hub is now an option, - * memory allocation based on kmalloc and kfree now, simple Bus error handling, - * INT and CTRL transfers enabled, Bulk included but disabled, ISO needs completion - * - * from Linus Torvalds (uhci.c): APM (not tested); hub, usb_device, bus and related stuff - * from Greg Smith (ohci.c): better reset ohci-controller handling, hub - * - * v0.1.0 1999/04/27 initial release - -to remove the module try: -rmmod usb-ohci-hcd - -Features: -- virtual root hub, all basic hub descriptors and commands (state: complete) - this is an option now (v0.2.0) - #define CONFIG_USB_OHCI_VROOTHUB includes the virtual hub code, (VROOTHUB) - default is with. - (at the moment: the Virtual Root Hub is included automatically) - - files: ohci-root-hub.c, ohci-root-hub.h - - -- Endpoint Descriptor (ED) handling more static approach - (EDs should be allocated in parallel to the SET CONFIGURATION command and they live - as long as the function (device) is alive or another configuration is choosen. - In the HCD layer the EDs has to be allocated manually either by calling a subroutine - or by sending a USB root hub vendor specific command to the virtual root hub. - At the alternate linux usb stack EDs will be added (allocated) at their first use. - ED will be unlinked from the HC chains if they are not bussy. - - files: ohci-hcd.c ohci-hcd.h - routines: (do not use for drivers, use the top layer alternate usb commands instead) - - int usb_ohci_add_ep(struct ohci * ohci, unsigned int ep_addr1, - int interval, int load, f_handler handler, int ep_size, int speed) - adds an endpoint, (if the endpoint already exists some parameters will be updated) - - int usb_ohci_rm_ep( ) - removes an endpoint and all pending TDs of that EP - - usb_ohci_rm_function( ) - removes all Endpoints of a function (device) - -- Transfer Descriptors (TD): handling and allocation of TDs is transparent to the upper layers - The HCD takes care of TDs and EDs memory allocation whereas the upper layers (UBSD ...) has - to take care of buffer allocation. - files: ohci-hcd.c ohci-hcd.h - - There is one basic command for all types of bus transfers (INT, BULK, ISO, CTRL): - - int ohci_trans_req(struct ohci * ohci, hcd_ed, int ctrl_len, void *ctrl, void * data, int data_len, __OHCI_BAG lw0, __OHCI_BAG lw1) - - CTRL: ctrl, ctrl_len ... cmd buffer - data, data_len ... data buffer (in or out) - INT, BULK: ctrl = NULL, ctrl_len=0, - data, data_len ... data buffer (in or out) - ISO: tbd - - There is no buffer reinsertion done by the internal HCD function. - (The interface layer does this for a INT-pipe on request.) - If you want a transfer then you have to - provide buffers by sending ohci_trans_req requests. As they are queued as TDs on an ED - you can send as many as you like. They should come back by the callback f_handler in - the same order (for each endpoint, not globally) If an error occurs all - queued transfers of an endpoint will return unsent. They will be marked with an error status. - - e.g double-buffering for int transfers: - - ohci_trans_req(ohci, ep_addr, 0, NULL, data0, data0_len, 0,0) - ohci_trans_req(ohci, ep_addr, 0, NULL, data1, data1_len, 0,0) - - and when a data0 packet returns by the callback f_handler requeue it: - ohci_trans_req(ohci, ep_addr, 0, NULL, data0, data0_len, 0,0) - and when a data1 packet returns by the callback f_handler requeue it: - ohci_trans_req(ohci, ep_addr, 0, NULL, data1, data1_len, 0,0) - - lw0, lw1 are private fields for upper layers for ids or fine grained handlers. - The alternate usb uses them for dev_id and usb_device_irq handler. - - -- Done list handling: returns the requests (callback f_handler in ED) and does - some error handling, root-hub request dequeuing - (files: ohci-done-list.c in ohci-hcd.c now(v0.2.0)) - - diff -ur --new-file old/linux/Documentation/usb/ohci.txt new/linux/Documentation/usb/ohci.txt --- old/linux/Documentation/usb/ohci.txt Thu Jan 1 01:00:00 1970 +++ new/linux/Documentation/usb/ohci.txt Sat Jan 22 03:17:56 2000 @@ -0,0 +1,98 @@ + +The OHCI HCD layer is a simple but nearly complete implementation of what the +USB people would call a HCD for the OHCI. + (ISO comming soon, Bulk, INT u. CTRL transfers enabled) +It is based on Linus Torvalds UHCI code and Gregory Smith OHCI fragments (0.03 source tree). +The layer (functions) on top of it, is for interfacing to the alternate-usb device-drivers. + +- Roman Weissgaerber + + * v4.0 1999/08/18 removed all dummy eds, unlink unused eds, code cleanup, bulk transfers + * v2.1 1999/05/09 ep_addr correction, code cleanup + * v0.2.0 1999/05/04 + * everything has been moved into 2 files (ohci-hcd.c, ohci-hub-root.c and headers) + * virtual root hub is now an option, + * memory allocation based on kmalloc and kfree now, simple Bus error handling, + * INT and CTRL transfers enabled, Bulk included but disabled, ISO needs completion + * + * from Linus Torvalds (uhci.c): APM (not tested); hub, usb_device, bus and related stuff + * from Greg Smith (ohci.c): better reset ohci-controller handling, hub + * + * v0.1.0 1999/04/27 initial release + +to remove the module try: +rmmod usb-ohci + +Features: +- virtual root hub, all basic hub descriptors and commands (state: complete) + this is an option now (v0.2.0) + #define CONFIG_USB_OHCI_VROOTHUB includes the virtual hub code, (VROOTHUB) + default is with. + (at the moment: the Virtual Root Hub is included automatically) + + files: ohci-root-hub.c, ohci-root-hub.h + + +- Endpoint Descriptor (ED) handling more static approach + (EDs should be allocated in parallel to the SET CONFIGURATION command and they live + as long as the function (device) is alive or another configuration is choosen. + In the HCD layer the EDs has to be allocated manually either by calling a subroutine + or by sending a USB root hub vendor specific command to the virtual root hub. + At the alternate linux usb stack EDs will be added (allocated) at their first use. + ED will be unlinked from the HC chains if they are not bussy. + + files: ohci-hcd.c ohci-hcd.h + routines: (do not use for drivers, use the top layer alternate usb commands instead) + + int usb_ohci_add_ep(struct ohci * ohci, unsigned int ep_addr1, + int interval, int load, f_handler handler, int ep_size, int speed) + adds an endpoint, (if the endpoint already exists some parameters will be updated) + + int usb_ohci_rm_ep( ) + removes an endpoint and all pending TDs of that EP + + usb_ohci_rm_function( ) + removes all Endpoints of a function (device) + +- Transfer Descriptors (TD): handling and allocation of TDs is transparent to the upper layers + The HCD takes care of TDs and EDs memory allocation whereas the upper layers (UBSD ...) has + to take care of buffer allocation. + files: ohci-hcd.c ohci-hcd.h + + There is one basic command for all types of bus transfers (INT, BULK, ISO, CTRL): + + int ohci_trans_req(struct ohci * ohci, hcd_ed, int ctrl_len, void *ctrl, void * data, int data_len, __OHCI_BAG lw0, __OHCI_BAG lw1) + + CTRL: ctrl, ctrl_len ... cmd buffer + data, data_len ... data buffer (in or out) + INT, BULK: ctrl = NULL, ctrl_len=0, + data, data_len ... data buffer (in or out) + ISO: tbd + + There is no buffer reinsertion done by the internal HCD function. + (The interface layer does this for a INT-pipe on request.) + If you want a transfer then you have to + provide buffers by sending ohci_trans_req requests. As they are queued as TDs on an ED + you can send as many as you like. They should come back by the callback f_handler in + the same order (for each endpoint, not globally) If an error occurs all + queued transfers of an endpoint will return unsent. They will be marked with an error status. + + e.g double-buffering for int transfers: + + ohci_trans_req(ohci, ep_addr, 0, NULL, data0, data0_len, 0,0) + ohci_trans_req(ohci, ep_addr, 0, NULL, data1, data1_len, 0,0) + + and when a data0 packet returns by the callback f_handler requeue it: + ohci_trans_req(ohci, ep_addr, 0, NULL, data0, data0_len, 0,0) + and when a data1 packet returns by the callback f_handler requeue it: + ohci_trans_req(ohci, ep_addr, 0, NULL, data1, data1_len, 0,0) + + lw0, lw1 are private fields for upper layers for ids or fine grained handlers. + The alternate usb uses them for dev_id and usb_device_irq handler. + + +- Done list handling: returns the requests (callback f_handler in ED) and does + some error handling, root-hub request dequeuing + (files: ohci-done-list.c in ohci-hcd.c now(v0.2.0)) + + diff -ur --new-file old/linux/Documentation/usb/ov511.txt new/linux/Documentation/usb/ov511.txt --- old/linux/Documentation/usb/ov511.txt Tue Jan 18 01:24:48 2000 +++ new/linux/Documentation/usb/ov511.txt Mon Jan 24 07:39:14 2000 @@ -11,10 +11,6 @@ grab a frame in color (YUV420) at 640x480 or 320x240 using either vidcat or xawtv. Other utilities may work but have not yet been tested. -NOTE: 320x240 does not work reliably for me, and causes complete system crashes. - I recommend not using it until a later version, and if you do, run "sync" - first. - SUPPORTED CAMERAS: ________________________________________________________ Manufacturer | Model | Custom ID | Status @@ -24,6 +20,7 @@ Creative Labs | WebCam 3 | 21 | Working Lifeview | RoboCam | 100 | Untested AverMedia | InterCam Elite | 102 | Working +MediaForte | MV300 | 112 | Untested -------------------------------------------------------- Any camera using the OV511 and the OV7610 CCD should work with this driver. The @@ -39,7 +36,8 @@ http://www.ovt.com/omniusbp.html - A Video4Linux compatible frame grabber program (I recommend vidcat and xawtv) - (see: http://www.exploits.org/v4l/ ) + vidcat is part of the w3cam package: http://www.hdk-berlin.de/~rasca/w3cam/ + xawtv is available at: http://www.in-berlin.de/User/kraxel/xawtv.html HOW TO USE IT: @@ -83,7 +81,7 @@ Now you should be able to run xawtv. Right click for the options dialog. WORKING FEATURES: - o Color streaming/capture at 640x480 (reliably) and 320x240 (unreliably) + o Color streaming/capture at 640x480 and 320x240 o YUV420 color o Setting/getting of saturation, contrast and brightness (no color yet) diff -ur --new-file old/linux/Documentation/usb/scanner-hp-sane.txt new/linux/Documentation/usb/scanner-hp-sane.txt --- old/linux/Documentation/usb/scanner-hp-sane.txt Wed Jan 5 01:12:59 2000 +++ new/linux/Documentation/usb/scanner-hp-sane.txt Mon Jan 24 07:39:14 2000 @@ -1,8 +1,10 @@ -Oct. 19, 1999 +Copyright (C) 1999, 2000 David E. Nelson + +Jan. 22, 2000 CHANGES -- Ammended for Linux-2.3.22+ +- Amended for Linux-2.3.40 INTRODUCTION @@ -11,22 +13,25 @@ working with a Hewlett Packard USB capable scanner using the USB interface. The majority of HP Scanners support the Scanner Control Language (SCL) which is both published by HP and supported by SANE. -The only HP Scanner that I'm aware of that does not support SCL is the -4200C. All other HP scanners with USB interfaces should work (4100C, -5200C, 6200C, and 6300C). Of course as HP releases new scanners this -information may change. +The only HP Scanners that I'm aware of that do not support SCL are the +4200C and the 3300C. All other HP scanners with USB interfaces should +work (4100C, 5200C, 6200C, and 6300C). Of course as HP releases new +scanners this information may change. REQUIREMENTS In order to get this running you'll need USB support in your kernel in -addition to USB Scanner support. Please refer to README.scanner -for issues pertaining to Linux USB and USB Scanner support. +addition to USB Scanner support. Please refer to scanner.txt for +issues pertaining to Linux USB and USB Scanner support. An installed version of SANE which is available from http://www.mostang.com/sane/. Testing has been performed using version SANE-1.0.1. For instructions on building and installing SANE, refer to the various README files within the SANE distribution. + +The latest SANE HP backend available from http://www.kirchgessner.net. +At the time of this writing, version 0.83 was available. OK, I'VE INSTALLED SANE. SO WHAT DO I DO NOW? diff -ur --new-file old/linux/Documentation/usb/scanner.txt new/linux/Documentation/usb/scanner.txt --- old/linux/Documentation/usb/scanner.txt Wed Jan 5 01:12:59 2000 +++ new/linux/Documentation/usb/scanner.txt Mon Jan 24 07:39:14 2000 @@ -1,8 +1,10 @@ -Oct 19, 1999 +Copyright (C) 1999, 2000 David E. Nelson + +Jan. 22, 2000 CHANGES -- Ammended for linux-2.3.22+ +- Amended for linux-2.3.40 - Appended hp_scan.c to end of this README - Removed most references to HP @@ -12,49 +14,63 @@ This README will address issues regarding how to configure the kernel to access a USB scanner. Although the driver was originally conceived for USB HP scanners, it's general enough so that it can be used with -other scanners. Also, one can now pass the USB Vendor and -Product ID's using module parameters for unknown scanners. Refer to -the document README.scanner_hp_sane for guidance on how to configure -SANE to use a USB HP Scanner. +other scanners. Also, one can now pass the USB Vendor and Product +ID's using module parameters for unknown scanners. Refer to the +document scanner_hp_sane.txt for guidance on how to configure SANE to +use a USB HP Scanner. ADDITIONAL INFORMATION http://www.linux-usb.org/ -http://www.dynamine.net/linux-usb/HOWTO/ REQUIREMENTS A host with a USB port. Ideally, either a UHCI (Intel) or OHCI (Compaq and others) hardware port should work. However, I've only -been able to really use an OHCI controller. I did have access to a -system with a UHCI controller but some very limited testing did not -produce satisfactory results. Luke Ordelmans - has reported success using the UHCI host -controller with kernel 2.3.18 and a ChainTech motherboard. Here -lately I've been having better success with the ohci-hcd driver. But -since Linux USB support is still in a state of constant development -that may change at a later date. I am confident that eventually all -the host contollers will perform without incident. - -A Linux kernel with USB support (preferably linux-2.3.18+) +been able to really use an OHCI controller. At the time of this +writing, both uhci and ohci work with scanner.c *except* for the HP +4100C which only works with ohci. This problem is being investigated. + +A Linux development kernel (2.3.x) with USB support enabled or a +backported version to linux-2.2.x. See http://www.linux-usb.org for +more information on accomplishing this. -A Linux kernel with USB Scanner support. +A Linux kernel with USB Scanner support enabled. +'lspci' which is only needed to determine the type of USB hardware +available in your machine. CONFIGURATION -Using `make menuconfig` or your prefered method for configuring the -kernel, select 'Support for USB', 'OHCI/OHCI-HCD/UHCI' depending on -your hardware, 'USB hub support', and 'USB Scanner support'. Compile -and install the modules (you may need to execute `depmod -a` to update -the module dependencies). Testing was performed only as modules, -YMMV. +Using `lspci -v`, determine the type of USB hardware available. + + If you see something like: + + USB Controller: ...... + Flags: ..... + I/O ports at .... + + Then you have a UHCI based controller. + + If you see something like: + + USB Controller: ..... + Flags: .... + Memory at ..... + + Then you have a OHCI based controller. + +Using `make menuconfig` or your preferred method for configuring the +kernel, select 'Support for USB', 'OHCI/UHCI' depending on your +hardware (determined from the steps above), 'USB Scanner support', and +'Preliminary USB device filesystem'. Compile and install the modules +(you may need to execute `depmod -a` to update the module +dependencies). Testing was performed only as modules, YMMV. Add a device for the USB scanner: - linux-2.3.22 and above: `mknod /dev/usbscanner c 180 48` - linux-2.3.21 and below: `mknod /dev/usbscanner c 16 1` + `mknod /dev/usbscanner c 180 48` Set appropriate permissions for /dev/usbscanner (don't forget about group and world permissions). Both read and write permissions are @@ -66,36 +82,71 @@ modprobe usb-ohci modprobe scanner - OHCI-HCD: - modprobe usb-ohci-hcd - modprobe hub - modprobe scanner - UHCI: modprobe usb-uhci - modprobe hub (don't know if this is required or not) modprobe scanner That's it. SANE should now be able to access the device. There is a small test program (hp_scan.c -- appended below) that can be used to test the scanner device if it's an HP scanner that supports -SCL. Its purpose is to test the driver without having to -retrieve/configure SANE. Hp_scan.c will scan the entire bed and put -the output into a file called 'out.dat' in the current directory. The -data in the file is raw data so it's not very useful for imaging. +SCL (Scanner Control Language). Known HP scanner that support SCL are +the 4100, 5200, 6200, the 6300 -- note that the 4200 is *not* +supported since it does not understand SCL; it's also strongly +suspected that the 3300 is not SCL compliant. Hp_scan.c's purpose is +to test the driver without having to retrieve/configure SANE. +Hp_scan.c will scan the entire bed and put the output into a file +called 'out.dat' in the current directory. The data in the file is +raw data so it's not very useful for imaging. + + +SUPPORTED SCANNERS + +NOTE: Just because a product is listed here does not mean that +applications exist that support the product. It's in the hopes that +this will allow developers a means to produce applications that will +support the listed USB products. + +At the time of this writing, the following scanners were supported by +scanner.c: + + Hewlett Packard + + 3300, 4100, 4200, 5200, 6200, 6300, PhotoSmart S20 + + AGFA + + SnapScan 1212U + + Umax + + Astra 2000U + + Seiko/Epson + + Perfection 636, Perfection 1200U + + Mustek + + 1200 CU + + User Specified. See MODULE PARAMETERS for details. MODULE PARAMETERS -If you have a device that wish to experiment with or try using this -driver with, but the Vendor and Product ID's are not coded in, don't -despair. If the driver was compiled as a module, you can pass options -to the driver. Simply add 'options scanner vendor=0x#### +If you have a device that you wish to experiment with or try using +this driver with, but the Vendor and Product ID's are not coded in, +don't despair. If the driver was compiled as a module, you can pass +options to the driver. Simply add 'options scanner vendor=0x#### product=0x****' to the conf.modules/modules.conf file replacing the #'s and the *'s with the correct ID's. The ID's can be retrieved from the messages file or using `cat /proc/bus/usb/devices` if USB /proc -support was selected during kernel configuration. +support was selected during kernel configuration. In later kernels +(2.3.38+), a new filesystem was introduced, usbdevfs. To mount the +filesystem, issue the command `mount -t usbdevfs /proc/bus/usb +/proc/bus/usb`. You can then issue ` cat /proc/bus/usb/devices` to +extract USB device information. BUGS diff -ur --new-file old/linux/Documentation/usb/usb-serial.txt new/linux/Documentation/usb/usb-serial.txt --- old/linux/Documentation/usb/usb-serial.txt Fri Jan 14 20:25:21 2000 +++ new/linux/Documentation/usb/usb-serial.txt Tue Jan 25 00:21:55 2000 @@ -59,14 +59,12 @@ possible. The driver cleans up properly when the device is removed, or the connection is canceled on the Visor. - I write _should_ because communication does not seem to work properly at - this time. I am in contact with the developers at HandSpring and am - working at getting this to work properly. + When the device is connected, try talking to it on the second port + (this is usually /dev/ttyUSB1 if you do not have any other usb-serial + devices in the system.) - There is a webpage for this portion of the driver at - http://milosch.net/visor/ and a project set up with mailing lists for - it at : - http://sourceforge.net/project/?group_id=1404 + There is a webpage and mailing lists for this portion of the driver at: + http://usbvisor.sourceforge.net/ Belkin single port serial converter diff -ur --new-file old/linux/Documentation/vm/balance new/linux/Documentation/vm/balance --- old/linux/Documentation/vm/balance Thu Jan 1 01:00:00 1970 +++ new/linux/Documentation/vm/balance Wed Jan 26 22:17:52 2000 @@ -0,0 +1,81 @@ +Started Jan 2000 by Kanoj Sarcar + +Memory balancing is needed for non __GFP_WAIT as well as for non +__GFP_IO allocations. + +There are two reasons to be requesting non __GFP_WAIT allocations: +the caller can not sleep (typically intr context), or does not want +to incur cost overheads of page stealing and possible swap io for +whatever reasons. + +__GFP_IO allocation requests are made to prevent file system deadlocks. + +In the absence of non sleepable allocation requests, it seems detrimental +to be doing balancing. Page reclamation can be kicked off lazily, that +is, only when needed (aka zone free memory is 0), instead of making it +a proactive process. + +That being said, the kernel should try to fulfill requests for direct +mapped pages from the direct mapped pool, instead of falling back on +the dma pool, so as to keep the dma pool filled for dma requests (atomic +or not). A similar argument applies to highmem and direct mapped pages. +OTOH, if there is a lot of free dma pages, it is preferable to satisfy +regular memory requests by allocating one from the dma pool, instead +of incurring the overhead of regular zone balancing. + +In 2.2, memory balancing/page reclamation would kick off only when the +_total_ number of free pages fell below 1/64 th of total memory. With the +right ratio of dma and regular memory, it is quite possible that balancing +would not be done even when the dma zone was completely empty. 2.2 has +been running production machines of varying memory sizes, and seems to be +doing fine even with the presence of this problem. In 2.3, due to +HIGHMEM, this problem is aggravated. + +In 2.3, zone balancing can be done in one of two ways: depending on the +zone size (and possibly of the size of lower class zones), we can decide +at init time how many free pages we should aim for while balancing any +zone. The good part is, while balancing, we do not need to look at sizes +of lower class zones, the bad part is, we might do too frequent balancing +due to ignoring possibly lower usage in the lower class zones. Also, +with a slight change in the allocation routine, it is possible to reduce +the memclass() macro to be a simple equality. + +Another possible solution is that we balance only when the free memory +of a zone _and_ all its lower class zones falls below 1/64th of the +total memory in the zone and its lower class zones. This fixes the 2.2 +balancing problem, and stays as close to 2.2 behavior as possible. Also, +the balancing algorithm works the same way on the various architectures, +which have different numbers and types of zones. If we wanted to get +fancy, we could assign different weights to free pages in different +zones in the future. + +Note that if the size of the regular zone is huge compared to dma zone, +it becomes less significant to consider the free dma pages while +deciding whether to balance the regular zone. The first solution +becomes more attractive then. + +The appended patch implements the second solution. It also "fixes" two +problems: first, kswapd is woken up as in 2.2 on low memory conditions +for non-sleepable allocations. Second, the HIGHMEM zone is also balanced, +so as to give a fighting chance for replace_with_highmem() to get a +HIGHMEM page, as well as to ensure that HIGHMEM allocations do not +fall back into regular zone. This also makes sure that HIGHMEM pages +are not leaked (for example, in situations where a HIGHMEM page is in +the swapcache but is not being used by anyone) + +kswapd also needs to know about the zones it should balance. kswapd is +primarily needed in a situation where balancing can not be done, +probably because all allocation requests are coming from intr context +and all process contexts are sleeping. For 2.3, kswapd does not really +need to balance the highmem zone, since intr context does not request +highmem pages. A zone aware kswapd still needs to be implemented. + +Page stealing from process memory and shm is done if stealing the page would +alleviate memory pressure on any zone in the page's node that has fallen below +its watermark. + +(Good) Ideas that I have heard: +1. Dynamic experience should influence balancing: number of failed requests +for a zone can be tracked and fed into the balancing scheme (jalvo@mbay.net) +2. Implement a replace_with_highmem()-like replace_with_regular() to preserve +dma pages. (lkd@tantalophile.demon.co.uk) diff -ur --new-file old/linux/MAINTAINERS new/linux/MAINTAINERS --- old/linux/MAINTAINERS Tue Jan 18 07:19:08 2000 +++ new/linux/MAINTAINERS Wed Jan 26 21:24:41 2000 @@ -503,7 +503,7 @@ M: vojtech@suse.cz L: linux-joystick@atrey.karlin.mff.cuni.cz W: http://www.suse.cz/development/joystick/ -S: Maintained +S: Supported KERNEL AUTOMOUNTER (AUTOFS) P: H. Peter Anvin @@ -551,11 +551,11 @@ S: Maintained M68K ON APPLE MACINTOSH -P: Alan Cox -M: Alan.Cox@linux.org -W: http://www.mac.linux-m68k.org/home.html -L: linux-mac68k@wave.lm.com -S: As time permits [Michael confess, you are the mac68k maintainer 8)] +P: Joshua Thompson +M: funaho@jurai.org +W: http://www.mac.linux-m68k.org/ +L: linux-mac68k@mac.linux-m68k.org +S: Maintained M68K ON HP9000/300 P: Philip Blundell @@ -631,7 +631,7 @@ S: Maintained NETWORKING [GENERAL] -P: Networking Teak +P: Networking Team M: netdev@oss.sgi.com L: linux-net@vger.rutgers.edu W: http://www.uk.linux.org/NetNews.html (2.0 only) @@ -979,6 +979,19 @@ W: http://www.linux-usb.org S: Supported +USB ACM DRIVER +P: Vojtech Pavlik +M: vojtech@suse.cz +L: linux-usb@suse.com +S: Supported + +USB HID/HIDBP/INPUT DRIVERS +P: Vojtech Pavlik +M: vojtech@suse.cz +L: linux-usb@suse.com +W: http://www.suse.cz/development/input/ +S: Supported + USB HUB P: Johannes Erdfelt M: jerdfelt@sventech.com @@ -986,12 +999,16 @@ S: Maintained USB OHCI DRIVER -P: Gregory P. Smith -M: greg@electricrain.com -M: greg@suitenine.com +P: Roman Weissgaerber +M: weissg@vienna.at L: linux-usb@suse.com -S: Maintained (not yet usable) -W: http://suitenine.com/usb/ +S: Maintained + +USB PRINTER DRIVER +P: Vojtech Pavlik +M: vojtech@suse.cz +L: linux-usb@suse.com +S: Supported USB SERIAL DRIVER P: Greg Kroah-Hartman diff -ur --new-file old/linux/Makefile new/linux/Makefile --- old/linux/Makefile Tue Jan 18 07:22:52 2000 +++ new/linux/Makefile Wed Jan 26 22:16:04 2000 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 3 -SUBLEVEL = 40 +SUBLEVEL = 41 EXTRAVERSION = ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) @@ -207,7 +207,7 @@ endif ifeq ($(CONFIG_ISAPNP),y) -DRIVERS := $(DRIVERS) drivers/pnp/isa-pnp.o +DRIVERS := $(DRIVERS) drivers/pnp/pnp.o endif ifdef CONFIG_SGI @@ -448,6 +448,10 @@ rm -f drivers/net/hamradio/soundmodem/gentbl rm -f drivers/char/hfmodem/gentbl drivers/char/hfmodem/tables.h rm -f drivers/sound/*_boot.h drivers/sound/.*.boot + rm -f drivers/sound/msndinit.c + rm -f drivers/sound/msndperm.c + rm -f drivers/sound/pndsperm.c + rm -f drivers/sound/pndspini.c rm -f .version .config* config.in config.old rm -f scripts/tkparse scripts/kconfig.tk scripts/kconfig.tmp rm -f scripts/lxdialog/*.o scripts/lxdialog/lxdialog diff -ur --new-file old/linux/arch/alpha/kernel/osf_sys.c new/linux/arch/alpha/kernel/osf_sys.c --- old/linux/arch/alpha/kernel/osf_sys.c Tue Jan 11 23:18:38 2000 +++ new/linux/arch/alpha/kernel/osf_sys.c Thu Jan 27 15:32:14 2000 @@ -504,7 +504,7 @@ { int error; - down(&uts_sem); + down_read(&uts_sem); error = -EFAULT; if (copy_to_user(name + 0, system_utsname.sysname, 32)) goto out; @@ -519,7 +519,7 @@ error = 0; out: - up(&uts_sem); + up_read(&uts_sem); return error; } @@ -569,7 +569,6 @@ unsigned len; int i, error; - lock_kernel(); error = verify_area(VERIFY_WRITE, name, namelen); if (error) goto out; @@ -578,15 +577,14 @@ if (namelen > 32) len = 32; - down(&uts_sem); + down_read(&uts_sem); for (i = 0; i < len; ++i) { __put_user(system_utsname.domainname[i], name + i); if (system_utsname.domainname[i] == '\0') break; } - up(&uts_sem); + up_read(&uts_sem); out: - unlock_kernel(); return error; } @@ -810,7 +808,6 @@ char *res; long len, err = -EINVAL; - lock_kernel(); offset = command-1; if (offset >= sizeof(sysinfo_table)/sizeof(char *)) { /* Digital UNIX has a few unpublished interfaces here */ @@ -818,7 +815,7 @@ goto out; } - down(&uts_sem); + down_read(&uts_sem); res = sysinfo_table[offset]; len = strlen(res)+1; if (len > count) @@ -827,9 +824,8 @@ err = -EFAULT; else err = 0; - up(&uts_sem); + up_read(&uts_sem); out: - unlock_kernel(); return err; } diff -ur --new-file old/linux/arch/arm/kernel/signal.c new/linux/arch/arm/kernel/signal.c --- old/linux/arch/arm/kernel/signal.c Thu Jan 13 22:30:31 2000 +++ new/linux/arch/arm/kernel/signal.c Fri Jan 21 18:48:31 2000 @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -502,7 +501,6 @@ info.si_code = SI_USER; info.si_pid = current->p_pptr->pid; info.si_uid = current->p_pptr->uid; - info.si_uid16 = high2lowuid(current->p_pptr->uid); } /* If the (new) signal is now blocked, requeue it. */ diff -ur --new-file old/linux/arch/arm/kernel/sys_arm.c new/linux/arch/arm/kernel/sys_arm.c --- old/linux/arch/arm/kernel/sys_arm.c Thu Jan 13 22:30:31 2000 +++ new/linux/arch/arm/kernel/sys_arm.c Thu Jan 27 15:32:14 2000 @@ -286,9 +286,9 @@ if(!name) return -EFAULT; - down(&uts_sem); + down_read(&uts_sem); err=copy_to_user (name, &system_utsname, sizeof (*name)); - up(&uts_sem); + up_read(&uts_sem); return err?-EFAULT:0; } @@ -309,7 +309,7 @@ if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; - down(&uts_sem); + down_read(&uts_sem); error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); error |= __put_user(0,name->sysname+__OLD_UTS_LEN); @@ -322,7 +322,7 @@ error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); error |= __put_user(0,name->machine+__OLD_UTS_LEN); - up(&uts_sem); + up_read(&uts_sem); error = error ? -EFAULT : 0; diff -ur --new-file old/linux/arch/i386/Makefile new/linux/arch/i386/Makefile --- old/linux/arch/i386/Makefile Sun Oct 17 06:00:11 1999 +++ new/linux/arch/i386/Makefile Mon Jan 24 20:04:37 2000 @@ -22,7 +22,10 @@ LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS) CFLAGS_PIPE := -pipe -CFLAGS_NSR := -fno-strength-reduce + +# only work around strength reduction bug(s) on older gcc versions +CFLAGS_NSR := $(shell if $(CC) -march=i486 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo ""; else echo "-fno-strength-reduce"; fi) + CFLAGS := $(CFLAGS) $(CFLAGS_PIPE) $(CFLAGS_NSR) # prevent gcc from keeping the stack 16 byte aligned @@ -55,6 +58,12 @@ CFLAGS := $(CFLAGS) -DCPU=686 CFLAGS += $(shell if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686"; fi) AFLAGS := $(AFLAGS) -DCPU=686 +endif + +ifdef CONFIG_MK6 +CFLAGS := $(CFLAGS) -DCPU=586 +CFLAGS += $(shell if $(CC) -march=k6 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=k6"; fi) +AFLAGS := $(AFLAGS) -DCPU=586 endif ifdef CONFIG_MK7 diff -ur --new-file old/linux/arch/i386/config.in new/linux/arch/i386/config.in --- old/linux/arch/i386/config.in Thu Jan 20 18:51:42 2000 +++ new/linux/arch/i386/config.in Tue Jan 25 23:13:46 2000 @@ -20,8 +20,9 @@ "386 CONFIG_M386 \ 486/Cx486 CONFIG_M486 \ 586/K5/5x86/6x86 CONFIG_M586 \ - Pentium/K6/TSC CONFIG_M586TSC \ + Pentium/TSC CONFIG_M586TSC \ PPro/6x86MX CONFIG_M686 \ + K6/II/II CONFIG_MK6 \ Athlon CONFIG_MK7" PPro # # Define implied options from the CPU selection here @@ -38,6 +39,9 @@ if [ "$CONFIG_M686" = "y" ]; then define_bool CONFIG_X86_GOOD_APIC y define_bool CONFIG_X86_PGE y +fi +if [ "$CONFIG_MK6" = "y" ]; then + define_bool CONFIG_X86_TSC y fi if [ "$CONFIG_MK7" = "y" ]; then define_bool CONFIG_X86_TSC y diff -ur --new-file old/linux/arch/i386/defconfig new/linux/arch/i386/defconfig --- old/linux/arch/i386/defconfig Fri Jan 21 01:00:45 2000 +++ new/linux/arch/i386/defconfig Tue Jan 25 21:46:48 2000 @@ -18,6 +18,7 @@ # CONFIG_M586 is not set # CONFIG_M586TSC is not set CONFIG_M686=y +# CONFIG_MK6 is not set # CONFIG_MK7 is not set CONFIG_X86_WP_WORKS_OK=y CONFIG_X86_INVLPG=y @@ -123,7 +124,6 @@ # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_BLK_DEV_DAC960 is not set -CONFIG_PARIDE_PARPORT=y # CONFIG_PARIDE is not set CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_HD is not set @@ -423,32 +423,46 @@ # Filesystems # # CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=y +# CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_BFS_FS_WRITE is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_MINIX_FS is not set # CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set # CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # # CONFIG_CODA_FS is not set CONFIG_NFS_FS=y +# CONFIG_ROOT_NFS is not set CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set @@ -459,8 +473,6 @@ # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_SGI_PARTITION is not set -# CONFIG_SUN_PARTITION is not set # CONFIG_NLS is not set # diff -ur --new-file old/linux/arch/i386/kernel/Makefile new/linux/arch/i386/kernel/Makefile --- old/linux/arch/i386/kernel/Makefile Thu Jan 20 18:51:42 2000 +++ new/linux/arch/i386/kernel/Makefile Thu Jan 27 17:58:15 2000 @@ -14,7 +14,8 @@ O_TARGET := kernel.o O_OBJS := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ - ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o + ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \ + pci-dma.o OX_OBJS := i386_ksyms.o MX_OBJS := @@ -39,8 +40,16 @@ endif endif +ifdef CONFIG_ACPI +OX_OBJS += pm.o +else +ifdef CONFIG_APM +OX_OBJS += pm.o +endif +endif + ifeq ($(CONFIG_ACPI),y) - OX_OBJS += acpi.o + O_OBJS += acpi.o endif ifeq ($(CONFIG_APM),y) diff -ur --new-file old/linux/arch/i386/kernel/acpi.c new/linux/arch/i386/kernel/acpi.c --- old/linux/arch/i386/kernel/acpi.c Thu Jan 20 18:51:42 2000 +++ new/linux/arch/i386/kernel/acpi.c Wed Jan 26 22:34:37 2000 @@ -39,25 +39,10 @@ #include #include #include +#include #include /* - * Defines for 2.2.x - */ -#ifndef __exit -#define __exit -#endif -#ifndef module_init -#define module_init(x) int init_module(void) {return x();} -#endif -#ifndef module_exit -#define module_exit(x) void cleanup_module(void) {x();} -#endif -#ifndef DECLARE_WAIT_QUEUE_HEAD -#define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue * x = NULL -#endif - -/* * Yes, it's unfortunate that we are relying on get_cmos_time * because it is slow (> 1 sec.) and i386 only. It might be better * to use some of the code from drivers/char/rtc.c in the near future @@ -108,9 +93,6 @@ static volatile acpi_sstate_t acpi_event_state = ACPI_S0; static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait); -static spinlock_t acpi_devs_lock = SPIN_LOCK_UNLOCKED; -static LIST_HEAD(acpi_devs); - /* Make it impossible to enter C2/C3 until after we've initialized */ static unsigned long acpi_enter_lvl2_lat = ACPI_INFINITE_LAT; static unsigned long acpi_enter_lvl3_lat = ACPI_INFINITE_LAT; @@ -520,21 +502,14 @@ } /* - * Locate PIIX4 device and create a fake FACP + * Init PIIX4 device, create a fake FACP */ -static int __init acpi_find_piix4(void) +static int __init acpi_init_piix4(struct pci_dev *dev) { - struct pci_dev *dev; u32 base; u16 cmd; u8 pmregmisc; - dev = pci_find_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82371AB_3, - NULL); - if (!dev) - return -ENODEV; - pci_read_config_word(dev, PCI_COMMAND, &cmd); if (!(cmd & PCI_COMMAND_IO)) return -ENODEV; @@ -587,6 +562,124 @@ } /* + * Init VIA ACPI device and create a fake FACP + */ +static int __init acpi_init_via686a(struct pci_dev *dev) +{ + u32 base; + u8 tmp, irq; + + pci_read_config_byte(dev, 0x41, &tmp); + if (!(tmp & 0x80)) + return -ENODEV; + + pci_read_config_byte(dev, PCI_CLASS_REVISION, &tmp); + tmp = (tmp & 0x10 ? 0x48 : 0x20); + + pci_read_config_dword(dev, tmp, &base); + if (!(base & PCI_BASE_ADDRESS_SPACE_IO)) + return -ENODEV; + + base &= PCI_BASE_ADDRESS_IO_MASK; + if (!base) + return -ENODEV; + + pci_read_config_byte(dev, 0x42, &irq); + + printk(KERN_INFO "ACPI: found %s at 0x%04x\n", dev->name, base); + + acpi_facp = kmalloc(sizeof(struct acpi_facp), GFP_KERNEL); + if (!acpi_facp) + return -ENOMEM; + + acpi_fake_facp = 1; + memset(acpi_facp, 0, sizeof(struct acpi_facp)); + + acpi_facp->int_model = ACPI_VIA_INT_MODEL; + acpi_facp->sci_int = irq; + acpi_facp->smi_cmd = base + ACPI_VIA_SMI_CMD; + acpi_facp->acpi_enable = ACPI_VIA_ACPI_ENABLE; + acpi_facp->acpi_disable = ACPI_VIA_ACPI_DISABLE; + acpi_facp->pm1a_evt = base + ACPI_VIA_PM1_EVT; + acpi_facp->pm1a_cnt = base + ACPI_VIA_PM1_CNT; + acpi_facp->pm_tmr = base + ACPI_VIA_PM_TMR; + acpi_facp->gpe0 = base + ACPI_VIA_GPE0; + + acpi_facp->pm1_evt_len = ACPI_VIA_PM1_EVT_LEN; + acpi_facp->pm1_cnt_len = ACPI_VIA_PM1_CNT_LEN; + acpi_facp->pm_tm_len = ACPI_VIA_PM_TM_LEN; + acpi_facp->gpe0_len = ACPI_VIA_GPE0_LEN; + acpi_facp->p_lvl2_lat = (__u16) ACPI_INFINITE_LAT; + acpi_facp->p_lvl3_lat = (__u16) ACPI_INFINITE_LAT; + + acpi_facp->duty_offset = ACPI_VIA_DUTY_OFFSET; + acpi_facp->duty_width = ACPI_VIA_DUTY_WIDTH; + + acpi_facp->day_alarm = ACPI_VIA_DAY_ALARM; + acpi_facp->mon_alarm = ACPI_VIA_MON_ALARM; + acpi_facp->century = ACPI_VIA_CENTURY; + + acpi_facp_addr = virt_to_phys(acpi_facp); + acpi_dsdt_addr = 0; + + acpi_p_blk = base + ACPI_VIA_P_BLK; + + return 0; +} + +typedef enum +{ + CH_UNKNOWN = 0, + CH_INTEL_PIIX4, + CH_VIA_686A, +} acpi_chip_t; + +/* indexed by value of each enum in acpi_chip_t */ +const static struct +{ + int (*chip_init)(struct pci_dev *dev); +} acpi_chip_info[] = +{ + {NULL,}, + {acpi_init_piix4}, + {acpi_init_via686a}, +}; + +const static struct pci_device_id acpi_pci_tbl[] = +{ + {0x8086, 0x7113, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_INTEL_PIIX4}, + {0x1106, 0x3057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_686A}, + {0,}, /* terminate list */ +}; + +static int __init acpi_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + return acpi_chip_info[id->driver_data].chip_init(dev); +} + +static struct pci_driver acpi_driver = +{ + name: "acpi", + id_table: acpi_pci_tbl, + probe: acpi_probe, +}; +static int pci_driver_registered = 0; + +/* + * Locate a known ACPI chipset + */ +static int __init acpi_find_chipset(void) +{ + if (pci_register_driver(&acpi_driver) < 1) + return -ENODEV; + + pci_driver_registered = 1; + + return 0; +} + +/* * Handle an ACPI SCI (fixed or general purpose event) */ static void acpi_irq(int irq, void *dev_id, struct pt_regs *regs) @@ -693,7 +786,7 @@ /* The ACPI timer is just the low 24 bits */ #define TIME_BEGIN(tmr) inl(tmr) -#define TIME_END(tmr, begin) ((inl(tmr) - (begin)) & 0x00ffffff) +#define TIME_END(tmr, begin) ((inl(tmr) - (begin)) & 0x00ffffff) /* @@ -836,24 +929,11 @@ static int acpi_enter_dx(acpi_dstate_t state) { int status = 0; - struct list_head *i = acpi_devs.next; - - while (i != &acpi_devs) { - struct acpi_dev *dev = list_entry(i, struct acpi_dev, entry); - if (dev->state != state) { - int dev_status = 0; - if (dev->info.transition) - dev_status = dev->info.transition(dev, state); - if (!dev_status) { - // put hardware into D-state - dev->state = state; - } - if (dev_status) - status = dev_status; - } - - i = i->next; - } + + if (state == ACPI_D0) + status = pm_send_request(PM_RESUME, (void*) state); + else + status = pm_send_request(PM_SUSPEND, (void*) state); return status; } @@ -1208,6 +1288,7 @@ return 0; } + /* * Initialize and enable ACPI */ @@ -1218,17 +1299,17 @@ if (acpi_disabled) return -ENODEV; - if (acpi_find_tables() && acpi_find_piix4()) { - // no ACPI tables and not PIIX4 + if (acpi_find_tables() && acpi_find_chipset()) { + // no ACPI tables and not recognized chipset return -ENODEV; } - /* - * Internally we always keep latencies in timer - * ticks, which is simpler and more consistent (what is - * an uS to us?). Besides, that gives people more - * control in the /proc interfaces. - */ + /* + * Internally we always keep latencies in timer + * ticks, which is simpler and more consistent (what is + * an uS to us?). Besides, that gives people more + * control in the /proc interfaces. + */ if (acpi_facp->p_lvl2_lat && acpi_facp->p_lvl2_lat <= ACPI_MAX_P_LVL2_LAT) { acpi_p_lvl2_lat = ACPI_uS_TO_TMR_TICKS(acpi_facp->p_lvl2_lat); @@ -1249,7 +1330,11 @@ acpi_facp)) { printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n", acpi_facp->sci_int); + + if (pci_driver_registered) + pci_unregister_driver(&acpi_driver); acpi_destroy_tables(); + return -ENODEV; } @@ -1296,8 +1381,14 @@ free_irq(acpi_facp->sci_int, acpi_facp); acpi_destroy_tables(); + + if (pci_driver_registered) + pci_unregister_driver(&acpi_driver); } +/* + * Parse kernel command line options + */ static int __init acpi_setup(char *str) { while (str && *str) { @@ -1315,53 +1406,6 @@ __setup("acpi=", acpi_setup); /* - * Register a device with the ACPI subsystem - */ -struct acpi_dev* acpi_register(struct acpi_dev_info *info, unsigned long adr) -{ - struct acpi_dev *dev = NULL; - if (info) { - dev = kmalloc(sizeof(struct acpi_dev), GFP_KERNEL); - if (dev) { - unsigned long flags; - - memset(dev, 0, sizeof(*dev)); - memcpy(&dev->info, info, sizeof(dev->info)); - dev->adr = adr; - - spin_lock_irqsave(&acpi_devs_lock, flags); - list_add(&dev->entry, &acpi_devs); - spin_unlock_irqrestore(&acpi_devs_lock, flags); - } - } - return dev; -} - -/* - * Unregister a device with ACPI - */ -void acpi_unregister(struct acpi_dev *dev) -{ - if (dev) { - unsigned long flags; - - spin_lock_irqsave(&acpi_devs_lock, flags); - list_del(&dev->entry); - spin_unlock_irqrestore(&acpi_devs_lock, flags); - - kfree(dev); - } -} - -/* - * Wake up a device - */ -void acpi_wakeup(struct acpi_dev *dev) -{ - // run _PS0 or tell parent bus to wake device up -} - -/* * Manage idle devices */ static int acpi_control_thread(void *context) @@ -1382,11 +1426,3 @@ } __initcall(acpi_init); - -/* - * Module visible symbols - */ -EXPORT_SYMBOL(acpi_control_wait); -EXPORT_SYMBOL(acpi_register); -EXPORT_SYMBOL(acpi_unregister); -EXPORT_SYMBOL(acpi_wakeup); diff -ur --new-file old/linux/arch/i386/kernel/apm.c new/linux/arch/i386/kernel/apm.c --- old/linux/arch/i386/kernel/apm.c Thu Jan 6 19:16:48 2000 +++ new/linux/arch/i386/kernel/apm.c Mon Jan 24 20:04:37 2000 @@ -1413,18 +1413,11 @@ __setup("apm=", apm_setup); static struct file_operations apm_bios_fops = { - NULL, /* lseek */ - do_read, - NULL, /* write */ - NULL, /* readdir */ - do_poll, - do_ioctl, - NULL, /* mmap */ - do_open, - NULL, /* flush */ - do_release, - NULL, /* fsync */ - NULL /* fasync */ + read: do_read, + poll: do_poll, + ioctl: do_ioctl, + open: do_open, + release: do_release, }; static struct miscdevice apm_device = { diff -ur --new-file old/linux/arch/i386/kernel/entry.S new/linux/arch/i386/kernel/entry.S --- old/linux/arch/i386/kernel/entry.S Tue Jan 11 03:15:58 2000 +++ new/linux/arch/i386/kernel/entry.S Wed Jan 26 21:32:02 2000 @@ -617,6 +617,7 @@ .long SYMBOL_NAME(sys_setgid) .long SYMBOL_NAME(sys_setfsuid) /* 215 */ .long SYMBOL_NAME(sys_setfsgid) + .long SYMBOL_NAME(sys_pivot_root) /* @@ -625,6 +626,6 @@ * entries. Don't panic if you notice that this hasn't * been shrunk every time we add a new system call. */ - .rept NR_syscalls-216 + .rept NR_syscalls-217 .long SYMBOL_NAME(sys_ni_syscall) .endr diff -ur --new-file old/linux/arch/i386/kernel/i386_ksyms.c new/linux/arch/i386/kernel/i386_ksyms.c --- old/linux/arch/i386/kernel/i386_ksyms.c Thu Jan 20 18:51:42 2000 +++ new/linux/arch/i386/kernel/i386_ksyms.c Thu Jan 27 17:58:15 2000 @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -85,6 +86,9 @@ EXPORT_SYMBOL(__generic_copy_from_user); EXPORT_SYMBOL(__generic_copy_to_user); EXPORT_SYMBOL(strnlen_user); + +EXPORT_SYMBOL(pci_alloc_consistent); +EXPORT_SYMBOL(pci_free_consistent); #ifdef CONFIG_X86_USE_3DNOW EXPORT_SYMBOL(_mmx_memcpy); diff -ur --new-file old/linux/arch/i386/kernel/ls new/linux/arch/i386/kernel/ls --- old/linux/arch/i386/kernel/ls Mon Jan 17 23:37:56 2000 +++ new/linux/arch/i386/kernel/ls Thu Jan 1 01:00:00 1970 @@ -1 +0,0 @@ - diff -ur --new-file old/linux/arch/i386/kernel/pci-dma.c new/linux/arch/i386/kernel/pci-dma.c --- old/linux/arch/i386/kernel/pci-dma.c Thu Jan 1 01:00:00 1970 +++ new/linux/arch/i386/kernel/pci-dma.c Thu Jan 27 17:58:15 2000 @@ -0,0 +1,51 @@ +/* + * Dynamic DMA mapping support. + * + * On i386 there is no hardware dynamic DMA address translation, + * so consistent alloc/free are merely page allocation/freeing. + * The rest of the dynamic DMA mapping interface is implemented + * in asm/pci.h. + */ + +#include +#include +#include +#include +#include + +/* Pure 2^n version of get_order */ +extern __inline__ int __get_order(unsigned long size) +{ + int order; + + size = (size-1) >> (PAGE_SHIFT-1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + +void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, + dma_addr_t *dma_handle) +{ + void *ret; + int gfp = GFP_ATOMIC; + + if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) + gfp |= GFP_DMA; + ret = (void *)__get_free_pages(gfp, __get_order(size)); + + if (ret != NULL) { + memset(ret, 0, size); + *dma_handle = virt_to_bus(ret); + } + return ret; +} + +void pci_free_consistent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + free_pages((unsigned long)vaddr, __get_order(size)); +} diff -ur --new-file old/linux/arch/i386/kernel/pm.c new/linux/arch/i386/kernel/pm.c --- old/linux/arch/i386/kernel/pm.c Thu Jan 1 01:00:00 1970 +++ new/linux/arch/i386/kernel/pm.c Fri Jan 28 17:04:58 2000 @@ -0,0 +1,104 @@ +/* + * pm.c - Power management interface + * + * Copyright (C) 2000 Andrew Henroid + * + * 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 + */ + +#include +#include +#include +#include + +static spinlock_t pm_devs_lock = SPIN_LOCK_UNLOCKED; +static LIST_HEAD(pm_devs); + +/* + * Register a device with power management + */ +struct pm_dev *pm_register(pm_dev_t type, + unsigned long id, + pm_callback callback) +{ + struct pm_dev *dev = kmalloc(sizeof(struct pm_dev), GFP_KERNEL); + if (dev) { + unsigned long flags; + + memset(dev, 0, sizeof(*dev)); + dev->type = type; + dev->id = id; + dev->callback = callback; + + spin_lock_irqsave(&pm_devs_lock, flags); + list_add(&dev->entry, &pm_devs); + spin_unlock_irqrestore(&pm_devs_lock, flags); + } + return dev; +} + +/* + * Unregister a device with power management + */ +void pm_unregister(struct pm_dev *dev) +{ + if (dev) { + unsigned long flags; + + spin_lock_irqsave(&pm_devs_lock, flags); + list_del(&dev->entry); + spin_unlock_irqrestore(&pm_devs_lock, flags); + + kfree(dev); + } +} + +/* + * Send a request to all devices + */ +int pm_send_request(pm_request_t rqst, void *data) +{ + struct list_head *entry = pm_devs.next; + while (entry != &pm_devs) { + struct pm_dev *dev = list_entry(entry, struct pm_dev, entry); + if (dev->callback) { + int status = (*dev->callback)(dev, rqst, data); + if (status) + return status; + } + entry = entry->next; + } + return 0; +} + +/* + * Find a device + */ +struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from) +{ + struct list_head *entry = from ? from->entry.next:pm_devs.next; + while (entry != &pm_devs) { + struct pm_dev *dev = list_entry(entry, struct pm_dev, entry); + if (type == PM_UNKNOWN_DEV || dev->type == type) + return dev; + entry = entry->next; + } + return 0; +} + +EXPORT_SYMBOL(pm_register); +EXPORT_SYMBOL(pm_unregister); +EXPORT_SYMBOL(pm_send_request); +EXPORT_SYMBOL(pm_find); diff -ur --new-file old/linux/arch/i386/kernel/signal.c new/linux/arch/i386/kernel/signal.c --- old/linux/arch/i386/kernel/signal.c Tue Jan 11 03:15:58 2000 +++ new/linux/arch/i386/kernel/signal.c Fri Jan 21 18:48:31 2000 @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -643,7 +642,6 @@ info.si_code = SI_USER; info.si_pid = current->p_pptr->pid; info.si_uid = current->p_pptr->uid; - info.si_uid16 = high2lowuid(current->p_pptr->uid); } /* If the (new) signal is now blocked, requeue it. */ diff -ur --new-file old/linux/arch/i386/kernel/sys_i386.c new/linux/arch/i386/kernel/sys_i386.c --- old/linux/arch/i386/kernel/sys_i386.c Tue Dec 7 23:34:37 1999 +++ new/linux/arch/i386/kernel/sys_i386.c Thu Jan 27 15:32:14 2000 @@ -218,9 +218,9 @@ int err; if (!name) return -EFAULT; - down(&uts_sem); + down_read(&uts_sem); err=copy_to_user(name, &system_utsname, sizeof (*name)); - up(&uts_sem); + up_read(&uts_sem); return err?-EFAULT:0; } @@ -233,7 +233,7 @@ if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; - down(&uts_sem); + down_read(&uts_sem); error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); error |= __put_user(0,name->sysname+__OLD_UTS_LEN); @@ -246,7 +246,7 @@ error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); error |= __put_user(0,name->machine+__OLD_UTS_LEN); - up(&uts_sem); + up_read(&uts_sem); error = error ? -EFAULT : 0; diff -ur --new-file old/linux/arch/i386/mm/init.c new/linux/arch/i386/mm/init.c --- old/linux/arch/i386/mm/init.c Thu Jan 20 18:51:42 2000 +++ new/linux/arch/i386/mm/init.c Mon Jan 24 20:04:37 2000 @@ -196,7 +196,7 @@ kmap_prot = PAGE_KERNEL; } -#endif +#endif /* CONFIG_HIGHMEM */ void show_mem(void) { diff -ur --new-file old/linux/arch/m68k/amiga/amisound.c new/linux/arch/m68k/amiga/amisound.c --- old/linux/arch/m68k/amiga/amisound.c Thu Aug 26 21:42:31 1999 +++ new/linux/arch/m68k/amiga/amisound.c Wed Jan 26 21:44:20 2000 @@ -42,7 +42,7 @@ void __init amiga_init_sound(void) { - snd_data = amiga_chip_alloc(sizeof(sine_data)); + snd_data = amiga_chip_alloc(sizeof(sine_data), "Beep"); if (!snd_data) { printk (KERN_CRIT "amiga init_sound: failed to allocate chipmem\n"); return; diff -ur --new-file old/linux/arch/m68k/amiga/chipram.c new/linux/arch/m68k/amiga/chipram.c --- old/linux/arch/m68k/amiga/chipram.c Thu Aug 26 21:42:31 1999 +++ new/linux/arch/m68k/amiga/chipram.c Wed Jan 26 21:44:20 2000 @@ -8,6 +8,7 @@ #include #include #include +#include #include struct chip_desc { @@ -23,6 +24,8 @@ u_long amiga_chip_size; static unsigned long chipavail; +static struct resource chipram = { "Chip RAM", 0 }; + unsigned long amiga_chip_avail( void ) { #ifdef DEBUG @@ -39,6 +42,9 @@ if (!AMIGAHW_PRESENT(CHIP_RAM)) return; + chipram.end = amiga_chip_size; + request_resource(&iomem_resource, &chipram); + /* initialize start boundary */ dp = DP(chipaddr); @@ -61,7 +67,7 @@ #endif } -void *amiga_chip_alloc (long size) +void *amiga_chip_alloc(long size, const char *name) { /* last chunk */ struct chip_desc *dp; @@ -71,7 +77,7 @@ size = (size + 7) & ~7; #ifdef DEBUG - printk("chip_alloc: allocate %ld bytes\n", size); + printk("amiga_chip_alloc: allocate %ld bytes\n", size); #endif /* @@ -97,14 +103,14 @@ dp = DP((unsigned long)ptr + dp->length); dp->alloced = 1; #ifdef DEBUG - printk ("chip_alloc: no split\n"); + printk ("amiga_chip_alloc: no split\n"); #endif } else { /* split the extent; use the end part */ long newsize = dp->length - (2*sizeof(*dp) + size); #ifdef DEBUG - printk ("chip_alloc: splitting %d to %ld\n", dp->length, + printk ("amiga_chip_alloc: splitting %d to %ld\n", dp->length, newsize); #endif dp->length = newsize; @@ -123,14 +129,18 @@ } #ifdef DEBUG - printk ("chip_alloc: returning %p\n", ptr); + printk ("amiga_chip_alloc: returning %p\n", ptr); #endif if ((unsigned long)ptr & 7) - panic("chip_alloc: alignment violation\n"); + panic("amiga_chip_alloc: alignment violation\n"); chipavail -= size + (2*sizeof(*dp)); /*MILAN*/ + if (!request_mem_region(ZTWO_PADDR(ptr), size, name)) + printk(KERN_WARNING "amiga_chip_alloc: region of size %ld at 0x%08lx " + "is busy\n", size, ZTWO_PADDR(ptr)); + return ptr; } @@ -145,6 +155,7 @@ #endif /* deallocate the chunk */ sdp->alloced = edp->alloced = 0; + release_mem_region(ZTWO_PADDR(ptr), sdp->length); /* check if we should merge with the previous chunk */ if (!sdp->first && !sdp[-1].alloced) { diff -ur --new-file old/linux/arch/m68k/amiga/config.c new/linux/arch/m68k/amiga/config.c --- old/linux/arch/m68k/amiga/config.c Sun Aug 15 20:47:29 1999 +++ new/linux/arch/m68k/amiga/config.c Wed Jan 26 21:44:20 2000 @@ -116,6 +116,23 @@ extern void (*kd_mksound)(unsigned int, unsigned int); + + /* + * Motherboard Resources present in all Amiga models + */ + +static struct resource mb_resource[] = { + { "CIA B", 0x00bfd000, 0x00bfdfff }, + { "CIA A", 0x00bfe000, 0x00bfefff }, + { "Custom I/O", 0x00dff000, 0x00dfffff }, + { "Kickstart ROM", 0x00f80000, 0x00ffffff } +}; + +static struct resource rtc_resource = { + NULL, 0x00dc0000, 0x00dcffff +}; + + /* * Parse an Amiga-specific record in the bootinfo */ @@ -151,11 +168,15 @@ break; case BI_AMIGA_AUTOCON: - if (zorro_num_autocon < ZORRO_NUM_AUTO) - memcpy(&zorro_autocon[zorro_num_autocon++], - (const struct ConfigDev *)data, - sizeof(struct ConfigDev)); - else + if (zorro_num_autocon < ZORRO_NUM_AUTO) { + const struct ConfigDev *cd = (struct ConfigDev *)data; + struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++]; + dev->rom = cd->cd_Rom; + dev->slotaddr = cd->cd_SlotAddr; + dev->slotsize = cd->cd_SlotSize; + dev->resource.start = (unsigned long)cd->cd_BoardAddr; + dev->resource.end = dev->resource.start+cd->cd_BoardSize-1; + } else printk("amiga_parse_bootinfo: too many AutoConfig devices\n"); break; @@ -336,9 +357,16 @@ void __init config_amiga(void) { + int i; + amiga_debug_init(); amiga_identify(); + /* Yuk, we don't have PCI memory */ + iomem_resource.name = "Memory"; + for (i = 0; i < sizeof(mb_resource)/sizeof(mb_resource[0]); i++) + request_resource(&iomem_resource, &mb_resource[i]); + mach_sched_init = amiga_sched_init; mach_keyb_init = amiga_keyb_init; mach_kbdrate = amiga_kbdrate; @@ -354,9 +382,13 @@ mach_gettimeoffset = amiga_gettimeoffset; if (AMIGAHW_PRESENT(A3000_CLK)){ mach_gettod = a3000_gettod; + rtc_resource.name = "A3000 RTC"; + request_resource(&iomem_resource, &rtc_resource); } else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */ mach_gettod = a2000_gettod; + rtc_resource.name = "A2000 RTC"; + request_resource(&iomem_resource, &rtc_resource); } mach_max_dma_address = 0xffffffff; /* @@ -798,7 +830,7 @@ static void amiga_savekmsg_init(void) { - savekmsg = (struct savekmsg *)amiga_chip_alloc(SAVEKMSG_MAXMEM); + savekmsg = (struct savekmsg *)amiga_chip_alloc(SAVEKMSG_MAXMEM, "Debug"); savekmsg->magic1 = SAVEKMSG_MAGIC1; savekmsg->magic2 = SAVEKMSG_MAGIC2; savekmsg->magicptr = virt_to_phys(savekmsg); @@ -973,8 +1005,9 @@ AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick"); AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot"); if (AMIGAHW_PRESENT(ZORRO)) - len += sprintf(buffer+len, "\tZorro%s AutoConfig: %d Expansion Device%s\n", - AMIGAHW_PRESENT(ZORRO3) ? " III" : "", + len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion " + "Device%s\n", + AMIGAHW_PRESENT(ZORRO3) ? "I" : "", zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); #undef AMIGAHW_ANNOUNCE diff -ur --new-file old/linux/arch/m68k/apollo/Makefile new/linux/arch/m68k/apollo/Makefile --- old/linux/arch/m68k/apollo/Makefile Fri Feb 13 01:30:12 1998 +++ new/linux/arch/m68k/apollo/Makefile Wed Jan 26 21:44:20 2000 @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definitions are now in the main makefile... O_TARGET := apollo.o -O_OBJS := config.o dn_ints.o \ +O_OBJS := config.o dn_ints.o dma.o \ include $(TOPDIR)/Rules.make diff -ur --new-file old/linux/arch/m68k/apollo/config.c new/linux/arch/m68k/apollo/config.c --- old/linux/arch/m68k/apollo/config.c Mon Aug 9 21:27:30 1999 +++ new/linux/arch/m68k/apollo/config.c Wed Jan 26 21:44:20 2000 @@ -7,19 +7,26 @@ #include #include +#include #include #include #include #include #include +u_long sio01_physaddr; +u_long sio23_physaddr; +u_long rtc_physaddr; +u_long pica_physaddr; +u_long picb_physaddr; +u_long cpuctrl_physaddr; +u_long timer_physaddr; +u_long apollo_model; + extern void dn_sched_init(void (*handler)(int,void *,struct pt_regs *)); extern int dn_keyb_init(void); extern int dn_dummy_kbdrate(struct kbd_repeat *); extern void dn_init_IRQ(void); -#if 0 -extern void (*dn_default_handler[])(int,void *,struct pt_regs *); -#endif extern int dn_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); extern void dn_free_irq(unsigned int irq, void *dev_id); extern void dn_enable_irq(unsigned int); @@ -37,20 +44,93 @@ extern void (*kd_mksound)(unsigned int, unsigned int); extern void dn_dummy_video_setup(char *,int *); extern void dn_process_int(int irq, struct pt_regs *fp); - -static struct console dn_console_driver; -static void dn_debug_init(void); +#ifdef CONFIG_HEARTBEAT +static void dn_heartbeat(int on); +#endif static void dn_timer_int(int irq,void *, struct pt_regs *); static void (*sched_timer_handler)(int, void *, struct pt_regs *)=NULL; +static void dn_get_model(char *model); +static int dn_cpuctrl=0xff00; +static const char *apollo_models[] = { + "DN3000 (Otter)", + "DN3010 (Otter)", + "DN3500 (Cougar II)", + "DN4000 (Mink)", + "DN4500 (Roadrunner)" }; + +int apollo_parse_bootinfo(const struct bi_record *record) { + + int unknown = 0; + const unsigned long *data = record->data; + + switch(record->tag) { + case BI_APOLLO_MODEL: + apollo_model=*data; + break; + + default: + unknown=1; + } + + return unknown; +} + +void dn_setup_model(void) { + -int dn_serial_console_wait_key(void) { + printk("Apollo hardware found: "); + printk("[%s]\n", apollo_models[apollo_model - APOLLO_DN3000]); + + switch(apollo_model) { + case APOLLO_UNKNOWN: + panic("Unknown apollo model"); + break; + case APOLLO_DN3000: + case APOLLO_DN3010: + sio01_physaddr=SAU8_SIO01_PHYSADDR; + rtc_physaddr=SAU8_RTC_PHYSADDR; + pica_physaddr=SAU8_PICA; + picb_physaddr=SAU8_PICB; + cpuctrl_physaddr=SAU8_CPUCTRL; + timer_physaddr=SAU8_TIMER; + break; + case APOLLO_DN4000: + sio01_physaddr=SAU7_SIO01_PHYSADDR; + sio23_physaddr=SAU7_SIO23_PHYSADDR; + rtc_physaddr=SAU7_RTC_PHYSADDR; + pica_physaddr=SAU7_PICA; + picb_physaddr=SAU7_PICB; + cpuctrl_physaddr=SAU7_CPUCTRL; + timer_physaddr=SAU7_TIMER; + break; + case APOLLO_DN4500: + panic("Apollo model not yet supported"); + break; + case APOLLO_DN3500: + sio01_physaddr=SAU7_SIO01_PHYSADDR; + sio23_physaddr=SAU7_SIO23_PHYSADDR; + rtc_physaddr=SAU7_RTC_PHYSADDR; + pica_physaddr=SAU7_PICA; + picb_physaddr=SAU7_PICB; + cpuctrl_physaddr=SAU7_CPUCTRL; + timer_physaddr=SAU7_TIMER; + break; + default: + panic("Undefined apollo model"); + break; + } + + +} + +int dn_serial_console_wait_key(struct console *co) { while(!(sio01.srb_csrb & 1)) barrier(); return sio01.rhrb_thrb; } -void dn_serial_console_write (const char *str,unsigned int count) +void dn_serial_console_write (struct console *co, const char *str,unsigned int count) { while(count--) { if (*str == '\n') { @@ -80,12 +160,9 @@ void config_apollo(void) { - dn_serial_print("Config apollo !\n"); -#if 0 - dn_debug_init(); -#endif - printk("Config apollo !\n"); + int i; + dn_setup_model(); mach_sched_init=dn_sched_init; /* */ mach_keyb_init=dn_keyb_init; @@ -109,13 +186,19 @@ #endif mach_reset = dn_dummy_reset; /* */ #ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif -#if 0 - mach_fb_init = dn_fb_init; - mach_video_setup = dn_dummy_video_setup; + conswitchp = &dummy_con; #endif kd_mksound = dn_mksound; +#ifdef CONFIG_HEARTBEAT + mach_heartbeat = dn_heartbeat; +#endif + mach_get_model = dn_get_model; + + cpuctrl=0xaa00; + + /* clear DMA translation table */ + for(i=0;i<0x400;i++) + addr_xlat_map[i]=0; } @@ -125,44 +208,30 @@ sched_timer_handler(irq,dev_id,fp); - x=*(volatile unsigned char *)(IO_BASE+0x10803); - x=*(volatile unsigned char *)(IO_BASE+0x10805); + x=*(volatile unsigned char *)(timer+3); + x=*(volatile unsigned char *)(timer+5); } void dn_sched_init(void (*timer_routine)(int, void *, struct pt_regs *)) { - dn_serial_print("dn sched_init\n"); - -#if 0 - /* program timer 2 */ - *(volatile unsigned char *)(IO_BASE+0x10803)=0x00; - *(volatile unsigned char *)(IO_BASE+0x10809)=0; - *(volatile unsigned char *)(IO_BASE+0x1080b)=50; - - /* program timer 3 */ - *(volatile unsigned char *)(IO_BASE+0x10801)=0x00; - *(volatile unsigned char *)(IO_BASE+0x1080c)=0; - *(volatile unsigned char *)(IO_BASE+0x1080f)=50; -#endif /* program timer 1 */ - *(volatile unsigned char *)(IO_BASE+0x10803)=0x01; - *(volatile unsigned char *)(IO_BASE+0x10801)=0x40; - *(volatile unsigned char *)(IO_BASE+0x10805)=0x09; - *(volatile unsigned char *)(IO_BASE+0x10807)=0xc4; + *(volatile unsigned char *)(timer+3)=0x01; + *(volatile unsigned char *)(timer+1)=0x40; + *(volatile unsigned char *)(timer+5)=0x09; + *(volatile unsigned char *)(timer+7)=0xc4; /* enable IRQ of PIC B */ - *(volatile unsigned char *)(IO_BASE+PICA+1)&=(~8); - - + *(volatile unsigned char *)(pica+1)&=(~8); - printk("*(0x10803) %02x\n",*(volatile unsigned char *)(IO_BASE+0x10803)); - printk("*(0x10803) %02x\n",*(volatile unsigned char *)(IO_BASE+0x10803)); +#if 0 + printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3)); + printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3)); +#endif sched_timer_handler=timer_routine; request_irq(0,dn_timer_int,0,NULL,NULL); - } unsigned long dn_gettimeoffset(void) { @@ -187,7 +256,6 @@ int dn_dummy_hwclk(int op, struct hwclk_time *t) { - dn_serial_print("hwclk !\n"); if(!op) { /* read */ t->sec=rtc->second; @@ -208,7 +276,6 @@ rtc->year=t->year; } - dn_serial_print("hwclk end!\n"); return 0; } @@ -235,11 +302,25 @@ } -#if 0 -void dn_debug_init(void) { - - dn_console_driver.write=dn_serial_console_write; - register_console(&dn_console_driver); - +static void dn_get_model(char *model) +{ + strcpy(model, "Apollo "); + if (apollo_model >= APOLLO_DN3000 && apollo_model <= APOLLO_DN4500) + strcat(model, apollo_models[apollo_model - APOLLO_DN3000]); +} + +#ifdef CONFIG_HEARTBEAT +static void dn_heartbeat(int on) { + + if(on) { + dn_cpuctrl&=~0x100; + cpuctrl=dn_cpuctrl; + } + else { + dn_cpuctrl&=~0x100; + dn_cpuctrl|=0x100; + cpuctrl=dn_cpuctrl; + } } #endif + diff -ur --new-file old/linux/arch/m68k/apollo/dma.c new/linux/arch/m68k/apollo/dma.c --- old/linux/arch/m68k/apollo/dma.c Thu Jan 1 01:00:00 1970 +++ new/linux/arch/m68k/apollo/dma.c Fri Jan 28 17:04:58 2000 @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* note only works for 16 Bit 1 page DMA's */ + +static unsigned short next_free_xlat_entry=0; + +unsigned short dma_map_page(unsigned long phys_addr,int count,int type) { + + unsigned long page_aligned_addr=phys_addr & (~((1<<12)-1)); + unsigned short start_map_addr=page_aligned_addr >> 10; + unsigned short free_xlat_entry, *xlat_map_entry; + int i; + + free_xlat_entry=next_free_xlat_entry; + for(i=0,xlat_map_entry=addr_xlat_map+(free_xlat_entry<<2);i<8;i++,xlat_map_entry++) { +#if 0 + printk("phys_addr: %x, page_aligned_addr: %x, start_map_addr: %x\n",phys_addr,page_aligned_addr,start_map_addr+i); +#endif + outw(start_map_addr+i, xlat_map_entry); + } + + next_free_xlat_entry+=2; + if(next_free_xlat_entry>125) + next_free_xlat_entry=0; + +#if 0 + printk("next_free_xlat_entry: %d\n",next_free_xlat_entry); +#endif + + return free_xlat_entry<<10; +} + +void dma_unmap_page(unsigned short dma_addr) { + + return ; + +} + diff -ur --new-file old/linux/arch/m68k/apollo/dn_ints.c new/linux/arch/m68k/apollo/dn_ints.c --- old/linux/arch/m68k/apollo/dn_ints.c Thu Jan 7 17:41:55 1999 +++ new/linux/arch/m68k/apollo/dn_ints.c Wed Jan 26 21:44:20 2000 @@ -16,30 +16,19 @@ static char BellOnCommand[] = { 0xFF, 0x21, 0x81 }, BellOffCommand[] = { 0xFF, 0x21, 0x82 }; +extern void dn_serial_print (const char *str); void dn_process_int(int irq, struct pt_regs *fp) { -#if 0 - unsigned char x; -#endif - -#if 0 - printk("Aha DN interrupt ! : %d\n",irq); -#endif if(dn_irqs[irq-160].handler) { dn_irqs[irq-160].handler(irq,dn_irqs[irq-160].dev_id,fp); } else { - printk("spurious irq %d occurred\n",irq); + printk("spurious irq %d occured\n",irq); } -#if 0 - printk("*(0x10803) %02x\n",*(volatile unsigned char *)(IO_BASE+0x10803)); - x=*(volatile unsigned char *)(IO_BASE+0x10805); -#endif - - *(volatile unsigned char *)(IO_BASE+0x11000)=0x20; - *(volatile unsigned char *)(IO_BASE+0x11100)=0x20; + *(volatile unsigned char *)(pica)=0x20; + *(volatile unsigned char *)(picb)=0x20; } @@ -47,8 +36,6 @@ int i; - printk("Init IRQ\n"); - for(i=0;i<16;i++) { dn_irqs[i].handler=NULL; dn_irqs[i].flags=IRQ_FLG_STD; @@ -60,8 +47,6 @@ int dn_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { - printk("dn request IRQ\n"); - if((irq<0) || (irq>15)) { printk("Trying to request illegal IRQ\n"); return -ENXIO; @@ -73,9 +58,10 @@ dn_irqs[irq].dev_id=dev_id; dn_irqs[irq].devname=devname; if(irq<8) - *(volatile unsigned char *)(IO_BASE+PICA+1)&=~(1<15)) { printk("Trying to free illegal IRQ\n"); return ; } if(irq<8) - *(volatile unsigned char *)(IO_BASE+PICA+1)|=(1< #include #include +#include #include #include @@ -246,6 +247,9 @@ atari_debug_init(); + ioport_resource.end = 0xFFFFFFFF; /* Change size of I/O space from 64KB + to 4GB. */ + mach_sched_init = atari_sched_init; mach_keyb_init = atari_keyb_init; mach_kbdrate = atari_kbdrate; @@ -506,24 +510,6 @@ * serialized, writable */ : "d0" ); - } - - /* - * On the Hades map the PCI memory, I/O and configuration areas - * (0x80000000 - 0xbfffffff). - * - * Settings: supervisor only, non-cacheable, serialized, read and write. - */ - - if (MACH_IS_HADES) { - __asm__ __volatile__ ("movel %0,%/d0\n\t" - ".chip 68040\n\t" - "movec %%d0,%%itt0\n\t" - "movec %%d0,%%dtt0\n\t" - ".chip 68k\n\t" - : /* no outputs */ - : "g" (0x803fa040) - : "d0"); } /* Fetch tos version at Physical 2 */ diff -ur --new-file old/linux/arch/m68k/atari/hades-pci.c new/linux/arch/m68k/atari/hades-pci.c --- old/linux/arch/m68k/atari/hades-pci.c Thu Jan 1 01:00:00 1970 +++ new/linux/arch/m68k/atari/hades-pci.c Wed Jan 26 21:44:20 2000 @@ -0,0 +1,437 @@ +/* + * hades-pci.c - Hardware specific PCI BIOS functions the Hades Atari clone. + * + * Written by Wout Klaren. + */ + +#include +#include +#include +#include + +#if 0 +# define DBG_DEVS(args) printk args +#else +# define DBG_DEVS(args) +#endif + +#if defined(CONFIG_PCI) && defined(CONFIG_HADES) + +#include +#include +#include + +#include +#include +#include +#include + +#define HADES_MEM_BASE 0x80000000 +#define HADES_MEM_SIZE 0x20000000 +#define HADES_CONFIG_BASE 0xA0000000 +#define HADES_CONFIG_SIZE 0x10000000 +#define HADES_IO_BASE 0xB0000000 +#define HADES_IO_SIZE 0x10000000 +#define HADES_VIRT_IO_SIZE 0x00010000 /* Only 64k is remapped and actually used. */ + +#define N_SLOTS 4 /* Number of PCI slots. */ + +static const char pci_mem_name[] = "PCI memory space"; +static const char pci_io_name[] = "PCI I/O space"; +static const char pci_config_name[] = "PCI config space"; + +static struct resource config_space = { pci_config_name, HADES_CONFIG_BASE, + HADES_CONFIG_BASE + HADES_CONFIG_SIZE - 1 }; +static struct resource io_space = { pci_io_name, HADES_IO_BASE, HADES_IO_BASE + + HADES_IO_SIZE - 1 }; + +static const unsigned long pci_conf_base_phys[] = { 0xA0080000, 0xA0040000, + 0xA0020000, 0xA0010000 }; +static unsigned long pci_conf_base_virt[N_SLOTS]; +static unsigned long pci_io_base_virt; + +/* + * static void *mk_conf_addr(unsigned char bus, unsigned char device_fn, + * unsigned char where) + * + * Calculate the address of the PCI configuration area of the given + * device. + * + * BUG: boards with multiple functions are probably not correctly + * supported. + */ + +static void *mk_conf_addr(struct pci_dev *dev, int where) +{ + int device = dev->devfn >> 3, function = dev->devfn & 7; + void *result; + + DBG_DEVS(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p)\n", + dev->bus->number, dev->devfn, where, pci_addr)); + + if (device > 3) + { + DBG_DEVS(("mk_conf_addr: device (%d) > 3, returning NULL\n", device)); + return NULL; + } + + if (dev->bus->number != 0) + { + DBG_DEVS(("mk_conf_addr: bus (%d) > 0, returning NULL\n", device)); + return NULL; + } + + result = (void *) (pci_conf_base_virt[device] | (function << 8) | (where)); + DBG_DEVS(("mk_conf_addr: returning pci_addr 0x%lx\n", (unsigned long) result)); + return result; +} + +static int hades_read_config_byte(struct pci_dev *dev, int where, u8 *value) +{ + volatile unsigned char *pci_addr; + + *value = 0xff; + + if ((pci_addr = (unsigned char *) mk_conf_addr(dev, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + *value = *pci_addr; + + return PCIBIOS_SUCCESSFUL; +} + +static int hades_read_config_word(struct pci_dev *dev, int where, u16 *value) +{ + volatile unsigned short *pci_addr; + + *value = 0xffff; + + if (where & 0x1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if ((pci_addr = (unsigned short *) mk_conf_addr(dev, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + *value = le16_to_cpu(*pci_addr); + + return PCIBIOS_SUCCESSFUL; +} + +static int hades_read_config_dword(struct pci_dev *dev, int where, u32 *value) +{ + volatile unsigned int *pci_addr; + unsigned char header_type; + int result; + + *value = 0xffffffff; + + if (where & 0x3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if ((pci_addr = (unsigned int *) mk_conf_addr(dev, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + *value = le32_to_cpu(*pci_addr); + + /* + * Check if the value is an address on the bus. If true, add the + * base address of the PCI memory or PCI I/O area on the Hades. + */ + + if ((result = hades_read_config_byte(dev, PCI_HEADER_TYPE, + &header_type)) != PCIBIOS_SUCCESSFUL) + return result; + + if (((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_1)) || + ((header_type != PCI_HEADER_TYPE_BRIDGE) && ((where >= PCI_BASE_ADDRESS_2) && + (where <= PCI_BASE_ADDRESS_5)))) + { + if ((*value & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) + { + /* + * Base address register that contains an I/O address. If the + * address is valid on the Hades (0 <= *value < HADES_VIRT_IO_SIZE), + * add 'pci_io_base_virt' to the value. + */ + + if (*value < HADES_VIRT_IO_SIZE) + *value += pci_io_base_virt; + } + else + { + /* + * Base address register that contains an memory address. If the + * address is valid on the Hades (0 <= *value < HADES_MEM_SIZE), + * add HADES_MEM_BASE to the value. + */ + + if (*value == 0) + { + /* + * Base address is 0. Test if this base + * address register is used. + */ + + *pci_addr = 0xffffffff; + if (*pci_addr != 0) + { + *pci_addr = *value; + if (*value < HADES_MEM_SIZE) + *value += HADES_MEM_BASE; + } + } + else + { + if (*value < HADES_MEM_SIZE) + *value += HADES_MEM_BASE; + } + } + } + + return PCIBIOS_SUCCESSFUL; +} + +static int hades_write_config_byte(struct pci_dev *dev, int where, u8 value) +{ + volatile unsigned char *pci_addr; + + if ((pci_addr = (unsigned char *) mk_conf_addr(dev, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + *pci_addr = value; + + return PCIBIOS_SUCCESSFUL; +} + +static int hades_write_config_word(struct pci_dev *dev, int where, u16 value) +{ + volatile unsigned short *pci_addr; + + if ((pci_addr = (unsigned short *) mk_conf_addr(dev, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + *pci_addr = cpu_to_le16(value); + + return PCIBIOS_SUCCESSFUL; +} + +static int hades_write_config_dword(struct pci_dev *dev, int where, u32 value) +{ + volatile unsigned int *pci_addr; + unsigned char header_type; + int result; + + if ((pci_addr = (unsigned int *) mk_conf_addr(dev, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* + * Check if the value is an address on the bus. If true, subtract the + * base address of the PCI memory or PCI I/O area on the Hades. + */ + + if ((result = hades_read_config_byte(dev, PCI_HEADER_TYPE, + &header_type)) != PCIBIOS_SUCCESSFUL) + return result; + + if (((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_1)) || + ((header_type != PCI_HEADER_TYPE_BRIDGE) && ((where >= PCI_BASE_ADDRESS_2) && + (where <= PCI_BASE_ADDRESS_5)))) + { + if ((value & PCI_BASE_ADDRESS_SPACE) == + PCI_BASE_ADDRESS_SPACE_IO) + { + /* + * I/O address. Check if the address is valid address on + * the Hades (pci_io_base_virt <= value < pci_io_base_virt + + * HADES_VIRT_IO_SIZE) or if the value is 0xffffffff. If not + * true do not write the base address register. If it is a + * valid base address subtract 'pci_io_base_virt' from the value. + */ + + if ((value >= pci_io_base_virt) && (value < (pci_io_base_virt + + HADES_VIRT_IO_SIZE))) + value -= pci_io_base_virt; + else + { + if (value != 0xffffffff) + return PCIBIOS_SET_FAILED; + } + } + else + { + /* + * Memory address. Check if the address is valid address on + * the Hades (HADES_MEM_BASE <= value < HADES_MEM_BASE + HADES_MEM_SIZE) or + * if the value is 0xffffffff. If not true do not write + * the base address register. If it is a valid base address + * subtract HADES_MEM_BASE from the value. + */ + + if ((value >= HADES_MEM_BASE) && (value < (HADES_MEM_BASE + HADES_MEM_SIZE))) + value -= HADES_MEM_BASE; + else + { + if (value != 0xffffffff) + return PCIBIOS_SET_FAILED; + } + } + } + + *pci_addr = cpu_to_le32(value); + + return PCIBIOS_SUCCESSFUL; +} + +/* + * static inline void hades_fixup(void) + * + * Assign IRQ numbers as used by Linux to the interrupt pins + * of the PCI cards. + */ + +static void __init hades_fixup(int pci_modify) +{ + char irq_tab[4] = { + IRQ_TT_MFP_IO0, /* Slot 0. */ + IRQ_TT_MFP_IO1, /* Slot 1. */ + IRQ_TT_MFP_SCC, /* Slot 2. */ + IRQ_TT_MFP_SCSIDMA /* Slot 3. */ + }; + struct pci_dev *dev; + unsigned char slot; + + /* + * Go through all devices, fixing up irqs as we see fit: + */ + + for (dev = pci_devices; dev; dev = dev->next) + { + if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) + { + slot = PCI_SLOT(dev->devfn); /* Determine slot number. */ + dev->irq = irq_tab[slot]; + if (pci_modify) + pcibios_write_config_byte(dev->bus->number, dev->devfn, + PCI_INTERRUPT_LINE, dev->irq); + } + } +} + +/* + * static void hades_conf_device(unsigned char bus, unsigned char device_fn) + * + * Machine dependent Configure the given device. + * + * Parameters: + * + * bus - bus number of the device. + * device_fn - device and function number of the device. + */ + +static void __init hades_conf_device(unsigned char bus, unsigned char device_fn) +{ + pcibios_write_config_byte(bus, device_fn, PCI_CACHE_LINE_SIZE, 0); +} + +static struct pci_ops hades_pci_ops = { + read_byte: hades_read_config_byte + read_word: hades_read_config_word + read_dword: hades_read_config_dword + write_byte: hades_write_config_byte + write_word: hades_write_config_word + write_dword: hades_write_config_dword +}; + +/* + * struct pci_bus_info *init_hades_pci(void) + * + * Machine specific initialisation: + * + * - Allocate and initialise a 'pci_bus_info' structure + * - Initialise hardware + * + * Result: pointer to 'pci_bus_info' structure. + */ + +struct pci_bus_info * __init init_hades_pci(void) +{ + struct pci_bus_info *bus; + int i; + + /* + * Remap I/O and configuration space. + */ + + pci_io_base_virt = (unsigned long) ioremap(HADES_IO_BASE, HADES_VIRT_IO_SIZE); + + for (i = 0; i < N_SLOTS; i++) + pci_conf_base_virt[i] = (unsigned long) ioremap(pci_conf_base_phys[i], 0x10000); + + /* + * Allocate memory for bus info structure. + */ + + bus = kmalloc(sizeof(struct pci_bus_info), GFP_KERNEL); + memset(bus, 0, sizeof(struct pci_bus_info)); + + /* + * Claim resources. The m68k has no seperate I/O space, both + * PCI memory space and PCI I/O space are in memory space. Therefore + * the I/O resources are requested in memory space as well. + */ + + if (request_resource(&iomem_resource, &config_space) != 0) + { + kfree(bus); + return NULL; + } + + if (request_resource(&iomem_resource, &io_space) != 0) + { + release_resource(&config_space); + kfree(bus); + return NULL; + } + + bus->mem_space.start = HADES_MEM_BASE; + bus->mem_space.end = HADES_MEM_BASE + HADES_MEM_SIZE - 1; + bus->mem_space.name = pci_mem_name; +#if 1 + if (request_resource(&iomem_resource, &bus->mem_space) != 0) + { + release_resource(&io_space); + release_resource(&config_space); + kfree(bus); + return NULL; + } +#endif + bus->io_space.start = pci_io_base_virt; + bus->io_space.end = pci_io_base_virt + HADES_VIRT_IO_SIZE - 1; + bus->io_space.name = pci_io_name; +#if 1 + if (request_resource(&ioport_resource, &bus->io_space) != 0) + { + release_resource(&bus->mem_space); + release_resource(&io_space); + release_resource(&config_space); + kfree(bus); + return NULL; + } +#endif + /* + * Set hardware dependent functions. + */ + + bus->m68k_pci_ops = &hades_pci_ops; + bus->fixup = hades_fixup; + bus->conf_device = hades_conf_device; + + /* + * Select high to low edge for PCI interrupts. + */ + + tt_mfp.active_edge &= ~0x27; + + return bus; +} +#endif diff -ur --new-file old/linux/arch/m68k/atari/stram.c new/linux/arch/m68k/atari/stram.c --- old/linux/arch/m68k/atari/stram.c Wed Jan 19 03:54:20 2000 +++ new/linux/arch/m68k/atari/stram.c Wed Jan 26 21:44:20 2000 @@ -715,7 +715,7 @@ else { DPRINTK( "unswap_pte: replacing entry %08lx by new page %08lx", entry, page ); - set_pte(dir, pte_mkdirty(mk_pte(page,vma->vm_page_prot))); + set_pte(dir, pte_mkdirty(__mk_pte(page,vma->vm_page_prot))); atomic_inc(&mem_map[MAP_NR(page)].count); ++vma->vm_mm->rss; } diff -ur --new-file old/linux/arch/m68k/bvme6000/config.c new/linux/arch/m68k/bvme6000/config.c --- old/linux/arch/m68k/bvme6000/config.c Thu Aug 26 21:42:31 1999 +++ new/linux/arch/m68k/bvme6000/config.c Wed Jan 26 21:44:20 2000 @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -63,6 +64,15 @@ static void (*tick_handler)(int, void *, struct pt_regs *); + +int bvme6000_parse_bootinfo(const struct bi_record *bi) +{ + if (bi->tag == BI_VME_TYPE) + return 0; + else + return 1; +} + int bvme6000_kbdrate (struct kbd_repeat *k) { return 0; @@ -107,6 +117,13 @@ { volatile PitRegsPtr pit = (PitRegsPtr)BVME_PIT_BASE; + /* Board type is only set by newer versions of vmelilo/tftplilo */ + if (!vme_brdtype) { + if (m68k_cputype == CPU_68060) + vme_brdtype = VME_TYPE_BVME6000; + else + vme_brdtype = VME_TYPE_BVME4000; + } #if 0 /* Call bvme6000_set_vectors() so ABORT will work, along with BVMBug * debugger. Note trap_init() will splat the abort vector, but diff -ur --new-file old/linux/arch/m68k/bvme6000/rtc.c new/linux/arch/m68k/bvme6000/rtc.c --- old/linux/arch/m68k/bvme6000/rtc.c Thu Aug 26 21:42:31 1999 +++ new/linux/arch/m68k/bvme6000/rtc.c Wed Jan 26 21:44:20 2000 @@ -71,8 +71,9 @@ } case RTC_SET_TIME: /* Set the RTC */ { - unsigned char leap_yr; struct rtc_time rtc_tm; + unsigned char mon, day, hrs, min, sec, leap_yr; + unsigned int yrs; if (!suser()) return -EACCES; @@ -81,34 +82,46 @@ sizeof(struct rtc_time))) return -EFAULT; - leap_yr = ((!(rtc_tm.tm_year % 4) && (rtc_tm.tm_year % 100)) || !(rtc_tm.tm_year % 400)); + yrs = rtc_tm.tm_year; + if (yrs < 1900) + yrs += 1900; + mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ + day = rtc_tm.tm_mday; + hrs = rtc_tm.tm_hour; + min = rtc_tm.tm_min; + sec = rtc_tm.tm_sec; - if ((rtc_tm.tm_mon > 12) || (rtc_tm.tm_mday == 0)) + leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); + + if ((mon > 12) || (day == 0)) return -EINVAL; - if (rtc_tm.tm_mday > (days_in_mo[rtc_tm.tm_mon] + ((rtc_tm.tm_mon == 2) && leap_yr))) + if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) return -EINVAL; - - if ((rtc_tm.tm_hour >= 24) || (rtc_tm.tm_min >= 60) || (rtc_tm.tm_sec >= 60)) + + if ((hrs >= 24) || (min >= 60) || (sec >= 60)) return -EINVAL; + if (yrs >= 2070) + return -EINVAL; + save_flags(flags); cli(); /* Ensure clock and real-time-mode-register are accessible */ msr = rtc->msr & 0xc0; rtc->msr = 0x40; - rtc->t0cr_rtmr = rtc_tm.tm_year%4; + rtc->t0cr_rtmr = yrs%4; rtc->bcd_tenms = 0; - rtc->bcd_sec = BIN2BCD(rtc_tm.tm_sec); - rtc->bcd_min = BIN2BCD(rtc_tm.tm_min); - rtc->bcd_hr = BIN2BCD(rtc_tm.tm_hour); - rtc->bcd_dom = BIN2BCD(rtc_tm.tm_mday); - rtc->bcd_mth = BIN2BCD(rtc_tm.tm_mon + 1); - rtc->bcd_year = BIN2BCD(rtc_tm.tm_year%100); + rtc->bcd_sec = BIN2BCD(sec); + rtc->bcd_min = BIN2BCD(min); + rtc->bcd_hr = BIN2BCD(hrs); + rtc->bcd_dom = BIN2BCD(day); + rtc->bcd_mth = BIN2BCD(mon); + rtc->bcd_year = BIN2BCD(yrs%100); if (rtc_tm.tm_wday >= 0) rtc->bcd_dow = BIN2BCD(rtc_tm.tm_wday+1); - rtc->t0cr_rtmr = rtc_tm.tm_year%4 | 0x08; + rtc->t0cr_rtmr = yrs%4 | 0x08; rtc->msr = msr; restore_flags(flags); diff -ur --new-file old/linux/arch/m68k/config.in new/linux/arch/m68k/config.in --- old/linux/arch/m68k/config.in Wed Jan 12 18:20:56 2000 +++ new/linux/arch/m68k/config.in Wed Jan 26 21:44:20 2000 @@ -23,6 +23,9 @@ define_bool CONFIG_PCI y fi fi +if [ "$CONFIG_HADES" != "y" ]; then + define_bool CONFIG_PCI n +fi bool 'Macintosh support' CONFIG_MAC if [ "$CONFIG_MAC" = "y" ]; then define_bool CONFIG_NUBUS y @@ -127,7 +130,9 @@ fi fi -source drivers/pci/Config.in +if [ "$CONFIG_PCI" = "y" ]; then + source drivers/pci/Config.in +fi endmenu @@ -192,7 +197,7 @@ bool 'WarpEngine SCSI support (EXPERIMENTAL)' CONFIG_WARPENGINE_SCSI bool 'Blizzard PowerUP 603e+ SCSI (EXPERIMENTAL)' CONFIG_BLZ603EPLUS_SCSI dep_tristate 'BSC Oktagon SCSI support (EXPERIMENTAL)' CONFIG_OKTAGON_SCSI $CONFIG_SCSI - bool 'Cyberstorm Mk III SCSI support (EXPERIMENTAL)' CONFIG_CYBERSTORMIII_SCSI +# bool 'Cyberstorm Mk III SCSI support (EXPERIMENTAL)' CONFIG_CYBERSTORMIII_SCSI # bool 'GVP Turbo 040/060 SCSI support (EXPERIMENTAL)' CONFIG_GVP_TURBO_SCSI fi fi @@ -201,8 +206,8 @@ if [ "$CONFIG_ATARI_SCSI" != "n" ]; then bool ' Long delays for Toshiba CD-ROMs' CONFIG_ATARI_SCSI_TOSHIBA_DELAY bool ' Reset SCSI-devices at boottime' CONFIG_ATARI_SCSI_RESET_BOOT - if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_HADES" = "y" ]; then - bool ' Hades SCSI DMA emulator (EXPERIMENTAL)' CONFIG_TT_DMA_EMUL + if [ "$CONFIG_HADES" = "y" ]; then + bool ' Hades SCSI DMA emulator' CONFIG_TT_DMA_EMUL fi fi fi @@ -469,5 +474,4 @@ #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ -bool 'Remote debugging support' CONFIG_KGDB endmenu diff -ur --new-file old/linux/arch/m68k/defconfig new/linux/arch/m68k/defconfig --- old/linux/arch/m68k/defconfig Fri Nov 5 19:22:51 1999 +++ new/linux/arch/m68k/defconfig Wed Jan 26 21:44:20 2000 @@ -197,6 +197,7 @@ # CONFIG_AFFS_FS is not set # CONFIG_ROMFS_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_CRAMFS is not set # # Frame buffer devices diff -ur --new-file old/linux/arch/m68k/kernel/Makefile new/linux/arch/m68k/kernel/Makefile --- old/linux/arch/m68k/kernel/Makefile Mon Dec 20 23:43:39 1999 +++ new/linux/arch/m68k/kernel/Makefile Wed Jan 26 21:44:20 2000 @@ -21,10 +21,6 @@ sys_m68k.o time.o semaphore.o OX_OBJS := setup.o m68k_ksyms.o -ifdef CONFIG_KGDB -O_OBJS += kgdb.o -endif - ifdef CONFIG_PCI O_OBJS += bios32.o endif diff -ur --new-file old/linux/arch/m68k/kernel/bios32.c new/linux/arch/m68k/kernel/bios32.c --- old/linux/arch/m68k/kernel/bios32.c Thu Jan 6 18:54:06 2000 +++ new/linux/arch/m68k/kernel/bios32.c Wed Jan 26 21:44:20 2000 @@ -1,6 +1,5 @@ /* - * bios32.c - PCI BIOS functions for Alpha systems not using BIOS - * emulation code. + * bios32.c - PCI BIOS functions for m68k systems. * * Written by Wout Klaren. * @@ -22,25 +21,16 @@ /* * PCI support for Linux/m68k. Currently only the Hades is supported. * - * Notes: - * - * 1. The PCI memory area starts at address 0x80000000 and the - * I/O area starts at 0xB0000000. Therefore these offsets - * are added to the base addresses when they are read and - * substracted when they are written. - * - * 2. The support for PCI bridges in the DEC Alpha version has - * been removed in this version. + * The support for PCI bridges in the DEC Alpha version has + * been removed in this version. */ #include #include #include -#include -#include -#include #include +#include #include #define KB 1024 @@ -48,14 +38,7 @@ #define GB (1024*MB) #define MAJOR_REV 0 -#define MINOR_REV 1 - -/* - * Base addresses of the PCI memory and I/O areas on the Hades. - */ - -static unsigned long pci_mem_base = 0; -static unsigned long pci_io_base = 0; +#define MINOR_REV 5 /* * Align VAL to ALIGN, which must be a power of two. @@ -63,181 +46,51 @@ #define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1)) +#define MAX(val1, val2) (((val1) > (val2)) ? val1 : val2) + /* - * Calculate the address of the PCI configuration area of the given - * device. - * - * BUG: boards with multiple functions are probably not correctly - * supported. + * Offsets relative to the I/O and memory base addresses from where resources + * are allocated. */ -static int mk_conf_addr(unsigned char bus, unsigned char device_fn, - unsigned char where, unsigned long *pci_addr) -{ - static const unsigned long pci_conf_base[] = { 0xA0080000, 0xA0040000, - 0xA0020000, 0xA0010000 }; - int device = device_fn >> 3; - - DBG_DEVS(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p)\n", - bus, device_fn, where, pci_addr)); - - if (device > 3) { - DBG_DEVS(("mk_conf_addr: device (%d) > 3, returning -1\n", device)); - return -1; - } - - *pci_addr = pci_conf_base[device] | (where); - DBG_DEVS(("mk_conf_addr: returning pci_addr 0x%lx\n", *pci_addr)); - return 0; -} - -int pcibios_read_config_byte(unsigned char bus, unsigned char device_fn, - unsigned char where, unsigned char *value) -{ - unsigned long pci_addr; - - *value = 0xff; - - if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) - return PCIBIOS_DEVICE_NOT_FOUND; - - *value = *((unsigned char *)pci_addr); - - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_read_config_word(unsigned char bus, unsigned char device_fn, - unsigned char where, unsigned short *value) -{ - unsigned long pci_addr; - - *value = 0xffff; - - if (where & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mk_conf_addr(bus, device_fn, where, &pci_addr)) - return PCIBIOS_DEVICE_NOT_FOUND; - - *value = le16_to_cpu(*((unsigned short *)pci_addr)); - - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_read_config_dword(unsigned char bus, unsigned char device_fn, - unsigned char where, unsigned int *value) -{ - unsigned long pci_addr; - - *value = 0xffffffff; - - if (where & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mk_conf_addr(bus, device_fn, where, &pci_addr)) - return PCIBIOS_DEVICE_NOT_FOUND; - - *value = le32_to_cpu(*((unsigned int *)pci_addr)); - - if ((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_5)) - { - if ((*value & PCI_BASE_ADDRESS_SPACE) == - PCI_BASE_ADDRESS_SPACE_IO) - *value += pci_io_base; - else - { - if (*value == 0) - { - /* - * Base address is 0. Test if this base - * address register is used. - */ - - *((unsigned long *)pci_addr) = 0xffffffff; - if (*((unsigned long *)pci_addr) != 0) - *value += pci_mem_base; - } - else - *value += pci_mem_base; - } - } - - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_write_config_byte(unsigned char bus, unsigned char device_fn, - unsigned char where, unsigned char value) -{ - unsigned long pci_addr; - - if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) - return PCIBIOS_DEVICE_NOT_FOUND; - - *((unsigned char *)pci_addr) = value; - - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_write_config_word(unsigned char bus, unsigned char device_fn, - unsigned char where, unsigned short value) -{ - unsigned long pci_addr; - - if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) - return PCIBIOS_DEVICE_NOT_FOUND; - - *((unsigned short *)pci_addr) = cpu_to_le16(value); - - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_write_config_dword(unsigned char bus, unsigned char device_fn, - unsigned char where, unsigned int value) -{ - unsigned long pci_addr; - - if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) - return PCIBIOS_DEVICE_NOT_FOUND; - - if ((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_5)) - { - if ((value & PCI_BASE_ADDRESS_SPACE) == - PCI_BASE_ADDRESS_SPACE_IO) - value -= pci_io_base; - else - value -= pci_mem_base; - } - - *((unsigned int *)pci_addr) = cpu_to_le32(value); - - return PCIBIOS_SUCCESSFUL; -} +#define IO_ALLOC_OFFSET 0x00004000 +#define MEM_ALLOC_OFFSET 0x04000000 /* - * Macro to enable programming of the PCI devices. On the Hades this - * define should be true, because the Hades has no PCI BIOS. + * Declarations of hardware specific initialisation functions. */ -#define PCI_MODIFY 1 - -#if PCI_MODIFY +extern struct pci_bus_info *init_hades_pci(void); /* - * Leave some room for a VGA card. We assume that the VGA card is - * always in the first 32M of PCI memory. For the time being we do - * not program the VGA card, because to make this work we also - * need to change the frame buffer device. + * Bus info structure of the PCI bus. A pointer to this structure is + * put in the sysdata member of the pci_bus structure. */ -#define FIRST_IO_ADDR 0x10000 -#define FIRST_MEM_ADDR 0x02000000 +static struct pci_bus_info *bus_info; -static unsigned int io_base = FIRST_IO_ADDR; /* Skip first 64K. */ -static unsigned int mem_base = FIRST_MEM_ADDR; /* Skip first 32M. */ +static int pci_modify = 1; /* If set, layout the PCI bus ourself. */ +static int skip_vga = 0; /* If set do not modify base addresses + of vga cards.*/ +static int disable_pci_burst = 0; /* If set do not allow PCI bursts. */ + +static unsigned int io_base; +static unsigned int mem_base; + +struct pci_fixup pcibios_fixups[] = +{ + { 0 } +}; /* + * static void disable_dev(struct pci_dev *dev) + * * Disable PCI device DEV so that it does not respond to I/O or memory * accesses. + * + * Parameters: + * + * dev - device to disable. */ static void __init disable_dev(struct pci_dev *dev) @@ -245,9 +98,9 @@ struct pci_bus *bus; unsigned short cmd; - if (dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA || - dev->class >> 8 == PCI_CLASS_DISPLAY_VGA || - dev->class >> 8 == PCI_CLASS_DISPLAY_XGA) + if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) || + (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) || + (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga) return; bus = dev->bus; @@ -258,13 +111,16 @@ } /* - * Layout memory and I/O for a device: + * static void layout_dev(struct pci_dev *dev) + * + * Layout memory and I/O for a device. + * + * Parameters: + * + * device - device to layout memory and I/O for. */ -#define MAX(val1, val2) ( ((val1) > (val2)) ? val1 : val2) - -static void __init layout_dev(struct pci_dev *dev, unsigned long pci_mem_base, - unsigned long pci_io_base) +static void __init layout_dev(struct pci_dev *dev) { struct pci_bus *bus; unsigned short cmd; @@ -273,12 +129,12 @@ int i; /* - * Skip video cards for the time being. + * Skip video cards if requested. */ - if (dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA || - dev->class >> 8 == PCI_CLASS_DISPLAY_VGA || - dev->class >> 8 == PCI_CLASS_DISPLAY_XGA) + if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) || + (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) || + (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga) return; bus = dev->bus; @@ -298,7 +154,9 @@ if (!base) { /* this base-address register is unused */ - dev->base_address[i] = 0; + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; continue; } @@ -318,13 +176,21 @@ base &= PCI_BASE_ADDRESS_IO_MASK; mask = (~base << 1) | 0x1; size = (mask & base) & 0xffffffff; - /* align to multiple of size of minimum base */ - alignto = MAX(0x400, size) ; + + /* + * Align to multiple of size of minimum base. + */ + + alignto = MAX(0x040, size) ; base = ALIGN(io_base, alignto); io_base = base + size; pcibios_write_config_dword(bus->number, dev->devfn, - reg, base | 0x1); - dev->base_address[i] = (pci_io_base + base) | 1; + reg, base | PCI_BASE_ADDRESS_SPACE_IO); + + dev->resource[i].start = base; + dev->resource[i].end = dev->resource[i].start + size - 1; + dev->resource[i].flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO; + DBG_DEVS(("layout_dev: IO address: %lX\n", base)); } else @@ -343,16 +209,8 @@ switch (type) { case PCI_BASE_ADDRESS_MEM_TYPE_32: - break; - case PCI_BASE_ADDRESS_MEM_TYPE_64: - printk("bios32 WARNING: " - "ignoring 64-bit device in " - "slot %d, function %d: \n", - PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn)); - reg += 4; /* skip extra 4 bytes */ - continue; + break; case PCI_BASE_ADDRESS_MEM_TYPE_1M: printk("bios32 WARNING: slot %d, function %d " @@ -364,7 +222,7 @@ } /* - * Align to multiple of size of minimum base + * Align to multiple of size of minimum base. */ alignto = MAX(0x1000, size) ; @@ -372,7 +230,27 @@ mem_base = base + size; pcibios_write_config_dword(bus->number, dev->devfn, reg, base); - dev->base_address[i] = pci_mem_base + base; + + dev->resource[i].start = base; + dev->resource[i].end = dev->resource[i].start + size - 1; + dev->resource[i].flags = IORESOURCE_MEM; + + if (type == PCI_BASE_ADDRESS_MEM_TYPE_64) + { + /* + * 64-bit address, set the highest 32 bits + * to zero. + */ + + reg += 4; + pcibios_write_config_dword(bus->number, dev->devfn, + reg, 0); + + i++; + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; + } } } @@ -396,13 +274,30 @@ pcibios_write_config_word(bus->number, dev->devfn, PCI_COMMAND, cmd | PCI_COMMAND_MASTER); + + pcibios_write_config_byte(bus->number, dev->devfn, PCI_LATENCY_TIMER, + (disable_pci_burst) ? 0 : 32); + + if (bus_info != NULL) + bus_info->conf_device(bus->number, dev->devfn); /* Machine dependent configuration. */ + DBG_DEVS(("layout_dev: bus %d slot 0x%x VID 0x%x DID 0x%x class 0x%x\n", bus->number, PCI_SLOT(dev->devfn), dev->vendor, dev->device, dev->class)); } -static void __init layout_bus(struct pci_bus *bus, unsigned long pci_mem_base, - unsigned long pci_io_base) +/* + * static void layout_bus(struct pci_bus *bus) + * + * Layout memory and I/O for all devices on the given bus. + * + * Parameters: + * + * bus - bus. + */ + +static void __init layout_bus(struct pci_bus *bus) { + unsigned int bio, bmem; struct pci_dev *dev; DBG_DEVS(("layout_bus: starting bus %d\n", bus->number)); @@ -415,22 +310,25 @@ * IO and 1MB for memory). */ - io_base = ALIGN(io_base, 4*KB); - mem_base = ALIGN(mem_base, 1*MB); + bio = io_base = ALIGN(io_base, 4*KB); + bmem = mem_base = ALIGN(mem_base, 1*MB); /* * PCI devices might have been setup by a PCI BIOS emulation * running under TOS. In these cases there is a * window during which two devices may have an overlapping - * address range. To avoid this causing trouble, we first + * address range. To avoid this causing trouble, we first * turn off the I/O and memory address decoders for all PCI * devices. They'll be re-enabled only once all address * decoders are programmed consistently. */ + DBG_DEVS(("layout_bus: disable_dev for bus %d\n", bus->number)); + for (dev = bus->devices; dev; dev = dev->sibling) { - if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) + if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) || + (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)) disable_dev(dev); } @@ -442,94 +340,193 @@ for (dev = bus->devices; dev; dev = dev->sibling) { - if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) - layout_dev(dev, pci_mem_base, pci_io_base); + if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) || + (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)) + layout_dev(dev); } + + DBG_DEVS(("layout_bus: bus %d finished\n", bus->number)); } -#endif /* !PCI_MODIFY */ +/* + * static void pcibios_fixup(void) + * + * Layout memory and I/O of all devices on the PCI bus if 'pci_modify' is + * true. This might be necessary because not every m68k machine with a PCI + * bus has a PCI BIOS. This function should be called right after + * pci_scan_bus() in pcibios_init(). + */ -void __init pcibios_init(void) +static void __init pcibios_fixup(void) { - printk("Linux/m68k PCI BIOS32 revision %x.%02x\n", MAJOR_REV, MINOR_REV); + if (pci_modify) + { + /* + * Set base addresses for allocation of I/O and memory space. + */ -#if !PCI_MODIFY - printk("...NOT modifying existing PCI configuration\n"); -#endif + io_base = bus_info->io_space.start + IO_ALLOC_OFFSET; + mem_base = bus_info->mem_space.start + MEM_ALLOC_OFFSET; - pci_mem_base = 0x80000000; - pci_io_base = 0xB0000000; + /* + * Scan the tree, allocating PCI memory and I/O space. + */ + + layout_bus(pci_bus_b(pci_root.next)); + } + + /* + * Fix interrupt assignments, etc. + */ + + bus_info->fixup(pci_modify); } /* - * static inline void hades_fixup(void) + * static void pcibios_claim_resources(struct pci_bus *bus) + * + * Claim all resources that are assigned to devices on the given bus. * - * Assign IRQ numbers as used by Linux to the interrupt pins - * of the PCI cards. + * Parameters: + * + * bus - bus. */ -static inline void __init hades_fixup(void) +static void __init pcibios_claim_resources(struct pci_bus *bus) { - char irq_tab[4] = { - IRQ_TT_MFP_IO0, /* Slot 0. */ - IRQ_TT_MFP_IO1, /* Slot 1. */ - IRQ_TT_MFP_SCC, /* Slot 2. */ - IRQ_TT_MFP_SCSIDMA /* Slot 3. */ - }; struct pci_dev *dev; - unsigned char slot; - - /* - * Go through all devices, fixing up irqs as we see fit: - */ + int i; - for (dev = pci_devices; dev; dev = dev->next) + while (bus) { - if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) + for (dev = bus->devices; (dev != NULL); dev = dev->sibling) { - slot = PCI_SLOT(dev->devfn); /* Determine slot number. */ - dev->irq = irq_tab[slot]; -#if PCI_MODIFY - pcibios_write_config_byte(dev->bus->number, dev->devfn, - PCI_INTERRUPT_LINE, dev->irq); + for (i = 0; i < PCI_NUM_RESOURCES; i++) + { + struct resource *r = &dev->resource[i]; + struct resource *pr; + struct pci_bus_info *bus_info = (struct pci_bus_info *) dev->sysdata; + + if ((r->start == 0) || (r->parent != NULL)) + continue; +#if 1 + if (r->flags & IORESOURCE_IO) + pr = &bus_info->io_space; + else + pr = &bus_info->mem_space; +#else + if (r->flags & IORESOURCE_IO) + pr = &ioport_resource; + else + pr = &iomem_resource; #endif + if (request_resource(pr, r) < 0) + { + printk(KERN_ERR "PCI: Address space collision on region %d of device %s\n", i, dev->name); + } + } } + + if (bus->children) + pcibios_claim_resources(bus->children); + + bus = bus->next; } } -void __init pcibios_fixup(void) +/* + * int pcibios_assign_resource(struct pci_dev *dev, int i) + * + * Assign a new address to a PCI resource. + * + * Parameters: + * + * dev - device. + * i - resource. + * + * Result: 0 if successfull. + */ + +int __init pcibios_assign_resource(struct pci_dev *dev, int i) { -#if PCI_MODIFY - unsigned long orig_mem_base, orig_io_base; + struct resource *r = &dev->resource[i]; + struct resource *pr = pci_find_parent_resource(dev, r); + unsigned long size = r->end + 1; - orig_mem_base = pci_mem_base; - orig_io_base = pci_io_base; - pci_mem_base = 0; - pci_io_base = 0; + if (!pr) + return -EINVAL; - /* - * Scan the tree, allocating PCI memory and I/O space. - */ + if (r->flags & IORESOURCE_IO) + { + if (size > 0x100) + return -EFBIG; - layout_bus(pci_bus_b(pci_root.next), orig_mem_base, orig_io_base); + if (allocate_resource(pr, r, size, bus_info->io_space.start + + IO_ALLOC_OFFSET, bus_info->io_space.end, 1024)) + return -EBUSY; + } + else + { + if (allocate_resource(pr, r, size, bus_info->mem_space.start + + MEM_ALLOC_OFFSET, bus_info->mem_space.end, size)) + return -EBUSY; + } - pci_mem_base = orig_mem_base; - pci_io_base = orig_io_base; -#endif + if (i < 6) + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, r->start); - /* - * Now is the time to do all those dirty little deeds... - */ - - hades_fixup(); + return 0; } void __init pcibios_fixup_bus(struct pci_bus *bus) { + struct pci_dev *dev; + void *sysdata; + + sysdata = (bus->parent) ? bus->parent->sysdata : bus->sysdata; + + for (dev = bus->devices; (dev != NULL); dev = dev->sibling) + dev->sysdata = sysdata; +} + +void __init pcibios_init(void) +{ + printk("Linux/m68k PCI BIOS32 revision %x.%02x\n", MAJOR_REV, MINOR_REV); + + bus_info = NULL; +#ifdef CONFIG_HADES + if (MACH_IS_HADES) + bus_info = init_hades_pci(); +#endif + if (bus_info != NULL) + { + printk("PCI: Probing PCI hardware\n"); + pci_scan_bus(0, bus_info->m68k_pci_ops, bus_info); + pcibios_fixup(); + pcibios_claim_resources(pci_root); + } + else + printk("PCI: No PCI bus detected\n"); } char * __init pcibios_setup(char *str) { + if (!strcmp(str, "nomodify")) + { + pci_modify = 0; + return NULL; + } + else if (!strcmp(str, "skipvga")) + { + skip_vga = 1; + return NULL; + } + else if (!strcmp(str, "noburst")) + { + disable_pci_burst = 1; + return NULL; + } + return str; } #endif /* CONFIG_PCI */ diff -ur --new-file old/linux/arch/m68k/kernel/entry.S new/linux/arch/m68k/kernel/entry.S --- old/linux/arch/m68k/kernel/entry.S Tue Jan 11 03:15:58 2000 +++ new/linux/arch/m68k/kernel/entry.S Wed Jan 26 21:44:20 2000 @@ -83,18 +83,22 @@ jra SYMBOL_NAME(ret_from_exception) badsys: - movel #-ENOSYS,PT_D0(%sp) + movel #-ENOSYS,%sp@(PT_D0) jra SYMBOL_NAME(ret_from_exception) do_trace: - movel #-ENOSYS,PT_D0(%sp) | needed for strace + movel #-ENOSYS,%sp@(PT_D0) | needed for strace subql #4,%sp SAVE_SWITCH_STACK jbsr SYMBOL_NAME(syscall_trace) RESTORE_SWITCH_STACK addql #4,%sp - jbsr @(SYMBOL_NAME(sys_call_table),%d2:l:4)@(0) - movel %d0,%sp@(PT_D0) | save the return value + movel %sp@(PT_ORIG_D0),%d1 + movel #-ENOSYS,%d0 + cmpl #NR_syscalls,%d1 + jcc 1f + jbsr @(SYMBOL_NAME(sys_call_table),%d1:l:4)@(0) +1: movel %d0,%sp@(PT_D0) | save the return value subql #4,%sp | dummy return address SAVE_SWITCH_STACK jbsr SYMBOL_NAME(syscall_trace) @@ -106,17 +110,16 @@ ENTRY(system_call) SAVE_ALL_SYS - movel %d0,%d2 - GET_CURRENT(%d0) + GET_CURRENT(%d1) | save top of frame movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) - cmpl #NR_syscalls,%d2 - jcc badsys btst #PF_TRACESYS_BIT,%curptr@(TASK_FLAGS+PF_TRACESYS_OFF) jne do_trace - jbsr @(SYMBOL_NAME(sys_call_table),%d2:l:4)@(0) + cmpl #NR_syscalls,%d0 + jcc badsys + jbsr @(SYMBOL_NAME(sys_call_table),%d0:l:4)@(0) movel %d0,%sp@(PT_D0) | save the return value SYMBOL_NAME_LABEL(ret_from_exception) @@ -604,24 +607,27 @@ .long SYMBOL_NAME(sys_mmap2) .long SYMBOL_NAME(sys_truncate64) .long SYMBOL_NAME(sys_ftruncate64) - .long SYMBOL_NAME(sys_chown) /* 195 */ + .long SYMBOL_NAME(sys_stat64) /* 195 */ + .long SYMBOL_NAME(sys_lstat64) + .long SYMBOL_NAME(sys_fstat64) + .long SYMBOL_NAME(sys_chown) .long SYMBOL_NAME(sys_getuid) - .long SYMBOL_NAME(sys_getgid) + .long SYMBOL_NAME(sys_getgid) /* 200 */ .long SYMBOL_NAME(sys_geteuid) .long SYMBOL_NAME(sys_getegid) - .long SYMBOL_NAME(sys_setreuid) /* 200 */ + .long SYMBOL_NAME(sys_setreuid) .long SYMBOL_NAME(sys_setregid) - .long SYMBOL_NAME(sys_getgroups) + .long SYMBOL_NAME(sys_getgroups) /* 205 */ .long SYMBOL_NAME(sys_setgroups) .long SYMBOL_NAME(sys_fchown) - .long SYMBOL_NAME(sys_setresuid) /* 205 */ + .long SYMBOL_NAME(sys_setresuid) .long SYMBOL_NAME(sys_getresuid) - .long SYMBOL_NAME(sys_setresgid) + .long SYMBOL_NAME(sys_setresgid) /* 210 */ .long SYMBOL_NAME(sys_getresgid) .long SYMBOL_NAME(sys_lchown) - .long SYMBOL_NAME(sys_setuid) /* 210 */ + .long SYMBOL_NAME(sys_setuid) .long SYMBOL_NAME(sys_setgid) - .long SYMBOL_NAME(sys_setfsuid) + .long SYMBOL_NAME(sys_setfsuid) /* 215 */ .long SYMBOL_NAME(sys_setfsgid) .rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4 diff -ur --new-file old/linux/arch/m68k/kernel/head.S new/linux/arch/m68k/kernel/head.S --- old/linux/arch/m68k/kernel/head.S Sun Aug 15 20:47:29 1999 +++ new/linux/arch/m68k/kernel/head.S Wed Jan 26 21:44:20 2000 @@ -259,7 +259,9 @@ #include #include #include +#include #include +#include #include "m68k_defs.h" #ifdef CONFIG_MAC @@ -305,7 +307,7 @@ .globl SYMBOL_NAME(m68k_pgtable_cachemode) .globl SYMBOL_NAME(m68k_supervisor_cachemode) #ifdef CONFIG_MVME16x -.globl SYMBOL_NAME(mvme_bdid_ptr) +.globl SYMBOL_NAME(mvme_bdid) #endif #ifdef CONFIG_Q40 .globl SYMBOL_NAME(q40_mem_cptr) @@ -386,6 +388,12 @@ #endif #endif +/* The __INITDATA stuff is a no-op when ftrace or kgdb are turned on */ +#ifndef __INITDATA +#define __INITDATA .data +#define __FINIT .previous +#endif + /* Several macros to make the writing of subroutines easier: * - func_start marks the beginning of the routine which setups the frame * register and saves the registers, it also defines another macro @@ -503,18 +511,10 @@ .macro puts string #if defined(CONSOLE) || defined(SERIAL_DEBUG) -/* The __INITDATA stuff is a no-op when ftrace or kgdb are turned on */ -#if defined(CONFIG_FTRACE) || defined(CONFIG_KGDB) - bra 1f -#endif __INITDATA .Lstr\@: .string "\string" __FINIT -#if defined(CONFIG_FTRACE) || defined(CONFIG_KGDB) - .align 2 -1: -#endif pea %pc@(.Lstr\@) func_call puts addql #4,%sp @@ -533,10 +533,20 @@ #define is_not_mvme147(lab) cmpl &MACH_MVME147,%pc@(m68k_machtype); jne lab #define is_not_mvme16x(lab) cmpl &MACH_MVME16x,%pc@(m68k_machtype); jne lab #define is_not_bvme6000(lab) cmpl &MACH_BVME6000,%pc@(m68k_machtype); jne lab +#define is_mvme147(lab) cmpl &MACH_MVME147,%pc@(m68k_machtype); jeq lab +#define is_mvme16x(lab) cmpl &MACH_MVME16x,%pc@(m68k_machtype); jeq lab +#define is_bvme6000(lab) cmpl &MACH_BVME6000,%pc@(m68k_machtype); jeq lab #define is_not_hp300(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); jne lab +#define is_not_apollo(lab) cmpl &MACH_APOLLO,%pc@(m68k_machtype); jne lab #define is_not_q40(lab) cmpl &MACH_Q40,%pc@(m68k_machtype); jne lab #define is_not_sun3x(lab) cmpl &MACH_SUN3X,%pc@(m68k_machtype); jne lab +#define hasnt_leds(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); \ + jeq 42f; \ + cmpl &MACH_APOLLO,%pc@(m68k_machtype); \ + jne lab ;\ + 42:\ + #define is_040_or_060(lab) btst &CPUTYPE_0460,%pc@(L(cputype)+3); jne lab #define is_not_040_or_060(lab) btst &CPUTYPE_0460,%pc@(L(cputype)+3); jeq lab #define is_040(lab) btst &CPUTYPE_040,%pc@(L(cputype)+3); jne lab @@ -549,8 +559,8 @@ the console is running. Writing a 1 bit turns the corresponding LED _off_ - on the 340 bit 7 is towards the back panel of the machine. */ .macro leds mask -#ifdef CONFIG_HP300 - is_not_hp300(.Lled\@) +#if defined(CONFIG_HP300) || defined(CONFIG_APOLLO) + hasnt_leds(.Lled\@) pea \mask func_call set_leds addql #4,%sp @@ -809,6 +819,57 @@ L(notypetest): #endif +#ifdef CONFIG_VME + is_mvme147(L(getvmetype)) + is_bvme6000(L(getvmetype)) + is_not_mvme16x(L(gvtdone)) + + /* See if the loader has specified the BI_VME_TYPE tag. Recent + * versions of VMELILO and TFTPLILO do this. We have to do this + * early so we know how to handle console output. If the tag + * doesn't exist then we use the Bug for output on MVME16x. + */ +L(getvmetype): + get_bi_record BI_VME_TYPE + tstl %d0 + jbmi 1f + movel %a0@,%d3 + lea %pc@(SYMBOL_NAME(vme_brdtype)),%a0 + movel %d3,%a0@ +1: +#ifdef CONFIG_MVME16x + is_not_mvme16x(L(gvtdone)) + + /* Need to get the BRD_ID info to diferentiate between 162, 167, + * etc. This is available as a BI_VME_BRDINFO tag with later + * versions of VMELILO and TFTPLILO, otherwise we call the Bug. + */ + get_bi_record BI_VME_BRDINFO + tstl %d0 + jpl 1f + + /* Get pointer to board ID data from Bug */ + movel %d2,%sp@- + trap #15 + .word 0x70 /* trap 0x70 - .BRD_ID */ + movel %sp@+,%a0 +1: + lea %pc@(SYMBOL_NAME(mvme_bdid)),%a1 + /* Structure is 32 bytes long */ + movel %a0@+,%a1@+ + movel %a0@+,%a1@+ + movel %a0@+,%a1@+ + movel %a0@+,%a1@+ + movel %a0@+,%a1@+ + movel %a0@+,%a1@+ + movel %a0@+,%a1@+ + movel %a0@+,%a1@+ +#endif + +L(gvtdone): + +#endif + /* * Initialize serial port */ @@ -843,6 +904,7 @@ lea %pc@(L(phys_kernel_start)),%a0 lea %pc@(SYMBOL_NAME(_stext)),%a1 subl #SYMBOL_NAME(_stext),%a1 + addl #PAGE_OFFSET,%a1 movel %a1,%a0@ putc 'B' @@ -857,7 +919,7 @@ * First map the first 4 MB of kernel code & data */ - mmu_map #0,%pc@(L(phys_kernel_start)),#4*1024*1024,\ + mmu_map #PAGE_OFFSET,%pc@(L(phys_kernel_start)),#4*1024*1024,\ %pc@(SYMBOL_NAME(m68k_supervisor_cachemode)) putc 'C' @@ -1006,14 +1068,6 @@ is_not_mvme16x(L(not16x)) - /* Get pointer to board ID data */ - movel %d2,%sp@- - trap #15 - .word 0x70 /* trap 0x70 - .BRD_ID */ - movel %sp@+,%d2 - lea %pc@(SYMBOL_NAME(mvme_bdid_ptr)),%a0 - movel %d2,%a0@ - /* * On MVME16x we have already created kernel page tables for * 4MB of RAM at address 0, so now need to do a transparent @@ -1126,8 +1180,18 @@ /* setup tt1 for I/O */ mmu_map_tt #1,#0x40000000,#0x40000000,#_PAGE_NOCACHE_S + jbra L(mmu_init_done) L(notsun3x): +#endif + +#ifdef CONFIG_APOLLO + is_not_apollo(L(notapollo)) + + putc 'P' + mmu_map #0x80000000,#0,#0x02000000,#_PAGE_NOCACHE030 + +L(notapollo): jbra L(mmu_init_done) #endif @@ -1161,6 +1225,7 @@ * contains also kernel_pg_dir. */ movel %pc@(L(phys_kernel_start)),%d0 + subl #PAGE_OFFSET,%d0 lea %pc@(SYMBOL_NAME(_stext)),%a0 subl %d0,%a0 mmu_fixup_page_mmu_cache %a0 @@ -1249,6 +1314,14 @@ mmu_engage +/* + * After this point no new memory is allocated and + * the start of available memory is stored in availmem. + * (The bootmem allocator requires now the physicall address.) + */ + + movel L(memory_start),availmem + #ifdef CONFIG_AMIGA is_not_amiga(1f) /* fixup the Amiga custom register location before printing */ @@ -1294,20 +1367,19 @@ 1: #endif -/* - * Fixup the addresses for the kernel pointer table and availmem. - * Convert them from physical addresses to virtual addresses. - */ +#ifdef CONFIG_APOLLO + is_not_apollo(1f) + /* + * Fix up the iobase before printing + */ + movel #0x80000000,L(iobase) +1: +#endif + putc 'I' leds 0x10 - /* do the same conversion on the first available memory - * address (in a6). - */ - movel L(memory_start),%d0 - movel %d0,SYMBOL_NAME(availmem) - /* * Enable caches */ @@ -1352,14 +1424,23 @@ /* * Setup initial stack pointer */ - lea SYMBOL_NAME(init_task_union),%a2 - lea 0x2000(%a2),%sp + lea SYMBOL_NAME(init_task_union),%curptr + lea 0x2000(%curptr),%sp + + putc 'K' + + subl %a6,%a6 /* clear a6 for gdb */ + +/* + * The new 64bit printf support requires an early exception initialization. + */ + jbsr SYMBOL_NAME(base_trap_init) /* jump to the kernel start */ + putc '\n' leds 0x55 - subl %a6,%a6 /* clear a6 for gdb */ jbsr SYMBOL_NAME(start_kernel) /* @@ -2355,12 +2436,12 @@ .chip 68k L(mmu_engage_cleanup): + subl #PAGE_OFFSET,%d2 subl %d2,%a2 movel %a2,L(kernel_pgdir_ptr) subl %d2,%fp subl %d2,%sp subl %d2,ARG0 - subl %d2,L(memory_start) func_return mmu_engage @@ -2810,6 +2891,10 @@ 2: #endif +#ifdef CONFIG_APOLLO +/* We count on the PROM initializing SIO1 */ +#endif + L(serial_init_done): func_return serial_init @@ -2911,13 +2996,54 @@ #ifdef CONFIG_MVME16x is_not_mvme16x(2f) /* - * The VME 16x class has PROM support for serial output - * of some kind; the TRAP table is still valid. + * If the loader gave us a board type then we can use that to + * select an appropriate output routine; otherwise we just use + * the Bug code. If we haev to use the Bug that means the Bug + * workspace has to be valid, which means the Bug has to use + * the SRAM, which is non-standard. */ moveml %d0-%d7/%a2-%a6,%sp@- + movel SYMBOL_NAME(vme_brdtype),%d1 + jeq 1f | No tag - use the Bug + cmpi #VME_TYPE_MVME162,%d1 + jeq 6f + cmpi #VME_TYPE_MVME172,%d1 + jne 5f + /* 162/172; it's an SCC */ +6: btst #2,M162_SCC_CTRL_A + nop + nop + nop + jeq 6b + moveb #8,M162_SCC_CTRL_A + nop + nop + nop + moveb %d0,M162_SCC_CTRL_A + jra 3f +5: + /* 166/167/177; its a CD2401 */ + moveb #0,M167_CYCAR + moveb M167_CYIER,%d2 + moveb #0x02,M167_CYIER +7: + btst #5,M167_PCSCCTICR + jeq 7b + moveb M167_PCTPIACKR,%d1 + moveb M167_CYLICR,%d1 + jeq 8f + moveb #0x08,M167_CYTEOIR + jra 7b +8: + moveb %d0,M167_CYTDR + moveb #0,M167_CYTEOIR + moveb %d2,M167_CYIER + jra 3f +1: moveb %d0,%sp@- trap #15 .word 0x0020 /* TRAP 0x020 */ +3: moveml %sp@+,%d0-%d7/%a2-%a6 jbra L(serial_putc_done) 2: @@ -2944,9 +3070,20 @@ move.b %d0,%a0@ addq.l #4,%a0 move.l %a0,%a1@ + jbra L(serial_putc_done) 2: #endif +#ifdef CONFIG_APOLLO + is_not_apollo(2f) + movl %pc@(L(iobase)),%a1 + moveb %d0,%a1@(LTHRB0) +1: moveb %a1@(LSRB0),%d0 + andb #0x4,%d0 + beq 1b +2: +#endif + L(serial_putc_done): func_return serial_putc @@ -3029,11 +3166,23 @@ rts #endif /* CONFIG_MAC */ -#ifdef CONFIG_HP300 +#if defined(CONFIG_HP300) || defined(CONFIG_APOLLO) func_start set_leds,%d0/%a0 movel ARG1,%d0 - movel %pc@(Lcustom),%a0 +#ifdef CONFIG_HP300 + is_not_hp300(1f) + movel %pc@(L(custom)),%a0 moveb %d0,%a0@(0x1ffff) + jra 2f +#endif +1: +#ifdef CONFIG_APOLLO + movel %pc@(L(iobase)),%a0 + lsll #8,%d0 + eorw #0xff00,%d0 + moveb %d0,%a0@(LCPUCTRL) +#endif +2: func_return set_leds #endif @@ -3605,6 +3754,17 @@ M147_SCC_DATA_A = 0xfffe3003 #endif +#if defined (CONFIG_MVME16x) +M162_SCC_CTRL_A = 0xfff45005 +M167_CYCAR = 0xfff450ee +M167_CYIER = 0xfff45011 +M167_CYLICR = 0xfff45026 +M167_CYTEOIR = 0xfff45085 +M167_CYTDR = 0xfff450f8 +M167_PCSCCTICR = 0xfff4201e +M167_PCTPIACKR = 0xfff42025 +#endif + #if defined (CONFIG_BVME6000) BVME_SCC_CTRL_A = 0xffb0000b BVME_SCC_DATA_A = 0xffb0000f @@ -3627,6 +3787,14 @@ #endif /* MAC_SERIAL_DEBUG */ #endif +#if defined (CONFIG_APOLLO) +LSRB0 = 0x10412 +LTHRB0 = 0x10416 +LCPUCTRL = 0x10100 +L(iobase): + .long 0 +#endif + __FINIT .data .align 4 @@ -3638,8 +3806,8 @@ SYMBOL_NAME_LABEL(m68k_supervisor_cachemode) .long 0 #if defined(CONFIG_MVME16x) -SYMBOL_NAME_LABEL(mvme_bdid_ptr) - .long 0 +SYMBOL_NAME_LABEL(mvme_bdid) + .long 0,0,0,0,0,0,0,0 #endif #if defined(CONFIG_Q40) SYMBOL_NAME_LABEL(q40_mem_cptr) diff -ur --new-file old/linux/arch/m68k/kernel/kgdb.c new/linux/arch/m68k/kernel/kgdb.c --- old/linux/arch/m68k/kernel/kgdb.c Sat Sep 4 22:06:41 1999 +++ new/linux/arch/m68k/kernel/kgdb.c Thu Jan 1 01:00:00 1970 @@ -1,1362 +0,0 @@ -/* - * arch/m68k/kernel/kgdb.c -- Stub for GDB remote debugging protocol - * - * Originally written by Glenn Engel, Lake Stevens Instrument Division - * - * Contributed by HP Systems - * - * Modified for SPARC by Stu Grossman, Cygnus Support. - * Modified for Linux/MIPS (and MIPS in general) by Andreas Busse - * Modified and extended for Linux/68k by Roman Hodek - * - * Send complaints, suggestions etc. to - * - * - * Copyright (C) 1996-97 Roman Hodek - */ - -/* - * kgdb usage notes: - * ----------------- - * - * If you select CONFIG_KGDB in the configuration, the kernel will be built - * with different gccc flags: "-g" is added to get debug infos, and - * "-fomit-frame-pointer" is omitted to make debugging easier. Since the - * resulting kernel will be quite big (approx. > 7 MB), it will be stripped - * before compresion. Such a kernel will behave just as usually, except if - * given a "debug=" command line option. (Only serial devices are - * allowed for , i.e. no printers or the like; possible values are - * machine depedend and are the same as for the usual debug device, the one - * for logging kernel messages.) If that option is given and the device can be - * initialized, the kernel will connect to the remote gdb in trap_init(). The - * serial parameters are fixed to 8N1 and 9600bps, for easyness of - * implementation. - * - * Of course, you need a remote machine a suitable gdb there. I.e., it must - * have support for a m68k-linux target built in. If the remote machine - * doesn't run Linux/68k itself, you have to build a cross gdb. This is done - * by - * ./configure --target=m68k-linux - * in the gdb source directory. Until gdb comes with m68k-linux support by - * default, you have to apply some patches before. The remote debugging - * protocol itself is always built into gdb anyway, so you don't have to take - * special care about it. - * - * To start a debugging session, start that gdb with the debugging kernel - * image (the one with the symbols, vmlinux.debug) named on the command line. - * This file will be used by gdb to get symbol and debugging infos about the - * kernel. Next, select remote debug mode by - * target remote - * where is the name of the serial device over which the debugged - * machine is connected. Maybe you have to adjust the baud rate by - * set remotebaud - * or also other parameters with stty: - * shell stty ... #. - * - * where - * :: - * :: < two hex digits computed as modulo 256 sum of > - * - * When a packet is received, it is first acknowledged with either '+' or '-'. - * '+' indicates a successful transfer. '-' indicates a failed transfer. - * - * Example: - * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#ifdef CONFIG_ATARI -#include -#include -#endif -#ifdef CONFIG_AMIGA -#include -#include -#endif -#ifdef CONFIG_MAC -#include -#include -#include -#endif - - -#undef DEBUG - -/* - * global variable: register structure - */ - -struct gdb_regs kgdb_registers; - -/* - * serial i/o functions - */ - -static int (*serial_out)( unsigned char c ); -static unsigned char (*serial_in)( void ); -static unsigned char (*serial_intr)( void ); - -#define putDebugChar(c) serial_out(c) -#define getDebugChar() serial_in() - - -/***************************** Prototypes *****************************/ - -static int hex( unsigned char ch); -static void getpacket( char *buffer); -static void putpacket( char *buffer, int expect_ack); -static inline unsigned long *get_vbr( void ); -static int protected_read( char *p, unsigned long *vbr ); -static int protected_write( char *p, char val, unsigned long *vbr ); -static unsigned char *mem2hex( char *mem, char *buf, int count, int - may_fault); -static char *hex2mem( char *buf, char *mem, int count, int may_fault); -static int computeSignal( int tt); -static int hexToInt( char **ptr, int *intValue); -extern asmlinkage void kgdb_intr( int intno, void *data, struct pt_regs *fp ); -static asmlinkage void handle_exception( void ); -static void show_gdbregs( void ); -#ifdef CONFIG_ATARI -static int atari_mfp_out( unsigned char c ); -static unsigned char atari_mfp_in( void ); -static unsigned char atari_mfp_intr( void ); -static int atari_scc_out( unsigned char c ); -static unsigned char atari_scc_in( void ); -static unsigned char atari_scc_intr( void ); -#endif -#ifdef CONFIG_AMIGA -extern int amiga_ser_out( unsigned char c ); -extern unsigned char amiga_ser_in( void ); -#endif -#ifdef CONFIG_MAC -static unsigned char mac_scca_in( void ); -static unsigned char mac_scca_out( unsigned char c ); -static unsigned char mac_scca_intr( void ); -static unsigned char mac_sccb_in( void ); -static unsigned char mac_sccb_out( unsigned char c); -static unsigned char mac_sccb_intr( void ); -extern void mac_init_scc_port( int cflag, int port ); -#endif - -/************************* End of Prototypes **************************/ - - -int kgdb_initialized = 0; /* !0 means we've been initialized */ - -/* - * BUFMAX defines the maximum number of characters in inbound/outbound buffers - * at least NUMREGBYTES*2 are needed for register packets - */ -#define BUFMAX 2048 - -static char input_buffer[BUFMAX]; -static char output_buffer[BUFMAX]; -static const char hexchars[]="0123456789abcdef"; -/* debug > 0 prints ill-formed commands in valid packets & checksum errors */ -static int remote_debug = 0; - -/* sizes (in bytes) of CPU stack frames */ -static int frame_sizes[16] = { - 8, 8, 12, 12, /* $0..$3 */ - 16, 8, 8, 60, /* $4..$7 */ - 8, 20, 32, 92, /* $8..$B */ - 12, 4, 4, 4 /* $C..$F */ -}; - -/* - * Convert ch from a hex digit to an int - */ -static int hex(unsigned char ch) -{ - if (ch >= 'a' && ch <= 'f') - return ch-'a'+10; - if (ch >= '0' && ch <= '9') - return ch-'0'; - if (ch >= 'A' && ch <= 'F') - return ch-'A'+10; - return -1; -} - -/* - * scan for the sequence $# - */ -static void getpacket(char *buffer) -{ - unsigned char checksum; - unsigned char xmitcsum; - int i; - int count; - unsigned char ch; - - do { - /* - * wait around for the start character, - * ignore all other characters - */ - while ((ch = (getDebugChar() & 0x7f)) != '$') ; - - checksum = 0; - xmitcsum = -1; - count = 0; - - /* - * now, read until a # or end of buffer is found - */ - while (count < BUFMAX) { - ch = getDebugChar() & 0x7f; - if (ch == '#') - break; - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - - if (count >= BUFMAX) - continue; - - buffer[count] = 0; -#ifdef DEBUG - printk( "kgdb: received packet %s\n", buffer ); -#endif - - if (ch == '#') { - xmitcsum = hex(getDebugChar() & 0x7f) << 4; - xmitcsum |= hex(getDebugChar() & 0x7f); - - if (checksum != xmitcsum) { - if (remote_debug) - printk( "kgdb: bad checksum. count = 0x%x sent=0x%x " - "buf=%s\n", checksum, xmitcsum, buffer ); - putDebugChar('-'); /* failed checksum */ - } - else { - putDebugChar('+'); /* successful transfer */ - - /* - * if a sequence char is present, - * reply the sequence ID - */ - if (buffer[2] == ':') { - putDebugChar(buffer[0]); - putDebugChar(buffer[1]); - - /* - * remove sequence chars from buffer - */ - count = strlen(buffer); - for (i=3; i <= count; i++) - buffer[i-3] = buffer[i]; - } - } - } - } - while (checksum != xmitcsum); -} - -/* - * send the packet in buffer. - */ -static void putpacket(char *buffer, int expect_ack) -{ - unsigned char checksum; - int count; - unsigned char ch; - - /* - * $#. - */ - -#ifdef DEBUG - printk( "kgdb: sending packet %s\n", buffer ); -#endif - do { - putDebugChar('$'); - checksum = 0; - count = 0; - - while ((ch = buffer[count]) != 0) { - if (!(putDebugChar(ch))) - return; - checksum += ch; - count += 1; - } - - putDebugChar('#'); - putDebugChar(hexchars[checksum >> 4]); - putDebugChar(hexchars[checksum & 0xf]); - - } - while (expect_ack && (getDebugChar() & 0x7f) != '+'); -} - - -static inline unsigned long *get_vbr( void ) - -{ unsigned long *vbr; - - __asm__ __volatile__ ( "movec %/vbr,%0" : "=d" (vbr) : ); - return( vbr ); -} - -static int protected_read( char *p, unsigned long *vbr ) - -{ unsigned char val; - int rv; - - __asm__ __volatile__ - ( "movel %3@(8),%/a0\n\t" - "movel #Lberr1,%3@(8)\n\t" - "movel %/sp,%/a1\n\t" - "moveq #1,%1\n\t" - "moveb %2@,%0\n" - "nop \n\t" - "moveq #0,%1\n\t" - "Lberr1:\t" - "movel %/a1,%/sp\n\t" - "movel %/a0,%3@(8)" - : "=&d" (val), "=&r" (rv) - : "a" (p), "a" (vbr) - : "a0", "a1" ); - - return( rv ? -1 : val ); -} - -static int protected_write( char *p, char val, unsigned long *vbr ) - -{ int rv; - - __asm__ __volatile__ - ( "movel %3@(8),%/a0\n\t" - "movel #Lberr2,%3@(8)\n\t" - "movel %/sp,%/a1\n\t" - "moveq #1,%0\n\t" - "moveb %2,%1@\n" - "nop \n\t" - "moveq #0,%0\n\t" - "Lberr2:\t" - "movel %/a1,%/sp\n\t" - "movel %/a0,%3@(8)" - : "=&r" (rv) - : "a" (p), "d" (val), "a" (vbr) - : "a0", "a1" ); - - return( rv ); -} - -/* - * Convert the memory pointed to by mem into hex, placing result in buf. - * Return a pointer to the last char put in buf (null), in case of mem fault, - * return 0. - * If MAY_FAULT is non-zero, then we will handle memory faults by returning - * a 0, else treat a fault like any other fault in the stub. - */ -static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault) -{ - int ch; - unsigned long *vbr = get_vbr(); - - for( ; count-- > 0; ++mem ) { - if ((ch = protected_read( mem, vbr )) < 0) { - /* bus error happened */ - if (may_fault) - return 0; - else { - /* ignore, but print a warning */ - printk( "Bus error on read from %p\n", mem ); - ch = 0; - } - } - *buf++ = hexchars[(ch >> 4) & 0xf]; - *buf++ = hexchars[ch & 0xf]; - } - - *buf = 0; - - return buf; -} - -/* - * convert the hex array pointed to by buf into binary to be placed in mem - * return a pointer to the character AFTER the last byte written - */ -static char *hex2mem(char *buf, char *mem, int count, int may_fault) -{ - int i; - unsigned char ch; - unsigned long *vbr = get_vbr(); - - for( i = 0; i < count; i++, mem++ ) { - ch = hex(*buf++) << 4; - ch |= hex(*buf++); - if (protected_write( mem, ch, vbr )) { - /* bus error happened */ - if (may_fault) - return 0; - else - /* ignore, but print a warning */ - printk( "Bus error on write to %p\n", mem ); - } - } - - return mem; -} - -/* - * This table contains the mapping between SPARC hardware trap types, and - * signals, which are primarily what GDB understands. It also indicates - * which hardware traps we need to commandeer when initializing the stub. - */ -static struct hard_trap_info -{ - unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */ - unsigned char signo; /* Signal that we map this trap into */ -} hard_trap_info[] = { - { 1, SIGINT }, /* excep. 1 is used to fake SIGINT */ - { VEC_BUSERR, SIGSEGV }, /* bus/access error */ - { VEC_ADDRERR, SIGBUS }, /* address error */ - { VEC_ILLEGAL, SIGILL }, /* illegal insn */ - { VEC_ZERODIV, SIGFPE }, /* (integer) divison by zero */ - { VEC_CHK, SIGILL }, /* CHK insn */ - { VEC_TRAP, SIGFPE }, /* [F]TRAPcc insn */ - { VEC_PRIV, SIGILL }, /* priviledge violation (cannot happen) */ - { VEC_TRACE, SIGTRAP }, /* trace trap (single-stepping) */ - { VEC_LINE10, SIGILL }, /* A-line insn */ - { VEC_LINE11, SIGILL }, /* F-line insn */ - { VEC_COPROC, SIGIOT }, /* coprocessor protocol error */ - { VEC_FORMAT, SIGIOT }, /* frame format error */ - { VEC_UNINT, SIGIOT }, /* uninitialized intr. (should not happen) */ - { VEC_SYS, SIGILL }, /* TRAP #0 = system call (illegal in kernel) */ - { VEC_TRAP1, SIGILL }, /* TRAP #1 */ - { VEC_TRAP2, SIGILL }, /* TRAP #2 */ - { VEC_TRAP3, SIGILL }, /* TRAP #3 */ - { VEC_TRAP4, SIGILL }, /* TRAP #4 */ - { VEC_TRAP5, SIGILL }, /* TRAP #5 */ - { VEC_TRAP6, SIGILL }, /* TRAP #6 */ - { VEC_TRAP7, SIGILL }, /* TRAP #7 */ - { VEC_TRAP8, SIGILL }, /* TRAP #8 */ - { VEC_TRAP9, SIGILL }, /* TRAP #9 */ - { VEC_TRAP10, SIGILL }, /* TRAP #10 */ - { VEC_TRAP11, SIGILL }, /* TRAP #11 */ - { VEC_TRAP12, SIGILL }, /* TRAP #12 */ - { VEC_TRAP13, SIGILL }, /* TRAP #13 */ - { VEC_TRAP14, SIGABRT }, /* TRAP #14 (used by kgdb_abort) */ - { VEC_TRAP15, SIGTRAP }, /* TRAP #15 (breakpoint) */ - { VEC_FPBRUC, SIGFPE }, /* FPU */ - { VEC_FPIR, SIGFPE }, /* FPU */ - { VEC_FPDIVZ, SIGFPE }, /* FPU */ - { VEC_FPUNDER, SIGFPE }, /* FPU */ - { VEC_FPOE, SIGFPE }, /* FPU */ - { VEC_FPOVER, SIGFPE }, /* FPU */ - { VEC_FPNAN, SIGFPE }, /* FPU */ - { VEC_FPUNSUP, SIGFPE }, /* FPU */ - { VEC_UNIMPEA, SIGILL }, /* unimpl. effective address */ - { VEC_UNIMPII, SIGILL }, /* unimpl. integer insn */ - - { 0, 0 } /* Must be last */ -}; - - -/* - * Set up exception handlers for tracing and breakpoints - */ -void kgdb_init(void) -{ - extern char m68k_debug_device[]; - - /* fake usage to avoid gcc warnings about unused stuff (they're used in - * assembler code) The local variables will be optimized away... */ - void (*fake1)(void) = handle_exception; - int *fake2 = frame_sizes; - (void)fake1; (void)fake2; - - /* We don't modify the real exception vectors here for the m68k. - * handle_exception() will be called from bad_kernel_trap() or - * die_if_kernel() as needed. */ - - /* - * Initialize the serial port (name in 'm68k_debug_device') - */ - - serial_in = NULL; - serial_out = NULL; - serial_intr = NULL; - -#ifdef CONFIG_ATARI - if (MACH_IS_ATARI) { - if (!strcmp( m68k_debug_device, "ser" )) { - /* defaults to ser2 for a Falcon and ser1 otherwise */ - strcpy( m68k_debug_device, - ((atari_mch_cookie>>16) == ATARI_MCH_FALCON) ? - "ser2" : "ser1" ); - } - - if (!strcmp( m68k_debug_device, "ser1" )) { - /* ST-MFP Modem1 serial port init */ - mfp.trn_stat &= ~0x01; /* disable TX */ - mfp.rcv_stat &= ~0x01; /* disable RX */ - mfp.usart_ctr = 0x88; /* clk 1:16, 8N1 */ - mfp.tim_ct_cd &= 0x70; /* stop timer D */ - mfp.tim_dt_d = 2; /* 9600 bps */ - mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ - mfp.trn_stat |= 0x01; /* enable TX */ - mfp.rcv_stat |= 0x01; /* enable RX */ - - /* set function pointers */ - serial_in = atari_mfp_in; - serial_out = atari_mfp_out; - serial_intr = atari_mfp_intr; - - /* allocate interrupt */ - request_irq( IRQ_MFP_RECFULL, kgdb_intr, IRQ_TYPE_FAST, "kgdb", - NULL ); - } - else if (!strcmp( m68k_debug_device, "ser2" )) { - extern int atari_SCC_reset_done; - - /* SCC Modem2 serial port init */ - static unsigned char *p, scc_table[] = { - 9, 0xc0, /* Reset */ - 4, 0x44, /* x16, 1 stopbit, no parity */ - 3, 0xc0, /* receiver: 8 bpc */ - 5, 0xe2, /* transmitter: 8 bpc, assert dtr/rts */ - 2, 0x60, /* base int vector */ - 9, 0x09, /* int enab, with status low */ - 10, 0, /* NRZ */ - 11, 0x50, /* use baud rate generator */ - 12, 24, 13, 0, /* 9600 baud */ - 14, 2, 14, 3, /* use master clock for BRG, enable */ - 3, 0xc1, /* enable receiver */ - 5, 0xea, /* enable transmitter */ - 15, 0, /* no stat ints */ - 1, 0x10, /* Rx int every char, other ints off */ - 0 - }; - - (void)scc.cha_b_ctrl; /* reset reg pointer */ - MFPDELAY(); - for( p = scc_table; *p != 0; ) { - scc.cha_b_ctrl = *p++; - MFPDELAY(); - scc.cha_b_ctrl = *p++; - MFPDELAY(); - if (p[-2] == 9) - udelay(40); /* extra delay after WR9 access */ - } - /* avoid that atari_SCC.c resets the whole SCC again */ - atari_SCC_reset_done = 1; - - /* set function pointers */ - serial_in = atari_scc_in; - serial_out = atari_scc_out; - serial_intr = atari_scc_intr; - - /* allocate rx and spcond ints */ - request_irq( IRQ_SCCB_RX, kgdb_intr, IRQ_TYPE_FAST, "kgdb", NULL ); - request_irq( IRQ_SCCB_SPCOND, kgdb_intr, IRQ_TYPE_FAST, "kgdb", - NULL ); - } - } -#endif - -#ifdef CONFIG_AMIGA - if (MACH_IS_AMIGA) { - /* always use built-in serial port, no init required */ - serial_in = amiga_ser_in; - serial_out = amiga_ser_out; - } -#endif - -#ifdef CONFIG_MAC - if (MACH_IS_MAC) { - if (!strcmp( m68k_debug_device, "ser" ) || - !strcmp( m68k_debug_device, "ser1" )) { - mac_init_scc_port( B9600|CS8, 0 ); - serial_in = mac_scca_in; - serial_out = mac_scca_out; - serial_intr = mac_scca_intr; - } else if (!strcmp( m68k_debug_device, "ser2" )) { - mac_init_scc_port( B9600|CS8, 1 ); - serial_in = mac_sccb_in; - serial_out = mac_sccb_out; - serial_intr = mac_sccb_intr; - } - } - if (!serial_in || !serial_out) { - if (*m68k_debug_device) - printk( "kgdb_init failed: no valid serial device!\n" ); - else - printk( "kgdb not enabled\n" ); - return; - } - request_irq(4, kgdb_intr, IRQ_TYPE_FAST, "kgdb", NULL); -#endif - -#ifdef CONFIG_ATARI - if (!serial_in || !serial_out) { - if (*m68k_debug_device) - printk( "kgdb_init failed: no valid serial device!\n" ); - else - printk( "kgdb not enabled\n" ); - return; - } -#endif - - /* - * In case GDB is started before us, ack any packets - * (presumably "$?#xx") sitting there. - */ - - putDebugChar ('+'); - kgdb_initialized = 1; - printk( KERN_INFO "kgdb initialized.\n" ); -} - - -/* - * Convert the MIPS hardware trap type code to a unix signal number. - */ -static int computeSignal(int tt) -{ - struct hard_trap_info *ht; - - for (ht = hard_trap_info; ht->tt && ht->signo; ht++) - if (ht->tt == tt) - return ht->signo; - - return SIGHUP; /* default for things we don't know about */ -} - -/* - * While we find nice hex chars, build an int. - * Return number of chars processed. - */ -static int hexToInt(char **ptr, int *intValue) -{ - int numChars = 0; - int hexValue; - - *intValue = 0; - - while (**ptr) - { - hexValue = hex(**ptr); - if (hexValue < 0) - break; - - *intValue = (*intValue << 4) | hexValue; - numChars ++; - - (*ptr)++; - } - - return (numChars); -} - - -/* - * This assembler stuff copies a struct frame (passed as argument) into struct - * gdb_regs registers and then calls handle_exception. After return from - * there, register and the like are restored from 'registers', the stack is - * set up and execution is continued where registers->pc tells us. - */ - -/* offsets in struct frame */ -#define FRAMEOFF_D1 "0" /* d1..d5 */ -#define FRAMEOFF_A0 "5*4" /* a0..a2 */ -#define FRAMEOFF_D0 "8*4" -#define FRAMEOFF_SR "11*4" -#define FRAMEOFF_PC "11*4+2" -#define FRAMEOFF_VECTOR "12*4+2" - -/* offsets in struct gdb_regs */ -#define GDBOFF_D0 "0" -#define GDBOFF_D1 "1*4" -#define GDBOFF_D6 "6*4" -#define GDBOFF_A0 "8*4" -#define GDBOFF_A3 "11*4" -#define GDBOFF_A7 "15*4" -#define GDBOFF_VECTOR "16*4" -#define GDBOFF_SR "16*4+2" -#define GDBOFF_PC "17*4" -#define GDBOFF_FP0 "18*4" -#define GDBOFF_FPCTL "42*4" - -__asm__ -( " .globl " SYMBOL_NAME_STR(enter_kgdb) "\n" - SYMBOL_NAME_STR(enter_kgdb) ":\n" - /* return if not initialized */ - " tstl "SYMBOL_NAME_STR(kgdb_initialized)"\n" - " bne 1f\n" - " rts \n" - "1: orw #0x700,%sr\n" /* disable interrupts while in stub */ - " tstl %sp@+\n" /* pop off return address */ - " movel %sp@+,%a0\n" /* get pointer to fp->ptregs (param) */ - " movel #"SYMBOL_NAME_STR(kgdb_registers)",%a1\n" /* destination */ - /* copy d0-d5/a0-a1 into gdb_regs */ - " movel %a0@("FRAMEOFF_D0"),%a1@("GDBOFF_D0")\n" - " moveml %a0@("FRAMEOFF_D1"),%d1-%d5\n" - " moveml %d1-%d5,%a1@("GDBOFF_D1")\n" - " moveml %a0@("FRAMEOFF_A0"),%d0-%d2\n" - " moveml %d0-%d2,%a1@("GDBOFF_A0")\n" - /* copy sr and pc */ - " movel %a0@("FRAMEOFF_PC"),%a1@("GDBOFF_PC")\n" - " movew %a0@("FRAMEOFF_SR"),%a1@("GDBOFF_SR")\n" - /* copy format/vector word */ - " movew %a0@("FRAMEOFF_VECTOR"),%a1@("GDBOFF_VECTOR")\n" - /* save FPU regs */ -#ifndef CONFIG_M68KFPU_EMU_ONLY -#ifdef CONFIG_M68KFPU_EMU - " tstl "SYMBOL_NAME_STR(m68k_fputype)"\n" - " jeq 1f\n" -#endif - " fmovemx %fp0-%fp7,%a1@("GDBOFF_FP0")\n" - " fmoveml %fpcr/%fpsr/%fpiar,%a1@("GDBOFF_FPCTL")\n" - "1:\n" -#endif /* CONFIG_M68KFPU_EMU_ONLY */ - - /* set stack to CPU frame */ - " addl #"FRAMEOFF_SR",%a0\n" - " movel %a0,%sp\n" - " movew %sp@(6),%d0\n" - " andl #0xf000,%d0\n" - " lsrl #8,%d0\n" - " lsrl #2,%d0\n" /* get frame format << 2 */ - " lea "SYMBOL_NAME_STR(frame_sizes)",%a2\n" - " addl %a2@(%d0),%sp\n" - " movel %sp,%a1@("GDBOFF_A7")\n" /* save a7 now */ - - /* call handle_exception() now that the stack is set up */ - "Lcall_handle_excp:" - " jsr "SYMBOL_NAME_STR(handle_exception)"\n" - - /* after return, first restore FPU registers */ - " movel #"SYMBOL_NAME_STR(kgdb_registers)",%a0\n" /* source */ -#ifndef CONFIG_M68KFPU_EMU_ONLY -#ifdef CONFIG_M68KFPU_EMU - " tstl "SYMBOL_NAME_STR(m68k_fputype)"\n" - " jeq 1f\n" -#endif - " fmovemx %a0@("GDBOFF_FP0"),%fp0-%fp7\n" - " fmoveml %a0@("GDBOFF_FPCTL"),%fpcr/%fpsr/%fpiar\n" - "1:\n" -#endif /* CONFIG_M68KFPU_EMU_ONLY */ - /* set new stack pointer */ - " movel %a0@("GDBOFF_A7"),%sp\n" - " clrw %sp@-\n" /* fake format $0 frame */ - " movel %a0@("GDBOFF_PC"),%sp@-\n" /* new PC into frame */ - " movew %a0@("GDBOFF_SR"),%sp@-\n" /* new SR into frame */ - /* restore general registers */ - " moveml %a0@("GDBOFF_D0"),%d0-%d7/%a0-%a6\n" - /* and jump to new PC */ - " rte" - ); - - -/* - * This is the entry point for the serial interrupt handler. It calls the - * machine specific function pointer 'serial_intr' to get the char that - * interrupted. If that was C-c, the stub is entered as above, but based on - * just a struct intframe, not a struct frame. - */ - -__asm__ -( SYMBOL_NAME_STR(kgdb_intr) ":\n" - /* return if not initialized */ - " tstl "SYMBOL_NAME_STR(kgdb_initialized)"\n" - " bne 1f\n" - "2: rts \n" - "1: movel "SYMBOL_NAME_STR(serial_intr)",%a0\n" - " jsr (%a0)\n" /* get char from serial */ - " cmpb #3,%d0\n" /* is it C-c ? */ - " bne 2b\n" /* no -> just ignore */ - " orw #0x700,%sr\n" /* disable interrupts */ - " subql #1,"SYMBOL_NAME_STR(local_irq_count)"\n" - " movel %sp@(12),%sp\n" /* revert stack to where 'inthandler' set - * it up */ - /* restore regs from frame */ - " moveml %sp@+,%d1-%d5/%a0-%a2\n" - " movel %sp@+,%d0\n" - " addql #8,%sp\n" /* throw away orig_d0 and stkadj */ - /* save them into 'registers' */ - " moveml %d0-%d7/%a0-%a6,"SYMBOL_NAME_STR(kgdb_registers)"\n" - " movel #"SYMBOL_NAME_STR(kgdb_registers)",%a1\n" /* destination */ - /* copy sr and pc */ - " movel %sp@(2),%a1@("GDBOFF_PC")\n" - " movew %sp@,%a1@("GDBOFF_SR")\n" - /* fake format 0 and vector 1 (translated to SIGINT) */ - " movew #4,%a1@("GDBOFF_VECTOR")\n" - /* save FPU regs */ -#ifndef CONFIG_M68KFPU_EMU_ONLY -#ifdef CONFIG_M68KFPU_EMU - " tstl "SYMBOL_NAME_STR(m68k_fputype)"\n" - " jeq 1f\n" -#endif - " fmovemx %fp0-%fp7,%a1@("GDBOFF_FP0")\n" - " fmoveml %fpcr/%fpsr/%fpiar,%a1@("GDBOFF_FPCTL")\n" - "1:\n" -#endif /* CONFIG_M68KFPU_EMU_ONLY */ - /* pop off the CPU stack frame */ - " addql #8,%sp\n" - " movel %sp,%a1@("GDBOFF_A7")\n" /* save a7 now */ - /* proceed as in enter_kgdb */ - " jbra Lcall_handle_excp\n" - ); - -/* - * This function does all command processing for interfacing to gdb. It - * returns 1 if you should skip the instruction at the trap address, 0 - * otherwise. - */ -static asmlinkage void handle_exception( void ) -{ - int trap; /* Trap type */ - int sigval; - int addr; - int length; - char *ptr; - - trap = kgdb_registers.vector >> 2; - sigval = computeSignal(trap); - /* clear upper half of vector/sr word */ - kgdb_registers.vector = 0; - kgdb_registers.format = 0; - -#ifndef DEBUG - if (remote_debug) { -#endif - printk("in handle_exception() trap=%d sigval=%d\n", trap, sigval ); - show_gdbregs(); -#ifndef DEBUG - } -#endif - - /* - * reply to host that an exception has occurred - */ - ptr = output_buffer; - - /* - * Send trap type (converted to signal) - */ - *ptr++ = 'T'; - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; - - /* - * Send Error PC - */ - *ptr++ = hexchars[GDBREG_PC >> 4]; - *ptr++ = hexchars[GDBREG_PC & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((char *)&kgdb_registers.pc, ptr, 4, 0); - *ptr++ = ';'; - - /* - * Send frame pointer - */ - *ptr++ = hexchars[GDBREG_A6 >> 4]; - *ptr++ = hexchars[GDBREG_A6 & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((char *)&kgdb_registers.regs[GDBREG_A6], ptr, 4, 0); - *ptr++ = ';'; - - /* - * Send stack pointer - */ - *ptr++ = hexchars[GDBREG_SP >> 4]; - *ptr++ = hexchars[GDBREG_SP & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((char *)&kgdb_registers.regs[GDBREG_SP], ptr, 4, 0); - *ptr++ = ';'; - - *ptr++ = 0; - putpacket(output_buffer,1); /* send it off... */ - - /* - * Wait for input from remote GDB - */ - for(;;) { - output_buffer[0] = 0; - getpacket(input_buffer); - - switch (input_buffer[0]) { - case '?': - output_buffer[0] = 'S'; - output_buffer[1] = hexchars[sigval >> 4]; - output_buffer[2] = hexchars[sigval & 0xf]; - output_buffer[3] = 0; - break; - - case 'd': - /* toggle debug flag */ - remote_debug = !remote_debug; - break; - - /* - * Return the value of the CPU registers - */ - case 'g': - ptr = output_buffer; - ptr = mem2hex((char *)&kgdb_registers, ptr, NUMREGSBYTES, 0); - break; - - /* - * set the value of the CPU registers - return OK - */ - case 'G': - ptr = &input_buffer[1]; - ptr = hex2mem(ptr, (char *)&kgdb_registers, NUMREGSBYTES, 0); - strcpy(output_buffer,"OK"); - break; - - /* - * Pn...=r... Write register n - */ - case 'P': - ptr = &input_buffer[1]; - if (hexToInt(&ptr, &addr) && *ptr++ == '=') { - if (addr >= 0 && addr <= GDBREG_PC) - hex2mem(ptr, (char *)&kgdb_registers.regs[addr], 4, 0); - else if (addr >= GDBREG_FP0 && addr <= GDBREG_FP7) - hex2mem(ptr, (char *)&kgdb_registers.fpregs[addr-GDBREG_FP0], - 12, 0); - else if (addr >= GDBREG_FPCR && addr <= GDBREG_FPIAR) - hex2mem(ptr, (char *)&kgdb_registers.fpcntl[addr-GDBREG_FPCR], - 4, 0); - } - else - strcpy(output_buffer,"E01"); - break; - - /* - * mAA..AA,LLLL Read LLLL bytes at address AA..AA - */ - case 'm': - ptr = &input_buffer[1]; - - if (hexToInt(&ptr, &addr) - && *ptr++ == ',' - && hexToInt(&ptr, &length)) { - if (mem2hex((char *)addr, output_buffer, length, 1)) - break; - strcpy (output_buffer, "E03"); - } else - strcpy(output_buffer,"E01"); - break; - - /* - * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK - */ - case 'M': - ptr = &input_buffer[1]; - - if (hexToInt(&ptr, &addr) - && *ptr++ == ',' - && hexToInt(&ptr, &length) - && *ptr++ == ':') { - if (hex2mem(ptr, (char *)addr, length, 1)) - strcpy(output_buffer, "OK"); - else - strcpy(output_buffer, "E03"); - } - else - strcpy(output_buffer, "E02"); - break; - - /* - * cAA..AA Continue at address AA..AA(optional) - * sAA..AA Step one instruction from AA..AA(optional) - */ - case 'c': - case 's': - /* try to read optional parameter, pc unchanged if no parm */ - - ptr = &input_buffer[1]; - if (hexToInt(&ptr, &addr)) - kgdb_registers.pc = addr; - - kgdb_registers.sr &= 0x7fff; /* clear Trace bit */ - if (input_buffer[0] == 's') - kgdb_registers.sr |= 0x8000; /* set it if step command */ - - if (remote_debug) - printk( "cont; new PC=0x%08lx SR=0x%04x\n", - kgdb_registers.pc, kgdb_registers.sr ); - - /* - * Need to flush the instruction cache here, as we may - * have deposited a breakpoint, and the icache probably - * has no way of knowing that a data ref to some location - * may have changed something that is in the instruction - * cache. - */ - - if (m68k_is040or060) - __asm__ __volatile__ - ( ".word 0xf4f8\n\t" /* CPUSHA I/D */ - ".word 0xf498" /* CINVA I */ - ); - else - __asm__ __volatile__ - ( "movec %/cacr,%/d0\n\t" - "oriw #0x0008,%/d0\n\t" - "movec %/d0,%/cacr" - : : : "d0" ); - - return; - - /* - * kill the program means reset the machine - */ - case 'k' : - case 'r': - if (mach_reset) { - /* reply OK before actual reset */ - strcpy(output_buffer,"OK"); - putpacket(output_buffer,0); - mach_reset(); - } - else - strcpy(output_buffer,"E01"); - break; - - /* - * Set baud rate (bBB) - * FIXME: Needs to be written (in gdb, too...) - */ - case 'b': - strcpy(output_buffer,"E01"); - break; - - } /* switch */ - - /* - * reply to the request - */ - - putpacket(output_buffer,1); - - } -} - - -/* - * Print registers (on target console) - * Used only to debug the stub... - */ -static void show_gdbregs( void ) -{ - printk( "d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", - kgdb_registers.regs[0], kgdb_registers.regs[1], - kgdb_registers.regs[2], kgdb_registers.regs[3] ); - printk( "d4: %08lx d5: %08lx d6: %08lx d7: %08lx\n", - kgdb_registers.regs[4], kgdb_registers.regs[5], - kgdb_registers.regs[6], kgdb_registers.regs[7] ); - printk( "a0: %08lx a1: %08lx a2: %08lx a3: %08lx\n", - kgdb_registers.regs[8], kgdb_registers.regs[9], - kgdb_registers.regs[10], kgdb_registers.regs[11] ); - printk( "a4: %08lx a5: %08lx a6: %08lx a7: %08lx\n", - kgdb_registers.regs[12], kgdb_registers.regs[13], - kgdb_registers.regs[14], kgdb_registers.regs[15] ); - printk( "pc: %08lx sr: %04x\n", kgdb_registers.pc, kgdb_registers.sr ); -} - - -/* -------------------- Atari serial I/O -------------------- */ - -#ifdef CONFIG_ATARI - -static int atari_mfp_out( unsigned char c ) - -{ - while( !(mfp.trn_stat & 0x80) ) /* wait for tx buf empty */ - barrier(); - mfp.usart_dta = c; - return( 1 ); -} - - -static unsigned char atari_mfp_in( void ) - -{ - while( !(mfp.rcv_stat & 0x80) ) /* wait for rx buf filled */ - barrier(); - return( mfp.usart_dta ); -} - - -static unsigned char atari_mfp_intr( void ) - -{ - return( mfp.usart_dta ); -} - - -static int atari_scc_out( unsigned char c ) - -{ - do { - MFPDELAY(); - } while( !(scc.cha_b_ctrl & 0x04) ); /* wait for tx buf empty */ - MFPDELAY(); - scc.cha_b_data = c; - return( 1 ); -} - - -static unsigned char atari_scc_in( void ) - -{ - do { - MFPDELAY(); - } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */ - MFPDELAY(); - return( scc.cha_b_data ); -} - - -static unsigned char atari_scc_intr( void ) - -{ unsigned char c, stat; - - MFPDELAY(); - scc.cha_b_ctrl = 1; /* RR1 */ - MFPDELAY(); - stat = scc.cha_b_ctrl; - MFPDELAY(); - c = scc.cha_b_data; - MFPDELAY(); - if (stat & 0x30) { - scc.cha_b_ctrl = 0x30; /* error reset for overrun and parity */ - MFPDELAY(); - } - scc.cha_b_ctrl = 0x38; /* reset highest IUS */ - MFPDELAY(); - return( c ); -} - -#endif - -/* -------------------- Macintosh serial I/O -------------------- */ - -#ifdef CONFIG_MAC - -struct SCC - { - u_char cha_b_ctrl; - u_char char_dummy1; - u_char cha_a_ctrl; - u_char char_dummy2; - u_char cha_b_data; - u_char char_dummy3; - u_char cha_a_data; - }; - -#define scc (*((volatile struct SCC*)mac_bi_data.sccbase)) - -#define uSEC 1 -#define LONG_DELAY() \ - do { \ - int i; \ - for( i = 60*uSEC; i > 0; --i ) \ - barrier(); \ - } while(0) - -static unsigned char mac_sccb_out (unsigned char c) -{ - int i; - do { - LONG_DELAY(); - } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ - for( i = uSEC; i > 0; --i ) - barrier(); - scc.cha_b_data = c; -} - -static unsigned char mac_scca_out (unsigned char c) -{ - int i; - do { - LONG_DELAY(); - } while (!(scc.cha_a_ctrl & 0x04)); /* wait for tx buf empty */ - for( i = uSEC; i > 0; --i ) - barrier(); - scc.cha_a_data = c; -} - -static unsigned char mac_sccb_in( void ) -{ - do { - LONG_DELAY(); - } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */ - LONG_DELAY(); - return( scc.cha_b_data ); -} - -static unsigned char mac_scca_in( void ) - -{ - do { - LONG_DELAY(); - } while( !(scc.cha_a_ctrl & 0x01) ); /* wait for rx buf filled */ - LONG_DELAY(); - return( scc.cha_a_data ); -} - -static unsigned char mac_sccb_intr( void ) - -{ unsigned char c, stat; - - LONG_DELAY(); - scc.cha_b_ctrl = 1; /* RR1 */ - LONG_DELAY(); - stat = scc.cha_b_ctrl; - LONG_DELAY(); - c = scc.cha_b_data; - LONG_DELAY(); - if (stat & 0x30) { - scc.cha_b_ctrl = 0x30; /* error reset for overrun and parity */ - LONG_DELAY(); - } - scc.cha_b_ctrl = 0x38; /* reset highest IUS */ - LONG_DELAY(); - return( c ); -} - -static unsigned char mac_scca_intr( void ) - -{ unsigned char c, stat; - - LONG_DELAY(); - scc.cha_a_ctrl = 1; /* RR1 */ - LONG_DELAY(); - stat = scc.cha_a_ctrl; - LONG_DELAY(); - c = scc.cha_a_data; - LONG_DELAY(); - if (stat & 0x30) { - scc.cha_a_ctrl = 0x30; /* error reset for overrun and parity */ - LONG_DELAY(); - } - scc.cha_a_ctrl = 0x38; /* reset highest IUS */ - LONG_DELAY(); - return( c ); -} - -#endif diff -ur --new-file old/linux/arch/m68k/kernel/m68k_ksyms.c new/linux/arch/m68k/kernel/m68k_ksyms.c --- old/linux/arch/m68k/kernel/m68k_ksyms.c Mon Nov 8 23:28:34 1999 +++ new/linux/arch/m68k/kernel/m68k_ksyms.c Wed Jan 26 21:44:20 2000 @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include @@ -21,6 +21,7 @@ #include asmlinkage long long __ashrdi3 (long long, int); +asmlinkage long long __lshrdi3 (long long, int); extern char m68k_debug_device[]; extern void dump_thread(struct pt_regs *, struct user *); @@ -57,6 +58,9 @@ EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(kernel_thread); +#ifdef CONFIG_VME +EXPORT_SYMBOL(vme_brdtype); +#endif /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy); @@ -66,6 +70,7 @@ their interface isn't gonna change any time soon now, so it's OK to leave it out of version control. */ EXPORT_SYMBOL_NOVERS(__ashrdi3); +EXPORT_SYMBOL_NOVERS(__lshrdi3); EXPORT_SYMBOL_NOVERS(memcpy); EXPORT_SYMBOL_NOVERS(memset); EXPORT_SYMBOL_NOVERS(memcmp); diff -ur --new-file old/linux/arch/m68k/kernel/ptrace.c new/linux/arch/m68k/kernel/ptrace.c --- old/linux/arch/m68k/kernel/ptrace.c Sun Aug 15 20:47:29 1999 +++ new/linux/arch/m68k/kernel/ptrace.c Wed Jan 26 21:44:20 2000 @@ -87,210 +87,6 @@ return 0; } -/* - * This routine gets a long from any process space by following the page - * tables. NOTE! You should check that the long isn't on a page boundary, - * and that it is in the task area before calling this: this routine does - * no checking. - * - */ -static unsigned long get_long(struct task_struct * tsk, - struct vm_area_struct * vma, unsigned long addr) -{ - pgd_t * pgdir; - pmd_t * pgmiddle; - pte_t * pgtable; - unsigned long page; - -repeat: - pgdir = pgd_offset(vma->vm_mm, addr); - if (pgd_none(*pgdir)) { - handle_mm_fault(tsk, vma, addr, 0); - goto repeat; - } - if (pgd_bad(*pgdir)) { - printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir)); - pgd_clear(pgdir); - return 0; - } - pgmiddle = pmd_offset(pgdir,addr); - if (pmd_none(*pgmiddle)) { - handle_mm_fault(tsk, vma, addr, 0); - goto repeat; - } - if (pmd_bad(*pgmiddle)) { - printk("ptrace: bad page directory %08lx\n", - pmd_val(*pgmiddle)); - pmd_clear(pgmiddle); - return 0; - } - pgtable = pte_offset(pgmiddle, addr); - if (!pte_present(*pgtable)) { - handle_mm_fault(tsk, vma, addr, 0); - goto repeat; - } - page = pte_page(*pgtable); -/* this is a hack for non-kernel-mapped video buffers and similar */ - if (MAP_NR(page) >= max_mapnr) - return 0; - page += addr & ~PAGE_MASK; - return *(unsigned long *) page; -} - -/* - * This routine puts a long into any process space by following the page - * tables. NOTE! You should check that the long isn't on a page boundary, - * and that it is in the task area before calling this: this routine does - * no checking. - * - * Now keeps R/W state of page so that a text page stays readonly - * even if a debugger scribbles breakpoints into it. -M.U- - */ -static void put_long(struct task_struct * tsk, struct vm_area_struct * vma, unsigned long addr, - unsigned long data) -{ - pgd_t *pgdir; - pmd_t *pgmiddle; - pte_t *pgtable; - unsigned long page; - -repeat: - pgdir = pgd_offset(vma->vm_mm, addr); - if (!pgd_present(*pgdir)) { - handle_mm_fault(tsk, vma, addr, 1); - goto repeat; - } - if (pgd_bad(*pgdir)) { - printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir)); - pgd_clear(pgdir); - return; - } - pgmiddle = pmd_offset(pgdir,addr); - if (pmd_none(*pgmiddle)) { - handle_mm_fault(tsk, vma, addr, 1); - goto repeat; - } - if (pmd_bad(*pgmiddle)) { - printk("ptrace: bad page directory %08lx\n", - pmd_val(*pgmiddle)); - pmd_clear(pgmiddle); - return; - } - pgtable = pte_offset(pgmiddle, addr); - if (!pte_present(*pgtable)) { - handle_mm_fault(tsk, vma, addr, 1); - goto repeat; - } - page = pte_page(*pgtable); - if (!pte_write(*pgtable)) { - handle_mm_fault(tsk, vma, addr, 1); - goto repeat; - } -/* this is a hack for non-kernel-mapped video buffers and similar */ - if (MAP_NR(page) < max_mapnr) { - *(unsigned long *) (page + (addr & ~PAGE_MASK)) = data; - flush_page_to_ram (page); - } -/* we're bypassing pagetables, so we have to set the dirty bit ourselves */ -/* this should also re-instate whatever read-only mode there was before */ - *pgtable = pte_mkdirty(mk_pte(page, vma->vm_page_prot)); - flush_tlb_all(); -} - -/* - * This routine checks the page boundaries, and that the offset is - * within the task area. It then calls get_long() to read a long. - */ -static int read_long(struct task_struct * tsk, unsigned long addr, - unsigned long * result) -{ - struct vm_area_struct * vma = find_extend_vma(tsk, addr); - - if (!vma) - return -EIO; - if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) { - unsigned long low,high; - struct vm_area_struct * vma_low = vma; - - if (addr + sizeof(long) >= vma->vm_end) { - vma_low = vma->vm_next; - if (!vma_low || vma_low->vm_start != vma->vm_end) - return -EIO; - } - high = get_long(tsk, vma,addr & ~(sizeof(long)-1)); - low = get_long(tsk, vma_low,(addr+sizeof(long)) & ~(sizeof(long)-1)); - switch (addr & (sizeof(long)-1)) { - case 3: - low >>= 8; - low |= high << 24; - break; - case 2: - low >>= 16; - low |= high << 16; - break; - case 1: - low >>= 24; - low |= high << 8; - break; - } - *result = low; - } else - *result = get_long(tsk, vma,addr); - return 0; -} - -/* - * This routine checks the page boundaries, and that the offset is - * within the task area. It then calls put_long() to write a long. - */ -static int write_long(struct task_struct * tsk, unsigned long addr, - unsigned long data) -{ - struct vm_area_struct * vma = find_extend_vma(tsk, addr); - - if (!vma) - return -EIO; - if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) { - unsigned long low,high; - struct vm_area_struct * vma_low = vma; - - if (addr + sizeof(long) >= vma->vm_end) { - vma_low = vma->vm_next; - if (!vma_low || vma_low->vm_start != vma->vm_end) - return -EIO; - } - high = get_long(tsk, vma,addr & ~(sizeof(long)-1)); - low = get_long(tsk, vma_low,(addr+sizeof(long)) & ~(sizeof(long)-1)); - switch (addr & (sizeof(long)-1)) { - case 0: /* shouldn't happen, but safety first */ - high = data; - break; - case 3: - low &= 0x000000ff; - low |= data << 8; - high &= ~0xff; - high |= data >> 24; - break; - case 2: - low &= 0x0000ffff; - low |= data << 16; - high &= ~0xffff; - high |= data >> 16; - break; - case 1: - low &= 0x00ffffff; - low |= data << 24; - high &= ~0xffffff; - high |= data >> 8; - break; - } - put_long(tsk, vma,addr & ~(sizeof(long)-1),high); - put_long(tsk, vma_low,(addr+sizeof(long)) & ~(sizeof(long)-1),low); - } else - put_long(tsk, vma,addr,data); - return 0; -} - asmlinkage int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; @@ -361,12 +157,13 @@ case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKDATA: { unsigned long tmp; + int copied; - down(&child->mm->mmap_sem); - ret = read_long(child, addr, &tmp); - up(&child->mm->mmap_sem); - if (ret >= 0) - ret = put_user(tmp, (unsigned long *) data); + copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); + ret = -EIO; + if (copied != sizeof(tmp)) + goto out; + ret = put_user(tmp,(unsigned long *) data); goto out; } @@ -404,9 +201,10 @@ /* when I and D space are separate, this will have to be fixed. */ case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKEDATA: - down(&child->mm->mmap_sem); - ret = write_long(child,addr,data); - up(&child->mm->mmap_sem); + ret = 0; + if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data)) + goto out; + ret = -EIO; goto out; case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ @@ -416,8 +214,6 @@ addr = addr >> 2; /* temporary hack. */ - if (addr == PT_ORIG_D0) - goto out; if (addr == PT_SR) { data &= SR_MASK; data <<= 16; diff -ur --new-file old/linux/arch/m68k/kernel/semaphore.c new/linux/arch/m68k/kernel/semaphore.c --- old/linux/arch/m68k/kernel/semaphore.c Sat Sep 4 22:06:41 1999 +++ new/linux/arch/m68k/kernel/semaphore.c Wed Jan 26 21:44:20 2000 @@ -60,15 +60,11 @@ * */ -#define DOWN_VAR \ - struct task_struct *tsk = current; \ - wait_queue_t wait; \ - init_waitqueue_entry(&wait, tsk); #define DOWN_HEAD(task_state) \ \ \ - tsk->state = (task_state); \ + current->state = (task_state); \ add_wait_queue(&sem->wait, &wait); \ \ /* \ @@ -89,14 +85,15 @@ for (;;) { #define DOWN_TAIL(task_state) \ - tsk->state = (task_state); \ + current->state = (task_state); \ } \ - tsk->state = TASK_RUNNING; \ + current->state = TASK_RUNNING; \ remove_wait_queue(&sem->wait, &wait); void __down(struct semaphore * sem) { - DOWN_VAR + DECLARE_WAITQUEUE(wait, current); + DOWN_HEAD(TASK_UNINTERRUPTIBLE) if (waking_non_zero(sem)) break; @@ -106,11 +103,12 @@ int __down_interruptible(struct semaphore * sem) { + DECLARE_WAITQUEUE(wait, current); int ret = 0; - DOWN_VAR + DOWN_HEAD(TASK_INTERRUPTIBLE) - ret = waking_non_zero_interruptible(sem, tsk); + ret = waking_non_zero_interruptible(sem, current); if (ret) { if (ret == 1) @@ -126,4 +124,112 @@ int __down_trylock(struct semaphore * sem) { return waking_non_zero_trylock(sem); +} + + +/* Wait for the lock to become unbiased. Readers + * are non-exclusive. =) + */ +void down_read_failed(struct rw_semaphore *sem) +{ + DECLARE_WAITQUEUE(wait, current); + + __up_read(sem); /* this takes care of granting the lock */ + + add_wait_queue(&sem->wait, &wait); + + while (atomic_read(&sem->count) < 0) { + set_task_state(current, TASK_UNINTERRUPTIBLE); + if (atomic_read(&sem->count) >= 0) + break; + schedule(); + } + + remove_wait_queue(&sem->wait, &wait); + current->state = TASK_RUNNING; +} + +void down_read_failed_biased(struct rw_semaphore *sem) +{ + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(&sem->wait, &wait); /* put ourselves at the head of the list */ + + for (;;) { + if (sem->read_bias_granted && xchg(&sem->read_bias_granted, 0)) + break; + set_task_state(current, TASK_UNINTERRUPTIBLE); + if (!sem->read_bias_granted) + schedule(); + } + + remove_wait_queue(&sem->wait, &wait); + current->state = TASK_RUNNING; +} + + +/* Wait for the lock to become unbiased. Since we're + * a writer, we'll make ourselves exclusive. + */ +void down_write_failed(struct rw_semaphore *sem) +{ + DECLARE_WAITQUEUE(wait, current); + + __up_write(sem); /* this takes care of granting the lock */ + + add_wait_queue_exclusive(&sem->wait, &wait); + + while (atomic_read(&sem->count) < 0) { + set_task_state(current, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + if (atomic_read(&sem->count) >= 0) + break; /* we must attempt to aquire or bias the lock */ + schedule(); + } + + remove_wait_queue(&sem->wait, &wait); + current->state = TASK_RUNNING; +} + +void down_write_failed_biased(struct rw_semaphore *sem) +{ + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue_exclusive(&sem->write_bias_wait, &wait); /* put ourselves at the end of the list */ + + for (;;) { + if (sem->write_bias_granted && xchg(&sem->write_bias_granted, 0)) + break; + set_task_state(current, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); + if (!sem->write_bias_granted) + schedule(); + } + + remove_wait_queue(&sem->write_bias_wait, &wait); + current->state = TASK_RUNNING; + + /* if the lock is currently unbiased, awaken the sleepers + * FIXME: this wakes up the readers early in a bit of a + * stampede -> bad! + */ + if (atomic_read(&sem->count) >= 0) + wake_up(&sem->wait); +} + + +/* Called when someone has done an up that transitioned from + * negative to non-negative, meaning that the lock has been + * granted to whomever owned the bias. + */ +void rwsem_wake_readers(struct rw_semaphore *sem) +{ + if (xchg(&sem->read_bias_granted, 1)) + BUG(); + wake_up(&sem->wait); +} + +void rwsem_wake_writer(struct rw_semaphore *sem) +{ + if (xchg(&sem->write_bias_granted, 1)) + BUG(); + wake_up(&sem->write_bias_wait); } diff -ur --new-file old/linux/arch/m68k/kernel/setup.c new/linux/arch/m68k/kernel/setup.c --- old/linux/arch/m68k/kernel/setup.c Sat Sep 4 22:06:41 1999 +++ new/linux/arch/m68k/kernel/setup.c Wed Jan 26 21:44:20 2000 @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include #include #include @@ -35,13 +37,19 @@ #ifdef CONFIG_BLK_DEV_INITRD #include -#include +#endif + +#ifndef CONFIG_AMIGA +#define dbprintf printk #endif unsigned long m68k_machtype; unsigned long m68k_cputype; unsigned long m68k_fputype; unsigned long m68k_mmutype; +#ifdef CONFIG_VME +unsigned long vme_brdtype; +#endif int m68k_is040or060 = 0; @@ -50,6 +58,7 @@ int m68k_num_memory = 0; int m68k_realnum_memory = 0; +unsigned long m68k_memoffset; struct mem_info m68k_memory[NUM_MEMINFO]; static struct mem_info m68k_ramdisk = { 0, 0 }; @@ -91,14 +100,14 @@ void serial_unregister_serial(int); long ser_console_init(long, long ); #endif -#if defined(CONFIG_USERIAL)||defined(CONFIG_BVME6000_SCC)||defined(CONFIG_MVME162_SCC)||defined(CONFIG_HPDCA)||defined(CONFIG_WHIPPET_SERIAL)||defined(CONFIG_MULTIFACE_III_TTY)||defined(CONFIG_GVPIOEXT)||defined(CONFIG_AMIGA_BUILTIN_SERIAL)||defined(CONFIG_MAC_SCC)||defined(CONFIG_ATARI_MIDI)||defined(CONFIG_ATARI_SCC)||defined(CONFIG_ATARI_MFPSER) +#if defined(CONFIG_USERIAL)||defined(CONFIG_HPDCA)||defined(CONFIG_WHIPPET_SERIAL)||defined(CONFIG_MULTIFACE_III_TTY)||defined(CONFIG_GVPIOEXT)||defined(CONFIG_AMIGA_BUILTIN_SERIAL)||defined(CONFIG_MAC_SCC)||defined(CONFIG_ATARI_MIDI)||defined(CONFIG_ATARI_SCC)||defined(CONFIG_ATARI_MFPSER) #define M68K_SERIAL #endif #ifdef M68K_SERIAL long m68k_rs_init(void); int m68k_register_serial(struct serial_struct *); void m68k_unregister_serial(int); -long m68k_serial_console_init(long, long ); +long m68k_serial_console_init(void); #endif #ifdef CONFIG_HEARTBEAT void (*mach_heartbeat) (int) = NULL; @@ -107,8 +116,6 @@ void (*mach_l2_flush) (int) = NULL; #endif -extern void base_trap_init(void); - #ifdef CONFIG_MAGIC_SYSRQ int mach_sysrq_key = -1; int mach_sysrq_shift_state = 0; @@ -120,6 +127,9 @@ extern int atari_parse_bootinfo(const struct bi_record *); extern int mac_parse_bootinfo(const struct bi_record *); extern int q40_parse_bootinfo(const struct bi_record *); +extern int bvme6000_parse_bootinfo(const struct bi_record *); +extern int mvme16x_parse_bootinfo(const struct bi_record *); +extern int mvme147_parse_bootinfo(const struct bi_record *); extern void config_amiga(void); extern void config_atari(void); @@ -179,6 +189,12 @@ unknown = mac_parse_bootinfo(record); else if (MACH_IS_Q40) unknown = q40_parse_bootinfo(record); + else if (MACH_IS_BVME6000) + unknown = bvme6000_parse_bootinfo(record); + else if (MACH_IS_MVME16x) + unknown = mvme16x_parse_bootinfo(record); + else if (MACH_IS_MVME147) + unknown = mvme147_parse_bootinfo(record); else unknown = 1; } @@ -195,13 +211,14 @@ (m68k_num_memory - 1)); m68k_num_memory = 1; } + m68k_memoffset = m68k_memory[0].addr-PAGE_OFFSET; #endif } -void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, - unsigned long * memory_end_p) +void __init setup_arch(char **cmdline_p) { extern int _etext, _edata, _end; + unsigned long endmem, startmem; int i; char *p, *q; @@ -213,10 +230,6 @@ else if (CPU_IS_060) m68k_is040or060 = 6; -#ifndef CONFIG_SUN3 - base_trap_init(); -#endif - /* FIXME: m68k_fputype is passed in by Penguin booter, which can * be confused by software FPU emulation. BEWARE. * We should really do our own FPU check at startup. @@ -339,10 +352,25 @@ #endif #ifndef CONFIG_SUN3 - *memory_start_p = availmem; - *memory_end_p = 0; + startmem= m68k_memory[0].addr; + endmem = startmem + m68k_memory[0].size; + high_memory = PAGE_OFFSET; + for (i = 0; i < m68k_num_memory; i++) { + m68k_memory[i].size &= MASK_256K; + if (m68k_memory[i].addr < startmem) + startmem = m68k_memory[i].addr; + if (m68k_memory[i].addr+m68k_memory[i].size > endmem) + endmem = m68k_memory[i].addr+m68k_memory[i].size; + high_memory += m68k_memory[i].size; + } + + availmem += init_bootmem_node(0, availmem >> PAGE_SHIFT, + startmem >> PAGE_SHIFT, endmem >> PAGE_SHIFT); + for (i = 0; i < m68k_num_memory; i++) - *memory_end_p += m68k_memory[i].size & MASK_256K; + free_bootmem(m68k_memory[0].addr, m68k_memory[0].size); + + reserve_bootmem(m68k_memory[0].addr, availmem - m68k_memory[0].addr); #endif } @@ -479,16 +507,16 @@ EXPORT_SYMBOL(unregister_serial); #ifdef CONFIG_SERIAL_CONSOLE -long serial_console_init(long kmem_start, long kmem_end) +void serial_console_init(void) { -#ifdef CONFIG_SERIAL - if (MACH_IS_Q40) - return ser_console_init(kmem_start, kmem_end); +#ifdef CONFIG_Q40_SERIAL + if (MACH_IS_Q40) { + ser_console_init(); + return; + } #endif #if defined(M68K_SERIAL) && defined(CONFIG_SERIAL_CONSOLE) - return m68k_serial_console_init(kmem_start, kmem_end); -#else - return kmem_start; + m68k_serial_console_init(); #endif } #endif diff -ur --new-file old/linux/arch/m68k/kernel/signal.c new/linux/arch/m68k/kernel/signal.c --- old/linux/arch/m68k/kernel/signal.c Tue Jan 11 03:15:58 2000 +++ new/linux/arch/m68k/kernel/signal.c Wed Jan 26 21:44:20 2000 @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -1049,7 +1048,6 @@ info.si_code = SI_USER; info.si_pid = current->p_pptr->pid; info.si_uid = current->p_pptr->uid; - info.si_uid16 = high2lowuid(current->p_pptr->uid); } /* If the (new) signal is now blocked, requeue it. */ @@ -1076,7 +1074,8 @@ continue; switch (signr) { - case SIGCONT: case SIGCHLD: case SIGWINCH: + case SIGCONT: case SIGCHLD: + case SIGWINCH: case SIGURG: continue; case SIGTSTP: case SIGTTIN: case SIGTTOU: diff -ur --new-file old/linux/arch/m68k/kernel/sys_m68k.c new/linux/arch/m68k/kernel/sys_m68k.c --- old/linux/arch/m68k/kernel/sys_m68k.c Tue Dec 7 23:34:37 1999 +++ new/linux/arch/m68k/kernel/sys_m68k.c Wed Jan 26 21:44:20 2000 @@ -111,11 +111,12 @@ a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - error = do_mmap2(file, a.addr, a.len, a.prot, a.flags, a.offset >> PAGE_SHIFT); + error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); out: return error; } +#if 0 struct mmap_arg_struct64 { __u32 addr; __u32 len; @@ -160,6 +161,7 @@ up(¤t->mm->mmap_sem); return error; } +#endif extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); diff -ur --new-file old/linux/arch/m68k/kernel/traps.c new/linux/arch/m68k/kernel/traps.c --- old/linux/arch/m68k/kernel/traps.c Sat Sep 4 22:06:41 1999 +++ new/linux/arch/m68k/kernel/traps.c Wed Jan 26 21:44:20 2000 @@ -68,18 +68,37 @@ __ALIGN_STR "\n" SYMBOL_NAME_STR(nmihandler) ": rte"); +/* + * this must be called very early as the kernel might + * use some instruction that are emulated on the 060 + */ void __init base_trap_init(void) { -#ifdef CONFIG_SUN3 - /* Keep the keyboard interrupt working with PROM for debugging. --m */ - e_vector *old_vbr; - __asm__ volatile ("movec %%vbr,%1\n\t" - "movec %0,%%vbr" - : "=&r" (old_vbr) : "r" ((void*)vectors)); - vectors[0x1E] = old_vbr[0x1E]; /* Copy int6 vector. */ -#else /* setup the exception vector table */ __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors)); + + if (CPU_IS_060) { + /* set up ISP entry points */ + asmlinkage void unimp_vec(void) asm ("_060_isp_unimp"); + + vectors[VEC_UNIMPII] = unimp_vec; + } +} + +void __init trap_init (void) +{ + int i; + + for (i = 48; i < 64; i++) + if (!vectors[i]) + vectors[i] = trap; + + for (i = 64; i < 256; i++) + vectors[i] = inthandler; + +#ifdef CONFIG_M68KFPU_EMU + if (FPU_IS_EMU) + vectors[VEC_LINE11] = fpu_emu; #endif if (CPU_IS_040 && !FPU_IS_EMU) { @@ -104,12 +123,7 @@ vectors[VEC_LINE11] = fline_vec; vectors[VEC_FPUNSUP] = unsupp_vec; } - if (CPU_IS_060) { - /* set up ISP entry points */ - asmlinkage void unimp_vec(void) asm ("_060_isp_unimp"); - vectors[VEC_UNIMPII] = unimp_vec; - } if (CPU_IS_060 && !FPU_IS_EMU) { /* set up IFPSP entry points */ asmlinkage void snan_vec(void) asm ("_060_fpsp_snan"); @@ -132,32 +146,11 @@ vectors[VEC_FPUNSUP] = unsupp_vec; vectors[VEC_UNIMPEA] = effadd_vec; } -} - -void __init trap_init (void) -{ - int i; - - for (i = 48; i < 64; i++) - if (!vectors[i]) - vectors[i] = trap; - - for (i = 64; i < 256; i++) - vectors[i] = inthandler; - -#ifdef CONFIG_M68KFPU_EMU - if (FPU_IS_EMU) - vectors[VEC_LINE11] = fpu_emu; -#endif /* if running on an amiga, make the NMI interrupt do nothing */ if (MACH_IS_AMIGA) { vectors[VEC_INT7] = nmihandler; } -#ifdef CONFIG_SUN3 - /* Moved from setup_arch() */ - base_trap_init(); -#endif } diff -ur --new-file old/linux/arch/m68k/lib/Makefile new/linux/arch/m68k/lib/Makefile --- old/linux/arch/m68k/lib/Makefile Mon Dec 20 23:43:39 1999 +++ new/linux/arch/m68k/lib/Makefile Wed Jan 26 21:44:20 2000 @@ -6,6 +6,6 @@ $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $@ L_TARGET = lib.a -L_OBJS = ashrdi3.o checksum.o memcpy.o memcmp.o memset.o semaphore.o +L_OBJS = ashrdi3.o lshrdi3.o checksum.o memcpy.o memcmp.o memset.o semaphore.o include $(TOPDIR)/Rules.make diff -ur --new-file old/linux/arch/m68k/lib/lshrdi3.c new/linux/arch/m68k/lib/lshrdi3.c --- old/linux/arch/m68k/lib/lshrdi3.c Thu Jan 1 01:00:00 1970 +++ new/linux/arch/m68k/lib/lshrdi3.c Wed Jan 26 21:44:20 2000 @@ -0,0 +1,62 @@ +/* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */ +/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC 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, or (at your option) +any later version. + +GNU CC 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 GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#define BITS_PER_UNIT 8 + +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int word_type __attribute__ ((mode (__word__))); + +struct DIstruct {SItype high, low;}; + +typedef union +{ + struct DIstruct s; + DItype ll; +} DIunion; + +DItype +__lshrdi3 (DItype u, word_type b) +{ + DIunion w; + word_type bm; + DIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (SItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + w.s.high = 0; + w.s.low = (USItype)uu.s.high >> -bm; + } + else + { + USItype carries = (USItype)uu.s.high << bm; + w.s.high = (USItype)uu.s.high >> b; + w.s.low = ((USItype)uu.s.low >> b) | carries; + } + + return w.ll; +} diff -ur --new-file old/linux/arch/m68k/lib/semaphore.S new/linux/arch/m68k/lib/semaphore.S --- old/linux/arch/m68k/lib/semaphore.S Tue May 11 18:57:14 1999 +++ new/linux/arch/m68k/lib/semaphore.S Wed Jan 26 21:44:20 2000 @@ -7,6 +7,7 @@ */ #include +#include /* * The semaphore operations have a special calling sequence that @@ -49,3 +50,50 @@ movel (%sp)+,%a1 moveml (%sp)+,%a0/%d0/%d1 rts + +ENTRY(__down_read_failed) + moveml %a0/%d0/%d1,-(%sp) + jcc 3f +1: movel %a1,-(%sp) + jbsr SYMBOL_NAME(down_read_failed_biased) + movel (%sp)+,%a1 +2: moveml (%sp)+,%a0/%d0/%d1 + rts + +3: movel %a1,-(%sp) + jbsr SYMBOL_NAME(down_read_failed) + movel (%sp)+,%a1 + subql #1,%a1@ + jpl 2b + jcc 3b + jra 1b + +ENTRY(__down_write_failed) + moveml %a0/%d0/%d1,-(%sp) + jcc 3f +1: movel %a1,-(%sp) + jbsr SYMBOL_NAME(down_write_failed_biased) + movel (%sp)+,%a1 +2: moveml (%sp)+,%a0/%d0/%d1 + rts + +3: movel %a1,-(%sp) + jbsr SYMBOL_NAME(down_write_failed) + movel (%sp)+,%a1 + subl #RW_LOCK_BIAS,%a1@ + jpl 2b + jcc 3b + jra 1b + +ENTRY(__rwsem_wake) + moveml %a0/%d0/%d1,-(%sp) + jeq 1f + movel %a1,-(%sp) + jbsr SYMBOL_NAME(rwsem_wake_readers) + jra 2f +1: movel %a1,-(%sp) + jbsr rwsem_wake_writer +2: movel (%sp)+,%a1 + moveml (%sp)+,%a0/%d0/%d1 + rts + diff -ur --new-file old/linux/arch/m68k/mm/fault.c new/linux/arch/m68k/mm/fault.c --- old/linux/arch/m68k/mm/fault.c Mon Aug 9 21:27:30 1999 +++ new/linux/arch/m68k/mm/fault.c Wed Jan 26 21:44:20 2000 @@ -14,7 +14,7 @@ #include #include #include -#include +#include extern void die_if_kernel(char *, struct pt_regs *, long); extern const int frame_extra_sizes[]; /* in m68k/kernel/signal.c */ diff -ur --new-file old/linux/arch/m68k/mm/init.c new/linux/arch/m68k/mm/init.c --- old/linux/arch/m68k/mm/init.c Sat Oct 16 19:50:48 1999 +++ new/linux/arch/m68k/mm/init.c Wed Jan 26 21:44:20 2000 @@ -16,6 +16,7 @@ #include #include #include +#include #ifdef CONFIG_BLK_DEV_RAM #include #endif @@ -23,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -31,6 +32,8 @@ #include #endif +static unsigned long totalram_pages = 0; + #ifdef CONFIG_SUN3 void mmu_emu_reserve_pages(unsigned long max_page); #endif @@ -77,7 +80,7 @@ pte_t __bad_page(void) { memset ((void *)empty_bad_page, 0, PAGE_SIZE); - return pte_mkdirty(mk_pte(empty_bad_page, PAGE_SHARED)); + return pte_mkdirty(__mk_pte(empty_bad_page, PAGE_SHARED)); } unsigned long empty_zero_page; @@ -127,7 +130,7 @@ extern pmd_t *zero_pgtable; -void __init mem_init(unsigned long start_mem, unsigned long end_mem) +void __init mem_init(void) { int codepages = 0; int datapages = 0; @@ -135,15 +138,7 @@ unsigned long tmp; int i; - end_mem &= PAGE_MASK; - high_memory = (void *) end_mem; - max_mapnr = num_physpages = MAP_NR(end_mem); - - tmp = start_mem = PAGE_ALIGN(start_mem); - while (tmp < end_mem) { - clear_bit(PG_reserved, &mem_map[MAP_NR(tmp)].flags); - tmp += PAGE_SIZE; - } + max_mapnr = num_physpages = MAP_NR(high_memory); #ifdef CONFIG_ATARI if (MACH_IS_ATARI) @@ -155,11 +150,17 @@ mmu_emu_reserve_pages(max_mapnr); #endif - for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) { + /* this will put all memory onto the freelists */ + totalram_pages = free_all_bootmem(); + printk("tp:%ld\n", totalram_pages); + + for (tmp = PAGE_OFFSET ; tmp < (unsigned long)high_memory; tmp += PAGE_SIZE) { +#if 0 #ifndef CONFIG_SUN3 if (virt_to_phys ((void *)tmp) >= mach_max_dma_address) clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags); #endif +#endif if (PageReserved(mem_map+MAP_NR(tmp))) { if (tmp >= (unsigned long)&_text && tmp < (unsigned long)&_etext) @@ -171,12 +172,14 @@ datapages++; continue; } +#if 0 set_page_count(mem_map+MAP_NR(tmp), 1); #ifdef CONFIG_BLK_DEV_INITRD if (!initrd_start || (tmp < (initrd_start & PAGE_MASK) || tmp >= initrd_end)) #endif free_page(tmp); +#endif } #ifndef CONFIG_SUN3 @@ -184,7 +187,7 @@ init_pointer_table((unsigned long)kernel_pg_dir); for (i = 0; i < PTRS_PER_PGD; i++) { if (pgd_present(kernel_pg_dir[i])) - init_pointer_table(pgd_page(kernel_pg_dir[i])); + init_pointer_table(__pgd_page(kernel_pg_dir[i])); } /* insert also pointer table that we used to unmap the zero page */ @@ -193,22 +196,35 @@ #endif printk("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n", - (unsigned long) nr_free_pages << (PAGE_SHIFT-10), + (unsigned long)nr_free_pages() << (PAGE_SHIFT-10), max_mapnr << (PAGE_SHIFT-10), codepages << (PAGE_SHIFT-10), datapages << (PAGE_SHIFT-10), initpages << (PAGE_SHIFT-10)); } +#ifdef CONFIG_BLK_DEV_INITRD +void free_initrd_mem(unsigned long start, unsigned long end) +{ + for (; start < end; start += PAGE_SIZE) { + ClearPageReserved(mem_map + MAP_NR(start)); + set_page_count(mem_map+MAP_NR(start), 1); + free_page(start); + totalram_pages++; + } + printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); +} +#endif + void si_meminfo(struct sysinfo *val) { unsigned long i; i = max_mapnr; - val->totalram = 0; + val->totalram = totalram_pages; val->sharedram = 0; - val->freeram = nr_free_pages << PAGE_SHIFT; - val->bufferram = atomic_read(&buffermem); + val->freeram = nr_free_pages(); + val->bufferram = atomic_read(&buffermem_pages); while (i-- > 0) { if (PageReserved(mem_map+i)) continue; @@ -217,7 +233,7 @@ continue; val->sharedram += page_count(mem_map+i) - 1; } - val->totalram <<= PAGE_SHIFT; - val->sharedram <<= PAGE_SHIFT; + val->totalhigh = 0; + val->freehigh = 0; return; } diff -ur --new-file old/linux/arch/m68k/mm/kmap.c new/linux/arch/m68k/mm/kmap.c --- old/linux/arch/m68k/mm/kmap.c Fri Nov 19 04:32:51 1999 +++ new/linux/arch/m68k/mm/kmap.c Wed Jan 26 21:44:20 2000 @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include diff -ur --new-file old/linux/arch/m68k/mm/memory.c new/linux/arch/m68k/mm/memory.c --- old/linux/arch/m68k/mm/memory.c Sat Sep 4 22:06:41 1999 +++ new/linux/arch/m68k/mm/memory.c Wed Jan 26 21:44:20 2000 @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -46,8 +46,8 @@ pte = (pte_t *) __get_free_page(GFP_KERNEL); if (pmd_none(*pmd)) { if (pte) { - clear_page((unsigned long)pte); - flush_page_to_ram((unsigned long)pte); + clear_page(pte); + __flush_page_to_ram((unsigned long)pte); flush_tlb_kernel_page((unsigned long)pte); nocache_page((unsigned long)pte); pmd_set(pmd, pte); @@ -61,7 +61,7 @@ __bad_pte(pmd); return NULL; } - return (pte_t *) pmd_page(*pmd) + offset; + return (pte_t *)__pmd_page(*pmd) + offset; } pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset) @@ -82,7 +82,7 @@ __bad_pmd(pgd); return NULL; } - return (pmd_t *) pgd_page(*pgd) + offset; + return (pmd_t *)__pgd_page(*pgd) + offset; } @@ -90,11 +90,12 @@ struct page instead of separately kmalloced struct. Stolen from arch/sparc/mm/srmmu.c ... */ -typedef struct page ptable_desc; -static ptable_desc ptable_list = { &ptable_list, &ptable_list }; +typedef struct list_head ptable_desc; +static LIST_HEAD(ptable_list); -#define PD_MARKBITS(dp) (*(unsigned char *)&(dp)->offset) -#define PAGE_PD(page) ((ptable_desc *)&mem_map[MAP_NR(page)]) +#define PD_PTABLE(page) ((ptable_desc *)&mem_map[MAP_NR(page)]) +#define PD_PAGE(ptable) (list_entry(ptable, struct page, list)) +#define PD_MARKBITS(dp) (*(unsigned char *)&PD_PAGE(dp)->index) #define PTABLE_SIZE (PTRS_PER_PMD * sizeof(pmd_t)) @@ -104,11 +105,10 @@ unsigned long page = ptable & PAGE_MASK; unsigned char mask = 1 << ((ptable - page)/PTABLE_SIZE); - dp = PAGE_PD(page); + dp = PD_PTABLE(page); if (!(PD_MARKBITS(dp) & mask)) { PD_MARKBITS(dp) = 0xff; - (dp->prev = ptable_list.prev)->next = dp; - (dp->next = &ptable_list)->prev = dp; + list_add(dp, &ptable_list); } PD_MARKBITS(dp) &= ~mask; @@ -117,8 +117,8 @@ #endif /* unreserve the page so it's possible to free that page */ - dp->flags &= ~(1 << PG_reserved); - atomic_set(&dp->count, 1); + PD_PAGE(dp)->flags &= ~(1 << PG_reserved); + atomic_set(&PD_PAGE(dp)->count, 1); return; } @@ -146,36 +146,31 @@ flush_tlb_kernel_page(page); nocache_page (page); - new = PAGE_PD(page); + new = PD_PTABLE(page); PD_MARKBITS(new) = 0xfe; - (new->prev = dp->prev)->next = new; - (new->next = dp)->prev = new; + list_add_tail(new, dp); + return (pmd_t *)page; } - for (tmp = 1, off = 0; (mask & tmp) == 0; tmp <<= 1, off += PTABLE_SIZE); + for (tmp = 1, off = 0; (mask & tmp) == 0; tmp <<= 1, off += PTABLE_SIZE) + ; PD_MARKBITS(dp) = mask & ~tmp; if (!PD_MARKBITS(dp)) { - ptable_desc *last, *next; - /* move to end of list */ - next = dp->next; - (next->prev = dp->prev)->next = next; - - last = ptable_list.prev; - (dp->next = last->next)->prev = dp; - (dp->prev = last)->next = dp; + list_del(dp); + list_add_tail(dp, &ptable_list); } - return (pmd_t *) (page_address(dp) + off); + return (pmd_t *) (page_address(PD_PAGE(dp)) + off); } int free_pointer_table (pmd_t *ptable) { - ptable_desc *dp, *first; + ptable_desc *dp; unsigned long page = (unsigned long)ptable & PAGE_MASK; unsigned char mask = 1 << (((unsigned long)ptable - page)/PTABLE_SIZE); - dp = PAGE_PD(page); + dp = PD_PTABLE(page); if (PD_MARKBITS (dp) & mask) panic ("table already free!"); @@ -183,21 +178,17 @@ if (PD_MARKBITS(dp) == 0xff) { /* all tables in page are free, free page */ - ptable_desc *next = dp->next; - (next->prev = dp->prev)->next = next; + list_del(dp); cache_page (page); free_page (page); return 1; - } else if ((first = ptable_list.next) != dp) { + } else if (ptable_list.next != dp) { /* * move this descriptor to the front of the list, since * it has one or more free tables. */ - ptable_desc *next = dp->next; - (next->prev = dp->prev)->next = next; - - (dp->prev = first->prev)->next = dp; - (dp->next = first)->prev = dp; + list_del(dp); + list_add(dp, &ptable_list); } return 0; } diff -ur --new-file old/linux/arch/m68k/mm/motorola.c new/linux/arch/m68k/mm/motorola.c --- old/linux/arch/m68k/mm/motorola.c Sat Sep 4 22:06:41 1999 +++ new/linux/arch/m68k/mm/motorola.c Wed Jan 26 21:44:20 2000 @@ -17,6 +17,7 @@ #include #include #include +#include #ifdef CONFIG_BLK_DEV_RAM #include #endif @@ -24,10 +25,11 @@ #include #include #include -#include +#include #include #include #include +#include #ifdef CONFIG_ATARI #include #endif @@ -43,15 +45,14 @@ unsigned long mm_cachebits = 0; #endif -static pte_t * __init kernel_page_table(unsigned long *memavailp) +static pte_t * __init kernel_page_table(void) { pte_t *ptablep; - ptablep = (pte_t *)*memavailp; - *memavailp += PAGE_SIZE; + ptablep = (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE); - clear_page((unsigned long)ptablep); - flush_page_to_ram((unsigned long) ptablep); + clear_page(ptablep); + __flush_page_to_ram((unsigned long) ptablep); flush_tlb_kernel_page((unsigned long) ptablep); nocache_page ((unsigned long)ptablep); @@ -61,7 +62,7 @@ static pmd_t *last_pgtable __initdata = NULL; pmd_t *zero_pgtable __initdata = NULL; -static pmd_t * __init kernel_ptr_table(unsigned long *memavailp) +static pmd_t * __init kernel_ptr_table(void) { if (!last_pgtable) { unsigned long pmd, last; @@ -75,7 +76,7 @@ for (i = 0; i < PTRS_PER_PGD; i++) { if (!pgd_present(kernel_pg_dir[i])) continue; - pmd = pgd_page(kernel_pg_dir[i]); + pmd = __pgd_page(kernel_pg_dir[i]); if (pmd > last) last = pmd; } @@ -87,11 +88,10 @@ } if (((unsigned long)(last_pgtable + PTRS_PER_PMD) & ~PAGE_MASK) == 0) { - last_pgtable = (pmd_t *)*memavailp; - *memavailp += PAGE_SIZE; + last_pgtable = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE); - clear_page((unsigned long)last_pgtable); - flush_page_to_ram((unsigned long)last_pgtable); + clear_page(last_pgtable); + __flush_page_to_ram((unsigned long)last_pgtable); flush_tlb_kernel_page((unsigned long)last_pgtable); nocache_page((unsigned long)last_pgtable); } else @@ -101,7 +101,7 @@ } static unsigned long __init -map_chunk (unsigned long addr, long size, unsigned long *memavailp) +map_chunk (unsigned long addr, long size) { #define PTRTREESIZE (256*1024) #define ROOTTREESIZE (32*1024*1024) @@ -137,7 +137,7 @@ } } if (!pgd_present(*pgd_dir)) { - pmd_dir = kernel_ptr_table(memavailp); + pmd_dir = kernel_ptr_table(); #ifdef DEBUG printk ("[new pointer %p]", pmd_dir); #endif @@ -157,7 +157,7 @@ #ifdef DEBUG printk ("[zero map]"); #endif - zero_pgtable = kernel_ptr_table(memavailp); + zero_pgtable = kernel_ptr_table(); pte_dir = (pte_t *)zero_pgtable; pmd_dir->pmd[0] = virt_to_phys(pte_dir) | _PAGE_TABLE | _PAGE_ACCESSED; @@ -173,7 +173,7 @@ #ifdef DEBUG printk ("[new table]"); #endif - pte_dir = kernel_page_table(memavailp); + pte_dir = kernel_page_table(); pmd_set(pmd_dir, pte_dir); } pte_dir = pte_offset(pmd_dir, virtaddr); @@ -196,7 +196,6 @@ return virtaddr; } -extern unsigned long free_area_init(unsigned long, unsigned long); extern unsigned long empty_bad_page_table; extern unsigned long empty_bad_page; @@ -204,11 +203,11 @@ * paging_init() continues the virtual memory environment setup which * was begun by the code in arch/head.S. */ -unsigned long __init paging_init(unsigned long start_mem, - unsigned long end_mem) +void __init paging_init(void) { int chunk; unsigned long mem_avail = 0; + unsigned int zones_size[3] = { 0, }; #ifdef DEBUG { @@ -248,7 +247,7 @@ for (chunk = 0; chunk < m68k_num_memory; chunk++) { mem_avail = map_chunk (m68k_memory[chunk].addr, - m68k_memory[chunk].size, &start_mem); + m68k_memory[chunk].size); } @@ -263,12 +262,9 @@ * initialize the bad page table and bad page to point * to a couple of allocated pages */ - empty_bad_page_table = start_mem; - start_mem += PAGE_SIZE; - empty_bad_page = start_mem; - start_mem += PAGE_SIZE; - empty_zero_page = start_mem; - start_mem += PAGE_SIZE; + empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); + empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); + empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); memset((void *)empty_zero_page, 0, PAGE_SIZE); /* @@ -279,7 +275,14 @@ #ifdef DEBUG printk ("before free_area_init\n"); #endif - return PAGE_ALIGN(free_area_init(start_mem, end_mem)); + zones_size[0] = (mach_max_dma_address < (unsigned long)high_memory ? + mach_max_dma_address : (unsigned long)high_memory); + zones_size[1] = (unsigned long)high_memory - zones_size[0]; + + zones_size[0] = (zones_size[0] - PAGE_OFFSET) >> PAGE_SHIFT; + zones_size[1] >>= PAGE_SHIFT; + + free_area_init(zones_size); } extern char __init_begin, __init_end; diff -ur --new-file old/linux/arch/m68k/mm/sun3mmu.c new/linux/arch/m68k/mm/sun3mmu.c --- old/linux/arch/m68k/mm/sun3mmu.c Sat Sep 4 22:06:41 1999 +++ new/linux/arch/m68k/mm/sun3mmu.c Wed Jan 26 21:44:20 2000 @@ -80,7 +80,7 @@ /* now change pg_table to kernel virtual addresses */ pg_table = (pte_t *) __va ((unsigned long) pg_table); for (i=0; i= end_mem) pte_val (pte) = 0; set_pte (pg_table, pte); diff -ur --new-file old/linux/arch/m68k/mvme147/config.c new/linux/arch/m68k/mvme147/config.c --- old/linux/arch/m68k/mvme147/config.c Thu Aug 26 21:42:31 1999 +++ new/linux/arch/m68k/mvme147/config.c Wed Jan 26 21:44:21 2000 @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -62,6 +63,14 @@ void (*tick_handler)(int, void *, struct pt_regs *); +int mvme147_parse_bootinfo(const struct bi_record *bi) +{ + if (bi->tag == BI_VME_TYPE || bi->tag == BI_VME_BRDINFO) + return 0; + else + return 1; +} + int mvme147_kbdrate (struct kbd_repeat *k) { return 0; @@ -109,6 +118,10 @@ disable_irq = mvme147_disable_irq; mach_get_model = mvme147_get_model; mach_get_hardware_list = mvme147_get_hardware_list; + + /* Board type is only set by newer versions of vmelilo/tftplilo */ + if (!vme_brdtype) + vme_brdtype = VME_TYPE_MVME147; } diff -ur --new-file old/linux/arch/m68k/mvme16x/Makefile new/linux/arch/m68k/mvme16x/Makefile --- old/linux/arch/m68k/mvme16x/Makefile Sat Jun 13 22:14:33 1998 +++ new/linux/arch/m68k/mvme16x/Makefile Wed Jan 26 21:44:21 2000 @@ -9,6 +9,6 @@ O_TARGET := mvme16x.o O_OBJS := config.o 16xints.o rtc.o -#OX_OBJS = ksyms.o +OX_OBJS := mvme16x_ksyms.o include $(TOPDIR)/Rules.make diff -ur --new-file old/linux/arch/m68k/mvme16x/config.c new/linux/arch/m68k/mvme16x/config.c --- old/linux/arch/m68k/mvme16x/config.c Thu Aug 26 21:42:31 1999 +++ new/linux/arch/m68k/mvme16x/config.c Fri Jan 28 17:04:58 2000 @@ -14,7 +14,6 @@ * for more details. */ -#include #include #include #include @@ -25,6 +24,7 @@ #include #include +#include #include #include #include @@ -35,6 +35,7 @@ int atari_SCC_reset_done = 1; /* So SCC doesn't get reset */ u_long atari_mch_cookie = 0; +extern t_bdid mvme_bdid; static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE; @@ -71,6 +72,14 @@ unsigned short mvme16x_config; +int mvme16x_parse_bootinfo(const struct bi_record *bi) +{ + if (bi->tag == BI_VME_TYPE || bi->tag == BI_VME_BRDINFO) + return 0; + else + return 1; +} + int mvme16x_kbdrate (struct kbd_repeat *k) { return 0; @@ -91,7 +100,7 @@ static void mvme16x_get_model(char *model) { - p_bdid p = (p_bdid)mvme_bdid_ptr; + p_bdid p = &mvme_bdid; char suf[4]; suf[1] = p->brdsuffix[0]; @@ -105,7 +114,7 @@ static int mvme16x_get_hardware_list(char *buffer) { - p_bdid p = (p_bdid)mvme_bdid_ptr; + p_bdid p = &mvme_bdid; int len = 0; if (p->brdno == 0x0162 || p->brdno == 0x0172) @@ -133,7 +142,7 @@ void __init config_mvme16x(void) { - p_bdid p = (p_bdid)mvme_bdid_ptr; + p_bdid p = &mvme_bdid; char id[40]; mach_sched_init = mvme16x_sched_init; @@ -163,6 +172,10 @@ while (1) ; } + /* Board type is only set by newer versions of vmelilo/tftplilo */ + if (vme_brdtype == 0) + vme_brdtype = p->brdno; + mvme16x_get_model(id); printk ("\nBRD_ID: %s BUG %x.%x %02x/%02x/%02x\n", id, p->rev>>4, p->rev&0xf, p->yr, p->mth, p->day); @@ -199,7 +212,7 @@ static void mvme16x_abort_int (int irq, void *dev_id, struct pt_regs *fp) { - p_bdid p = (p_bdid)mvme_bdid_ptr; + p_bdid p = &mvme_bdid; unsigned long *new = (unsigned long *)vectors; unsigned long *old = (unsigned long *)0xffe00000; volatile unsigned char uc, *ucp; @@ -232,7 +245,7 @@ void mvme16x_sched_init (void (*timer_routine)(int, void *, struct pt_regs *)) { - p_bdid p = (p_bdid)mvme_bdid_ptr; + p_bdid p = &mvme_bdid; int irq; tick_handler = timer_routine; @@ -294,80 +307,3 @@ return 0; } -/*------------------- Serial console stuff ------------------------*/ - -extern void mvme167_serial_console_setup(int cflag); -extern void serial167_write(struct console *co, const char *str, unsigned cnt); -extern void vme_scc_write(struct console *co, const char *str, unsigned cnt); - - -void mvme16x_init_console_port (struct console *co, int cflag) -{ - p_bdid p = (p_bdid)mvme_bdid_ptr; - - switch (p->brdno) - { -#ifdef CONFIG_MVME162_SCC - case 0x0162: - case 0x0172: - co->write = vme_scc_write; - return; -#endif -#ifdef CONFIG_SERIAL167 - case 0x0166: - case 0x0167: - case 0x0176: - case 0x0177: - co->write = serial167_write; - mvme167_serial_console_setup (cflag); - return; -#endif - default: - panic ("No console support for MVME%x\n", p->brdno); - } - return; -} - - -#ifdef CONFIG_MVME162_SCC - -static void scc_delay (void) -{ - int n; - volatile int trash; - - for (n = 0; n < 20; n++) - trash = n; -} - -static void scc_write (char ch) -{ - volatile char *p = (volatile char *)MVME_SCC_A_ADDR; - - do { - scc_delay(); - } - while (!(*p & 4)); - scc_delay(); - *p = 8; - scc_delay(); - *p = ch; -} - - -void vme_scc_write (struct console *co, const char *str, unsigned count) -{ - unsigned long flags; - - save_flags(flags); - cli(); - - while (count--) - { - if (*str == '\n') - scc_write ('\r'); - scc_write (*str++); - } - restore_flags(flags); -} -#endif diff -ur --new-file old/linux/arch/m68k/mvme16x/mvme16x_ksyms.c new/linux/arch/m68k/mvme16x/mvme16x_ksyms.c --- old/linux/arch/m68k/mvme16x/mvme16x_ksyms.c Thu Jan 1 01:00:00 1970 +++ new/linux/arch/m68k/mvme16x/mvme16x_ksyms.c Wed Jan 26 21:44:21 2000 @@ -0,0 +1,6 @@ +#include +#include +#include +#include + +EXPORT_SYMBOL(mvme16x_config); diff -ur --new-file old/linux/arch/m68k/mvme16x/rtc.c new/linux/arch/m68k/mvme16x/rtc.c --- old/linux/arch/m68k/mvme16x/rtc.c Thu Aug 26 21:42:31 1999 +++ new/linux/arch/m68k/mvme16x/rtc.c Wed Jan 26 21:44:21 2000 @@ -67,8 +67,9 @@ } case RTC_SET_TIME: /* Set the RTC */ { - unsigned char leap_yr; struct rtc_time rtc_tm; + unsigned char mon, day, hrs, min, sec, leap_yr; + unsigned int yrs; if (!suser()) return -EACCES; @@ -77,31 +78,41 @@ sizeof(struct rtc_time))) return -EFAULT; - leap_yr = ((!(rtc_tm.tm_year % 4) && (rtc_tm.tm_year % 100)) || !(rtc_tm.tm_year % 400)); + yrs = rtc_tm.tm_year; + if (yrs < 1900) + yrs += 1900; + mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ + day = rtc_tm.tm_mday; + hrs = rtc_tm.tm_hour; + min = rtc_tm.tm_min; + sec = rtc_tm.tm_sec; - if ((rtc_tm.tm_mon > 12) || (rtc_tm.tm_mday == 0)) + leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); + + if ((mon > 12) || (day == 0)) return -EINVAL; - if (rtc_tm.tm_mday > (days_in_mo[rtc_tm.tm_mon] + ((rtc_tm.tm_mon == 2) && leap_yr))) + if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) return -EINVAL; - - if ((rtc_tm.tm_hour >= 24) || (rtc_tm.tm_min >= 60) || (rtc_tm.tm_sec >= 60)) + + if ((hrs >= 24) || (min >= 60) || (sec >= 60)) return -EINVAL; + if (yrs >= 2070) + return -EINVAL; + save_flags(flags); cli(); - rtc->ctrl = RTC_WRITE; + rtc->ctrl = RTC_WRITE; - rtc->bcd_sec = BIN2BCD(rtc_tm.tm_sec); - rtc->bcd_min = BIN2BCD(rtc_tm.tm_min); - rtc->bcd_hr = BIN2BCD(rtc_tm.tm_hour); - rtc->bcd_dom = BIN2BCD(rtc_tm.tm_mday); - rtc->bcd_mth = BIN2BCD(rtc_tm.tm_mon + 1); - rtc->bcd_year = BIN2BCD(rtc_tm.tm_year%100); - if (rtc_tm.tm_wday >= 0) - rtc->bcd_dow = BIN2BCD(rtc_tm.tm_wday+1); + rtc->bcd_sec = BIN2BCD(sec); + rtc->bcd_min = BIN2BCD(min); + rtc->bcd_hr = BIN2BCD(hrs); + rtc->bcd_dom = BIN2BCD(day); + rtc->bcd_mth = BIN2BCD(mon); + rtc->bcd_year = BIN2BCD(yrs%100); - rtc->ctrl = 0; + rtc->ctrl = 0; restore_flags(flags); return 0; } diff -ur --new-file old/linux/arch/m68k/sun3/Makefile new/linux/arch/m68k/sun3/Makefile --- old/linux/arch/m68k/sun3/Makefile Mon Dec 20 23:43:39 1999 +++ new/linux/arch/m68k/sun3/Makefile Wed Jan 26 21:44:21 2000 @@ -11,6 +11,7 @@ $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -Wa,-m68020 -c $< -o $*.o O_TARGET := sun3.o -O_OBJS := config.o idprom.o mmu_emu.o sun3ints.o leds.o dvma.o sbus.o +O_OBJS := config.o idprom.o mmu_emu.o sun3ints.o leds.o dvma.o sbus.o intersil.o +OX_OBJS := sun3_ksyms.o include $(TOPDIR)/Rules.make diff -ur --new-file old/linux/arch/m68k/sun3/config.c new/linux/arch/m68k/sun3/config.c --- old/linux/arch/m68k/sun3/config.c Wed Sep 8 20:20:42 1999 +++ new/linux/arch/m68k/sun3/config.c Wed Jan 26 21:44:21 2000 @@ -36,7 +36,7 @@ static int kernel_start, kernel_end; char sun3_reserved_pmeg[SUN3_PMEGS_NUM]; -static unsigned long sun3_gettimeoffset(void); +extern unsigned long sun3_gettimeoffset(void); extern int sun3_get_irq_list (char *); extern void sun3_sched_init(void (*handler)(int, void *, struct pt_regs *)); extern void sun3_init_IRQ (void); @@ -50,8 +50,9 @@ extern void sun3_disable_interrupts (void); extern void sun3_get_model (unsigned char* model); extern void idprom_init (void); -void sun3_gettod (int *yearp, int *monp, int *dayp, +extern void sun3_gettod (int *yearp, int *monp, int *dayp, int *hourp, int *minp, int *secp); +extern int sun3_hwclk(int set, struct hwclk_time *t); extern unsigned long sun_serial_setup(unsigned long memory_start); volatile char* clock_va; @@ -106,6 +107,11 @@ prom_reboot ("vmlinux"); } +static void sun3_halt (void) +{ + prom_halt (); +} + void __init config_sun3(unsigned long *start_mem_p, unsigned long *end_mem_p) { printk("ARCH: SUN3\n"); @@ -126,6 +132,8 @@ mach_reset = sun3_reboot; mach_gettimeoffset = sun3_gettimeoffset; mach_get_model = sun3_get_model; + mach_hwclk = sun3_hwclk; + mach_halt = sun3_halt; #ifndef CONFIG_SERIAL_CONSOLE conswitchp = &dummy_con; #endif @@ -151,23 +159,5 @@ intersil_clock->cmd_reg=(INTERSIL_RUN|INTERSIL_INT_ENABLE|INTERSIL_24H_MODE); sun3_enable_interrupts(); intersil_clear(); -} - -static unsigned long sun3_gettimeoffset(void) -{ - return 1; -} - -void sun3_gettod (int *yearp, int *monp, int *dayp, - int *hourp, int *minp, int *secp) -{ - struct intersil_dt* todintersil; - todintersil = (struct intersil_dt *) &intersil_clock->counter; - *secp = todintersil->second; - *minp = todintersil->minute; - *hourp = todintersil->hour; - *dayp = todintersil->day; - *monp = todintersil->month; - *yearp = todintersil->year+68; /* The base year for sun3 is 1968 */ } diff -ur --new-file old/linux/arch/m68k/sun3/intersil.c new/linux/arch/m68k/sun3/intersil.c --- old/linux/arch/m68k/sun3/intersil.c Thu Jan 1 01:00:00 1970 +++ new/linux/arch/m68k/sun3/intersil.c Wed Jan 26 21:44:21 2000 @@ -0,0 +1,100 @@ +/* + * arch/m68k/sun3/intersil.c + * + * basic routines for accessing the intersil clock within the sun3 machines + * + * started 11/12/1999 Sam Creasey + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include +#include + +#include +#include + + +/* bits to set for start/run of the intersil */ +#define STOP_VAL (INTERSIL_STOP | INTERSIL_INT_ENABLE | INTERSIL_24H_MODE) +#define START_VAL (INTERSIL_RUN | INTERSIL_INT_ENABLE | INTERSIL_24H_MODE) + +/* does this need to be implemented? */ +unsigned long sun3_gettimeoffset(void) +{ + return 1; +} + +void sun3_gettod (int *yearp, int *monp, int *dayp, + int *hourp, int *minp, int *secp) +{ + u_char wday; + volatile struct intersil_dt* todintersil; + unsigned long flags; + + todintersil = (struct intersil_dt *) &intersil_clock->counter; + + save_and_cli(flags); + + intersil_clock->cmd_reg = STOP_VAL; + + *secp = todintersil->csec; + *hourp = todintersil->hour; + *minp = todintersil->minute; + *secp = todintersil->second; + *monp = todintersil->month; + *dayp = todintersil->day; + *yearp = todintersil->year+68; /* The base year for sun3 is 1968 */ + wday = todintersil->weekday; + + intersil_clock->cmd_reg = START_VAL; + + restore_flags(flags); +} + + +/* get/set hwclock */ + +int sun3_hwclk(int set, struct hwclk_time *t) +{ + volatile struct intersil_dt *todintersil; + unsigned long flags; + + todintersil = (struct intersil_dt *) &intersil_clock->counter; + + save_and_cli(flags); + + intersil_clock->cmd_reg = STOP_VAL; + + /* set or read the clock */ + if(set) { + todintersil->csec = 0; + todintersil->hour = t->hour; + todintersil->minute = t->min; + todintersil->second = t->sec; + todintersil->month = t->mon; + todintersil->day = t->day; + todintersil->year = t->year - 68; + todintersil->weekday = t->wday; + } else { + /* read clock */ + t->sec = todintersil->csec; + t->hour = todintersil->hour; + t->min = todintersil->minute; + t->sec = todintersil->second; + t->mon = todintersil->month; + t->day = todintersil->day; + t->year = todintersil->year + 68; + t->wday = todintersil->weekday; + } + + intersil_clock->cmd_reg = START_VAL; + + restore_flags(flags); + + return 0; + +} + diff -ur --new-file old/linux/arch/m68k/sun3/mmu_emu.c new/linux/arch/m68k/sun3/mmu_emu.c --- old/linux/arch/m68k/sun3/mmu_emu.c Sat Sep 4 22:06:41 1999 +++ new/linux/arch/m68k/sun3/mmu_emu.c Wed Jan 26 21:44:21 2000 @@ -51,9 +51,7 @@ context. 0xffffffff is a marker for kernel context */ struct mm_struct *ctx_alloc[CONTEXTS_NUM] = {0xffffffff, 0, 0, 0, 0, 0, 0, 0}; /* has this context been mmdrop'd? */ -unsigned char ctx_live[CONTEXTS_NUM] = {1, 0, 0, 0, 0, 0, 0, 0}; static unsigned char ctx_avail = CONTEXTS_NUM-1; -unsigned char ctx_next_to_die = 1; /* array of pages to be marked off for the rom when we do mem_init later */ /* 256 pages lets the rom take up to 2mb of physical ram.. I really @@ -213,45 +211,29 @@ unsigned char oldctx; unsigned long i; - if(!ctx_alloc[context]) - panic("clear_context: context not allocated\n"); + if(context) { + if(!ctx_alloc[context]) + panic("clear_context: context not allocated\n"); + + ctx_alloc[context]->context = SUN3_INVALID_CONTEXT; + ctx_alloc[context] = (struct mm_struct *)0; + ctx_avail++; + } oldctx = sun3_get_context(); sun3_put_context(context); - /* ctx_live denotes if we're clearing a context with an active - mm, in which case we can use the pgd for clues and also should - mark that mm as lacking a context. if the context has been - mmdrop'd, then flush outright. */ - - if(!ctx_live[context]) { - for(i = 0; i < TASK_SIZE ; i += SUN3_PMEG_SIZE) - sun3_put_segmap(i, SUN3_INVALID_PMEG); - } else { - pgd_t *pgd; - - pgd = ctx_alloc[context]->pgd; - ctx_alloc[context]->context = SUN3_INVALID_CONTEXT; - for(i = 0; i < (TASK_SIZE>>PGDIR_SHIFT); i++, pgd++) - { - if(pgd_val(*pgd)) { - sun3_put_segmap(i< +#include +#include +#include + +/* + * Add things here when you find the need for it. + */ +EXPORT_SYMBOL(sun3_dvma_malloc); +EXPORT_SYMBOL(idprom); diff -ur --new-file old/linux/arch/ppc/kernel/entry.S new/linux/arch/ppc/kernel/entry.S --- old/linux/arch/ppc/kernel/entry.S Fri Jan 14 03:03:57 2000 +++ new/linux/arch/ppc/kernel/entry.S Tue Jan 25 20:17:07 2000 @@ -271,6 +271,7 @@ bl schedule_tail b ret_from_except #endif + .globl ret_from_intercept ret_from_intercept: /* @@ -278,7 +279,16 @@ * -- Cort */ cmpi 0,r3,0 - beq 10f + bne ret_from_except + /* + * If we're returning from user mode we do things differently + * -- Cort + */ + lwz r3,_MSR(r1) + andi. r3,r3,MSR_PR + beq+ 10f + b 8f + .globl ret_from_except ret_from_except: 0: /* disable interrupts */ @@ -315,7 +325,6 @@ lwz r30,0(r30) mtlr r30 blrl - lwz r3,_MSR(r1) /* Returning to user mode? */ andi. r3,r3,MSR_PR beq+ 10f /* if so, check need_resched and signals */ @@ -337,7 +346,13 @@ stw r4,THREAD+KSP(r2) /* save kernel stack pointer */ tophys(r3,r1) mtspr SPRG2,r3 /* phys exception stack pointer */ -10: lwz r2,_CTR(r1) +10: /* make sure we hard disable here, even if rtl is active -- Cort */ + mfmsr r0 /* Get current interrupt state */ + rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ + sync /* Some chip revs have problems here... */ + mtmsr r0 /* Update machine state */ + + lwz r2,_CTR(r1) lwz r0,_LINK(r1) mtctr r2 mtlr r0 diff -ur --new-file old/linux/arch/ppc/kernel/i8259.c new/linux/arch/ppc/kernel/i8259.c --- old/linux/arch/ppc/kernel/i8259.c Thu Oct 7 19:17:08 1999 +++ new/linux/arch/ppc/kernel/i8259.c Tue Jan 25 20:17:07 2000 @@ -10,6 +10,8 @@ #define cached_A1 (cached_8259[0]) #define cached_21 (cached_8259[1]) +int i8259_pic_irq_offset; + int i8259_irq(int cpu) { int irq; @@ -46,8 +48,8 @@ static void i8259_mask_and_ack_irq(unsigned int irq_nr) { - if ( irq_nr >= i8259_pic.irq_offset ) - irq_nr -= i8259_pic.irq_offset; + if ( irq_nr >= i8259_pic_irq_offset ) + irq_nr -= i8259_pic_irq_offset; if (irq_nr > 7) { cached_A1 |= 1 << (irq_nr-8); @@ -71,8 +73,8 @@ static void i8259_mask_irq(unsigned int irq_nr) { - if ( irq_nr >= i8259_pic.irq_offset ) - irq_nr -= i8259_pic.irq_offset; + if ( irq_nr >= i8259_pic_irq_offset ) + irq_nr -= i8259_pic_irq_offset; if ( irq_nr < 8 ) cached_21 |= 1 << irq_nr; else @@ -83,8 +85,8 @@ static void i8259_unmask_irq(unsigned int irq_nr) { - if ( irq_nr >= i8259_pic.irq_offset ) - irq_nr -= i8259_pic.irq_offset; + if ( irq_nr >= i8259_pic_irq_offset ) + irq_nr -= i8259_pic_irq_offset; if ( irq_nr < 8 ) cached_21 &= ~(1 << irq_nr); else @@ -123,7 +125,7 @@ outb(0xFF, 0xA1); /* Mask all */ outb(cached_A1, 0xA1); outb(cached_21, 0x21); - request_irq( i8259_pic.irq_offset + 2, no_action, SA_INTERRUPT, + request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT, "82c59 secondary cascade", NULL ); - enable_irq(i8259_pic.irq_offset + 2); /* Enable cascade interrupt */ + enable_irq(i8259_pic_irq_offset + 2); /* Enable cascade interrupt */ } diff -ur --new-file old/linux/arch/ppc/kernel/misc.S new/linux/arch/ppc/kernel/misc.S --- old/linux/arch/ppc/kernel/misc.S Thu Dec 2 23:37:34 1999 +++ new/linux/arch/ppc/kernel/misc.S Tue Jan 25 20:17:07 2000 @@ -1068,4 +1068,6 @@ .long sys_ni_syscall /* streams2 */ .long sys_vfork .long sys_getrlimit /* 190 */ - .space (NR_syscalls-190)*4 + .rept NR_syscalls-190 + .long sys_ni_syscall + .endr diff -ur --new-file old/linux/arch/ppc/xmon/start.c new/linux/arch/ppc/xmon/start.c --- old/linux/arch/ppc/xmon/start.c Tue Jan 11 03:25:06 2000 +++ new/linux/arch/ppc/xmon/start.c Tue Jan 25 20:17:07 2000 @@ -70,7 +70,7 @@ sccd = sccc + (0xf3013030 - 0xf3013020); #endif } - else + else if ( _machine & _MACH_chrp ) { /* should already be mapped by the kernel boot */ sccc = (volatile unsigned char *) (isa_io_base + 0x3fd); @@ -78,6 +78,15 @@ TXRDY = 0x20; RXRDY = 1; } + else if ( _machine & _MACH_gemini ) + { + /* should already be mapped by the kernel boot */ + sccc = (volatile unsigned char *) 0xffeffb0d; + sccd = (volatile unsigned char *) 0xffeffb08; + TXRDY = 0x20; + RXRDY = 1; + console = 1; + } } static int scc_initialized = 0; @@ -226,7 +235,7 @@ void xmon_init_scc() { - if ( _machine == _MACH_chrp ) + if ( _machine & (_MACH_chrp|_MACH_gemini) ) { sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */ sccd[0] = 3; eieio(); /* DLL = 38400 baud */ @@ -235,7 +244,7 @@ sccd[3] = 3; eieio(); /* LCR = 8N1 */ sccd[1] = 0; eieio(); /* IER = 0 */ } - else + else if ( _machine == _MACH_Pmac ) { int i, x; diff -ur --new-file old/linux/arch/sh/kernel/sys_sh.c new/linux/arch/sh/kernel/sys_sh.c --- old/linux/arch/sh/kernel/sys_sh.c Sat Nov 6 19:40:31 1999 +++ new/linux/arch/sh/kernel/sys_sh.c Thu Jan 27 15:32:14 2000 @@ -170,9 +170,9 @@ int err; if (!name) return -EFAULT; - down(&uts_sem); + down_read(&uts_sem); err=copy_to_user(name, &system_utsname, sizeof (*name)); - up(&uts_sem); + up_read(&uts_sem); return err?-EFAULT:0; } diff -ur --new-file old/linux/arch/sparc/config.in new/linux/arch/sparc/config.in --- old/linux/arch/sparc/config.in Sun Jan 16 07:08:28 2000 +++ new/linux/arch/sparc/config.in Mon Jan 24 04:48:47 2000 @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.80 2000/01/14 07:12:30 davem Exp $ +# $Id: config.in,v 1.81 2000/01/22 05:14:44 zaitcev Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -37,7 +37,6 @@ mainmenu_option next_comment comment 'Console drivers' bool 'PROM console' CONFIG_PROM_CONSOLE - bool 'Support Frame buffer devices' CONFIG_FB source drivers/video/Config.in endmenu diff -ur --new-file old/linux/arch/sparc/kernel/ebus.c new/linux/arch/sparc/kernel/ebus.c --- old/linux/arch/sparc/kernel/ebus.c Tue Dec 21 07:05:52 1999 +++ new/linux/arch/sparc/kernel/ebus.c Mon Jan 24 04:48:47 2000 @@ -1,4 +1,4 @@ -/* $Id: ebus.c,v 1.8 1999/11/27 22:40:38 zaitcev Exp $ +/* $Id: ebus.c,v 1.9 2000/01/22 07:35:25 zaitcev Exp $ * ebus.c: PCI to EBus bridge device. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -22,14 +22,6 @@ #include #include -#undef PROM_DEBUG - -#if 0 /* separate from PROM_DEBUG for the sake of PROLL */ -#define dprintk prom_printf -#else -#define dprintk printk -#endif - struct linux_ebus *ebus_chain = 0; #ifdef CONFIG_SUN_OPENPROMIO @@ -51,11 +43,62 @@ /* We are together with pcic.c under CONFIG_PCI. */ extern unsigned int pcic_pin_to_irq(unsigned int, char *name); +/* + * IRQ Blacklist + * Here we list PROMs and systems that are known to supply crap as IRQ numbers. + */ +struct ebus_device_irq { + char *name; + unsigned int pin; +}; + +struct ebus_system_entry { + char *esname; + struct ebus_device_irq *ipt; +}; + +static struct ebus_device_irq je1_1[] = { + { "8042", 3 }, + { "SUNW,CS4231", 0 }, + { "parallel", 0 }, + { "se", 2 }, + { 0, 0 } +}; + +/* + * Gleb's JE1 supplied reasonable pin numbers, but mine did not (OBP 2.32). + * Blacklist the sucker... Note that Gleb's system will work. + */ +static struct ebus_system_entry ebus_blacklist[] = { + { "SUNW,JavaEngine1", je1_1 }, + { 0, 0 } +}; + +static struct ebus_device_irq *ebus_blackp = NULL; + +/* + */ static inline unsigned long ebus_alloc(size_t size) { return (unsigned long)kmalloc(size, GFP_ATOMIC); } +/* + */ +int __init ebus_blacklist_irq(char *name) +{ + struct ebus_device_irq *dp; + + if ((dp = ebus_blackp) != NULL) { + for (; dp->name != NULL; dp++) { + if (strcmp(name, dp->name) == 0) { + return pcic_pin_to_irq(dp->pin, name); + } + } + } + return 0; +} + void __init fill_ebus_child(int node, struct linux_prom_registers *preg, struct linux_ebus_child *dev) { @@ -81,14 +124,10 @@ dev->resource[i].start = dev->parent->resource[regs[i]].start; /* XXX resource */ } - /* - * Houston, we have a problem... - * Sometimes PROM supplies absolutely meaningless properties. - * Still, we take what it gives since we have nothing better. - * Children of ebus may be wired on any input pin of PCIC. - */ - len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs)); - if ((len == -1) || (len == 0)) { + if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_name)) != 0) { + dev->num_irqs = 1; + } else if ((len = prom_getproperty(node, "interrupts", + (char *)&irqs, sizeof(irqs)) == -1) || (len == 0)) { dev->num_irqs = 0; dev->irqs[0] = 0; if (dev->parent->num_irqs != 0) { @@ -177,8 +216,10 @@ dev->resource[i].start = baseaddr; /* XXX Unaligned */ } - len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs)); - if ((len == -1) || (len == 0)) { + if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_name)) != 0) { + dev->num_irqs = 1; + } else if ((len = prom_getproperty(node, "interrupts", + (char *)&irqs, sizeof(irqs)) == -1) || (len == 0)) { dev->num_irqs = 0; if ((dev->irqs[0] = dev->bus->self->irq) != 0) { dev->num_irqs = 1; @@ -226,6 +267,7 @@ struct linux_pbm_info *pbm; struct linux_ebus_device *dev; struct linux_ebus *ebus; + struct ebus_system_entry *sp; struct pci_dev *pdev; struct pcidev_cookie *cookie; char lbuf[128]; @@ -238,11 +280,16 @@ if (!pci_present()) return; + prom_getstring(prom_root_node, "name", lbuf, sizeof(lbuf)); + for (sp = ebus_blacklist; sp->esname != NULL; sp++) { + if (strcmp(lbuf, sp->esname) == 0) { + ebus_blackp = sp->ipt; + break; + } + } + pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0); if (!pdev) { -#ifdef PROM_DEBUG - dprintk("ebus: No EBus's found.\n"); -#endif return; } cookie = pdev->sysdata; @@ -253,9 +300,6 @@ ebus->next = 0; while (ebusnd) { -#ifdef PROM_DEBUG - dprintk("ebus%d:", num_ebus); -#endif prom_getstring(ebusnd, "name", lbuf, sizeof(lbuf)); ebus->prom_node = ebusnd; @@ -284,13 +328,7 @@ addr = regs[reg].phys_lo; *base++ = addr; -#ifdef PROM_DEBUG - dprintk(" %lx[%x]", addr, regs[reg].size_lo); -#endif } -#ifdef PROM_DEBUG - dprintk("\n"); -#endif nd = prom_getchild(ebusnd); if (!nd) diff -ur --new-file old/linux/arch/sparc/kernel/ioport.c new/linux/arch/sparc/kernel/ioport.c --- old/linux/arch/sparc/kernel/ioport.c Mon Jan 3 21:01:31 2000 +++ new/linux/arch/sparc/kernel/ioport.c Thu Jan 27 17:58:15 2000 @@ -1,4 +1,4 @@ -/* $Id: ioport.c,v 1.28 1999/12/27 06:08:28 anton Exp $ +/* $Id: ioport.c,v 1.29 2000/01/22 07:35:25 zaitcev Exp $ * ioport.c: Simple io mapping allocator. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -203,6 +203,7 @@ tlen = strlen(name); tack = kmalloc(sizeof (struct resource) + tlen + 1, GFP_KERNEL); if (tack == NULL) return NULL; + memset(tack, 0, sizeof(struct resource)); res = (struct resource *) tack; tack += sizeof (struct resource); } @@ -285,8 +286,10 @@ * Allocate a chunk of memory suitable for DMA. * Typically devices use them for control blocks. * CPU may access them without any explicit flushing. + * + * XXX Some clever people know that sdev is not used and supply NULL. Watch. */ -void *sbus_alloc_consistant(struct sbus_dev *sdev, long len, u32 *dma_addrp) +void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp) { unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK; unsigned long va; @@ -310,26 +313,27 @@ /* * printk here may be flooding... Consider removal XXX. */ - printk("sbus_alloc_consistant: no %ld pages\n", len_total>>PAGE_SHIFT); + printk("sbus_alloc_consistent: no %ld pages\n", len_total>>PAGE_SHIFT); return NULL; } if ((res = kmalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) { free_pages(va, order); - printk("sbus_alloc_consistant: no core\n"); + printk("sbus_alloc_consistent: no core\n"); return NULL; } + memset((char*)res, 0, sizeof(struct resource)); if (allocate_resource(&sparc_dvma, res, len_total, sparc_dvma.start, sparc_dvma.end, PAGE_SIZE, NULL, NULL) != 0) { - printk("sbus_alloc_consistant: cannot occupy 0x%lx", len); + printk("sbus_alloc_consistent: cannot occupy 0x%lx", len_total); free_pages(va, order); kfree(res); return NULL; } *dma_addrp = res->start; - mmu_map_dma_area(va, res->start, len); + mmu_map_dma_area(va, res->start, len_total); /* * "Official" or "natural" address of pages we got is va. @@ -342,7 +346,7 @@ return (void *)res->start; } -void sbus_free_consistant(struct sbus_dev *sdev, long n, void *p, u32 ba) +void sbus_free_consistent(struct sbus_dev *sdev, long n, void *p, u32 ba) { struct resource *res; unsigned long pgp; @@ -350,18 +354,18 @@ if ((res = sparc_find_resource_bystart(&sparc_dvma, (unsigned long)p)) == NULL) { - printk("sbus_free_consistant: cannot free %p\n", p); + printk("sbus_free_consistent: cannot free %p\n", p); return; } if (((unsigned long)p & (PAGE_MASK-1)) != 0) { - printk("sbus_free_consistant: unaligned va %p\n", p); + printk("sbus_free_consistent: unaligned va %p\n", p); return; } n = (n + PAGE_SIZE-1) & PAGE_MASK; if ((res->end-res->start)+1 != n) { - printk("sbus_free_consistant: region 0x%lx asked 0x%lx\n", + printk("sbus_free_consistent: region 0x%lx asked 0x%lx\n", (long)((res->end-res->start)+1), n); return; } @@ -386,7 +390,7 @@ */ u32 sbus_map_single(struct sbus_dev *sdev, void *va, long len) { -#if 0 /* This is the version that abuses consistant space */ +#if 0 /* This is the version that abuses consistent space */ unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK; struct resource *res; @@ -403,6 +407,7 @@ printk("sbus_map_single: no core\n"); return 0; } + memset((char*)res, 0, sizeof(struct resource)); res->name = va; if (allocate_resource(&sparc_dvma, res, len_total, @@ -433,7 +438,7 @@ void sbus_unmap_single(struct sbus_dev *sdev, u32 ba, long n) { -#if 0 /* This is the version that abuses consistant space */ +#if 0 /* This is the version that abuses consistent space */ struct resource *res; unsigned long va; diff -ur --new-file old/linux/arch/sparc/kernel/pcic.c new/linux/arch/sparc/kernel/pcic.c --- old/linux/arch/sparc/kernel/pcic.c Tue Dec 21 07:05:52 1999 +++ new/linux/arch/sparc/kernel/pcic.c Mon Jan 24 04:48:47 2000 @@ -1,4 +1,4 @@ -/* $Id: pcic.c,v 1.11 1999/11/25 05:22:05 zaitcev Exp $ +/* $Id: pcic.c,v 1.12 2000/01/22 07:35:25 zaitcev Exp $ * pcic.c: Sparc/PCI controller support * * Copyright (C) 1998 V. Roganov and G. Raiko @@ -84,8 +84,6 @@ * Once we know the map we take device configuration address and * find PCIC pin number where INT line goes. Then we may either program * preferred irq into the PCIC or supply the preexisting irq to the device. - * - * XXX Entries for JE-1 are completely bogus. Gleb, Vladimir, please fill them. */ struct pcic_ca2irq { unsigned char busno; /* PCI bus number */ @@ -102,14 +100,28 @@ }; /* - * XXX JE-1 is a little known beast. - * One rumor has the map this way: pin 0 - parallel, audio; - * pin 1 - Ethernet; pin 2 - su; pin 3 - PS/2 kbd and mouse. - * All other comparable systems tie serial and keyboard together, - * so we do not code this rumor just yet. + * JavaEngine-1 apparently has different versions. + * + * According to communications with Sun folks, for P2 build 501-4628-03: + * pin 0 - parallel, audio; + * pin 1 - Ethernet; + * pin 2 - su; + * pin 3 - PS/2 kbd and mouse. + * + * OEM manual (805-1486): + * pin 0: Ethernet + * pin 1: All EBus + * pin 2: IGA (unused) + * pin 3: Not connected + * OEM manual says that 501-4628 & 501-4811 are the same thing, + * only the latter has NAND flash in place. + * + * So far unofficial Sun wins over the OEM manual. Poor OEMs... */ -static struct pcic_ca2irq pcic_i_je1[] = { +static struct pcic_ca2irq pcic_i_je1a[] = { /* 501-4811-03 */ + { 0, 0x00, 2, 12, 0 }, /* EBus: hogs all */ { 0, 0x01, 1, 6, 1 }, /* Happy Meal */ + { 0, 0x80, 0, 7, 0 }, /* IGA (unused) */ }; /* XXX JS-E entry is incomplete - PCI Slot 2 address (pin 7)? */ @@ -159,7 +171,7 @@ { name, map, sizeof(map)/sizeof(struct pcic_ca2irq) } static struct pcic_sn2list pcic_known_sysnames[] = { - SN2L_INIT("JE-1-name", pcic_i_je1), /* XXX Gleb, put name here, pls */ + SN2L_INIT("SUNW,JavaEngine1", pcic_i_je1a), /* JE1, PROM 2.32 */ SN2L_INIT("SUNW,JS-E", pcic_i_jse), /* PROLL JavaStation-E */ SN2L_INIT("SUNW,SPARCengine-6", pcic_i_se6), /* SPARCengine-6/CP-1200 */ SN2L_INIT("SUNW,JS-NC", pcic_i_jk), /* PROLL JavaStation-NC */ @@ -602,11 +614,19 @@ p->irq, dev->device, dev->vendor); dev->irq = p->irq; - ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_HI); - ivec &= ~(0xF << ((p->pin - 4) << 2)); - ivec |= p->irq << ((p->pin - 4) << 2); - writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_HI); - } + i = p->pin; + if (i >= 4) { + ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_HI); + ivec &= ~(0xF << ((i - 4) << 2)); + ivec |= p->irq << ((i - 4) << 2); + writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_HI); + } else { + ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_LO); + ivec &= ~(0xF << (i << 2)); + ivec |= p->irq << (i << 2); + writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_LO); + } + } return; } @@ -616,7 +636,7 @@ */ void __init pcibios_fixup_bus(struct pci_bus *bus) { - struct pci_dev *dev; + struct list_head *walk; int i, has_io, has_mem; unsigned short cmd; struct linux_pcic *pcic; @@ -638,7 +658,10 @@ return; } - for (dev = bus->devices; dev; dev = dev->sibling) { + walk = &bus->devices; + for (walk = walk->next; walk != &bus->devices; walk = walk->next) { + struct pci_dev *dev = pci_dev_b(walk); + /* * Comment from i386 branch: * There are buggy BIOSes that forget to enable I/O and memory @@ -832,6 +855,46 @@ } /* + */ +void pcibios_update_resource(struct pci_dev *pdev, struct resource *res1, + struct resource *res2, int index) +{ +} + +#if 0 +void pcibios_update_irq(struct pci_dev *pdev, int irq) +{ +} + +unsigned long resource_fixup(struct pci_dev *pdev, struct resource *res, + unsigned long start, unsigned long size) +{ + return start; +} + +void pcibios_fixup_pbus_ranges(struct pci_bus *pbus, + struct pbus_set_ranges_data *pranges) +{ +} +#endif + +void pcibios_align_resource(void *data, struct resource *res, unsigned long size) +{ +} + +#if 0 +int pci_assign_resource(struct pci_dev *dev, int i) +{ + return -ENOSYS; /* :-)... actually implement this soon */ +} +#endif + +int pcibios_enable_device(struct pci_dev *pdev) +{ + return 0; +} + +/* * NMI */ void pcic_nmi(unsigned int pend, struct pt_regs *regs) @@ -1015,6 +1078,72 @@ int pcibios_assign_resource(struct pci_dev *pdev, int resource) { return -ENXIO; +} + +/* + * This probably belongs here rather than ioport.c because + * we do not want this crud linked into SBus kernels. + * Also, think for a moment about likes of floppy.c that + * include architecture specific parts. They may want to redefine ins/outs. + * + * We do not use horroble macroses here because we want to + * advance pointer by sizeof(size). + */ +void outsb(unsigned long addr, const void *src, unsigned long count) { + while (count) { + count -= 1; + writeb(*(const char *)src, addr); + src += 1; + addr += 1; + } +} + +void outsw(unsigned long addr, const void *src, unsigned long count) { + while (count) { + count -= 2; + writew(*(const short *)src, addr); + src += 2; + addr += 2; + } +} + +void outsl(unsigned long addr, const void *src, unsigned long count) { + while (count) { + count -= 4; + writel(*(const long *)src, addr); + src += 4; + addr += 4; + } +} + +void insb(unsigned long addr, void *dst, unsigned long count) { + while (count) { + count -= 1; + *(unsigned char *)dst = readb(addr); + dst += 1; + addr += 1; + } +} + +void insw(unsigned long addr, void *dst, unsigned long count) { + while (count) { + count -= 2; + *(unsigned short *)dst = readw(addr); + dst += 2; + addr += 2; + } +} + +void insl(unsigned long addr, void *dst, unsigned long count) { + while (count) { + count -= 4; + /* + * XXX I am sure we are in for an unaligned trap here. + */ + *(unsigned long *)dst = readl(addr); + dst += 4; + addr += 4; + } } #endif diff -ur --new-file old/linux/arch/sparc/kernel/process.c new/linux/arch/sparc/kernel/process.c --- old/linux/arch/sparc/kernel/process.c Thu Jan 13 21:03:00 2000 +++ new/linux/arch/sparc/kernel/process.c Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.143 2000/01/09 09:13:28 anton Exp $ +/* $Id: process.c,v 1.144 2000/01/21 11:38:39 jj Exp $ * linux/arch/sparc/kernel/process.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -293,7 +293,6 @@ printk("uwinmask: 0x%08lx kregs: 0x%08lx\n", thread->uwinmask, (unsigned long)thread->kregs); show_regs(thread->kregs); - printk("sig_address: 0x%08lx sig_desc: 0x%08lx\n", thread->sig_address, thread->sig_desc); printk("ksp: 0x%08lx kpc: 0x%08lx\n", thread->ksp, thread->kpc); printk("kpsr: 0x%08lx kwim: 0x%08lx\n", thread->kpsr, thread->kwim); printk("fork_kpsr: 0x%08lx fork_kwim: 0x%08lx\n", thread->fork_kpsr, thread->fork_kwim); @@ -595,7 +594,7 @@ dump->fpu.fpstatus.fpq_count = current->thread.fpqdepth; memcpy(&dump->fpu.fpstatus.fpq[0], ¤t->thread.fpqueue[0], ((sizeof(unsigned long) * 2) * 16)); - dump->sigcode = current->thread.sig_desc; + dump->sigcode = 0; } /* diff -ur --new-file old/linux/arch/sparc/kernel/signal.c new/linux/arch/sparc/kernel/signal.c --- old/linux/arch/sparc/kernel/signal.c Mon Jan 3 21:01:31 2000 +++ new/linux/arch/sparc/kernel/signal.c Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.99 1999/12/27 06:08:32 anton Exp $ +/* $Id: signal.c,v 1.101 2000/01/21 11:38:38 jj Exp $ * linux/arch/sparc/kernel/signal.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -424,12 +424,15 @@ } static inline void -setup_frame(struct sigaction *sa, unsigned long pc, unsigned long npc, - struct pt_regs *regs, int signr, sigset_t *oldset) +setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *oldset, siginfo_t *info) { struct signal_sframe *sframep; struct sigcontext *sc; int window = 0, err; + unsigned long pc = regs->pc; + unsigned long npc = regs->npc; + void *sig_address; + int sig_code; synchronize_user_stack(); sframep = (struct signal_sframe *)get_sigframe(sa, regs, SF_ALIGNEDSZ); @@ -474,18 +477,63 @@ sizeof(struct reg_window)); current->thread.w_saved = 0; /* So process is allowed to execute. */ + err |= __put_user(signr, &sframep->sig_num); - if(signr == SIGSEGV || - signr == SIGILL || - signr == SIGFPE || - signr == SIGBUS || - signr == SIGEMT) { - err |= __put_user(current->thread.sig_desc, &sframep->sig_code); - err |= __put_user(current->thread.sig_address, &sframep->sig_address); - } else { - err |= __put_user(0, &sframep->sig_code); - err |= __put_user(0, &sframep->sig_address); + sig_address = NULL; + sig_code = 0; + if (SI_FROMKERNEL (info) && (info->si_code & __SI_MASK) == __SI_FAULT) { + sig_address = info->si_addr; + switch (signr) { + case SIGSEGV: + switch (info->si_code) { + case SEGV_MAPERR: sig_code = SUBSIG_NOMAPPING; break; + default: sig_code = SUBSIG_PROTECTION; break; + } + break; + case SIGILL: + switch (info->si_code) { + case ILL_ILLOPC: sig_code = SUBSIG_ILLINST; break; + case ILL_PRVOPC: sig_code = SUBSIG_PRIVINST; break; + case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP (info->si_trapno); break; + default: sig_code = SUBSIG_STACK; break; + } + break; + case SIGFPE: + switch (info->si_code) { + case FPE_INTDIV: sig_code = SUBSIG_IDIVZERO; break; + case FPE_INTOVF: sig_code = SUBSIG_FPINTOVFL; break; + case FPE_FLTDIV: sig_code = SUBSIG_FPDIVZERO; break; + case FPE_FLTOVF: sig_code = SUBSIG_FPOVFLOW; break; + case FPE_FLTUND: sig_code = SUBSIG_FPUNFLOW; break; + case FPE_FLTRES: sig_code = SUBSIG_FPINEXACT; break; + case FPE_FLTINV: sig_code = SUBSIG_FPOPERROR; break; + default: sig_code = SUBSIG_FPERROR; break; + } + break; + case SIGBUS: + switch (info->si_code) { + case BUS_ADRALN: sig_code = SUBSIG_ALIGNMENT; break; + case BUS_ADRERR: sig_code = SUBSIG_MISCERROR; break; + default: sig_code = SUBSIG_BUSTIMEOUT; break; + } + break; + case SIGEMT: + switch (info->si_code) { + case EMT_TAGOVF: sig_code = SUBSIG_TAG; break; + } + break; + case SIGSYS: + if (info->si_code == (__SI_FAULT|0x100)) { + /* See sys_sunos.c */ + sig_code = info->si_trapno; + break; + } + default: + sig_address = NULL; + } } + err |= __put_user((long)sig_address, &sframep->sig_address); + err |= __put_user(sig_code, &sframep->sig_code); err |= __put_user(sc, &sframep->sig_scptr); if (err) goto sigsegv; @@ -791,8 +839,7 @@ /* Setup the signal information. Solaris expects a bunch of * information to be passed to the signal handler, we don't provide - * that much currently, should use those that David already - * is providing with thread.sig_desc + * that much currently, should use siginfo. */ err |= __put_user(signr, &si->siginfo.signo); err |= __put_user(SVR4_SINOINFO, &si->siginfo.code); @@ -977,7 +1024,7 @@ else if (current->thread.new_signal) new_setup_frame (ka, regs, signr, oldset); else - setup_frame(&ka->sa, regs->pc, regs->npc, regs, signr, oldset); + setup_frame(&ka->sa, regs, signr, oldset, info); } if(ka->sa.sa_flags & SA_ONESHOT) ka->sa.sa_handler = SIG_DFL; @@ -1074,7 +1121,16 @@ struct k_sigaction *ka; siginfo_t info; + /* + * XXX Disable svr4 signal handling until solaris emulation works. + * It is buggy - Anton + */ +#define SVR4_SIGNAL_BROKEN 1 +#ifdef SVR4_SIGNAL_BROKEN + int svr4_signal = 0; +#else int svr4_signal = current->personality == PER_SVR4; +#endif if (!oldset) oldset = ¤t->blocked; diff -ur --new-file old/linux/arch/sparc/kernel/smp.c new/linux/arch/sparc/kernel/smp.c --- old/linux/arch/sparc/kernel/smp.c Mon Jan 3 21:01:31 2000 +++ new/linux/arch/sparc/kernel/smp.c Sat Jan 22 03:22:54 2000 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -51,7 +52,7 @@ unsigned char boot_cpu_id = 0; unsigned char boot_cpu_id4 = 0; /* boot_cpu_id << 2 */ int smp_activated = 0; -volatile int cpu_number_map[NR_CPUS]; +volatile int __cpu_number_map[NR_CPUS]; volatile int __cpu_logical_map[NR_CPUS]; cycles_t cacheflush_time = 0; /* XXX */ diff -ur --new-file old/linux/arch/sparc/kernel/sparc_ksyms.c new/linux/arch/sparc/kernel/sparc_ksyms.c --- old/linux/arch/sparc/kernel/sparc_ksyms.c Thu Jan 13 21:03:00 2000 +++ new/linux/arch/sparc/kernel/sparc_ksyms.c Thu Jan 27 17:58:15 2000 @@ -1,4 +1,4 @@ -/* $Id: sparc_ksyms.c,v 1.86 2000/01/09 10:46:49 anton Exp $ +/* $Id: sparc_ksyms.c,v 1.87 2000/01/21 17:41:14 anton Exp $ * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -182,8 +183,8 @@ EXPORT_SYMBOL(sbus_root); EXPORT_SYMBOL(dma_chain); EXPORT_SYMBOL(sbus_set_sbus64); -EXPORT_SYMBOL(sbus_alloc_consistant); -EXPORT_SYMBOL(sbus_free_consistant); +EXPORT_SYMBOL(sbus_alloc_consistent); +EXPORT_SYMBOL(sbus_free_consistent); EXPORT_SYMBOL(sbus_map_single); EXPORT_SYMBOL(sbus_unmap_single); EXPORT_SYMBOL(sbus_map_sg); diff -ur --new-file old/linux/arch/sparc/kernel/sun4d_smp.c new/linux/arch/sparc/kernel/sun4d_smp.c --- old/linux/arch/sparc/kernel/sun4d_smp.c Mon Jan 3 21:01:31 2000 +++ new/linux/arch/sparc/kernel/sun4d_smp.c Sat Jan 22 03:22:54 2000 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -57,13 +58,15 @@ extern unsigned long cpu_offset[NR_CPUS]; extern unsigned char boot_cpu_id; extern int smp_activated; -extern volatile int cpu_number_map[NR_CPUS]; +extern volatile int __cpu_number_map[NR_CPUS]; extern volatile int __cpu_logical_map[NR_CPUS]; extern volatile unsigned long ipi_count; extern volatile int smp_process_available; extern volatile int smp_commenced; extern int __smp4d_processor_id(void); +extern unsigned long totalram_pages; + /* #define SMP_DEBUG */ #ifdef SMP_DEBUG @@ -138,10 +141,10 @@ cpu_leds[cpuid] = 0x9; show_leds(cpuid); - current->mm->mmap->vm_page_prot = PAGE_SHARED; - current->mm->mmap->vm_start = PAGE_OFFSET; - current->mm->mmap->vm_end = init_mm.mmap->vm_end; - + /* Attach to the address space of init_task. */ + atomic_inc(&init_mm.mm_count); + current->active_mm = &init_mm; + local_flush_cache_all(); local_flush_tlb_all(); @@ -189,12 +192,12 @@ cpu_present_map |= (1<processor = boot_cpu_id; smp_store_cpu_info(boot_cpu_id); @@ -218,12 +221,19 @@ /* Cook up an idler for this guy. */ kernel_thread(start_secondary, NULL, CLONE_PID); - p = task[++cpucount]; + cpucount++; + + p = init_task.prev_task; + init_tasks[i] = p; p->processor = i; p->has_cpu = 1; /* we schedule the first task manually */ + current_set[i] = p; - + + del_from_runqueue(p); + unhash_process(p); + for (no = 0; no < linux_num_cpus; no++) if (linux_cpus[no].mid == i) break; @@ -254,7 +264,7 @@ if(cpu_callin_map[i]) { /* Another "Red Snapper". */ - cpu_number_map[i] = cpucount; + __cpu_number_map[i] = cpucount; __cpu_logical_map[cpucount] = i; } else { cpucount--; @@ -263,7 +273,7 @@ } if(!(cpu_callin_map[i])) { cpu_present_map &= ~(1 << i); - cpu_number_map[i] = -1; + __cpu_number_map[i] = -1; } } local_flush_cache_all(); @@ -289,13 +299,23 @@ } /* Free unneeded trap tables */ - - mem_map[MAP_NR((unsigned long)trapbase_cpu1)].flags &= ~(1 << PG_reserved); + ClearPageReserved(mem_map + MAP_NR(trapbase_cpu1)); + set_page_count(mem_map + MAP_NR(trapbase_cpu1), 1); free_page((unsigned long)trapbase_cpu1); - mem_map[MAP_NR((unsigned long)trapbase_cpu2)].flags &= ~(1 << PG_reserved); + totalram_pages++; + num_physpages++; + + ClearPageReserved(mem_map + MAP_NR(trapbase_cpu2)); + set_page_count(mem_map + MAP_NR(trapbase_cpu2), 1); free_page((unsigned long)trapbase_cpu2); - mem_map[MAP_NR((unsigned long)trapbase_cpu3)].flags &= ~(1 << PG_reserved); + totalram_pages++; + num_physpages++; + + ClearPageReserved(mem_map + MAP_NR(trapbase_cpu3)); + set_page_count(mem_map + MAP_NR(trapbase_cpu3), 1); free_page((unsigned long)trapbase_cpu3); + totalram_pages++; + num_physpages++; /* Ok, they are spinning and ready to go. */ smp_processors_ready = 1; diff -ur --new-file old/linux/arch/sparc/kernel/sun4m_smp.c new/linux/arch/sparc/kernel/sun4m_smp.c --- old/linux/arch/sparc/kernel/sun4m_smp.c Mon Jan 3 21:01:31 2000 +++ new/linux/arch/sparc/kernel/sun4m_smp.c Sat Jan 22 03:22:54 2000 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -52,13 +53,15 @@ extern unsigned long cpu_offset[NR_CPUS]; extern unsigned char boot_cpu_id; extern int smp_activated; -extern volatile int cpu_number_map[NR_CPUS]; +extern volatile int __cpu_number_map[NR_CPUS]; extern volatile int __cpu_logical_map[NR_CPUS]; extern volatile unsigned long ipi_count; extern volatile int smp_process_available; extern volatile int smp_commenced; extern int __smp4m_processor_id(void); +extern unsigned long totalram_pages; + /*#define SMP_DEBUG*/ #ifdef SMP_DEBUG @@ -84,6 +87,7 @@ local_flush_cache_all(); local_flush_tlb_all(); + set_irq_udt(mid_xlate[boot_cpu_id]); /* Get our local ticker going. */ @@ -91,6 +95,7 @@ calibrate_delay(); smp_store_cpu_info(cpuid); + local_flush_cache_all(); local_flush_tlb_all(); @@ -104,22 +109,21 @@ /* Allow master to continue. */ swap((unsigned long *)&cpu_callin_map[cpuid], 1); + local_flush_cache_all(); local_flush_tlb_all(); cpu_probe(); - while(!task[cpuid] || current_set[cpuid] != task[cpuid]) - barrier(); - /* Fix idle thread fields. */ __asm__ __volatile__("ld [%0], %%g6\n\t" : : "r" (¤t_set[cpuid]) : "memory" /* paranoid */); - current->mm->mmap->vm_page_prot = PAGE_SHARED; - current->mm->mmap->vm_start = PAGE_OFFSET; - current->mm->mmap->vm_end = init_mm.mmap->vm_end; - + + /* Attach to the address space of init_task. */ + atomic_inc(&init_mm.mm_count); + current->active_mm = &init_mm; + while(!smp_commenced) barrier(); @@ -152,21 +156,23 @@ printk("Entering SMP Mode...\n"); - for (i = 0; i < NR_CPUS; i++) - cpu_offset[i] = (char *)&cpu_data[i] - (char *)&cpu_data; - __sti(); cpu_present_map = 0; + for(i=0; i < linux_num_cpus; i++) cpu_present_map |= (1<processor = boot_cpu_id; + smp_store_cpu_info(boot_cpu_id); set_irq_udt(mid_xlate[boot_cpu_id]); smp_setup_percpu_timer(); @@ -187,12 +193,19 @@ /* Cook up an idler for this guy. */ kernel_thread(start_secondary, NULL, CLONE_PID); - p = task[++cpucount]; + cpucount++; + + p = init_task.prev_task; + init_tasks[i] = p; p->processor = i; p->has_cpu = 1; /* we schedule the first task manually */ + current_set[i] = p; + del_from_runqueue(p); + unhash_process(p); + /* See trampoline.S for details... */ entry += ((i-1) * 3); @@ -220,7 +233,7 @@ } if(cpu_callin_map[i]) { /* Another "Red Snapper". */ - cpu_number_map[i] = i; + __cpu_number_map[i] = i; __cpu_logical_map[i] = i; } else { cpucount--; @@ -229,7 +242,7 @@ } if(!(cpu_callin_map[i])) { cpu_present_map &= ~(1 << i); - cpu_number_map[i] = -1; + __cpu_number_map[i] = -1; } } local_flush_cache_all(); @@ -265,18 +278,26 @@ cpu_data[prev].next = first; /* Free unneeded trap tables */ - if (!(cpu_present_map & (1 << 1))) { - mem_map[MAP_NR((unsigned long)trapbase_cpu1)].flags &= ~(1 << PG_reserved); + ClearPageReserved(mem_map + MAP_NR(trapbase_cpu1)); + set_page_count(mem_map + MAP_NR(trapbase_cpu1), 1); free_page((unsigned long)trapbase_cpu1); + totalram_pages++; + num_physpages++; } if (!(cpu_present_map & (1 << 2))) { - mem_map[MAP_NR((unsigned long)trapbase_cpu2)].flags &= ~(1 << PG_reserved); + ClearPageReserved(mem_map + MAP_NR(trapbase_cpu2)); + set_page_count(mem_map + MAP_NR(trapbase_cpu2), 1); free_page((unsigned long)trapbase_cpu2); + totalram_pages++; + num_physpages++; } if (!(cpu_present_map & (1 << 3))) { - mem_map[MAP_NR((unsigned long)trapbase_cpu3)].flags &= ~(1 << PG_reserved); + ClearPageReserved(mem_map + MAP_NR(trapbase_cpu3)); + set_page_count(mem_map + MAP_NR(trapbase_cpu3), 1); free_page((unsigned long)trapbase_cpu3); + totalram_pages++; + num_physpages++; } /* Ok, they are spinning and ready to go. */ diff -ur --new-file old/linux/arch/sparc/kernel/sys_sparc.c new/linux/arch/sparc/kernel/sys_sparc.c --- old/linux/arch/sparc/kernel/sys_sparc.c Tue Jan 4 20:17:47 2000 +++ new/linux/arch/sparc/kernel/sys_sparc.c Thu Jan 27 15:32:14 2000 @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.56 2000/01/04 11:01:26 jj Exp $ +/* $Id: sys_sparc.c,v 1.57 2000/01/21 11:38:42 jj Exp $ * linux/arch/sparc/kernel/sys_sparc.c * * This file contains various random system calls that @@ -260,11 +260,19 @@ asmlinkage void sparc_breakpoint (struct pt_regs *regs) { + siginfo_t info; + lock_kernel(); #ifdef DEBUG_SPARC_BREAKPOINT printk ("TRAP: Entering kernel PC=%x, nPC=%x\n", regs->pc, regs->npc); #endif - force_sig(SIGTRAP, current); + info.si_signo = SIGTRAP; + info.si_errno = 0; + info.si_code = TRAP_BRKPT; + info.si_addr = (void *)regs->pc; + info.si_trapno = 0; + force_sig_info(SIGTRAP, &info, current); + #ifdef DEBUG_SPARC_BREAKPOINT printk ("TRAP: Returning to space: PC=%x nPC=%x\n", regs->pc, regs->npc); #endif @@ -360,7 +368,7 @@ int nlen; int err = -EFAULT; - down(&uts_sem); + down_read(&uts_sem); nlen = strlen(system_utsname.domainname) + 1; @@ -372,7 +380,7 @@ goto done; err = 0; done: - up(&uts_sem); + up_read(&uts_sem); return err; } diff -ur --new-file old/linux/arch/sparc/kernel/sys_sunos.c new/linux/arch/sparc/kernel/sys_sunos.c --- old/linux/arch/sparc/kernel/sys_sunos.c Fri Jan 7 01:17:19 2000 +++ new/linux/arch/sparc/kernel/sys_sunos.c Thu Jan 27 15:32:14 2000 @@ -1,4 +1,4 @@ -/* $Id: sys_sunos.c,v 1.108 2000/01/06 23:51:46 davem Exp $ +/* $Id: sys_sunos.c,v 1.111 2000/01/22 05:17:55 anton Exp $ * sys_sunos.c: SunOS specific syscall compatibility support. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -366,6 +366,7 @@ spin_lock_irq(¤t->sigmask_lock); old = current->blocked.sig[0]; current->blocked.sig[0] |= (blk_mask & _BLOCKABLE); + recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); return old; } @@ -377,6 +378,7 @@ spin_lock_irq(¤t->sigmask_lock); retval = current->blocked.sig[0]; current->blocked.sig[0] = (newmask & _BLOCKABLE); + recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); return retval; } @@ -579,7 +581,7 @@ asmlinkage int sunos_uname(struct sunos_utsname *name) { int ret; - down(&uts_sem); + down_read(&uts_sem); ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1); if (!ret) { ret |= __copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1); @@ -588,22 +590,29 @@ ret |= __copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1); ret |= __copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1); } - up(&uts_sem); + up_read(&uts_sem); return ret; } asmlinkage int sunos_nosys(void) { struct pt_regs *regs; + siginfo_t info; + static int cnt; lock_kernel(); regs = current->thread.kregs; - current->thread.sig_address = regs->pc; - current->thread.sig_desc = regs->u_regs[UREG_G1]; - send_sig(SIGSYS, current, 1); - printk("Process makes ni_syscall number %d, register dump:\n", - (int) regs->u_regs[UREG_G1]); - show_regs(regs); + info.si_signo = SIGSYS; + info.si_errno = 0; + info.si_code = __SI_FAULT|0x100; + info.si_addr = (void *)regs->pc; + info.si_trapno = regs->u_regs[UREG_G1]; + send_sig_info(SIGSYS, &info, current); + if (cnt++ < 4) { + printk("Process makes ni_syscall number %d, register dump:\n", + (int) regs->u_regs[UREG_G1]); + show_regs(regs); + } unlock_kernel(); return -ENOSYS; } diff -ur --new-file old/linux/arch/sparc/kernel/systbls.S new/linux/arch/sparc/kernel/systbls.S --- old/linux/arch/sparc/kernel/systbls.S Thu Jan 13 21:03:00 2000 +++ new/linux/arch/sparc/kernel/systbls.S Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.90 2000/01/11 17:33:20 jj Exp $ +/* $Id: systbls.S,v 1.91 2000/01/16 06:20:44 davem Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * @@ -33,15 +33,15 @@ /*60*/ .long sys_umask, sys_chroot, sys_newfstat, sys_fstat64, sys_getpagesize /*65*/ .long sys_msync, sys_vfork, sys_pread, sys_pwrite, sys_geteuid /*70*/ .long sys_getegid, sys_mmap, sys_setreuid, sys_munmap, sys_mprotect -/*75*/ .long sys_setregid, sys_vhangup, sys_truncate64, sys_getgroups, sys_getgroups16 +/*75*/ .long sys_nis_syscall, sys_vhangup, sys_truncate64, sys_nis_syscall, sys_getgroups16 /*80*/ .long sys_setgroups16, sys_getpgrp, sys_setgroups, sys_setitimer, sys_ftruncate64 /*85*/ .long sys_swapon, sys_getitimer, sys_setuid, sys_sethostname, sys_setgid /*90*/ .long sys_dup2, sys_setfsuid, sys_fcntl, sys_select, sys_setfsgid /*95*/ .long sys_fsync, sys_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall /*100*/ .long sys_getpriority, sys_rt_sigreturn, sys_rt_sigaction, sys_rt_sigprocmask, sys_rt_sigpending /*105*/ .long sys_rt_sigtimedwait, sys_rt_sigqueueinfo, sys_rt_sigsuspend, sys_setresuid, sys_getresuid -/*110*/ .long sys_setresgid, sys_getresgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall -/*115*/ .long sys_nis_syscall, sys_gettimeofday, sys_getrusage, sys_nis_syscall, sys_getcwd +/*110*/ .long sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall +/*115*/ .long sys_getgroups, sys_gettimeofday, sys_getrusage, sys_nis_syscall, sys_getcwd /*120*/ .long sys_readv, sys_writev, sys_settimeofday, sys_fchown16, sys_fchmod /*125*/ .long sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate /*130*/ .long sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall diff -ur --new-file old/linux/arch/sparc/kernel/time.c new/linux/arch/sparc/kernel/time.c --- old/linux/arch/sparc/kernel/time.c Tue Dec 21 07:05:52 1999 +++ new/linux/arch/sparc/kernel/time.c Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.49 1999/11/17 07:34:07 zaitcev Exp $ +/* $Id: time.c,v 1.50 2000/01/21 04:35:53 anton Exp $ * linux/arch/sparc/kernel/time.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -229,7 +229,7 @@ sp_clock_typ = INTERSIL; r.start = sun4_clock_physaddr; intersil_clock = (struct intersil *) - sparc_ioremap(&r, 0, sizeof(*intersil_clock), "intersil"); + sbus_ioremap(&r, 0, sizeof(*intersil_clock), "intersil"); mstk48t02_regs = 0; /* just be sure */ mstk48t08_regs = 0; /* ditto */ /* initialise the clock */ diff -ur --new-file old/linux/arch/sparc/kernel/traps.c new/linux/arch/sparc/kernel/traps.c --- old/linux/arch/sparc/kernel/traps.c Tue Aug 31 20:23:29 1999 +++ new/linux/arch/sparc/kernel/traps.c Sat Jan 22 03:22:54 2000 @@ -1,7 +1,8 @@ -/* $Id: traps.c,v 1.60 1999/08/14 03:51:31 anton Exp $ +/* $Id: traps.c,v 1.61 2000/01/21 11:38:41 jj Exp $ * arch/sparc/kernel/traps.c * * Copyright 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright 2000 Jakub Jelinek (jakub@redhat.com) */ /* @@ -128,6 +129,8 @@ void do_hw_interrupt(unsigned long type, unsigned long psr, unsigned long pc) { + siginfo_t info; + lock_kernel(); if(type < 0x80) { /* Sun OS's puke from bad traps, Linux survives! */ @@ -135,22 +138,23 @@ die_if_kernel("Whee... Hello Mr. Penguin", current->thread.kregs); } - if(type == SP_TRAP_SBPT) { - send_sig(SIGTRAP, current, 1); - } else { - if(psr & PSR_PS) - die_if_kernel("Kernel bad trap", current->thread.kregs); + if(psr & PSR_PS) + die_if_kernel("Kernel bad trap", current->thread.kregs); - current->thread.sig_desc = SUBSIG_BADTRAP(type - 0x80); - current->thread.sig_address = pc; - send_sig(SIGILL, current, 1); - } + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = ILL_ILLTRP; + info.si_addr = (void *)pc; + info.si_trapno = type - 0x80; + force_sig_info(SIGILL, &info, current); unlock_kernel(); } void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { + siginfo_t info; + lock_kernel(); if(psr & PSR_PS) die_if_kernel("Kernel illegal instruction", regs); @@ -163,9 +167,12 @@ if (!do_user_muldiv (regs, pc)) goto out; } - current->thread.sig_address = pc; - current->thread.sig_desc = SUBSIG_ILLINST; - send_sig(SIGILL, current, 1); + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = ILL_ILLOPC; + info.si_addr = (void *)pc; + info.si_trapno = 0; + send_sig_info(SIGILL, &info, current); out: unlock_kernel(); } @@ -173,12 +180,17 @@ void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { + siginfo_t info; + lock_kernel(); if(psr & PSR_PS) die_if_kernel("Penguin instruction from Penguin mode??!?!", regs); - current->thread.sig_address = pc; - current->thread.sig_desc = SUBSIG_PRIVINST; - send_sig(SIGILL, current, 1); + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = ILL_PRVOPC; + info.si_addr = (void *)pc; + info.si_trapno = 0; + send_sig_info(SIGILL, &info, current); unlock_kernel(); } @@ -187,6 +199,8 @@ void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { + siginfo_t info; + lock_kernel(); if(regs->psr & PSR_PS) { printk("KERNEL MNA at pc %08lx npc %08lx called by %08lx\n", pc, npc, @@ -194,14 +208,17 @@ die_if_kernel("BOGUS", regs); /* die_if_kernel("Kernel MNA access", regs); */ } - current->thread.sig_address = pc; - current->thread.sig_desc = SUBSIG_PRIVINST; #if 0 show_regs (regs); instruction_dump ((unsigned long *) regs->pc); printk ("do_MNA!\n"); #endif - send_sig(SIGBUS, current, 1); + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = BUS_ADRALN; + info.si_addr = /* FIXME: Should dig out mna address */ (void *)0; + info.si_trapno = 0; + send_sig_info(SIGBUS, &info, current); unlock_kernel(); } @@ -269,6 +286,8 @@ unsigned long psr) { static int calls = 0; + siginfo_t info; + unsigned long fsr; int ret = 0; #ifndef __SMP__ struct task_struct *fpt = last_task_used_math; @@ -326,8 +345,6 @@ } /* nope, better SIGFPE the offending process... */ - fpt->thread.sig_address = pc; - fpt->thread.sig_desc = SUBSIG_FPERROR; /* as good as any */ #ifdef __SMP__ fpt->flags &= ~PF_USEDFPU; #endif @@ -345,7 +362,26 @@ regs); goto out; } - send_sig(SIGFPE, fpt, 1); + + fsr = fpt->thread.fsr; + info.si_signo = SIGFPE; + info.si_errno = 0; + info.si_addr = (void *)pc; + info.si_trapno = 0; + info.si_code = __SI_FAULT; + if ((fsr & 0x1c000) == (1 << 14)) { + if (fsr & 0x10) + info.si_code = FPE_FLTINV; + else if (fsr & 0x08) + info.si_code = FPE_FLTOVF; + else if (fsr & 0x04) + info.si_code = FPE_FLTUND; + else if (fsr & 0x02) + info.si_code = FPE_FLTDIV; + else if (fsr & 0x01) + info.si_code = FPE_FLTRES; + } + send_sig_info(SIGFPE, &info, fpt); #ifndef __SMP__ last_task_used_math = NULL; #endif @@ -359,12 +395,17 @@ void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { + siginfo_t info; + lock_kernel(); if(psr & PSR_PS) die_if_kernel("Penguin overflow trap from kernel mode", regs); - current->thread.sig_address = pc; - current->thread.sig_desc = SUBSIG_TAG; /* as good as any */ - send_sig(SIGEMT, current, 1); + info.si_signo = SIGEMT; + info.si_errno = 0; + info.si_code = EMT_TAGOVF; + info.si_addr = (void *)pc; + info.si_trapno = 0; + send_sig_info(SIGEMT, &info, current); unlock_kernel(); } @@ -385,40 +426,69 @@ void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { + siginfo_t info; + lock_kernel(); #ifdef TRAP_DEBUG printk("Register Access Exception at PC %08lx NPC %08lx PSR %08lx\n", pc, npc, psr); #endif - send_sig(SIGILL, current, 1); + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = BUS_OBJERR; + info.si_addr = (void *)pc; + info.si_trapno = 0; + force_sig_info(SIGBUS, &info, current); unlock_kernel(); } void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { + siginfo_t info; + lock_kernel(); - send_sig(SIGILL, current, 1); + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = ILL_COPROC; + info.si_addr = (void *)pc; + info.si_trapno = 0; + send_sig_info(SIGILL, &info, current); unlock_kernel(); } void handle_cp_exception(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { + siginfo_t info; + lock_kernel(); #ifdef TRAP_DEBUG printk("Co-Processor Exception at PC %08lx NPC %08lx PSR %08lx\n", pc, npc, psr); #endif - send_sig(SIGILL, current, 1); + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = ILL_COPROC; + info.si_addr = (void *)pc; + info.si_trapno = 0; + send_sig_info(SIGILL, &info, current); unlock_kernel(); } void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { + siginfo_t info; + lock_kernel(); - send_sig(SIGILL, current, 1); + info.si_signo = SIGFPE; + info.si_errno = 0; + info.si_code = FPE_INTDIV; + info.si_addr = (void *)pc; + info.si_trapno = 0; + send_sig_info(SIGFPE, &info, current); + unlock_kernel(); } diff -ur --new-file old/linux/arch/sparc/kernel/unaligned.c new/linux/arch/sparc/kernel/unaligned.c --- old/linux/arch/sparc/kernel/unaligned.c Tue Aug 31 20:23:29 1999 +++ new/linux/arch/sparc/kernel/unaligned.c Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: unaligned.c,v 1.19 1999/08/14 03:51:33 anton Exp $ +/* $Id: unaligned.c,v 1.20 2000/01/21 11:38:42 jj Exp $ * unaligned.c: Unaligned load/store trap handling with special * cases for the kernel to do them more quickly. * @@ -422,9 +422,14 @@ void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) { - current->thread.sig_address = regs->pc; - current->thread.sig_desc = SUBSIG_PRIVINST; - send_sig(SIGBUS, current, 1); + siginfo_t info; + + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = BUS_ADRALN; + info.si_addr = (void *)compute_effective_address(regs, insn); + info.si_trapno = 0; + send_sig_info(SIGBUS, &info, current); } asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn) @@ -487,9 +492,7 @@ } kill_user: - current->thread.sig_address = regs->pc; - current->thread.sig_desc = SUBSIG_PRIVINST; - send_sig(SIGBUS, current, 1); + user_mna_trap_fault(regs, insn); out: unlock_kernel(); } diff -ur --new-file old/linux/arch/sparc/mm/asyncd.c new/linux/arch/sparc/mm/asyncd.c --- old/linux/arch/sparc/mm/asyncd.c Sun Jan 9 06:36:20 2000 +++ new/linux/arch/sparc/mm/asyncd.c Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: asyncd.c,v 1.19 2000/01/08 20:22:16 davem Exp $ +/* $Id: asyncd.c,v 1.20 2000/01/21 11:38:47 jj Exp $ * The asyncd kernel daemon. This handles paging on behalf of * processes that receive page faults due to remote (async) memory * accesses. @@ -116,6 +116,7 @@ pgd_t *pgd; pmd_t *pmd; pte_t *pte; + siginfo_t info; if (!tsk || !tsk->mm) return 1; @@ -179,9 +180,12 @@ bad_area: stats.failure++; - tsk->thread.sig_address = address; - tsk->thread.sig_desc = SUBSIG_NOMAPPING; - send_sig(SIGSEGV, tsk, 1); + info.si_signo = SIGSEGV; + info.si_errno = 0; + info.si_code = SEGV_MAPERR; + info.si_addr = (void *)address; + info.si_trapno = 0; + send_sig_info(SIGSEGV, &info, tsk); return 1; } diff -ur --new-file old/linux/arch/sparc/mm/fault.c new/linux/arch/sparc/mm/fault.c --- old/linux/arch/sparc/mm/fault.c Tue Dec 21 07:05:52 1999 +++ new/linux/arch/sparc/mm/fault.c Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.111 1999/10/24 13:45:59 anton Exp $ +/* $Id: fault.c,v 1.113 2000/01/21 11:38:47 jj Exp $ * fault.c: Page fault handlers for the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -197,8 +197,10 @@ struct mm_struct *mm = tsk->mm; unsigned int fixup; unsigned long g2; + siginfo_t info; int from_user = !(regs->psr & PSR_PS); + info.si_code = SEGV_MAPERR; if(text_fault) address = regs->pc; @@ -207,10 +209,12 @@ * context, we must not take the fault.. */ if (in_interrupt() || !mm) - goto do_kernel_fault; + goto no_context; down(&mm->mmap_sem); - /* The kernel referencing a bad kernel pointer can lock up + + /* + * The kernel referencing a bad kernel pointer can lock up * a sun4c machine completely, so we must attempt recovery. */ if(!from_user && address >= PAGE_OFFSET) @@ -230,6 +234,7 @@ * we can handle it.. */ good_area: + info.si_code = SEGV_ACCERR; if(write) { if(!(vma->vm_flags & VM_WRITE)) goto bad_area; @@ -238,18 +243,47 @@ if(!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; } - if (!handle_mm_fault(current, vma, address, write)) - goto do_sigbus; + + /* + * If for any reason at all we couldn't handle the fault, + * make sure we exit gracefully rather than endlessly redo + * the fault. + */ + { + int fault = handle_mm_fault(tsk, vma, address, write); + if (fault < 0) + goto out_of_memory; + if (!fault) + goto do_sigbus; + } up(&mm->mmap_sem); return; + /* * Something tried to access memory that isn't in our memory map.. * Fix it, but check if it's kernel or user first.. */ bad_area: up(&mm->mmap_sem); + + /* User mode accesses just cause a SIGSEGV */ + if(from_user) { +#if 0 + printk("Fault whee %s [%d]: segfaults at %08lx pc=%08lx\n", + tsk->comm, tsk->pid, address, regs->pc); +#endif + info.si_signo = SIGSEGV; + info.si_errno = 0; + /* info.si_code set above to make clear whether + this was a SEGV_MAPERR or SEGV_ACCERR fault. */ + info.si_addr = (void *)address; + info.si_trapno = 0; + force_sig_info (SIGSEGV, &info, tsk); + return; + } + /* Is this in ex_table? */ -do_kernel_fault: +no_context: g2 = regs->u_regs[UREG_G2]; if (!from_user && (fixup = search_exception_table (regs->pc, &g2))) { if (fixup > 10) { /* Values below are reserved for other things */ @@ -276,26 +310,31 @@ return; } } - if(from_user) { -#if 0 - printk("Fault whee %s [%d]: segfaults at %08lx pc=%08lx\n", - tsk->comm, tsk->pid, address, regs->pc); -#endif - tsk->thread.sig_address = address; - tsk->thread.sig_desc = SUBSIG_NOMAPPING; - force_sig(SIGSEGV, tsk); - return; - } + unhandled_fault (address, tsk, regs); - return; + do_exit(SIGKILL); + +/* + * We ran out of memory, or some other thing happened to us that made + * us unable to handle the page fault gracefully. + */ +out_of_memory: + up(&mm->mmap_sem); + printk("VM: killing process %s\n", tsk->comm); + if (from_user) + do_exit(SIGKILL); + goto no_context; do_sigbus: up(&mm->mmap_sem); - tsk->thread.sig_address = address; - tsk->thread.sig_desc = SUBSIG_MISCERROR; - force_sig(SIGBUS, tsk); - if (! from_user) - goto do_kernel_fault; + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = BUS_ADRERR; + info.si_addr = (void *)address; + info.si_trapno = 0; + force_sig_info (SIGBUS, &info, tsk); + if (!from_user) + goto no_context; } asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write, @@ -385,6 +424,9 @@ struct vm_area_struct *vma; struct task_struct *tsk = current; struct mm_struct *mm = tsk->mm; + siginfo_t info; + + info.si_code = SEGV_MAPERR; #if 0 printk("wf\n", @@ -401,6 +443,7 @@ if(expand_stack(vma, address)) goto bad_area; good_area: + info.si_code = SEGV_ACCERR; if(write) { if(!(vma->vm_flags & VM_WRITE)) goto bad_area; @@ -418,16 +461,23 @@ printk("Window whee %s [%d]: segfaults at %08lx\n", tsk->comm, tsk->pid, address); #endif - tsk->thread.sig_address = address; - tsk->thread.sig_desc = SUBSIG_NOMAPPING; - send_sig(SIGSEGV, tsk, 1); + info.si_signo = SIGSEGV; + info.si_errno = 0; + /* info.si_code set above to make clear whether + this was a SEGV_MAPERR or SEGV_ACCERR fault. */ + info.si_addr = (void *)address; + info.si_trapno = 0; + force_sig_info (SIGSEGV, &info, tsk); return; do_sigbus: up(&mm->mmap_sem); - tsk->thread.sig_address = address; - tsk->thread.sig_desc = SUBSIG_MISCERROR; - force_sig(SIGBUS, tsk); + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = BUS_ADRERR; + info.si_addr = (void *)address; + info.si_trapno = 0; + force_sig_info (SIGBUS, &info, tsk); } void window_overflow_fault(void) diff -ur --new-file old/linux/arch/sparc/mm/init.c new/linux/arch/sparc/mm/init.c --- old/linux/arch/sparc/mm/init.c Sun Jan 16 07:08:28 2000 +++ new/linux/arch/sparc/mm/init.c Tue Jan 25 19:26:04 2000 @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.73 2000/01/15 00:51:26 anton Exp $ +/* $Id: init.c,v 1.78 2000/01/24 03:22:38 anton Exp $ * linux/arch/sparc/mm/init.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -45,9 +45,9 @@ struct pgtable_cache_struct pgt_quicklists; /* References to section boundaries */ -extern char __init_begin, __init_end, _start, _end, etext , edata; +extern char __init_begin, __init_end, _start, end, etext , edata; -static unsigned long totalram_pages = 0; +unsigned long totalram_pages = 0; /* * BAD_PAGE is the page that is used for page faults when linux @@ -165,7 +165,7 @@ /* Start with page aligned address of last symbol in kernel * image. */ - start_pfn = (unsigned long)__pa(PAGE_ALIGN((unsigned long) &_end)); + start_pfn = (unsigned long)__pa(PAGE_ALIGN((unsigned long) &end)); /* Adjust up to the physical address where the kernel begins. */ start_pfn += phys_base; @@ -199,11 +199,11 @@ #ifdef DEBUG_BOOTMEM prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", phys_base, - (((start_pfn << PAGE_SHIFT) + - bootmap_size) - phys_base)); + (start_pfn << PAGE_SHIFT) + + bootmap_size + PAGE_SIZE-1 - phys_base); #endif - reserve_bootmem(phys_base, (((start_pfn << PAGE_SHIFT) + - bootmap_size) - phys_base)); + reserve_bootmem(phys_base, (start_pfn << PAGE_SHIFT) + + bootmap_size + PAGE_SIZE-1 - phys_base); #ifdef DEBUG_BOOTMEM prom_printf("init_bootmem: return end_pfn[%lx]\n", end_pfn); @@ -366,10 +366,12 @@ int datapages = 0; int initpages = 0; int i; +#ifdef CONFIG_BLK_DEV_INITRD unsigned long addr, last; +#endif /* Saves us work later. */ - memset((void *) ZERO_PAGE(0), 0, PAGE_SIZE); + memset((void *)&empty_zero_page, 0, PAGE_SIZE); i = last_valid_pfn >> (8 + 5); i += 1; @@ -386,7 +388,7 @@ /* fix this */ #ifdef CONFIG_BLK_DEV_INITRD addr = __va(phys_base); - last = PAGE_ALIGN((unsigned long)&_end) + phys_base; + last = PAGE_ALIGN((unsigned long)&end) + phys_base; while(addr < last) { if (initrd_below_start_ok && addr >= initrd_start && addr < initrd_end) mem_map[MAP_NR(addr)].flags &= ~(1<> 10); } void si_meminfo(struct sysinfo *val) diff -ur --new-file old/linux/arch/sparc/mm/srmmu.c new/linux/arch/sparc/mm/srmmu.c --- old/linux/arch/sparc/mm/srmmu.c Sun Jan 16 07:08:28 2000 +++ new/linux/arch/sparc/mm/srmmu.c Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: srmmu.c,v 1.203 2000/01/15 00:51:28 anton Exp $ +/* $Id: srmmu.c,v 1.205 2000/01/21 17:59:46 anton Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -1204,8 +1204,12 @@ { int i; + if (phys_base > 0) { + do_large_mapping(PAGE_OFFSET, phys_base); + } + for (i = 0; sp_banks[i].num_bytes != 0; i++) { - map_spbank(__va(sp_banks[i].base_addr), i); + map_spbank((unsigned long)__va(sp_banks[i].base_addr), i); } init_mm.mmap->vm_start = PAGE_OFFSET; @@ -1255,7 +1259,7 @@ last_valid_pfn = end_pfn = bootmem_init(); - srmmu_allocate_ptable_skeleton(KERNBASE, __va(end_of_phys_memory)); + srmmu_allocate_ptable_skeleton(KERNBASE, (unsigned long)__va(end_of_phys_memory)); #if CONFIG_SUN_IO srmmu_allocate_ptable_skeleton(sparc_iomap.start, IOBASE_END); srmmu_allocate_ptable_skeleton(DVMA_VADDR, DVMA_END); diff -ur --new-file old/linux/arch/sparc64/config.in new/linux/arch/sparc64/config.in --- old/linux/arch/sparc64/config.in Mon Jan 31 16:04:07 2000 +++ new/linux/arch/sparc64/config.in Mon Jan 31 16:05:40 2000 @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.86 1999/12/23 01:46:09 davem Exp $ +# $Id: config.in,v 1.87 2000/01/16 06:18:53 davem Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # diff -ur --new-file old/linux/arch/sparc64/kernel/binfmt_aout32.c new/linux/arch/sparc64/kernel/binfmt_aout32.c --- old/linux/arch/sparc64/kernel/binfmt_aout32.c Thu Aug 26 21:42:32 1999 +++ new/linux/arch/sparc64/kernel/binfmt_aout32.c Tue Jan 25 19:26:04 2000 @@ -30,16 +30,16 @@ #include #include -#include +#include static int load_aout32_binary(struct linux_binprm *, struct pt_regs * regs); static int load_aout32_library(int fd); -static int aout32_core_dump(long signr, struct pt_regs * regs); +static int aout32_core_dump(long signr, struct pt_regs * regs, struct file *file); extern void dump_thread(struct pt_regs *, struct user *); static struct linux_binfmt aout32_format = { - NULL, NULL, load_aout32_binary, load_aout32_library, aout32_core_dump, + NULL, THIS_MODULE, load_aout32_binary, load_aout32_library, aout32_core_dump, PAGE_SIZE }; @@ -214,7 +214,6 @@ struct file * file; int fd; unsigned long error; - unsigned long p = bprm->p; unsigned long fd_offset; unsigned long rlim; int retval; @@ -275,9 +274,13 @@ read_exec(bprm->dentry, fd_offset, (char *) N_TXTADDR(ex), ex.a_text+ex.a_data, 0); } else { + static unsigned long error_time; if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && - (N_MAGIC(ex) != NMAGIC)) + (N_MAGIC(ex) != NMAGIC) && (jiffies-error_time) > 5*HZ) + { printk(KERN_NOTICE "executable not page aligned\n"); + error_time = jiffies; + } fd = open_dentry(bprm->dentry, O_RDONLY); if (fd < 0) @@ -285,7 +288,7 @@ file = fget(fd); if (!file->f_op || !file->f_op->mmap) { - fput(fd); + fput(file); sys_close(fd); do_brk(0, ex.a_text+ex.a_data); read_exec(bprm->dentry, fd_offset, @@ -452,8 +455,17 @@ return retval; } - -int __init init_aout32_binfmt(void) +static int __init init_aout32_binfmt(void) { return register_binfmt(&aout32_format); } + +static void __exit exit_aout32_binfmt(void) +{ + unregister_binfmt(&aout32_format); +} + +EXPORT_NO_SYMBOLS; + +module_init(init_aout32_binfmt); +module_exit(exit_aout32_binfmt); diff -ur --new-file old/linux/arch/sparc64/kernel/ioctl32.c new/linux/arch/sparc64/kernel/ioctl32.c --- old/linux/arch/sparc64/kernel/ioctl32.c Mon Jan 31 16:04:07 2000 +++ new/linux/arch/sparc64/kernel/ioctl32.c Mon Jan 31 16:05:40 2000 @@ -1,4 +1,4 @@ -/* $Id: ioctl32.c,v 1.73 2000/01/11 01:06:47 davem Exp $ +/* $Id: ioctl32.c,v 1.74 2000/01/15 04:47:48 davem Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -39,6 +39,7 @@ #include #include #include +#include #include /* Ugly hack. */ @@ -1746,6 +1747,24 @@ return 0; } +static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + mm_segment_t old_fs = get_fs(); + __kernel_uid_t kuid; + int err; + + cmd = SMB_IOC_GETMOUNTUID; + + set_fs(KERNEL_DS); + err = sys_ioctl(fd, cmd, (unsigned long)&kuid); + set_fs(old_fs); + + if (err >= 0) + err = put_user(kuid, (__kernel_uid_t32 *)arg); + + return err; +} + struct atmif_sioc32 { int number; int length; @@ -1758,7 +1777,7 @@ }; #define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32) -#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atmif_iobuf32) +#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32) #define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32) #define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32) #define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32) @@ -1794,6 +1813,7 @@ #define NR_ATM_IOCTL (sizeof(atm_ioctl_map)/sizeof(atm_ioctl_map[0])) + static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg) { struct atm_iobuf32 iobuf32; @@ -1827,10 +1847,10 @@ old_fs = get_fs(); set_fs (KERNEL_DS); err = sys_ioctl (fd, cmd, (unsigned long)&iobuf); set_fs (old_fs); - if (err) + if(err) goto out; - if (iobuf.buffer && iobuf.length > 0) { + if(iobuf.buffer && iobuf.length > 0) { err = copy_to_user(A(iobuf32.buffer), iobuf.buffer, iobuf.length); if (err) { err = -EFAULT; @@ -1839,8 +1859,8 @@ } err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length)); -out: - if (iobuf32.buffer && iobuf32.length > 0) + out: + if(iobuf32.buffer && iobuf32.length > 0) kfree(iobuf.buffer); return err; @@ -1881,10 +1901,11 @@ old_fs = get_fs(); set_fs (KERNEL_DS); err = sys_ioctl (fd, cmd, (unsigned long)&sioc); set_fs (old_fs); - if (err) + if(err) { goto out; + } - if (sioc.arg && sioc.length > 0) { + if(sioc.arg && sioc.length > 0) { err = copy_to_user(A(sioc32.arg), sioc.arg, sioc.length); if (err) { err = -EFAULT; @@ -1894,7 +1915,7 @@ err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length)); out: - if (sioc32.arg && sioc32_length > 0) + if(sioc32.arg && sioc32.length > 0) kfree(sioc.arg); return err; @@ -1927,14 +1948,15 @@ break; } } + if (i == NR_ATM_IOCTL) { + return -EINVAL; + } } - - if (i == NR_ATM_IOCTL) - return -ENOIOCTLCMD; switch (cmd) { case ATM_GETNAMES: return do_atm_iobuf(fd, cmd, arg); + case ATM_GETLINKRATE: case ATM_GETTYPE: case ATM_GETESI: @@ -1951,7 +1973,7 @@ return do_atmif_sioc(fd, cmd, arg); } - return -ENOIOCTLCMD; + return -EINVAL; } asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) @@ -2141,6 +2163,11 @@ error = do_video_ioctl(fd, cmd, arg); goto out; + /* One SMB ioctl needs translations. */ + case _IOR('u', 1, __kernel_uid_t32): /* SMB_IOC_GETMOUNTUID */ + error = do_smb_getmountuid(fd, cmd, arg); + goto out; + case ATM_GETLINKRATE32: case ATM_GETNAMES32: case ATM_GETTYPE32: @@ -2674,6 +2701,9 @@ case RAW_SETBIND: case RAW_GETBIND: + /* SMB ioctls which do not need any translations */ + case SMB_IOC_NEWCONN: + /* Little a */ case ATMSIGD_CTRL: case ATMARPD_CTRL: @@ -2681,7 +2711,6 @@ case ATMLEC_MCAST: case ATMLEC_DATA: case ATM_SETSC: - case ATM_CREATE_LEAF: case SIOCSIFATMTCP: case SIOCMKCLIP: case ATMARP_MKIP: diff -ur --new-file old/linux/arch/sparc64/kernel/iommu_common.c new/linux/arch/sparc64/kernel/iommu_common.c --- old/linux/arch/sparc64/kernel/iommu_common.c Tue Dec 21 07:05:52 1999 +++ new/linux/arch/sparc64/kernel/iommu_common.c Thu Jan 27 17:58:15 2000 @@ -59,7 +59,6 @@ { struct scatterlist *sg = *__sg; iopte_t *iopte = *__iopte; - int retval = 0; u32 dlen = dma_sg->dvma_length; u32 daddr = dma_sg->dvma_address; unsigned int sglen; @@ -75,7 +74,7 @@ printk("verify_one_map: Wrong start offset " "sg[%08lx] dma[%08x]\n", sgaddr, daddr); - retval = -nents; + nents = -1; goto out; } @@ -85,7 +84,7 @@ printk("verify_one_map: IOPTE[%08lx] maps the " "wrong page, should be [%08lx]\n", iopte_val(*iopte), (sgaddr & PAGE_MASK) - PAGE_OFFSET); - retval = -nents; + nents = -1; goto out; } @@ -114,6 +113,8 @@ iopte++; sg++; + if (--nents <= 0) + break; sgaddr = (unsigned long) sg->address; sglen = sg->length; } @@ -121,7 +122,7 @@ /* Transfer overrun, big problems. */ printk("verify_one_map: Transfer overrun by %d bytes.\n", -dlen); - retval = -nents; + nents = -1; } else { /* Advance to next dma_sg implies that the next iopte will * begin it. @@ -132,7 +133,7 @@ out: *__sg = sg; *__iopte = iopte; - return retval; + return nents; } int verify_maps(struct scatterlist *sg, int nents, iopte_t *iopte) diff -ur --new-file old/linux/arch/sparc64/kernel/irq.c new/linux/arch/sparc64/kernel/irq.c --- old/linux/arch/sparc64/kernel/irq.c Tue Dec 21 07:05:52 1999 +++ new/linux/arch/sparc64/kernel/irq.c Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.80 1999/12/06 03:14:48 davem Exp $ +/* $Id: irq.c,v 1.81 2000/01/21 06:33:59 davem Exp $ * irq.c: UltraSparc IRQ handling/init/registry. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -756,7 +756,7 @@ * of our buddy. */ if(should_forward != 0) { - buddy = cpu_number_map[cpu] + 1; + buddy = cpu_number_map(cpu) + 1; if (buddy >= NR_CPUS || (buddy = cpu_logical_map(buddy)) == -1) buddy = cpu_logical_map(0); diff -ur --new-file old/linux/arch/sparc64/kernel/pci_iommu.c new/linux/arch/sparc64/kernel/pci_iommu.c --- old/linux/arch/sparc64/kernel/pci_iommu.c Tue Dec 21 07:05:52 1999 +++ new/linux/arch/sparc64/kernel/pci_iommu.c Thu Jan 27 17:58:15 2000 @@ -2,7 +2,7 @@ * pci_iommu.c: UltraSparc PCI controller IOM/STC support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) - * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com) + * Copyright (C) 1999, 2000 Jakub Jelinek (jakub@redhat.com) */ #include @@ -63,7 +63,7 @@ return iopte; } -static inline void free_streaming_cluster(struct pci_iommu *iommu, u32 base, unsigned long npages) +static inline void free_streaming_cluster(struct pci_iommu *iommu, dma_addr_t base, unsigned long npages) { unsigned long cnum, ent; @@ -76,8 +76,8 @@ iommu->lowest_free[cnum] = ent; } -/* We allocate consistant mappings from the end of cluster zero. */ -static iopte_t *alloc_consistant_cluster(struct pci_iommu *iommu, unsigned long npages) +/* We allocate consistent mappings from the end of cluster zero. */ +static iopte_t *alloc_consistent_cluster(struct pci_iommu *iommu, unsigned long npages) { iopte_t *iopte; @@ -109,11 +109,11 @@ #define IOPTE_INVALID 0UL -/* Allocate and map kernel buffer of size SIZE using consistant mode +/* Allocate and map kernel buffer of size SIZE using consistent mode * DMA for PCI device PDEV. Return non-NULL cpu-side address if * successful and set *DMA_ADDRP to the PCI side dma address. */ -void *pci_alloc_consistant(struct pci_dev *pdev, long size, u32 *dma_addrp) +void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp) { struct pcidev_cookie *pcp; struct pci_iommu *iommu; @@ -122,10 +122,6 @@ void *ret; int npages; - if (size <= 0 || pdev == NULL || - pdev->sysdata == NULL || dma_addrp == NULL) - return NULL; - size = PAGE_ALIGN(size); for (order = 0; order < 10; order++) { if ((PAGE_SIZE << order) >= size) @@ -134,6 +130,11 @@ if (order == 10) return NULL; + /* We still don't support devices which don't recognize at least 30 bits + of bus address. Bug me to code it (is pretty easy actually). -jj */ + if ((pdev->dma_mask & 0x3fffffff) != 0x3fffffff) + BUG(); + first_page = __get_free_pages(GFP_ATOMIC, order); if (first_page == 0UL) return NULL; @@ -143,7 +144,7 @@ iommu = &pcp->pbm->parent->iommu; spin_lock_irqsave(&iommu->lock, flags); - iopte = alloc_consistant_cluster(iommu, size >> PAGE_SHIFT); + iopte = alloc_consistent_cluster(iommu, size >> PAGE_SHIFT); if (iopte == NULL) { spin_unlock_irqrestore(&iommu->lock, flags); free_pages(first_page, order); @@ -182,18 +183,14 @@ return ret; } -/* Free and unmap a consistant DMA translation. */ -void pci_free_consistant(struct pci_dev *pdev, long size, void *cpu, u32 dvma) +/* Free and unmap a consistent DMA translation. */ +void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_t dvma) { struct pcidev_cookie *pcp; struct pci_iommu *iommu; iopte_t *iopte; unsigned long flags, order, npages, i; - if (size <= 0 || pdev == NULL || - pdev->sysdata == NULL || cpu == NULL) - return; - npages = PAGE_ALIGN(size) >> PAGE_SHIFT; pcp = pdev->sysdata; iommu = &pcp->pbm->parent->iommu; @@ -202,7 +199,7 @@ spin_lock_irqsave(&iommu->lock, flags); - /* Data for consistant mappings cannot enter the streaming + /* Data for consistent mappings cannot enter the streaming * buffers, so we only need to update the TSB. Flush of the * IOTLB is done later when these ioptes are used for a new * allocation. @@ -224,16 +221,25 @@ /* Map a single buffer at PTR of SZ bytes for PCI DMA * in streaming mode. */ -u32 pci_map_single(struct pci_dev *pdev, void *ptr, long sz) +dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz) { - struct pcidev_cookie *pcp = pdev->sysdata; - struct pci_iommu *iommu = &pcp->pbm->parent->iommu; - struct pci_strbuf *strbuf = &pcp->pbm->stc; + struct pcidev_cookie *pcp; + struct pci_iommu *iommu; + struct pci_strbuf *strbuf; iopte_t *base; unsigned long flags, npages, oaddr; unsigned long i, base_paddr, ctx; u32 bus_addr, ret; + pcp = pdev->sysdata; + iommu = &pcp->pbm->parent->iommu; + strbuf = &pcp->pbm->stc; + + /* We still don't support devices which don't recognize at least 30 bits + of bus address. Bug me to code it (is pretty easy actually). -jj */ + if ((pdev->dma_mask & 0x3fffffff) != 0x3fffffff) + BUG(); + oaddr = (unsigned long)ptr; npages = PAGE_ALIGN(oaddr + sz) - (oaddr & PAGE_MASK); npages >>= PAGE_SHIFT; @@ -270,18 +276,26 @@ } /* Unmap a single streaming mode DMA translation. */ -void pci_unmap_single(struct pci_dev *pdev, u32 bus_addr, long sz) +void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz) { - struct pcidev_cookie *pcp = pdev->sysdata; - struct pci_iommu *iommu = &pcp->pbm->parent->iommu; - struct pci_strbuf *strbuf = &pcp->pbm->stc; + struct pcidev_cookie *pcp; + struct pci_iommu *iommu; + struct pci_strbuf *strbuf; iopte_t *base; unsigned long flags, npages, i, ctx; + pcp = pdev->sysdata; + iommu = &pcp->pbm->parent->iommu; + strbuf = &pcp->pbm->stc; + npages = PAGE_ALIGN(bus_addr + sz) - (bus_addr & PAGE_MASK); npages >>= PAGE_SHIFT; base = iommu->page_table + ((bus_addr - iommu->page_table_map_base) >> PAGE_SHIFT); +#ifdef DEBUG_PCI_IOMMU + if (iopte_val(*base) == IOPTE_INVALID) + printk("pci_unmap_single called on non-mapped region %08x,%08x from %016lx\n", bus_addr, sz, __builtin_return_address(0)); +#endif bus_addr &= PAGE_MASK; spin_lock_irqsave(&iommu->lock, flags); @@ -327,11 +341,12 @@ spin_unlock_irqrestore(&iommu->lock, flags); } -static inline struct scatterlist *fill_sg(iopte_t *iopte, struct scatterlist *sg, int nents, unsigned long ctx, int streaming) +static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, unsigned long ctx, int streaming) { struct scatterlist *dma_sg = sg; + int i; - do { + for (i = 0; i < nused; i++) { unsigned long pteval = ~0UL; u32 dma_npages; @@ -396,8 +411,7 @@ pteval = ~0UL; } while (dma_npages != 0); dma_sg++; - } while (dma_sg->dvma_length != 0); - return dma_sg; + } } /* Map a set of buffers described by SGLIST with NELEMS array @@ -414,7 +428,7 @@ iopte_t *base; u32 dma_base; struct scatterlist *sgtmp; - int tmp; + int used; /* Fast path single entry scatterlists. */ if (nelems == 1) { @@ -422,11 +436,16 @@ sglist->dvma_length = sglist->length; return 1; } - + pcp = pdev->sysdata; iommu = &pcp->pbm->parent->iommu; strbuf = &pcp->pbm->stc; + /* We still don't support devices which don't recognize at least 30 bits + of bus address. Bug me to code it (is pretty easy actually). -jj */ + if ((pdev->dma_mask & 0x3fffffff) != 0x3fffffff) + BUG(); + /* Step 1: Prepare scatter list. */ npages = prepare_sg(sglist, nelems); @@ -439,13 +458,15 @@ dma_base = iommu->page_table_map_base + ((base - iommu->page_table) << PAGE_SHIFT); /* Step 3: Normalize DMA addresses. */ - tmp = nelems; + used = nelems; sgtmp = sglist; - while (tmp-- && sgtmp->dvma_length) { + while (used && sgtmp->dvma_length) { sgtmp->dvma_address += dma_base; sgtmp++; + used--; } + used = nelems - used; /* Step 4: Choose a context if necessary. */ ctx = 0; @@ -453,7 +474,7 @@ ctx = iommu->iommu_cur_ctx++; /* Step 5: Create the mappings. */ - sgtmp = fill_sg (base, sglist, nelems, ctx, strbuf->strbuf_enabled); + fill_sg (base, sglist, used, ctx, strbuf->strbuf_enabled); #ifdef VERIFY_SG verify_sglist(sglist, nelems, base, npages); #endif @@ -468,33 +489,39 @@ spin_unlock_irqrestore(&iommu->lock, flags); - return sgtmp - sglist; + return used; } /* Unmap a set of streaming mode DMA translations. */ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems) { - struct pcidev_cookie *pcp = pdev->sysdata; - struct pci_iommu *iommu = &pcp->pbm->parent->iommu; - struct pci_strbuf *strbuf = &pcp->pbm->stc; + struct pcidev_cookie *pcp; + struct pci_iommu *iommu; + struct pci_strbuf *strbuf; iopte_t *base; unsigned long flags, ctx, i, npages; u32 bus_addr; + + pcp = pdev->sysdata; + iommu = &pcp->pbm->parent->iommu; + strbuf = &pcp->pbm->stc; bus_addr = sglist->dvma_address & PAGE_MASK; - i = 0; - if (nelems > 1) { - for (; i < nelems; i++) - if (sglist[i].dvma_length == 0) - break; - i--; - } + for (i = 1; i < nelems; i++) + if (sglist[i].dvma_length == 0) + break; + i--; npages = (PAGE_ALIGN(sglist[i].dvma_address + sglist[i].dvma_length) - bus_addr) >> PAGE_SHIFT; base = iommu->page_table + ((bus_addr - iommu->page_table_map_base) >> PAGE_SHIFT); +#ifdef DEBUG_PCI_IOMMU + if (iopte_val(*base) == IOPTE_INVALID) + printk("pci_unmap_sg called on non-mapped region %08x,%d from %016lx\n", sglist->dvma_address, nelems, __builtin_return_address(0)); +#endif + spin_lock_irqsave(&iommu->lock, flags); /* Step 1: Kick data out of streaming buffers if necessary. */ @@ -538,16 +565,20 @@ spin_unlock_irqrestore(&iommu->lock, flags); } -/* Make physical memory consistant for a single +/* Make physical memory consistent for a single * streaming mode DMA translation after a transfer. */ -void pci_dma_sync_single(struct pci_dev *pdev, u32 bus_addr, long sz) +void pci_dma_sync_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz) { - struct pcidev_cookie *pcp = pdev->sysdata; - struct pci_iommu *iommu = &pcp->pbm->parent->iommu; - struct pci_strbuf *strbuf = &pcp->pbm->stc; + struct pcidev_cookie *pcp; + struct pci_iommu *iommu; + struct pci_strbuf *strbuf; unsigned long flags, ctx, npages; + pcp = pdev->sysdata; + iommu = &pcp->pbm->parent->iommu; + strbuf = &pcp->pbm->stc; + if (!strbuf->strbuf_enabled) return; @@ -595,16 +626,20 @@ spin_unlock_irqrestore(&iommu->lock, flags); } -/* Make physical memory consistant for a set of streaming +/* Make physical memory consistent for a set of streaming * mode DMA translations after a transfer. */ void pci_dma_sync_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems) { - struct pcidev_cookie *pcp = pdev->sysdata; - struct pci_iommu *iommu = &pcp->pbm->parent->iommu; - struct pci_strbuf *strbuf = &pcp->pbm->stc; + struct pcidev_cookie *pcp; + struct pci_iommu *iommu; + struct pci_strbuf *strbuf; unsigned long flags, ctx; + pcp = pdev->sysdata; + iommu = &pcp->pbm->parent->iommu; + strbuf = &pcp->pbm->stc; + if (!strbuf->strbuf_enabled) return; @@ -636,15 +671,12 @@ unsigned long i, npages; u32 bus_addr; - i = 0; bus_addr = sglist[0].dvma_address & PAGE_MASK; - if (nelems > 1) { - for(; i < nelems; i++) - if (!sglist[i].dvma_length) - break; - i--; - } + for(i = 1; i < nelems; i++) + if (!sglist[i].dvma_length) + break; + i--; npages = (PAGE_ALIGN(sglist[i].dvma_address + sglist[i].dvma_length) - bus_addr) >> PAGE_SHIFT; for (i = 0; i < npages; i++, bus_addr += PAGE_SIZE) pci_iommu_write(strbuf->strbuf_pflush, bus_addr); diff -ur --new-file old/linux/arch/sparc64/kernel/pci_psycho.c new/linux/arch/sparc64/kernel/pci_psycho.c --- old/linux/arch/sparc64/kernel/pci_psycho.c Thu Jan 13 21:03:00 2000 +++ new/linux/arch/sparc64/kernel/pci_psycho.c Thu Jan 27 17:58:15 2000 @@ -1284,6 +1284,10 @@ memset((char *)tsbbase, 0, PAGE_SIZE << 7); #endif + /* Make sure DMA address 0 is never returned just to allow catching + of buggy drivers. */ + p->iommu.lowest_free[0] = 1; + #ifndef NEW_PCI_DMA_MAP iopte = (iopte_t *)tsbbase; /* Initialize to "none" settings. */ diff -ur --new-file old/linux/arch/sparc64/kernel/pci_sabre.c new/linux/arch/sparc64/kernel/pci_sabre.c --- old/linux/arch/sparc64/kernel/pci_sabre.c Thu Jan 13 21:03:00 2000 +++ new/linux/arch/sparc64/kernel/pci_sabre.c Thu Jan 27 17:58:15 2000 @@ -1150,6 +1150,10 @@ p->iommu.page_table_map_base = dvma_offset; memset((char *)tsbbase, 0, PAGE_SIZE << order); + /* Make sure DMA address 0 is never returned just to allow catching + of buggy drivers. */ + p->iommu.lowest_free[0] = 1; + #ifndef NEW_PCI_DMA_MAP iopte = (iopte_t *)tsbbase; diff -ur --new-file old/linux/arch/sparc64/kernel/process.c new/linux/arch/sparc64/kernel/process.c --- old/linux/arch/sparc64/kernel/process.c Tue Dec 21 07:05:52 1999 +++ new/linux/arch/sparc64/kernel/process.c Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.102 1999/12/15 22:24:49 davem Exp $ +/* $Id: process.c,v 1.103 2000/01/21 11:38:53 jj Exp $ * arch/sparc64/kernel/process.c * * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) @@ -364,8 +364,6 @@ printk("kregs: 0x%016lx\n", (unsigned long)thread->kregs); show_regs(thread->kregs); #endif - printk("sig_address: 0x%016lx\n", thread->sig_address); - printk("sig_desc: 0x%016lx\n", thread->sig_desc); printk("ksp: 0x%016lx\n", thread->ksp); if (thread->w_saved) { @@ -701,7 +699,6 @@ memcpy(&dump->fpu.fpstatus.fregs.regs[0], ¤t->thread.float_regs[0], (sizeof(unsigned long) * 32)); dump->fpu.fpstatus.fsr = current->thread.fsr; dump->fpu.fpstatus.flags = dump->fpu.fpstatus.extra = 0; - dump->sigcode = current->thread.sig_desc; #endif } diff -ur --new-file old/linux/arch/sparc64/kernel/sbus.c new/linux/arch/sparc64/kernel/sbus.c --- old/linux/arch/sparc64/kernel/sbus.c Tue Dec 21 07:05:52 1999 +++ new/linux/arch/sparc64/kernel/sbus.c Thu Jan 27 17:58:15 2000 @@ -212,8 +212,8 @@ iommu->lowest_free[cnum] = ent; } -/* We allocate consistant mappings from the end of cluster zero. */ -static iopte_t *alloc_consistant_cluster(struct sbus_iommu *iommu, unsigned long npages) +/* We allocate consistent mappings from the end of cluster zero. */ +static iopte_t *alloc_consistent_cluster(struct sbus_iommu *iommu, unsigned long npages) { iopte_t *iopte; @@ -235,7 +235,7 @@ return NULL; } -static void free_consistant_cluster(struct sbus_iommu *iommu, u32 base, unsigned long npages) +static void free_consistent_cluster(struct sbus_iommu *iommu, u32 base, unsigned long npages) { iopte_t *iopte = iommu->page_table + ((base - MAP_BASE) >> PAGE_SHIFT); @@ -243,7 +243,7 @@ *iopte++ = __iopte(0UL); } -void *sbus_alloc_consistant(struct sbus_dev *sdev, long size, u32 *dvma_addr) +void *sbus_alloc_consistent(struct sbus_dev *sdev, size_t size, dma_addr_t *dvma_addr) { unsigned long order, first_page, flags; struct sbus_iommu *iommu; @@ -269,7 +269,7 @@ iommu = sdev->bus->iommu; spin_lock_irqsave(&iommu->lock, flags); - iopte = alloc_consistant_cluster(iommu, size >> PAGE_SHIFT); + iopte = alloc_consistent_cluster(iommu, size >> PAGE_SHIFT); if (iopte == NULL) { spin_unlock_irqrestore(&iommu->lock, flags); free_pages(first_page, order); @@ -291,7 +291,7 @@ return ret; } -void sbus_free_consistant(struct sbus_dev *sdev, long size, void *cpu, u32 dvma) +void sbus_free_consistent(struct sbus_dev *sdev, size_t size, void *cpu, dma_addr_t dvma) { unsigned long order, npages; struct sbus_iommu *iommu; @@ -303,7 +303,7 @@ iommu = sdev->bus->iommu; spin_lock_irq(&iommu->lock); - free_consistant_cluster(iommu, dvma, npages); + free_consistent_cluster(iommu, dvma, npages); spin_unlock_irq(&iommu->lock); for (order = 0; order < 10; order++) { @@ -314,7 +314,7 @@ free_pages((unsigned long)cpu, order); } -u32 sbus_map_single(struct sbus_dev *sdev, void *ptr, long size) +dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t size) { struct sbus_iommu *iommu = sdev->bus->iommu; unsigned long npages, phys_base, flags; @@ -344,7 +344,7 @@ return (dma_base | offset); } -void sbus_unmap_single(struct sbus_dev *sdev, u32 dma_addr, long size) +void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size) { struct sbus_iommu *iommu = sdev->bus->iommu; u32 dma_base = dma_addr & PAGE_MASK; @@ -358,11 +358,12 @@ spin_unlock_irqrestore(&iommu->lock, flags); } -static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nents) +static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused) { struct scatterlist *dma_sg = sg; + int i; - do { + for (i = 0; i < nused; i++) { unsigned long pteval = ~0UL; u32 dma_npages; @@ -426,7 +427,7 @@ pteval = ~0UL; } while (dma_npages != 0); dma_sg++; - } while (dma_sg->dvma_length != 0); + } } int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents) @@ -436,7 +437,7 @@ iopte_t *iopte; u32 dma_base; struct scatterlist *sgtmp; - int unused; + int used; /* Fast path single entry scatterlists. */ if (nents == 1) { @@ -453,22 +454,23 @@ /* Normalize DVMA addresses. */ sgtmp = sg; - unused = nents; + used = nents; - while (unused && sgtmp->dvma_length) { + while (used && sgtmp->dvma_length) { sgtmp->dvma_address += dma_base; sgtmp++; - unused--; + used--; } + used = nents - used; - fill_sg(iopte, sg, nents); + fill_sg(iopte, sg, used); #ifdef VERIFY_SG verify_sglist(sg, nents, iopte, npages); #endif iommu_flush(iommu, dma_base, npages); spin_unlock_irqrestore(&iommu->lock, flags); - return nents - unused; + return used; } void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents) @@ -499,7 +501,7 @@ spin_unlock_irqrestore(&iommu->lock, flags); } -void sbus_dma_sync_single(struct sbus_dev *sdev, u32 base, long size) +void sbus_dma_sync_single(struct sbus_dev *sdev, dma_addr_t base, size_t size) { struct sbus_iommu *iommu = sdev->bus->iommu; unsigned long flags; @@ -1053,6 +1055,10 @@ ~(SMP_CACHE_BYTES - 1UL)); memset(iommu, 0, sizeof(*iommu)); + + /* Make sure DMA address 0 is never returned just to allow catching + of buggy drivers. */ + iommu->lowest_free[0] = 1; /* Setup spinlock. */ spin_lock_init(&iommu->lock); diff -ur --new-file old/linux/arch/sparc64/kernel/signal32.c new/linux/arch/sparc64/kernel/signal32.c --- old/linux/arch/sparc64/kernel/signal32.c Sun Jan 16 07:08:28 2000 +++ new/linux/arch/sparc64/kernel/signal32.c Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: signal32.c,v 1.58 2000/01/14 09:40:08 jj Exp $ +/* $Id: signal32.c,v 1.59 2000/01/21 11:38:52 jj Exp $ * arch/sparc64/kernel/signal32.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -101,6 +101,44 @@ #define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame32) + 7) & (~7))) #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 7) & (~7))) +int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from) +{ + int err; + + if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32))) + return -EFAULT; + + err = __put_user(from->si_signo, &to->si_signo); + err |= __put_user(from->si_errno, &to->si_errno); + err |= __put_user(from->si_code, &to->si_code); + if (from->si_code < 0) + err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); + else { + int signo = from->si_signo; + if (from->si_code == SI_USER || from->si_code == SI_KERNEL) + signo = SIGRTMIN; + switch (signo) { + case SIGCHLD: + err |= __put_user(from->si_utime, &to->si_utime); + err |= __put_user(from->si_stime, &to->si_stime); + err |= __put_user(from->si_status, &to->si_status); + default: + err |= __put_user(from->si_pid, &to->si_pid); + err |= __put_user(from->si_uid, &to->si_uid); + break; + case SIGSEGV: + case SIGILL: + case SIGFPE: + case SIGBUS: + case SIGEMT: + err |= __put_user(from->si_trapno, &to->si_trapno); + err |= __put_user((long)from->si_addr, &to->si_addr); + break; + } + } + return err; +} + /* * atomically swap in the new signal mask, and wait for a signal. * This is really tricky on the Sparc, watch out... @@ -436,13 +474,16 @@ } static void -setup_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc, - struct pt_regs *regs, int signr, sigset_t *oldset) +setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *oldset, siginfo_t *info) { struct signal_sframe32 *sframep; struct sigcontext32 *sc; unsigned seta[_NSIG_WORDS32]; int err = 0; + void *sig_address; + int sig_code; + unsigned long pc = regs->tpc; + unsigned long npc = regs->tnpc; #if 0 int window = 0; @@ -513,17 +554,61 @@ current->thread.w_saved = 0; /* So process is allowed to execute. */ err |= __put_user(signr, &sframep->sig_num); - if(signr == SIGSEGV || - signr == SIGILL || - signr == SIGFPE || - signr == SIGBUS || - signr == SIGEMT) { - err |= __put_user(current->thread.sig_desc, &sframep->sig_code); - err |= __put_user(current->thread.sig_address, &sframep->sig_address); - } else { - err |= __put_user(0, &sframep->sig_code); - err |= __put_user(0, &sframep->sig_address); + sig_address = NULL; + sig_code = 0; + if (SI_FROMKERNEL (info) && (info->si_code & __SI_MASK) == __SI_FAULT) { + sig_address = info->si_addr; + switch (signr) { + case SIGSEGV: + switch (info->si_code) { + case SEGV_MAPERR: sig_code = SUBSIG_NOMAPPING; break; + default: sig_code = SUBSIG_PROTECTION; break; + } + break; + case SIGILL: + switch (info->si_code) { + case ILL_ILLOPC: sig_code = SUBSIG_ILLINST; break; + case ILL_PRVOPC: sig_code = SUBSIG_PRIVINST; break; + case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP (info->si_trapno); break; + default: sig_code = SUBSIG_STACK; break; + } + break; + case SIGFPE: + switch (info->si_code) { + case FPE_INTDIV: sig_code = SUBSIG_IDIVZERO; break; + case FPE_INTOVF: sig_code = SUBSIG_FPINTOVFL; break; + case FPE_FLTDIV: sig_code = SUBSIG_FPDIVZERO; break; + case FPE_FLTOVF: sig_code = SUBSIG_FPOVFLOW; break; + case FPE_FLTUND: sig_code = SUBSIG_FPUNFLOW; break; + case FPE_FLTRES: sig_code = SUBSIG_FPINEXACT; break; + case FPE_FLTINV: sig_code = SUBSIG_FPOPERROR; break; + default: sig_code = SUBSIG_FPERROR; break; + } + break; + case SIGBUS: + switch (info->si_code) { + case BUS_ADRALN: sig_code = SUBSIG_ALIGNMENT; break; + case BUS_ADRERR: sig_code = SUBSIG_MISCERROR; break; + default: sig_code = SUBSIG_BUSTIMEOUT; break; + } + break; + case SIGEMT: + switch (info->si_code) { + case EMT_TAGOVF: sig_code = SUBSIG_TAG; break; + } + break; + case SIGSYS: + if (info->si_code == (__SI_FAULT|0x100)) { + /* See sys_sunos32.c */ + sig_code = info->si_trapno; + break; + } + default: + sig_address = NULL; + } } + err |= __put_user((long)sig_address, &sframep->sig_address); + err |= __put_user(sig_code, &sframep->sig_code); err |= __put_user((u64)sc, &sframep->sig_scptr); if (err) goto sigsegv; @@ -790,8 +875,7 @@ /* Setup the signal information. Solaris expects a bunch of * information to be passed to the signal handler, we don't provide - * that much currently, should use those that David already - * is providing with thread.sig_desc + * that much currently, should use siginfo. */ err |= __put_user(signr, &si->siginfo.signo); err |= __put_user(SVR4_SINOINFO, &si->siginfo.code); @@ -1034,61 +1118,8 @@ err |= __put_user(0, &sf->fpu_save); } - /* Update the siginfo structure. Is this good? */ - if (info->si_code == 0) { - info->si_signo = signr; - info->si_errno = 0; - - switch (signr) { - case SIGSEGV: - case SIGILL: - case SIGFPE: - case SIGBUS: - case SIGEMT: - info->si_code = current->thread.sig_desc; - info->si_addr = (void *)current->thread.sig_address; - info->si_trapno = 0; - break; - default: - break; - } - } - - err = __put_user (info->si_signo, &sf->info.si_signo); - err |= __put_user (info->si_errno, &sf->info.si_errno); - err |= __put_user (info->si_code, &sf->info.si_code); - if (info->si_code < 0) - err |= __copy_to_user (sf->info._sifields._pad, info->_sifields._pad, SI_PAD_SIZE); - else { - i = info->si_signo; - if (info->si_code == SI_USER) - i = SIGRTMIN; - switch (i) { - case SIGPOLL: - err |= __put_user (info->si_band, &sf->info.si_band); - err |= __put_user (info->si_fd, &sf->info.si_fd); - break; - case SIGCHLD: - err |= __put_user (info->si_pid, &sf->info.si_pid); - err |= __put_user (info->si_uid, &sf->info.si_uid); - err |= __put_user (info->si_status, &sf->info.si_status); - err |= __put_user (info->si_utime, &sf->info.si_utime); - err |= __put_user (info->si_stime, &sf->info.si_stime); - break; - case SIGSEGV: - case SIGILL: - case SIGFPE: - case SIGBUS: - case SIGEMT: - err |= __put_user ((long)info->si_addr, &sf->info.si_addr); - err |= __put_user (info->si_trapno, &sf->info.si_trapno); - break; - default: - err |= __put_user (info->si_pid, &sf->info.si_pid); - err |= __put_user (info->si_uid, &sf->info.si_uid); - break; - } - } + /* Update the siginfo structure. */ + err |= copy_siginfo_to_user32(&sf->info, info); /* Setup sigaltstack */ err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); @@ -1174,7 +1205,7 @@ else if (current->thread.flags & SPARC_FLAG_NEWSIGNALS) new_setup_frame32(ka, regs, signr, oldset); else - setup_frame32(&ka->sa, regs->tpc, regs->tnpc, regs, signr, oldset); + setup_frame32(&ka->sa, regs, signr, oldset, info); } if(ka->sa.sa_flags & SA_ONESHOT) ka->sa.sa_handler = SIG_DFL; diff -ur --new-file old/linux/arch/sparc64/kernel/smp.c new/linux/arch/sparc64/kernel/smp.c --- old/linux/arch/sparc64/kernel/smp.c Tue Dec 21 07:05:52 1999 +++ new/linux/arch/sparc64/kernel/smp.c Sat Jan 22 03:22:54 2000 @@ -38,7 +38,7 @@ struct cpuinfo_sparc cpu_data[NR_CPUS] __attribute__ ((aligned (64))); -volatile int cpu_number_map[NR_CPUS] __attribute__ ((aligned (64))); +volatile int __cpu_number_map[NR_CPUS] __attribute__ ((aligned (64))); volatile int __cpu_logical_map[NR_CPUS] __attribute__ ((aligned (64))); /* Please don't make this stuff initdata!!! --DaveM */ @@ -243,7 +243,7 @@ udelay(100); } if(callin_flag) { - cpu_number_map[i] = cpucount; + __cpu_number_map[i] = cpucount; __cpu_logical_map[cpucount] = i; prom_cpu_nodes[i] = linux_cpus[no].prom_node; prom_printf("OK\n"); @@ -255,7 +255,7 @@ } if(!callin_flag) { cpu_present_map &= ~(1UL << i); - cpu_number_map[i] = -1; + __cpu_number_map[i] = -1; } } cpu_new_task = NULL; @@ -697,10 +697,10 @@ for(i = 0; i < linux_num_cpus; i++) cpu_present_map |= (1UL << linux_cpus[i].mid); for(i = 0; i < NR_CPUS; i++) { - cpu_number_map[i] = -1; + __cpu_number_map[i] = -1; __cpu_logical_map[i] = -1; } - cpu_number_map[boot_cpu_id] = 0; + __cpu_number_map[boot_cpu_id] = 0; prom_cpu_nodes[boot_cpu_id] = linux_cpus[0].prom_node; __cpu_logical_map[0] = boot_cpu_id; current->processor = boot_cpu_id; diff -ur --new-file old/linux/arch/sparc64/kernel/sparc64_ksyms.c new/linux/arch/sparc64/kernel/sparc64_ksyms.c --- old/linux/arch/sparc64/kernel/sparc64_ksyms.c Fri Jan 7 20:15:27 2000 +++ new/linux/arch/sparc64/kernel/sparc64_ksyms.c Thu Jan 27 17:58:15 2000 @@ -185,8 +185,8 @@ EXPORT_SYMBOL(sbus_root); EXPORT_SYMBOL(dma_chain); EXPORT_SYMBOL(sbus_set_sbus64); -EXPORT_SYMBOL(sbus_alloc_consistant); -EXPORT_SYMBOL(sbus_free_consistant); +EXPORT_SYMBOL(sbus_alloc_consistent); +EXPORT_SYMBOL(sbus_free_consistent); EXPORT_SYMBOL(sbus_map_single); EXPORT_SYMBOL(sbus_unmap_single); EXPORT_SYMBOL(sbus_map_sg); @@ -208,6 +208,16 @@ EXPORT_SYMBOL(insb); EXPORT_SYMBOL(insw); EXPORT_SYMBOL(insl); +#endif +#ifdef NEW_PCI_DMA_MAP +EXPORT_SYMBOL(pci_alloc_consistent); +EXPORT_SYMBOL(pci_free_consistent); +EXPORT_SYMBOL(pci_map_single); +EXPORT_SYMBOL(pci_unmap_single); +EXPORT_SYMBOL(pci_map_sg); +EXPORT_SYMBOL(pci_unmap_sg); +EXPORT_SYMBOL(pci_dma_sync_single); +EXPORT_SYMBOL(pci_dma_sync_sg); #endif /* Solaris/SunOS binary compatibility */ diff -ur --new-file old/linux/arch/sparc64/kernel/sys_sparc.c new/linux/arch/sparc64/kernel/sys_sparc.c --- old/linux/arch/sparc64/kernel/sys_sparc.c Thu Jan 13 21:03:00 2000 +++ new/linux/arch/sparc64/kernel/sys_sparc.c Thu Jan 27 15:32:14 2000 @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.33 2000/01/11 17:33:25 jj Exp $ +/* $Id: sys_sparc.c,v 1.34 2000/01/21 11:39:06 jj Exp $ * linux/arch/sparc64/kernel/sys_sparc.c * * This file contains various random system calls that @@ -223,11 +223,18 @@ asmlinkage void sparc_breakpoint (struct pt_regs *regs) { + siginfo_t info; + lock_kernel(); #ifdef DEBUG_SPARC_BREAKPOINT printk ("TRAP: Entering kernel PC=%lx, nPC=%lx\n", regs->tpc, regs->tnpc); #endif - force_sig(SIGTRAP, current); + info.si_signo = SIGTRAP; + info.si_errno = 0; + info.si_code = TRAP_BRKPT; + info.si_addr = (void *)regs->tpc; + info.si_trapno = 0; + force_sig_info(SIGTRAP, &info, current); #ifdef DEBUG_SPARC_BREAKPOINT printk ("TRAP: Returning to space: PC=%lx nPC=%lx\n", regs->tpc, regs->tnpc); #endif @@ -241,7 +248,7 @@ int nlen; int err = -EFAULT; - down(&uts_sem); + down_read(&uts_sem); nlen = strlen(system_utsname.domainname) + 1; @@ -253,7 +260,7 @@ goto done; err = 0; done: - up(&uts_sem); + up_read(&uts_sem); return err; } diff -ur --new-file old/linux/arch/sparc64/kernel/sys_sparc32.c new/linux/arch/sparc64/kernel/sys_sparc32.c --- old/linux/arch/sparc64/kernel/sys_sparc32.c Sun Jan 16 07:08:29 2000 +++ new/linux/arch/sparc64/kernel/sys_sparc32.c Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.130 2000/01/14 09:40:07 jj Exp $ +/* $Id: sys_sparc32.c,v 1.131 2000/01/21 11:38:54 jj Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -2082,7 +2082,7 @@ sigset_t s; sigset_t32 s32; struct timespec t; - int ret, err, i; + int ret; mm_segment_t old_fs = get_fs(); siginfo_t info; @@ -2104,42 +2104,8 @@ ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize); set_fs (old_fs); if (ret >= 0 && uinfo) { - err = put_user (info.si_signo, &uinfo->si_signo); - err |= __put_user (info.si_errno, &uinfo->si_errno); - err |= __put_user (info.si_code, &uinfo->si_code); - if (info.si_code < 0) - err |= __copy_to_user (uinfo->_sifields._pad, info._sifields._pad, SI_PAD_SIZE); - else { - i = info.si_signo; - if (info.si_code == SI_USER) - i = SIGRTMIN; - switch (i) { - case SIGPOLL: - err |= __put_user (info.si_band, &uinfo->si_band); - err |= __put_user (info.si_fd, &uinfo->si_fd); - break; - case SIGCHLD: - err |= __put_user (info.si_pid, &uinfo->si_pid); - err |= __put_user (info.si_uid, &uinfo->si_uid); - err |= __put_user (info.si_status, &uinfo->si_status); - err |= __put_user (info.si_utime, &uinfo->si_utime); - err |= __put_user (info.si_stime, &uinfo->si_stime); - break; - case SIGSEGV: - case SIGILL: - case SIGFPE: - case SIGBUS: - case SIGEMT: - err |= __put_user ((long)info.si_addr, &uinfo->si_addr); - err |= __put_user (info.si_trapno, &uinfo->si_trapno); - break; - default: - err |= __put_user (info.si_pid, &uinfo->si_pid); - err |= __put_user (info.si_uid, &uinfo->si_uid); - break; - } - } - if (err) + extern int copy_siginfo_to_user32(siginfo_t32 *, siginfo_t *); + if (copy_siginfo_to_user32(uinfo, &info)) ret = -EFAULT; } return ret; diff -ur --new-file old/linux/arch/sparc64/kernel/sys_sunos32.c new/linux/arch/sparc64/kernel/sys_sunos32.c --- old/linux/arch/sparc64/kernel/sys_sunos32.c Fri Jan 7 01:17:19 2000 +++ new/linux/arch/sparc64/kernel/sys_sunos32.c Thu Jan 27 15:32:14 2000 @@ -1,4 +1,4 @@ -/* $Id: sys_sunos32.c,v 1.35 2000/01/06 23:51:50 davem Exp $ +/* $Id: sys_sunos32.c,v 1.37 2000/01/21 11:39:03 jj Exp $ * sys_sunos32.c: SunOS binary compatability layer on sparc64. * * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu) @@ -323,6 +323,7 @@ spin_lock_irq(¤t->sigmask_lock); old = (u32) current->blocked.sig[0]; current->blocked.sig[0] |= (blk_mask & _BLOCKABLE); + recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); return old; } @@ -334,6 +335,7 @@ spin_lock_irq(¤t->sigmask_lock); retval = (u32) current->blocked.sig[0]; current->blocked.sig[0] = (newmask & _BLOCKABLE); + recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); return retval; } @@ -541,29 +543,36 @@ { int ret; - down(&uts_sem); + down_read(&uts_sem); ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1); ret |= copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1); ret |= put_user('\0', &name->nname[8]); ret |= copy_to_user(&name->rel[0], &system_utsname.release[0], sizeof(name->rel) - 1); ret |= copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1); ret |= copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1); - up(&uts_sem); + up_read(&uts_sem); return ret; } asmlinkage int sunos_nosys(void) { struct pt_regs *regs; + siginfo_t info; + static int cnt; lock_kernel(); regs = current->thread.kregs; - current->thread.sig_address = regs->tpc; - current->thread.sig_desc = regs->u_regs[UREG_G1]; - send_sig(SIGSYS, current, 1); - printk("Process makes ni_syscall number %d, register dump:\n", - (int) regs->u_regs[UREG_G1]); - show_regs(regs); + info.si_signo = SIGSYS; + info.si_errno = 0; + info.si_code = __SI_FAULT|0x100; + info.si_addr = (void *)regs->tpc; + info.si_trapno = regs->u_regs[UREG_G1]; + send_sig_info(SIGSYS, &info, current); + if (cnt++ < 4) { + printk("Process makes ni_syscall number %d, register dump:\n", + (int) regs->u_regs[UREG_G1]); + show_regs(regs); + } unlock_kernel(); return -ENOSYS; } diff -ur --new-file old/linux/arch/sparc64/kernel/systbls.S new/linux/arch/sparc64/kernel/systbls.S --- old/linux/arch/sparc64/kernel/systbls.S Sun Jan 16 07:08:29 2000 +++ new/linux/arch/sparc64/kernel/systbls.S Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.65 2000/01/14 07:12:34 davem Exp $ +/* $Id: systbls.S,v 1.66 2000/01/16 06:20:48 davem Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * @@ -34,15 +34,15 @@ /*60*/ .word sys_umask, sys_chroot, sys32_newfstat, sys_fstat64, sys_getpagesize .word sys_msync, sys_vfork, sys32_pread, sys32_pwrite, sys_geteuid /*70*/ .word sys_getegid, sys32_mmap, sys_setreuid, sys_munmap, sys_mprotect - .word sys_setregid, sys_vhangup, sys32_truncate64, sys_getgroups, sys32_getgroups16 + .word sys_nis_syscall, sys_vhangup, sys32_truncate64, sys_nis_syscall, sys32_getgroups16 /*80*/ .word sys32_setgroups16, sys_getpgrp, sys_setgroups, sys32_setitimer, sys32_ftruncate64 .word sys_swapon, sys32_getitimer, sys_setuid, sys_sethostname, sys_setgid /*90*/ .word sys_dup2, sys_setfsuid, sys32_fcntl, sys32_select, sys_setfsgid .word sys_fsync, sys_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall /*100*/ .word sys_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending .word sys32_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_setresuid, sys_getresuid -/*110*/ .word sys_setresgid, sys_getresgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall - .word sys_nis_syscall, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd +/*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall + .word sys_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd /*120*/ .word sys32_readv, sys32_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod .word sys_nis_syscall, sys32_setreuid16, sys32_setregid16, sys_rename, sys_truncate /*130*/ .word sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall diff -ur --new-file old/linux/arch/sparc64/kernel/traps.c new/linux/arch/sparc64/kernel/traps.c --- old/linux/arch/sparc64/kernel/traps.c Tue Dec 21 07:05:52 1999 +++ new/linux/arch/sparc64/kernel/traps.c Sat Jan 22 03:22:54 2000 @@ -1,8 +1,8 @@ -/* $Id: traps.c,v 1.64 1999/12/19 23:53:13 davem Exp $ +/* $Id: traps.c,v 1.65 2000/01/21 11:39:01 jj Exp $ * arch/sparc64/kernel/traps.c * * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) - * Copyright (C) 1997,1999 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com) */ /* @@ -253,6 +253,8 @@ void bad_trap (struct pt_regs *regs, long lvl) { + siginfo_t info; + lock_kernel (); if (lvl < 0x100) { char buffer[24]; @@ -262,9 +264,12 @@ } if (regs->tstate & TSTATE_PRIV) die_if_kernel ("Kernel bad trap", regs); - current->thread.sig_desc = SUBSIG_BADTRAP(lvl - 0x100); - current->thread.sig_address = regs->tpc; - force_sig(SIGILL, current); + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = ILL_ILLTRP; + info.si_addr = (void *)regs->tpc; + info.si_trapno = lvl - 0x100; + force_sig_info(SIGILL, &info, current); unlock_kernel (); } @@ -281,6 +286,8 @@ void instruction_access_exception (struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) { + siginfo_t info; + lock_kernel(); if (regs->tstate & TSTATE_PRIV) { #if 1 @@ -289,15 +296,20 @@ #endif die_if_kernel("Iax", regs); } - current->thread.sig_desc = SUBSIG_ILLINST; - current->thread.sig_address = regs->tpc; - force_sig(SIGILL, current); + info.si_signo = SIGSEGV; + info.si_errno = 0; + info.si_code = SEGV_MAPERR; + info.si_addr = (void *)regs->tpc; + info.si_trapno = 0; + force_sig_info(SIGSEGV, &info, current); unlock_kernel(); } void data_access_exception (struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) { + siginfo_t info; + if (regs->tstate & TSTATE_PRIV) { /* Test if this comes from uaccess places. */ unsigned long fixup, g2; @@ -326,8 +338,13 @@ else rtrap_check(regs); #endif + info.si_signo = SIGSEGV; + info.si_errno = 0; + info.si_code = SEGV_MAPERR; + info.si_addr = (void *)sfar; + info.si_trapno = 0; lock_kernel(); - force_sig(SIGSEGV, current); + force_sig_info(SIGSEGV, &info, current); unlock_kernel(); } @@ -361,6 +378,22 @@ : "memory"); } +void do_iae(struct pt_regs *regs) +{ + siginfo_t info; + + clean_and_reenable_l1_caches(); + + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = BUS_OBJERR; + info.si_addr = (void *)0; + info.si_trapno = 0; + lock_kernel(); + force_sig_info(SIGBUS, &info, current); + unlock_kernel(); +} + void do_dae(struct pt_regs *regs) { #ifdef CONFIG_PCI @@ -381,19 +414,7 @@ return; } #endif - clean_and_reenable_l1_caches(); - lock_kernel(); - force_sig(SIGSEGV, current); - unlock_kernel(); -} - -void do_iae(struct pt_regs *regs) -{ - clean_and_reenable_l1_caches(); - - lock_kernel(); - force_sig(SIGSEGV, current); - unlock_kernel(); + do_iae(regs); } static char ecc_syndrome_table[] = { @@ -521,22 +542,26 @@ regs->tnpc += 4; } else { unsigned long fsr = current->thread.xfsr[0]; + siginfo_t info; - current->thread.sig_address = regs->tpc; - current->thread.sig_desc = SUBSIG_FPERROR; + info.si_signo = SIGFPE; + info.si_errno = 0; + info.si_addr = (void *)regs->tpc; + info.si_trapno = 0; + info.si_code = __SI_FAULT; if ((fsr & 0x1c000) == (1 << 14)) { - if (fsr & 0x01) - current->thread.sig_desc = SUBSIG_FPINEXACT; - else if (fsr & 0x02) - current->thread.sig_desc = SUBSIG_FPDIVZERO; - else if (fsr & 0x04) - current->thread.sig_desc = SUBSIG_FPUNFLOW; + if (fsr & 0x10) + info.si_code = FPE_FLTINV; else if (fsr & 0x08) - current->thread.sig_desc = SUBSIG_FPOVFLOW; - else if (fsr & 0x10) - current->thread.sig_desc = SUBSIG_FPINTOVFL; + info.si_code = FPE_FLTOVF; + else if (fsr & 0x04) + info.si_code = FPE_FLTUND; + else if (fsr & 0x02) + info.si_code = FPE_FLTDIV; + else if (fsr & 0x01) + info.si_code = FPE_FLTRES; } - send_sig(SIGFPE, current, 1); + send_sig_info(SIGFPE, &info, current); } } @@ -570,24 +595,34 @@ void do_tof(struct pt_regs *regs) { + siginfo_t info; + if(regs->tstate & TSTATE_PRIV) die_if_kernel("Penguin overflow trap from kernel mode", regs); - current->thread.sig_address = regs->tpc; - current->thread.sig_desc = SUBSIG_TAG; /* as good as any */ - send_sig(SIGEMT, current, 1); + info.si_signo = SIGEMT; + info.si_errno = 0; + info.si_code = EMT_TAGOVF; + info.si_addr = (void *)regs->tpc; + info.si_trapno = 0; + send_sig_info(SIGEMT, &info, current); } void do_div0(struct pt_regs *regs) { - current->thread.sig_address = regs->tpc; - current->thread.sig_desc = SUBSIG_IDIVZERO; - send_sig(SIGFPE, current, 1); + siginfo_t info; + + info.si_signo = SIGFPE; + info.si_errno = 0; + info.si_code = FPE_INTDIV; + info.si_addr = (void *)regs->tpc; + info.si_trapno = 0; + send_sig_info(SIGFPE, &info, current); } void instruction_dump (unsigned int *pc) { int i; - + if((((unsigned long) pc) & 3)) return; @@ -671,6 +706,7 @@ unsigned long pc = regs->tpc; unsigned long tstate = regs->tstate; u32 insn; + siginfo_t info; if(tstate & TSTATE_PRIV) die_if_kernel("Kernel illegal instruction", regs); @@ -685,56 +721,48 @@ return; } } - current->thread.sig_address = pc; - current->thread.sig_desc = SUBSIG_ILLINST; - send_sig(SIGILL, current, 1); + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = ILL_ILLOPC; + info.si_addr = (void *)pc; + info.si_trapno = 0; + send_sig_info(SIGILL, &info, current); } void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr) { + siginfo_t info; + if(regs->tstate & TSTATE_PRIV) { extern void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, unsigned long sfar, unsigned long sfsr); return kernel_unaligned_trap(regs, *((unsigned int *)regs->tpc), sfar, sfsr); - } else { - current->thread.sig_address = regs->tpc; - current->thread.sig_desc = SUBSIG_PRIVINST; - send_sig(SIGBUS, current, 1); } + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = BUS_ADRALN; + info.si_addr = (void *)sfar; + info.si_trapno = 0; + send_sig_info(SIGBUS, &info, current); } void do_privop(struct pt_regs *regs) { - current->thread.sig_address = regs->tpc; - current->thread.sig_desc = SUBSIG_PRIVINST; - send_sig(SIGILL, current, 1); -} + siginfo_t info; -void do_privact(struct pt_regs *regs) -{ - current->thread.sig_address = regs->tpc; - current->thread.sig_desc = SUBSIG_PRIVINST; - send_sig(SIGILL, current, 1); + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = ILL_PRVOPC; + info.si_addr = (void *)regs->tpc; + info.si_trapno = 0; + send_sig_info(SIGILL, &info, current); } -void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc, - unsigned long tstate) +void do_privact(struct pt_regs *regs) { - if(tstate & TSTATE_PRIV) - die_if_kernel("Penguin instruction from Penguin mode??!?!", regs); - current->thread.sig_address = pc; - current->thread.sig_desc = SUBSIG_PRIVINST; - send_sig(SIGILL, current, 1); -} - -void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, - unsigned long npc, unsigned long psr) -{ - current->thread.sig_address = regs->tpc; - current->thread.sig_desc = SUBSIG_IDIVZERO; - send_sig(SIGFPE, current, 1); + do_privop(regs); } /* Trap level 1 stuff or other traps we should never see... */ diff -ur --new-file old/linux/arch/sparc64/lib/Makefile new/linux/arch/sparc64/lib/Makefile --- old/linux/arch/sparc64/lib/Makefile Sun Jul 4 18:53:12 1999 +++ new/linux/arch/sparc64/lib/Makefile Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.19 1999/07/03 22:11:08 davem Exp $ +# $Id: Makefile,v 1.20 2000/01/19 04:06:03 davem Exp $ # Makefile for Sparc library files.. # @@ -6,8 +6,8 @@ OBJS = PeeCeeI.o blockops.o debuglocks.o strlen.o strncmp.o \ memscan.o strncpy_from_user.o strlen_user.o memcmp.o checksum.o \ - VIScopy.o VISbzero.o VISmemset.o VIScsum.o VIScsumcopy.o VISsave.o \ - atomic.o rwlock.o + VIScopy.o VISbzero.o VISmemset.o VIScsum.o VIScsumcopy.o \ + VIScsumcopyusr.o VISsave.o atomic.o rwlock.o lib.a: $(OBJS) $(AR) rcs lib.a $(OBJS) diff -ur --new-file old/linux/arch/sparc64/lib/VIScsumcopy.S new/linux/arch/sparc64/lib/VIScsumcopy.S --- old/linux/arch/sparc64/lib/VIScsumcopy.S Thu May 27 18:55:21 1999 +++ new/linux/arch/sparc64/lib/VIScsumcopy.S Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: VIScsumcopy.S,v 1.6 1999/05/25 16:53:03 jj Exp $ +/* $Id: VIScsumcopy.S,v 1.7 2000/01/19 04:06:03 davem Exp $ * VIScsumcopy.S: High bandwidth IP checksumming with simultaneous * copying utilizing the UltraSparc Visual Instruction Set. * @@ -75,7 +75,7 @@ membar #Sync -#define DO_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,F0,F2,F4,F6,F8,F10,F12,F14,DUMMY1,A0,A2,A4,A6,A8,A10,A12,A14,B14,DYMMY2,LOAD,STORE1,STORE2,STORE3,STORE4,STORE5,STORE6,STORE7,STORE8,DUMMY3,BRANCH...) \ +#define DO_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,F0,F2,F4,F6,F8,F10,F12,F14,DUMMY1,A0,A2,A4,A6,A8,A10,A12,A14,B14,DUMMY2,LOAD,STORE1,STORE2,STORE3,STORE4,STORE5,STORE6,STORE7,STORE8,DUMMY3,BRANCH...) \ LOAD /* Load Group */; \ faligndata %A14, %F0, %A14 /* FPA Group */; \ inc %x5 /* IEU0 */; \ diff -ur --new-file old/linux/arch/sparc64/lib/VIScsumcopyusr.S new/linux/arch/sparc64/lib/VIScsumcopyusr.S --- old/linux/arch/sparc64/lib/VIScsumcopyusr.S Thu Jan 1 01:00:00 1970 +++ new/linux/arch/sparc64/lib/VIScsumcopyusr.S Sat Jan 22 03:22:54 2000 @@ -0,0 +1,914 @@ +/* $Id: VIScsumcopyusr.S,v 1.1 2000/01/19 04:06:04 davem Exp $ + * VIScsumcopyusr.S: High bandwidth IP checksumming with simultaneous + * copying utilizing the UltraSparc Visual Instruction Set. + * + * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz) + * Copyright (C) 2000 David S. Miller (davem@redhat.com) + * + * Based on older sparc32/sparc64 checksum.S, which is: + * + * Copyright(C) 1995 Linus Torvalds + * Copyright(C) 1995 Miguel de Icaza + * Copyright(C) 1996,1997 David S. Miller + * derived from: + * Linux/Alpha checksum c-code + * Linux/ix86 inline checksum assembly + * RFC1071 Computing the Internet Checksum (esp. Jacobsons m68k code) + * David Mosberger-Tang for optimized reference c-code + * BSD4.4 portable checksum routine + */ + +#ifdef __sparc_v9__ +#define STACKOFF 0x7ff+128 +#else +#define STACKOFF 64 +#endif + +#ifdef __KERNEL__ +#include +#include +#include +#include +#define ASI_BLK_XOR 0 +#define ASI_BLK_XOR1 (ASI_BLK_P ^ (ASI_BLK_P >> 3) ^ ASI_P) +#define ASI_BLK_OR (ASI_BLK_P & ~ASI_P) +#else +#define ASI_P 0x80 +#define ASI_BLK_P 0xf0 +#define FRPS_FEF 0x04 +#define FPRS_DU 0x02 +#define FPRS_DL 0x01 +#define ASI_BLK_XOR (ASI_BLK_P ^ ASI_P) +#endif + +#define src o0 +#define dst o1 +#define len o2 +#define sum o3 +#define x1 g1 +#define x2 g2 +#define x3 o4 +#define x4 g4 +#define x5 g5 +#define x6 g7 +#define x7 g3 +#define x8 o5 + +/* Dobrou noc, SunSoft engineers. Spete sladce. + * This has a couple of tricks in and those + * tricks are UltraLinux trade secrets :)) + * Once AGAIN, the SunSoft engineers are caught + * asleep at the keyboard :)). + * The main loop does about 20 superscalar cycles + * per 64bytes checksummed/copied. + */ + +#define LDBLK(O0) \ + ldda [%src] ASI_BLK_P, %O0 /* Load Group */ + +#define STBLK \ + stda %f48, [%dst] %asi /* Store */ + +#ifdef __KERNEL__ +#define STBLK_XORASI(tmpreg1,tmpreg2) \ + stda %f48, [%dst] %asi /* Store */; \ + rd %asi, %tmpreg1; \ + srl %tmpreg1, 3, %tmpreg2; \ + xor %tmpreg1, ASI_BLK_XOR1, %tmpreg1; \ + wr %tmpreg1, %tmpreg2, %asi; +#else +#define STBLK_XORASI(tmpreg1,tmpreg2) \ + stda %f48, [%dst] %asi /* Store */; \ + rd %asi, %tmpreg1; \ + wr %tmpreg1, ASI_BLK_XOR, %asi; +#endif + +#define ST(fx,off) \ + stda %fx, [%dst + off] %asi /* Store */ + +#define SYNC \ + membar #Sync + + +#define DO_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,F0,F2,F4,F6,F8,F10,F12,F14,DUMMY1,A0,A2,A4,A6,A8,A10,A12,A14,B14,DUMMY2,LOAD,STORE1,STORE2,STORE3,STORE4,STORE5,STORE6,STORE7,STORE8,DUMMY3,BRANCH...) \ + LOAD /* Load Group */; \ + faligndata %A14, %F0, %A14 /* FPA Group */; \ + inc %x5 /* IEU0 */; \ + STORE1 /* Store (optional) */; \ + faligndata %F0, %F2, %A0 /* FPA Group */; \ + srl %x5, 1, %x5 /* IEU0 */; \ + add %sum, %x4, %sum /* IEU1 */; \ + fpadd32 %F0, %f0, %F0 /* FPA Group */; \ + inc %x6 /* IEU0 */; \ + STORE2 /* Store (optional) */; \ + faligndata %F2, %F4, %A2 /* FPA Group */; \ + srl %x6, 1, %x6 /* IEU0 */; \ + add %sum, %x5, %sum /* IEU1 */; \ + fpadd32 %F2, %f2, %F2 /* FPA Group */; \ + add %src, 64, %src /* IEU0 */; \ + add %dst, 64, %dst /* IEU1 */; \ + fcmpgt32 %f0, %F0, %x1 /* FPM Group */; \ + inc %x7 /* IEU0 */; \ + STORE3 /* Store (optional) */; \ + faligndata %F4, %F6, %A4 /* FPA */; \ + srl %x7, 1, %x7 /* IEU0 Group */; \ + add %sum, %x6, %sum /* IEU1 */; \ + fpadd32 %F4, %f4, %F4 /* FPA */; \ + fcmpgt32 %f2, %F2, %x2 /* FPM Group */; \ + inc %x8 /* IEU0 */; \ + STORE4 /* Store (optional) */; \ + faligndata %F6, %F8, %A6 /* FPA */; \ + srl %x8, 1, %x8 /* IEU0 Group */; \ + add %sum, %x7, %sum /* IEU1 */; \ + fpadd32 %F6, %f6, %F6 /* FPA */; \ + fcmpgt32 %f4, %F4, %x3 /* FPM Group */; \ + inc %x1 /* IEU0 */; \ + STORE5 /* Store (optional) */; \ + faligndata %F8, %F10, %A8 /* FPA */; \ + srl %x1, 1, %x1 /* IEU0 Group */; \ + add %sum, %x8, %sum /* IEU1 */; \ + fpadd32 %F8, %f8, %F8 /* FPA */; \ + fcmpgt32 %f6, %F6, %x4 /* FPM Group */; \ + inc %x2 /* IEU0 */; \ + STORE6 /* Store (optional) */; \ + faligndata %F10, %F12, %A10 /* FPA */; \ + srl %x2, 1, %x2 /* IEU0 Group */; \ + add %sum, %x1, %sum /* IEU1 */; \ + fpadd32 %F10, %f10, %F10 /* FPA */; \ + fcmpgt32 %f8, %F8, %x5 /* FPM Group */; \ + inc %x3 /* IEU0 */; \ + STORE7 /* Store (optional) */; \ + faligndata %F12, %F14, %A12 /* FPA */; \ + srl %x3, 1, %x3 /* IEU0 Group */; \ + add %sum, %x2, %sum /* IEU1 */; \ + fpadd32 %F12, %f12, %F12 /* FPA */; \ + fcmpgt32 %f10, %F10, %x6 /* FPM Group */; \ + inc %x4 /* IEU0 */; \ + STORE8 /* Store (optional) */; \ + fmovd %F14, %B14 /* FPA */; \ + srl %x4, 1, %x4 /* IEU0 Group */; \ + add %sum, %x3, %sum /* IEU1 */; \ + fpadd32 %F14, %f14, %F14 /* FPA */; \ + fcmpgt32 %f12, %F12, %x7 /* FPM Group */; \ + subcc %len, 64, %len /* IEU1 */; \ + BRANCH /* CTI */; \ + fcmpgt32 %f14, %F14, %x8 /* FPM Group */; \ + +#define END_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,FA,FB,S0,S1,S2,S3,T0,T1,U0,fz) \ + inc %x5 /* IEU0 Group */; \ + fpadd32 %f2, %f0, %S0 /* FPA */; \ + srl %x5, 1, %x5 /* IEU0 Group */; \ + add %sum, %x4, %sum /* IEU1 */; \ + fpadd32 %f6, %f4, %S1 /* FPA */; \ + inc %x6 /* IEU0 Group */; \ + add %sum, %x5, %sum /* IEU1 */; \ + fcmpgt32 %f0, %S0, %x1 /* FPM Group */; \ + srl %x6, 1, %x6 /* IEU0 */; \ + inc %x7 /* IEU1 */; \ + fpadd32 %f10, %f8, %S2 /* FPA */; \ + fcmpgt32 %f4, %S1, %x2 /* FPM Group */; \ + srl %x7, 1, %x7 /* IEU0 */; \ + add %sum, %x6, %sum /* IEU1 */; \ + fpadd32 %f14, %f12, %S3 /* FPA */; \ + inc %x8 /* IEU0 Group */; \ + add %sum, %x7, %sum /* IEU1 */; \ + fzero %fz /* FPA */; \ + fcmpgt32 %f8, %S2, %x3 /* FPM Group */; \ + srl %x8, 1, %x8 /* IEU0 */; \ + inc %x1 /* IEU1 */; \ + fpadd32 %S0, %S1, %T0 /* FPA */; \ + fcmpgt32 %f12, %S3, %x4 /* FPM Group */; \ + srl %x1, 1, %x1 /* IEU0 */; \ + add %sum, %x8, %sum /* IEU1 */; \ + fpadd32 %S2, %S3, %T1 /* FPA */; \ + inc %x2 /* IEU0 Group */; \ + add %sum, %x1, %sum /* IEU1 */; \ + fcmpgt32 %S0, %T0, %x5 /* FPM Group */; \ + srl %x2, 1, %x2 /* IEU0 */; \ + inc %x3 /* IEU1 */; \ + fcmpgt32 %S2, %T1, %x6 /* FPM Group */; \ + srl %x3, 1, %x3 /* IEU0 */; \ + add %sum, %x2, %sum /* IEU1 */; \ + inc %x4 /* IEU0 Group */; \ + add %sum, %x3, %sum /* IEU1 */; \ + fcmpgt32 %fz, %f2, %x7 /* FPM Group */; \ + srl %x4, 1, %x4 /* IEU0 */; \ + inc %x5 /* IEU1 */; \ + fpadd32 %T0, %T1, %U0 /* FPA */; \ + fcmpgt32 %fz, %f6, %x8 /* FPM Group */; \ + srl %x5, 1, %x5 /* IEU0 */; \ + add %sum, %x4, %sum /* IEU1 */; \ + inc %x6 /* IEU0 Group */; \ + add %sum, %x5, %sum /* IEU1 */; \ + fcmpgt32 %fz, %f10, %x1 /* FPM Group */; \ + srl %x6, 1, %x6 /* IEU0 */; \ + inc %x7 /* IEU1 */; \ + fcmpgt32 %fz, %f14, %x2 /* FPM Group */; \ + ba,pt %xcc, ett /* CTI */; \ + fmovd %FA, %FB /* FPA */; \ + +#define END_THE_TRICK1(f0,f2,f4,f6,f8,f10,f12,f14,FA,FB) \ + END_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,FA,FB,f48,f50,f52,f54,f56,f58,f60,f62) + +#define END_THE_TRICK2(S0,S1,S2,S3,T0,T1,U0,U1,V0,fz) \ + fpadd32 %U0, %U1, %V0 /* FPA Group */; \ + srl %x7, 1, %x7 /* IEU0 */; \ + add %sum, %x6, %sum /* IEU1 */; \ + std %V0, [%sp + STACKOFF] /* Store Group */; \ + inc %x8 /* IEU0 */; \ + sub %sum, %x7, %sum /* IEU1 */; \ + fcmpgt32 %fz, %S1, %x3 /* FPM Group */; \ + srl %x8, 1, %x8 /* IEU0 */; \ + inc %x1 /* IEU1 */; \ + fcmpgt32 %fz, %S3, %x4 /* FPM Group */; \ + srl %x1, 1, %x1 /* IEU0 */; \ + sub %sum, %x8, %sum /* IEU1 */; \ + ldx [%sp + STACKOFF], %x8 /* Load Group */; \ + inc %x2 /* IEU0 */; \ + sub %sum, %x1, %sum /* IEU1 */; \ + fcmpgt32 %fz, %T1, %x5 /* FPM Group */; \ + srl %x2, 1, %x2 /* IEU0 */; \ + inc %x3 /* IEU1 */; \ + fcmpgt32 %T0, %U0, %x6 /* FPM Group */; \ + srl %x3, 1, %x3 /* IEU0 */; \ + sub %sum, %x2, %sum /* IEU1 */; \ + inc %x4 /* IEU0 Group */; \ + sub %sum, %x3, %sum /* IEU1 */; \ + fcmpgt32 %fz, %U1, %x7 /* FPM Group */; \ + srl %x4, 1, %x4 /* IEU0 */; \ + inc %x5 /* IEU1 */; \ + fcmpgt32 %U0, %V0, %x1 /* FPM Group */; \ + srl %x5, 1, %x5 /* IEU0 */; \ + sub %sum, %x4, %sum /* IEU1 */; \ + fcmpgt32 %fz, %V0, %x2 /* FPM Group */; \ + inc %x6 /* IEU0 */; \ + sub %sum, %x5, %sum /* IEU1 */; \ + srl %x6, 1, %x6 /* IEU0 Group */; \ + inc %x7 /* IEU1 */; \ + srl %x7, 1, %x7 /* IEU0 Group */; \ + add %sum, %x6, %sum /* IEU1 */; \ + inc %x1 /* IEU0 Group */; \ + sub %sum, %x7, %sum /* IEU1 */; \ + srl %x1, 1, %x1 /* IEU0 Group */; \ + inc %x2 /* IEU1 */; \ + srl %x2, 1, %x2 /* IEU0 Group */; \ + add %sum, %x1, %sum /* IEU1 */; \ + sub %sum, %x2, %sum /* IEU0 Group */; \ + addcc %sum, %x8, %sum /* IEU Group */; \ + bcs,a,pn %xcc, 33f /* CTI */; \ + add %sum, 1, %sum /* IEU0 */; \ +33: /* That's it */; + + .text + .globl csum_partial_copy_user_vis + .align 32 +/* %asi should be either ASI_P or ASI_AIUS for csum_partial_copy resp. csum_partial_copy_from_user */ +/* This assumes that !((%src^%dst)&3) && !((%src|%dst)&1) && %len >= 256 */ +csum_partial_copy_user_vis: + andcc %dst, 7, %g0 /* IEU1 Group */ + be,pt %icc, 4f /* CTI */ + and %dst, 0x38, %o4 /* IEU0 */ + mov 1, %g5 /* IEU0 Group */ + andcc %dst, 2, %g0 /* IEU1 */ + be,pt %icc, 1f /* CTI */ + and %dst, 4, %g7 /* IEU0 Group */ + lduh [%src], %g2 /* Load */ + sub %len, 2, %len /* IEU0 Group */ + add %dst, 2, %dst /* IEU1 */ + andcc %dst, 4, %g7 /* IEU1 Group */ + sll %g5, 16, %g5 /* IEU0 */ + stha %g2, [%dst - 2] %asi /* Store Group */ + sll %g2, 16, %g2 /* IEU0 */ + add %src, 2, %src /* IEU1 */ + addcc %g2, %sum, %sum /* IEU1 Group */ + bcs,a,pn %icc, 1f /* CTI */ + add %sum, %g5, %sum /* IEU0 */ +1: lduw [%src], %g2 /* Load */ + brz,a,pn %g7, 4f /* CTI+IEU1 Group */ + and %dst, 0x38, %o4 /* IEU0 */ + add %dst, 4, %dst /* IEU0 Group */ + sub %len, 4, %len /* IEU1 */ + addcc %g2, %sum, %sum /* IEU1 Group */ + bcs,a,pn %icc, 1f /* CTI */ + add %sum, 1, %sum /* IEU0 */ +1: and %dst, 0x38, %o4 /* IEU0 Group */ + stwa %g2, [%dst - 4] %asi /* Store */ + add %src, 4, %src /* IEU1 */ +4: +#ifdef __KERNEL__ + VISEntry +#endif + mov %src, %g7 /* IEU1 Group */ + fzero %f48 /* FPA */ + alignaddr %src, %g0, %src /* Single Group */ + subcc %g7, %src, %g7 /* IEU1 Group */ + be,pt %xcc, 1f /* CTI */ + mov 0x40, %g1 /* IEU0 */ + lduw [%src], %g2 /* Load Group */ + subcc %sum, %g2, %sum /* IEU1 Group+load stall */ + bcs,a,pn %icc, 1f /* CTI */ + sub %sum, 1, %sum /* IEU0 */ +1: srl %sum, 0, %sum /* IEU0 Group */ + clr %g5 /* IEU1 */ + brz,pn %o4, 3f /* CTI+IEU1 Group */ + sub %g1, %o4, %g1 /* IEU0 */ + ldd [%src], %f0 /* Load */ + clr %o4 /* IEU0 Group */ + andcc %dst, 8, %g0 /* IEU1 */ + be,pn %icc, 1f /* CTI */ + ldd [%src + 8], %f2 /* Load Group */ + add %src, 8, %src /* IEU0 */ + sub %len, 8, %len /* IEU1 */ + fpadd32 %f0, %f48, %f50 /* FPA */ + addcc %dst, 8, %dst /* IEU1 Group */ + faligndata %f0, %f2, %f16 /* FPA */ + fcmpgt32 %f48, %f50, %o4 /* FPM Group */ + fmovd %f2, %f0 /* FPA Group */ + ldd [%src + 8], %f2 /* Load */ + stda %f16, [%dst - 8] %asi /* Store */ + fmovd %f50, %f48 /* FPA */ +1: andcc %g1, 0x10, %g0 /* IEU1 Group */ + be,pn %icc, 1f /* CTI */ + and %g1, 0x20, %g1 /* IEU0 */ + fpadd32 %f0, %f48, %f50 /* FPA */ + ldd [%src + 16], %f4 /* Load Group */ + add %src, 16, %src /* IEU0 */ + add %dst, 16, %dst /* IEU1 */ + faligndata %f0, %f2, %f16 /* FPA */ + fcmpgt32 %f48, %f50, %g5 /* FPM Group */ + sub %len, 16, %len /* IEU0 */ + inc %o4 /* IEU1 */ + stda %f16, [%dst - 16] %asi /* Store Group */ + fpadd32 %f2, %f50, %f48 /* FPA */ + srl %o4, 1, %o5 /* IEU0 */ + faligndata %f2, %f4, %f18 /* FPA Group */ + stda %f18, [%dst - 8] %asi /* Store */ + fcmpgt32 %f50, %f48, %o4 /* FPM Group */ + add %o5, %sum, %sum /* IEU0 */ + ldd [%src + 8], %f2 /* Load */ + fmovd %f4, %f0 /* FPA */ +1: brz,a,pn %g1, 4f /* CTI+IEU1 Group */ + rd %asi, %g2 /* LSU Group + 4 bubbles */ + inc %g5 /* IEU0 */ + fpadd32 %f0, %f48, %f50 /* FPA */ + ldd [%src + 16], %f4 /* Load Group */ + srl %g5, 1, %g5 /* IEU0 */ + add %dst, 32, %dst /* IEU1 */ + faligndata %f0, %f2, %f16 /* FPA */ + fcmpgt32 %f48, %f50, %o5 /* FPM Group */ + inc %o4 /* IEU0 */ + ldd [%src + 24], %f6 /* Load */ + srl %o4, 1, %o4 /* IEU0 Group */ + add %g5, %sum, %sum /* IEU1 */ + ldd [%src + 32], %f8 /* Load */ + fpadd32 %f2, %f50, %f48 /* FPA */ + faligndata %f2, %f4, %f18 /* FPA Group */ + sub %len, 32, %len /* IEU0 */ + stda %f16, [%dst - 32] %asi /* Store */ + fcmpgt32 %f50, %f48, %g3 /* FPM Group */ + inc %o5 /* IEU0 */ + add %o4, %sum, %sum /* IEU1 */ + fpadd32 %f4, %f48, %f50 /* FPA */ + faligndata %f4, %f6, %f20 /* FPA Group */ + srl %o5, 1, %o5 /* IEU0 */ + fcmpgt32 %f48, %f50, %g5 /* FPM Group */ + add %o5, %sum, %sum /* IEU0 */ + stda %f18, [%dst - 24] %asi /* Store */ + fpadd32 %f6, %f50, %f48 /* FPA */ + inc %g3 /* IEU0 Group */ + stda %f20, [%dst - 16] %asi /* Store */ + add %src, 32, %src /* IEU1 */ + faligndata %f6, %f8, %f22 /* FPA */ + fcmpgt32 %f50, %f48, %o4 /* FPM Group */ + srl %g3, 1, %g3 /* IEU0 */ + stda %f22, [%dst - 8] %asi /* Store */ + add %g3, %sum, %sum /* IEU0 Group */ +3: rd %asi, %g2 /* LSU Group + 4 bubbles */ +#ifdef __KERNEL__ +4: sethi %hi(vis0s), %g7 /* IEU0 Group */ + or %g2, ASI_BLK_OR, %g2 /* IEU1 */ +#else +4: rd %pc, %g7 /* LSU Group + 4 bubbles */ +#endif + inc %g5 /* IEU0 Group */ + and %src, 0x38, %g3 /* IEU1 */ + membar #StoreLoad /* LSU Group */ + srl %g5, 1, %g5 /* IEU0 */ + inc %o4 /* IEU1 */ + sll %g3, 8, %g3 /* IEU0 Group */ + sub %len, 0xc0, %len /* IEU1 */ + addcc %g5, %sum, %sum /* IEU1 Group */ + srl %o4, 1, %o4 /* IEU0 */ + add %g7, %g3, %g7 /* IEU0 Group */ + add %o4, %sum, %sum /* IEU1 */ +#ifdef __KERNEL__ + jmpl %g7 + %lo(vis0s), %g0 /* CTI+IEU1 Group */ +#else + jmpl %g7 + (vis0s - 4b), %g0 /* CTI+IEU1 Group */ +#endif + fzero %f32 /* FPA */ + + .align 2048 +vis0s: wr %g2, ASI_BLK_XOR, %asi /* LSU Group */ + ldda [%src] ASI_BLK_P, %f0 /* Load Group */ + add %src, 64, %src /* IEU0 Group */ + ldda [%src] ASI_BLK_P, %f16 /* Load Group */ + add %src, 64, %src /* IEU0 Group */ + fmovd %f48, %f62 /* FPA Group f0 available */ + faligndata %f0, %f2, %f48 /* FPA Group f2 available */ + fcmpgt32 %f32, %f2, %x1 /* FPM Group f4 available */ + fpadd32 %f0, %f62, %f0 /* FPA */ + fcmpgt32 %f32, %f4, %x2 /* FPM Group f6 available */ + faligndata %f2, %f4, %f50 /* FPA */ + fcmpgt32 %f62, %f0, %x3 /* FPM Group f8 available */ + faligndata %f4, %f6, %f52 /* FPA */ + fcmpgt32 %f32, %f6, %x4 /* FPM Group f10 available */ + inc %x1 /* IEU0 */ + faligndata %f6, %f8, %f54 /* FPA */ + fcmpgt32 %f32, %f8, %x5 /* FPM Group f12 available */ + srl %x1, 1, %x1 /* IEU0 */ + inc %x2 /* IEU1 */ + faligndata %f8, %f10, %f56 /* FPA */ + fcmpgt32 %f32, %f10, %x6 /* FPM Group f14 available */ + srl %x2, 1, %x2 /* IEU0 */ + add %sum, %x1, %sum /* IEU1 */ + faligndata %f10, %f12, %f58 /* FPA */ + fcmpgt32 %f32, %f12, %x7 /* FPM Group */ + inc %x3 /* IEU0 */ + add %sum, %x2, %sum /* IEU1 */ + faligndata %f12, %f14, %f60 /* FPA */ + fcmpgt32 %f32, %f14, %x8 /* FPM Group */ + srl %x3, 1, %x3 /* IEU0 */ + inc %x4 /* IEU1 */ + fmovd %f14, %f62 /* FPA */ + srl %x4, 1, %x4 /* IEU0 Group */ + add %sum, %x3, %sum /* IEU1 */ +vis0: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f48,f50,f52,f54,f56,f58,f60,f62,f62, + ,LDBLK(f32), STBLK,,,,,,,, + ,bcs,pn %icc, vis0e1) + DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f48,f50,f52,f54,f56,f58,f60,f62,f62, + ,LDBLK(f0), STBLK,,,,,,,, + ,bcs,pn %icc, vis0e2) + DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f48,f50,f52,f54,f56,f58,f60,f62,f62, + ,LDBLK(f16), STBLK,,,,,,,, + ,bcc,pt %icc, vis0) +vis0e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f48,f50,f52,f54,f56,f58,f60,f62,f32, + ,SYNC, STBLK_XORASI(x1,x2),ST(f48,64),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40),ST(f60,48), + ,add %dst, 56, %dst; add %len, 192 - 8*8, %len; ba,pt %icc, e2) +vis0e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f48,f50,f52,f54,f56,f58,f60,f62,f0, + ,SYNC, STBLK_XORASI(x1,x2),ST(f48,64),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40),ST(f60,48), + ,add %dst, 56, %dst; add %len, 192 - 8*8, %len; ba,pt %icc, e3) +vis0e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f48,f50,f52,f54,f56,f58,f60,f62,f16, + ,SYNC, STBLK_XORASI(x1,x2),ST(f48,64),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40),ST(f60,48), + ,add %dst, 56, %dst; add %len, 192 - 8*8, %len; ba,pt %icc, e1) + .align 2048 +vis1s: wr %g2, ASI_BLK_XOR, %asi /* LSU Group */ + sub %src, 8, %src /* IEU0 Group */ + ldda [%src] ASI_BLK_P, %f0 /* Load Group */ + add %src, 64, %src /* IEU0 Group */ + ldda [%src] ASI_BLK_P, %f16 /* Load Group */ + add %src, 64, %src /* IEU0 Group */ + fmovd %f0, %f58 /* FPA Group */ + fmovd %f48, %f0 /* FPA Group */ + fcmpgt32 %f32, %f2, %x2 /* FPM Group */ + faligndata %f2, %f4, %f48 /* FPA */ + fcmpgt32 %f32, %f4, %x3 /* FPM Group */ + faligndata %f4, %f6, %f50 /* FPA */ + fcmpgt32 %f32, %f6, %x4 /* FPM Group */ + faligndata %f6, %f8, %f52 /* FPA */ + fcmpgt32 %f32, %f8, %x5 /* FPM Group */ + inc %x2 /* IEU1 */ + faligndata %f8, %f10, %f54 /* FPA */ + fcmpgt32 %f32, %f10, %x6 /* FPM Group */ + srl %x2, 1, %x2 /* IEU0 */ + faligndata %f10, %f12, %f56 /* FPA */ + fcmpgt32 %f32, %f12, %x7 /* FPM Group */ + inc %x3 /* IEU0 */ + add %sum, %x2, %sum /* IEU1 */ + faligndata %f12, %f14, %f58 /* FPA */ + fcmpgt32 %f32, %f14, %x8 /* FPM Group */ + srl %x3, 1, %x3 /* IEU0 */ + inc %x4 /* IEU1 */ + fmovd %f14, %f60 /* FPA */ + srl %x4, 1, %x4 /* IEU0 Group */ + add %sum, %x3, %sum /* IEU1 */ +vis1: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f62,f48,f50,f52,f54,f56,f58,f60,f60, + ,LDBLK(f32), ,STBLK,,,,,,, + ,bcs,pn %icc, vis1e1) + DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f62,f48,f50,f52,f54,f56,f58,f60,f60, + ,LDBLK(f0), ,STBLK,,,,,,, + ,bcs,pn %icc, vis1e2) + DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f62,f48,f50,f52,f54,f56,f58,f60,f60, + ,LDBLK(f16), ,STBLK,,,,,,, + ,bcc,pt %icc, vis1) +vis1e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f62,f48,f50,f52,f54,f56,f58,f60,f32, + ,SYNC, ,STBLK_XORASI(x1,x2),ST(f48,0),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40), + ,add %dst, 48, %dst; add %len, 192 - 7*8, %len; ba,pt %icc, e2) +vis1e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f62,f48,f50,f52,f54,f56,f58,f60,f0, + ,SYNC, ,STBLK_XORASI(x1,x2),ST(f48,0),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40), + ,add %dst, 48, %dst; add %len, 192 - 7*8, %len; ba,pt %icc, e3) +vis1e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f62,f48,f50,f52,f54,f56,f58,f60,f16, + ,SYNC, ,STBLK_XORASI(x1,x2),ST(f48,0),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40), + ,add %dst, 48, %dst; add %len, 192 - 7*8, %len; ba,pt %icc, e1) + .align 2048 +vis2s: wr %g2, ASI_BLK_XOR, %asi /* LSU Group */ + sub %src, 16, %src /* IEU0 Group */ + ldda [%src] ASI_BLK_P, %f0 /* Load Group */ + add %src, 64, %src /* IEU0 Group */ + ldda [%src] ASI_BLK_P, %f16 /* Load Group */ + add %src, 64, %src /* IEU0 Group */ + fmovd %f0, %f56 /* FPA Group */ + fmovd %f48, %f0 /* FPA Group */ + sub %dst, 64, %dst /* IEU0 */ + fpsub32 %f2, %f2, %f2 /* FPA Group */ + fcmpgt32 %f32, %f4, %x3 /* FPM Group */ + faligndata %f4, %f6, %f48 /* FPA */ + fcmpgt32 %f32, %f6, %x4 /* FPM Group */ + faligndata %f6, %f8, %f50 /* FPA */ + fcmpgt32 %f32, %f8, %x5 /* FPM Group */ + faligndata %f8, %f10, %f52 /* FPA */ + fcmpgt32 %f32, %f10, %x6 /* FPM Group */ + faligndata %f10, %f12, %f54 /* FPA */ + fcmpgt32 %f32, %f12, %x7 /* FPM Group */ + inc %x3 /* IEU0 */ + faligndata %f12, %f14, %f56 /* FPA */ + fcmpgt32 %f32, %f14, %x8 /* FPM Group */ + srl %x3, 1, %x3 /* IEU0 */ + inc %x4 /* IEU1 */ + fmovd %f14, %f58 /* FPA */ + srl %x4, 1, %x4 /* IEU0 Group */ + add %sum, %x3, %sum /* IEU1 */ +vis2: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f60,f62,f48,f50,f52,f54,f56,f58,f58, + ,LDBLK(f32), ,,STBLK,,,,,, + ,bcs,pn %icc, vis2e1) + DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f60,f62,f48,f50,f52,f54,f56,f58,f58, + ,LDBLK(f0), ,,STBLK,,,,,, + ,bcs,pn %icc, vis2e2) + DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f60,f62,f48,f50,f52,f54,f56,f58,f58, + ,LDBLK(f16), ,,STBLK,,,,,, + ,bcc,pt %icc, vis2) +vis2e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f60,f62,f48,f50,f52,f54,f56,f58,f32, + ,SYNC, ,,STBLK_XORASI(x2,x3),ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88),ST(f56,96), + ,add %dst, 104, %dst; add %len, 192 - 6*8, %len; ba,pt %icc, e2) +vis2e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f60,f62,f48,f50,f52,f54,f56,f58,f0, + ,SYNC, ,,STBLK_XORASI(x2,x3),ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88),ST(f56,96), + ,add %dst, 104, %dst; add %len, 192 - 6*8, %len; ba,pt %icc, e3) +vis2e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f60,f62,f48,f50,f52,f54,f56,f58,f16, + ,SYNC, ,,STBLK_XORASI(x2,x3),ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88),ST(f56,96), + ,add %dst, 104, %dst; add %len, 192 - 6*8, %len; ba,pt %icc, e1) + .align 2048 +vis3s: wr %g2, ASI_BLK_XOR, %asi /* LSU Group */ + sub %src, 24, %src /* IEU0 Group */ + ldda [%src] ASI_BLK_P, %f0 /* Load Group */ + add %src, 64, %src /* IEU0 Group */ + ldda [%src] ASI_BLK_P, %f16 /* Load Group */ + add %src, 64, %src /* IEU0 Group */ + fmovd %f0, %f54 /* FPA Group */ + fmovd %f48, %f0 /* FPA Group */ + sub %dst, 64, %dst /* IEU0 */ + fpsub32 %f2, %f2, %f2 /* FPA Group */ + fpsub32 %f4, %f4, %f4 /* FPA Group */ + fcmpgt32 %f32, %f6, %x4 /* FPM Group */ + faligndata %f6, %f8, %f48 /* FPA */ + fcmpgt32 %f32, %f8, %x5 /* FPM Group */ + faligndata %f8, %f10, %f50 /* FPA */ + fcmpgt32 %f32, %f10, %x6 /* FPM Group */ + faligndata %f10, %f12, %f52 /* FPA */ + fcmpgt32 %f32, %f12, %x7 /* FPM Group */ + faligndata %f12, %f14, %f54 /* FPA */ + fcmpgt32 %f32, %f14, %x8 /* FPM Group */ + fmovd %f14, %f56 /* FPA */ + inc %x4 /* IEU0 */ + srl %x4, 1, %x4 /* IEU0 Group */ +vis3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f58,f60,f62,f48,f50,f52,f54,f56,f56, + ,LDBLK(f32), ,,,STBLK,,,,, + ,bcs,pn %icc, vis3e1) + DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f58,f60,f62,f48,f50,f52,f54,f56,f56, + ,LDBLK(f0), ,,,STBLK,,,,, + ,bcs,pn %icc, vis3e2) + DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f58,f60,f62,f48,f50,f52,f54,f56,f56, + ,LDBLK(f16), ,,,STBLK,,,,, + ,bcc,pt %icc, vis3) +vis3e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f58,f60,f62,f48,f50,f52,f54,f56,f32, + ,SYNC, ,,,STBLK_XORASI(x3,x4),ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88), + ,add %dst, 96, %dst; add %len, 192 - 5*8, %len; ba,pt %icc, e2) +vis3e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f58,f60,f62,f48,f50,f52,f54,f56,f0, + ,SYNC, ,,,STBLK_XORASI(x3,x4),ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88), + ,add %dst, 96, %dst; add %len, 192 - 5*8, %len; ba,pt %icc, e3) +vis3e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f58,f60,f62,f48,f50,f52,f54,f56,f16, + ,SYNC, ,,,STBLK_XORASI(x3,x4),ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88), + ,add %dst, 96, %dst; add %len, 192 - 5*8, %len; ba,pt %icc, e1) + .align 2048 +vis4s: wr %g2, ASI_BLK_XOR, %asi /* LSU Group */ + sub %src, 32, %src /* IEU0 Group */ + ldda [%src] ASI_BLK_P, %f0 /* Load Group */ + add %src, 64, %src /* IEU0 Group */ + ldda [%src] ASI_BLK_P, %f16 /* Load Group */ + add %src, 64, %src /* IEU0 Group */ + fmovd %f0, %f52 /* FPA Group */ + fmovd %f48, %f0 /* FPA Group */ + sub %dst, 64, %dst /* IEU0 */ + fpsub32 %f2, %f2, %f2 /* FPA Group */ + fpsub32 %f4, %f4, %f4 /* FPA Group */ + fpsub32 %f6, %f6, %f6 /* FPA Group */ + clr %x4 /* IEU0 */ + fcmpgt32 %f32, %f8, %x5 /* FPM Group */ + faligndata %f8, %f10, %f48 /* FPA */ + fcmpgt32 %f32, %f10, %x6 /* FPM Group */ + faligndata %f10, %f12, %f50 /* FPA */ + fcmpgt32 %f32, %f12, %x7 /* FPM Group */ + faligndata %f12, %f14, %f52 /* FPA */ + fcmpgt32 %f32, %f14, %x8 /* FPM Group */ + fmovd %f14, %f54 /* FPA */ +vis4: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f56,f58,f60,f62,f48,f50,f52,f54,f54, + ,LDBLK(f32), ,,,,STBLK,,,, + ,bcs,pn %icc, vis4e1) + DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f56,f58,f60,f62,f48,f50,f52,f54,f54, + ,LDBLK(f0), ,,,,STBLK,,,, + ,bcs,pn %icc, vis4e2) + DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f56,f58,f60,f62,f48,f50,f52,f54,f54, + ,LDBLK(f16), ,,,,STBLK,,,, + ,bcc,pt %icc, vis4) +vis4e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f56,f58,f60,f62,f48,f50,f52,f54,f32, + ,SYNC, ,,,,STBLK_XORASI(x4,x5),ST(f48,64),ST(f50,72),ST(f52,80), + ,add %dst, 88, %dst; add %len, 192 - 4*8, %len; ba,pt %icc, e2) +vis4e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f56,f58,f60,f62,f48,f50,f52,f54,f0, + ,SYNC, ,,,,STBLK_XORASI(x4,x5),ST(f48,64),ST(f50,72),ST(f52,80), + ,add %dst, 88, %dst; add %len, 192 - 4*8, %len; ba,pt %icc, e3) +vis4e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f56,f58,f60,f62,f48,f50,f52,f54,f16, + ,SYNC, ,,,,STBLK_XORASI(x4,x5),ST(f48,64),ST(f50,72),ST(f52,80), + ,add %dst, 88, %dst; add %len, 192 - 4*8, %len; ba,pt %icc, e1) + .align 2048 +vis5s: ldd [%src+0], %f10 /* Load Group */ + ldd [%src+8], %f12 /* Load Group */ + ldd [%src+16], %f14 /* Load Group */ + add %src, 24, %src /* IEU0 Group */ + wr %g2, ASI_BLK_XOR, %asi /* LSU Group */ + ldda [%src] ASI_BLK_P, %f16 /* Load Group */ + add %src, 64, %src /* IEU0 Group */ + fmovd %f48, %f0 /* FPA Group */ + fmuld %f32, %f32, %f2 /* FPM */ + clr %x4 /* IEU0 */ + faddd %f32, %f32, %f4 /* FPA Group */ + fmuld %f32, %f32, %f6 /* FPM */ + clr %x5 /* IEU0 */ + faddd %f32, %f32, %f8 /* FPA Group */ + fcmpgt32 %f32, %f10, %x6 /* FPM Group */ + sub %dst, 64, %dst /* IEU0 */ + faligndata %f10, %f12, %f48 /* FPA */ + fcmpgt32 %f32, %f12, %x7 /* FPM Group */ + faligndata %f12, %f14, %f50 /* FPA */ + fcmpgt32 %f32, %f14, %x8 /* FPM Group */ + fmovd %f14, %f52 /* FPA */ +vis5: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f54,f56,f58,f60,f62,f48,f50,f52,f52, + ,LDBLK(f32), ,,,,,STBLK,,, + ,bcs,pn %icc, vis5e1) + DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f54,f56,f58,f60,f62,f48,f50,f52,f52, + ,LDBLK(f0), ,,,,,STBLK,,, + ,bcs,pn %icc, vis5e2) + DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f54,f56,f58,f60,f62,f48,f50,f52,f52, + ,LDBLK(f16), ,,,,,STBLK,,, + ,bcc,pt %icc, vis5) +vis5e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f54,f56,f58,f60,f62,f48,f50,f52,f32, + ,SYNC, ,,,,,STBLK_XORASI(x5,x6),ST(f48,64),ST(f50,72), + ,add %dst, 80, %dst; add %len, 192 - 3*8, %len; ba,pt %icc, e2) +vis5e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f54,f56,f58,f60,f62,f48,f50,f52,f0, + ,SYNC, ,,,,,STBLK_XORASI(x5,x6),ST(f48,64),ST(f50,72), + ,add %dst, 80, %dst; add %len, 192 - 3*8, %len; ba,pt %icc, e3) +vis5e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f54,f56,f58,f60,f62,f48,f50,f52,f16, + ,SYNC, ,,,,,STBLK_XORASI(x5,x6),ST(f48,64),ST(f50,72), + ,add %dst, 80, %dst; add %len, 192 - 3*8, %len; ba,pt %icc, e1) + .align 2048 +vis6s: ldd [%src+0], %f12 /* Load Group */ + ldd [%src+8], %f14 /* Load Group */ + add %src, 16, %src /* IEU0 Group */ + wr %g2, ASI_BLK_XOR, %asi /* LSU Group */ + ldda [%src] ASI_BLK_P, %f16 /* Load Group */ + add %src, 64, %src /* IEU0 Group */ + fmovd %f48, %f0 /* FPA Group */ + fmuld %f32, %f32, %f2 /* FPM */ + clr %x4 /* IEU0 */ + faddd %f32, %f32, %f4 /* FPA Group */ + fmuld %f32, %f32, %f6 /* FPM */ + clr %x5 /* IEU0 */ + faddd %f32, %f32, %f8 /* FPA Group */ + fmuld %f32, %f32, %f10 /* FPM */ + clr %x6 /* IEU0 */ + fcmpgt32 %f32, %f12, %x7 /* FPM Group */ + sub %dst, 64, %dst /* IEU0 */ + fcmpgt32 %f32, %f14, %x8 /* FPM Group */ + faligndata %f12, %f14, %f48 /* FPA */ + fmovd %f14, %f50 /* FPA Group */ +vis6: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f52,f54,f56,f58,f60,f62,f48,f50,f50, + ,LDBLK(f32), ,,,,,,STBLK,, + ,bcs,pn %icc, vis6e1) + DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f52,f54,f56,f58,f60,f62,f48,f50,f50, + ,LDBLK(f0), ,,,,,,STBLK,, + ,bcs,pn %icc, vis6e2) + DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f52,f54,f56,f58,f60,f62,f48,f50,f50, + ,LDBLK(f16), ,,,,,,STBLK,, + ,bcc,pt %icc, vis6) +vis6e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f52,f54,f56,f58,f60,f62,f48,f50,f32, + ,SYNC, ,,,,,,STBLK_XORASI(x6,x7),ST(f48,64), + ,add %dst, 72, %dst; add %len, 192 - 2*8, %len; ba,pt %icc, e2) +vis6e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f52,f54,f56,f58,f60,f62,f48,f50,f0, + ,SYNC, ,,,,,,STBLK_XORASI(x6,x7),ST(f48,64), + ,add %dst, 72, %dst; add %len, 192 - 2*8, %len; ba,pt %icc, e3) +vis6e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f52,f54,f56,f58,f60,f62,f48,f50,f16, + ,SYNC, ,,,,,,STBLK_XORASI(x6,x7),ST(f48,64), + ,add %dst, 72, %dst; add %len, 192 - 2*8, %len; ba,pt %icc, e1) + .align 2048 +vis7s: ldd [%src+0], %f14 /* Load Group */ + add %src, 8, %src /* IEU0 Group */ + wr %g2, ASI_BLK_XOR, %asi /* LSU Group */ + ldda [%src] ASI_BLK_P, %f16 /* Load Group */ + add %src, 64, %src /* IEU0 Group */ + fmovd %f48, %f0 /* FPA Group */ + fmuld %f32, %f32, %f2 /* FPM */ + clr %x4 /* IEU0 */ + faddd %f32, %f32, %f4 /* FPA Group */ + fmuld %f32, %f32, %f6 /* FPM */ + clr %x5 /* IEU0 */ + faddd %f32, %f32, %f8 /* FPA Group */ + fmuld %f32, %f32, %f10 /* FPM */ + clr %x6 /* IEU0 */ + faddd %f32, %f32, %f12 /* FPA Group */ + clr %x7 /* IEU0 */ + fcmpgt32 %f32, %f14, %x8 /* FPM Group */ + sub %dst, 64, %dst /* IEU0 */ + fmovd %f14, %f48 /* FPA */ +vis7: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f50,f52,f54,f56,f58,f60,f62,f48,f48, + ,LDBLK(f32), ,,,,,,,STBLK, + ,bcs,pn %icc, vis7e1) + DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f50,f52,f54,f56,f58,f60,f62,f48,f48, + ,LDBLK(f0), ,,,,,,,STBLK, + ,bcs,pn %icc, vis7e2) + DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f50,f52,f54,f56,f58,f60,f62,f48,f48, + ,LDBLK(f16), ,,,,,,,STBLK, + ,bcc,pt %icc, vis7) +vis7e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30, + ,f50,f52,f54,f56,f58,f60,f62,f48,f32, + ,SYNC, ,,,,,,,STBLK_XORASI(x7,x8), + ,add %dst, 64, %dst; add %len, 192 - 1*8, %len; ba,pt %icc, e2) +vis7e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46, + ,f50,f52,f54,f56,f58,f60,f62,f48,f0, + ,SYNC, ,,,,,,,STBLK_XORASI(x7,x8), + ,add %dst, 64, %dst; add %len, 192 - 1*8, %len; ba,pt %icc, e3) +vis7e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14, + ,f50,f52,f54,f56,f58,f60,f62,f48,f16, + ,SYNC, ,,,,,,,STBLK_XORASI(x7,x8), + ,add %dst, 64, %dst; add %len, 192 - 1*8, %len; ba,pt %icc, e1) +e1: END_THE_TRICK1( f0,f2,f4,f6,f8,f10,f12,f14,f16,f6) +e2: END_THE_TRICK1( f16,f18,f20,f22,f24,f26,f28,f30,f32,f6) +e3: END_THE_TRICK1( f32,f34,f36,f38,f40,f42,f44,f46,f0,f6) +ett: rd %gsr, %x3 /* LSU Group+4bubbles */ + andcc %x3, 7, %x3 /* IEU1 Group */ + add %dst, 8, %dst /* IEU0 */ + bne,pn %icc, 1f /* CTI */ + fzero %f10 /* FPA */ + brz,a,pn %len, 2f /* CTI+IEU1 Group */ + stda %f6, [%dst - 8] %asi /* Store */ +1: cmp %len, 8 /* IEU1 */ + blu,pn %icc, 3f /* CTI */ + sub %src, 64, %src /* IEU0 Group */ +1: ldd [%src], %f2 /* Load Group */ + fpadd32 %f10, %f2, %f12 /* FPA Group+load stall */ + add %src, 8, %src /* IEU0 */ + add %dst, 8, %dst /* IEU1 */ + faligndata %f6, %f2, %f14 /* FPA Group */ + fcmpgt32 %f10, %f12, %x5 /* FPM Group */ + stda %f14, [%dst - 16] %asi /* Store */ + fmovd %f2, %f6 /* FPA */ + fmovd %f12, %f10 /* FPA Group */ + sub %len, 8, %len /* IEU1 */ + fzero %f16 /* FPA Group - FPU nop */ + fzero %f18 /* FPA Group - FPU nop */ + inc %x5 /* IEU0 */ + srl %x5, 1, %x5 /* IEU0 Group (regdep) */ + cmp %len, 8 /* IEU1 */ + bgeu,pt %icc, 1b /* CTI */ + add %x5, %sum, %sum /* IEU0 Group */ +3: brz,a,pt %x3, 2f /* CTI+IEU1 */ + stda %f6, [%dst - 8] %asi /* Store Group */ + sta %f7, [%dst - 8] %asi /* Store Group */ + sub %dst, 4, %dst /* IEU0 */ + add %len, 4, %len /* IEU1 */ +2: +#ifdef __KERNEL__ + sub %sp, 8, %sp /* IEU0 Group */ +#endif + END_THE_TRICK2( f48,f50,f52,f54,f56,f58,f60,f10,f12,f62) + membar #Sync /* LSU Group */ +#ifdef __KERNEL__ + VISExit + add %sp, 8, %sp /* IEU0 Group */ +#endif +23: brnz,pn %len, 26f /* CTI+IEU1 Group */ +24: sllx %sum, 32, %g1 /* IEU0 */ +25: addcc %sum, %g1, %src /* IEU1 Group */ + srlx %src, 32, %src /* IEU0 Group (regdep) */ + bcs,a,pn %xcc, 1f /* CTI */ + add %src, 1, %src /* IEU1 */ +#ifndef __KERNEL__ +1: retl /* CTI Group brk forced */ + srl %src, 0, %src /* IEU0 */ +#else +1: sethi %uhi(PAGE_OFFSET), %g4 /* IEU0 Group */ + retl /* CTI Group brk forced */ + sllx %g4, 32, %g4 /* IEU0 */ +#endif +26: andcc %len, 8, %g0 /* IEU1 Group */ + be,pn %icc, 1f /* CTI */ + lduw [%src], %o4 /* Load */ + lduw [%src+4], %g2 /* Load Group */ + add %src, 8, %src /* IEU0 */ + add %dst, 8, %dst /* IEU1 */ + sllx %o4, 32, %g5 /* IEU0 Group */ + stwa %o4, [%dst - 8] %asi /* Store */ + or %g5, %g2, %g5 /* IEU0 Group */ + stwa %g2, [%dst - 4] %asi /* Store */ + addcc %g5, %sum, %sum /* IEU1 Group */ + bcs,a,pn %xcc, 1f /* CTI */ + add %sum, 1, %sum /* IEU0 */ +1: andcc %len, 4, %g0 /* IEU1 Group */ + be,a,pn %icc, 1f /* CTI */ + clr %g2 /* IEU0 */ + lduw [%src], %g7 /* Load */ + add %src, 4, %src /* IEU0 Group */ + add %dst, 4, %dst /* IEU1 */ + sllx %g7, 32, %g2 /* IEU0 Group */ + stwa %g7, [%dst - 4] %asi /* Store */ +1: andcc %len, 2, %g0 /* IEU1 */ + be,a,pn %icc, 1f /* CTI */ + clr %g3 /* IEU0 Group */ + lduh [%src], %g7 /* Load */ + add %src, 2, %src /* IEU1 */ + add %dst, 2, %dst /* IEU0 Group */ + sll %g7, 16, %g3 /* IEU0 Group */ + stha %g7, [%dst - 2] %asi /* Store */ +1: andcc %len, 1, %g0 /* IEU1 */ + be,a,pn %icc, 1f /* CTI */ + clr %o5 /* IEU0 Group */ + ldub [%src], %g7 /* Load */ + sll %g7, 8, %o5 /* IEU0 Group */ + stba %g7, [%dst] %asi /* Store */ +1: or %g2, %g3, %g3 /* IEU1 */ + or %o5, %g3, %g3 /* IEU0 Group (regdep) */ + addcc %g3, %sum, %sum /* IEU1 Group (regdep) */ + bcs,a,pn %xcc, 1f /* CTI */ + add %sum, 1, %sum /* IEU0 */ +1: ba,pt %xcc, 25b /* CTI Group */ + sllx %sum, 32, %g1 /* IEU0 */ + +#ifdef __KERNEL__ +end: + + .section __ex_table + .align 4 + .word csum_partial_copy_user_vis, 0, end, cpc_handler +#endif diff -ur --new-file old/linux/arch/sparc64/lib/checksum.S new/linux/arch/sparc64/lib/checksum.S --- old/linux/arch/sparc64/lib/checksum.S Tue Aug 3 07:07:16 1999 +++ new/linux/arch/sparc64/lib/checksum.S Sat Jan 22 03:22:54 2000 @@ -2,7 +2,7 @@ * * Copyright(C) 1995 Linus Torvalds * Copyright(C) 1995 Miguel de Icaza - * Copyright(C) 1996 David S. Miller + * Copyright(C) 1996, 2000 David S. Miller * Copyright(C) 1997 Jakub Jelinek * * derived from: @@ -263,6 +263,238 @@ srl %o0, 0, %o0 cpc_end: + /* Now the version with userspace as the destination */ +#define CSUMCOPY_LASTCHUNK_USER(off, t0, t1) \ + ldx [%src - off - 0x08], t0; \ + ldx [%src - off - 0x00], t1; \ + nop; nop; \ + addcc t0, %sum, %sum; \ + stwa t0, [%dst - off - 0x04] %asi; \ + srlx t0, 32, t0; \ + bcc,pt %xcc, 51f; \ + stwa t0, [%dst - off - 0x08] %asi; \ + add %sum, 1, %sum; \ +51: addcc t1, %sum, %sum; \ + stwa t1, [%dst - off + 0x04] %asi; \ + srlx t1, 32, t1; \ + bcc,pt %xcc, 52f; \ + stwa t1, [%dst - off - 0x00] %asi; \ + add %sum, 1, %sum; \ +52: + +cpc_user_start: +cc_user_end_cruft: + andcc %g7, 8, %g0 ! IEU1 Group + be,pn %icc, 1f ! CTI + and %g7, 4, %g5 ! IEU0 + ldx [%src + 0x00], %g2 ! Load Group + add %dst, 8, %dst ! IEU0 + add %src, 8, %src ! IEU1 + addcc %g2, %sum, %sum ! IEU1 Group + 2 bubbles + stwa %g2, [%dst - 0x04] %asi ! Store + srlx %g2, 32, %g2 ! IEU0 + bcc,pt %xcc, 1f ! CTI Group + stwa %g2, [%dst - 0x08] %asi ! Store + add %sum, 1, %sum ! IEU0 +1: brz,pt %g5, 1f ! CTI Group + clr %g2 ! IEU0 + lduw [%src + 0x00], %g2 ! Load + add %dst, 4, %dst ! IEU0 Group + add %src, 4, %src ! IEU1 + stwa %g2, [%dst - 0x04] %asi ! Store Group + 2 bubbles + sllx %g2, 32, %g2 ! IEU0 +1: andcc %g7, 2, %g0 ! IEU1 + be,pn %icc, 1f ! CTI Group + clr %o4 ! IEU1 + lduh [%src + 0x00], %o4 ! Load + add %src, 2, %src ! IEU0 Group + add %dst, 2, %dst ! IEU1 + stha %o4, [%dst - 0x2] %asi ! Store Group + 2 bubbles + sll %o4, 16, %o4 ! IEU0 +1: andcc %g7, 1, %g0 ! IEU1 + be,pn %icc, 1f ! CTI Group + clr %o5 ! IEU0 + ldub [%src + 0x00], %o5 ! Load + stba %o5, [%dst + 0x00] %asi ! Store Group + 2 bubbles + sll %o5, 8, %o5 ! IEU0 +1: or %g2, %o4, %o4 ! IEU1 + or %o5, %o4, %o4 ! IEU0 Group + addcc %o4, %sum, %sum ! IEU1 + bcc,pt %xcc, ccuserfold ! CTI + sethi %uhi(PAGE_OFFSET), %g4 ! IEU0 Group + b,pt %xcc, ccuserfold ! CTI + add %sum, 1, %sum ! IEU1 + +cc_user_fixit: + cmp %len, 6 ! IEU1 Group + bl,a,pn %icc, ccuserte ! CTI + andcc %len, 0xf, %g7 ! IEU1 Group + andcc %src, 2, %g0 ! IEU1 Group + be,pn %icc, 1f ! CTI + andcc %src, 0x4, %g0 ! IEU1 Group + lduh [%src + 0x00], %g4 ! Load + sub %len, 2, %len ! IEU0 + add %src, 2, %src ! IEU0 Group + add %dst, 2, %dst ! IEU1 + sll %g4, 16, %g3 ! IEU0 Group + 1 bubble + addcc %g3, %sum, %sum ! IEU1 + bcc,pt %xcc, 0f ! CTI + srl %sum, 16, %g3 ! IEU0 Group + add %g3, 1, %g3 ! IEU0 4 clocks (mispredict) +0: andcc %src, 0x4, %g0 ! IEU1 Group + stha %g4, [%dst - 0x2] %asi ! Store + sll %sum, 16, %sum ! IEU0 + sll %g3, 16, %g3 ! IEU0 Group + srl %sum, 16, %sum ! IEU0 Group + or %g3, %sum, %sum ! IEU0 Group (regdep) +1: be,pt %icc, ccusermerge ! CTI + andcc %len, 0xf0, %g1 ! IEU1 + lduw [%src + 0x00], %g4 ! Load Group + sub %len, 4, %len ! IEU0 + add %src, 4, %src ! IEU1 + add %dst, 4, %dst ! IEU0 Group + addcc %g4, %sum, %sum ! IEU1 Group + 1 bubble + stwa %g4, [%dst - 0x4] %asi ! Store + bcc,pt %xcc, ccusermerge ! CTI + andcc %len, 0xf0, %g1 ! IEU1 Group + b,pt %xcc, ccusermerge ! CTI 4 clocks (mispredict) + add %sum, 1, %sum ! IEU0 + + .align 32 + .globl csum_partial_copy_user_sparc64 +csum_partial_copy_user_sparc64: /* %o0=src, %o1=dest, %o2=len, %o3=sum */ + xorcc %src, %dst, %o4 ! IEU1 Group + srl %sum, 0, %sum ! IEU0 + andcc %o4, 3, %g0 ! IEU1 Group + srl %len, 0, %len ! IEU0 + bne,pn %icc, ccuserslow ! CTI + andcc %src, 1, %g0 ! IEU1 Group + bne,pn %icc, ccuserslow ! CTI + cmp %len, 256 ! IEU1 Group + bgeu,pt %icc, csum_partial_copy_user_vis ! CTI + andcc %src, 7, %g0 ! IEU1 Group + bne,pn %icc, cc_user_fixit ! CTI + andcc %len, 0xf0, %g1 ! IEU1 Group +ccusermerge: + be,pn %icc, ccuserte ! CTI + andcc %len, 0xf, %g7 ! IEU1 Group + sll %g1, 2, %o4 ! IEU0 +13: sethi %hi(12f), %o5 ! IEU0 Group + add %src, %g1, %src ! IEU1 + sub %o5, %o4, %o5 ! IEU0 Group + jmpl %o5 + %lo(12f), %g0 ! CTI Group brk forced + add %dst, %g1, %dst ! IEU0 Group +ccusertbl: + CSUMCOPY_LASTCHUNK_USER(0xe8,%g2,%g3) + CSUMCOPY_LASTCHUNK_USER(0xd8,%g2,%g3) + CSUMCOPY_LASTCHUNK_USER(0xc8,%g2,%g3) + CSUMCOPY_LASTCHUNK_USER(0xb8,%g2,%g3) + CSUMCOPY_LASTCHUNK_USER(0xa8,%g2,%g3) + CSUMCOPY_LASTCHUNK_USER(0x98,%g2,%g3) + CSUMCOPY_LASTCHUNK_USER(0x88,%g2,%g3) + CSUMCOPY_LASTCHUNK_USER(0x78,%g2,%g3) + CSUMCOPY_LASTCHUNK_USER(0x68,%g2,%g3) + CSUMCOPY_LASTCHUNK_USER(0x58,%g2,%g3) + CSUMCOPY_LASTCHUNK_USER(0x48,%g2,%g3) + CSUMCOPY_LASTCHUNK_USER(0x38,%g2,%g3) + CSUMCOPY_LASTCHUNK_USER(0x28,%g2,%g3) + CSUMCOPY_LASTCHUNK_USER(0x18,%g2,%g3) + CSUMCOPY_LASTCHUNK_USER(0x08,%g2,%g3) +12: + andcc %len, 0xf, %g7 ! IEU1 Group +ccuserte: + bne,pn %icc, cc_user_end_cruft ! CTI + sethi %uhi(PAGE_OFFSET), %g4 ! IEU0 +ccuserfold: + sllx %sum, 32, %o0 ! IEU0 Group + addcc %sum, %o0, %o0 ! IEU1 Group (regdep) + srlx %o0, 32, %o0 ! IEU0 Group (regdep) + bcs,a,pn %xcc, 1f ! CTI + add %o0, 1, %o0 ! IEU1 4 clocks (mispredict) +1: retl ! CTI Group brk forced + sllx %g4, 32, %g4 ! IEU0 Group + +ccuserslow: + mov 0, %g5 + brlez,pn %len, 4f + andcc %src, 1, %o5 + be,a,pt %icc, 1f + srl %len, 1, %g7 + sub %len, 1, %len + ldub [%src], %g5 + add %src, 1, %src + stba %g5, [%dst] %asi + srl %len, 1, %g7 + add %dst, 1, %dst +1: brz,a,pn %g7, 3f + andcc %len, 1, %g0 + andcc %src, 2, %g0 + be,a,pt %icc, 1f + srl %g7, 1, %g7 + lduh [%src], %o4 + sub %len, 2, %len + srl %o4, 8, %g2 + sub %g7, 1, %g7 + stba %g2, [%dst] %asi + add %o4, %g5, %g5 + stba %o4, [%dst + 1] %asi + add %src, 2, %src + srl %g7, 1, %g7 + add %dst, 2, %dst +1: brz,a,pn %g7, 2f + andcc %len, 2, %g0 + lduw [%src], %o4 +5: srl %o4, 24, %g2 + srl %o4, 16, %g3 + stba %g2, [%dst] %asi + srl %o4, 8, %g2 + stba %g3, [%dst + 1] %asi + add %src, 4, %src + stba %g2, [%dst + 2] %asi + addcc %o4, %g5, %g5 + stba %o4, [%dst + 3] %asi + addc %g5, %g0, %g5 + add %dst, 4, %dst + subcc %g7, 1, %g7 + bne,a,pt %icc, 5b + lduw [%src], %o4 + sll %g5, 16, %g2 + srl %g5, 16, %g5 + srl %g2, 16, %g2 + andcc %len, 2, %g0 + add %g2, %g5, %g5 +2: be,a,pt %icc, 3f + andcc %len, 1, %g0 + lduh [%src], %o4 + andcc %len, 1, %g0 + srl %o4, 8, %g2 + add %src, 2, %src + stba %g2, [%dst] %asi + add %g5, %o4, %g5 + stba %o4, [%dst + 1] %asi + add %dst, 2, %dst +3: be,a,pt %icc, 1f + sll %g5, 16, %o4 + ldub [%src], %g2 + sll %g2, 8, %o4 + stba %g2, [%dst] %asi + add %g5, %o4, %g5 + sll %g5, 16, %o4 +1: addcc %o4, %g5, %g5 + srl %g5, 16, %o4 + addc %g0, %o4, %g5 + brz,pt %o5, 4f + srl %g5, 8, %o4 + and %g5, 0xff, %g2 + and %o4, 0xff, %o4 + sll %g2, 8, %g2 + or %g2, %o4, %g5 +4: addcc %sum, %g5, %sum + addc %g0, %sum, %o0 + retl + srl %o0, 0, %o0 +cpc_user_end: + .globl cpc_handler cpc_handler: ldx [%sp + 0x7ff + 128], %g1 @@ -277,5 +509,5 @@ .section __ex_table .align 4 - .word cpc_start, 0, cpc_end, cpc_handler - + .word cpc_start, 0, cpc_end, cpc_handler + .word cpc_user_start, 0, cpc_user_end, cpc_handler diff -ur --new-file old/linux/arch/sparc64/mm/asyncd.c new/linux/arch/sparc64/mm/asyncd.c --- old/linux/arch/sparc64/mm/asyncd.c Sun Jan 9 06:36:20 2000 +++ new/linux/arch/sparc64/mm/asyncd.c Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: asyncd.c,v 1.11 2000/01/08 20:22:19 davem Exp $ +/* $Id: asyncd.c,v 1.12 2000/01/21 11:39:13 jj Exp $ * The asyncd kernel daemon. This handles paging on behalf of * processes that receive page faults due to remote (async) memory * accesses. @@ -20,6 +20,7 @@ #include #include #include +#include #include #include /* for cli()/sti() */ @@ -113,6 +114,7 @@ { static unsigned last_address; static int last_task, loop_counter; + siginfo_t info; #warning Need some fixing here... -DaveM struct task_struct *tsk = current /* XXX task[taskid] */; pgd_t *pgd; @@ -181,9 +183,12 @@ bad_area: stats.failure++; - tsk->thread.sig_address = address; - tsk->thread.sig_desc = SUBSIG_NOMAPPING; - send_sig(SIGSEGV, tsk, 1); + info.si_signo = SIGSEGV; + info.si_errno = 0; + info.si_code = SEGV_MAPERR; + info.si_addr = (void *)address; + info.si_trapno = 0; + send_sig_info(SIGSEGV, &info, tsk); return 1; } diff -ur --new-file old/linux/arch/sparc64/mm/fault.c new/linux/arch/sparc64/mm/fault.c --- old/linux/arch/sparc64/mm/fault.c Tue Dec 21 07:05:52 1999 +++ new/linux/arch/sparc64/mm/fault.c Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.40 1999/12/01 10:44:53 davem Exp $ +/* $Id: fault.c,v 1.42 2000/01/21 11:39:13 jj Exp $ * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -149,10 +149,13 @@ struct mm_struct *mm = current->mm; struct vm_area_struct *vma; unsigned int insn = 0; + siginfo_t info; #ifdef DEBUG_LOCKUPS static unsigned long lastaddr, lastpc; static int lastwrite, lockcnt; #endif + + info.si_code = SEGV_MAPERR; /* * If we're in an interrupt or have no user * context, we must not take the fault.. @@ -233,6 +236,7 @@ * we can handle it.. */ good_area: + info.si_code = SEGV_ACCERR; if(write) { if(!(vma->vm_flags & VM_WRITE)) goto bad_area; @@ -242,8 +246,14 @@ goto bad_area; } current->mm->segments = (void *) (address & PAGE_SIZE); - if (!handle_mm_fault(current, vma, address, write)) - goto do_sigbus; + { + int fault = handle_mm_fault(current, vma, address, write); + + if (fault < 0) + goto out_of_memory; + if (!fault) + goto do_sigbus; + } up(&mm->mmap_sem); return; /* @@ -324,20 +334,45 @@ while(1) barrier(); #endif - current->thread.sig_address = address; - current->thread.sig_desc = SUBSIG_NOMAPPING; - force_sig(SIGSEGV, current); + info.si_signo = SIGSEGV; + info.si_errno = 0; + /* info.si_code set above to make clear whether + this was a SEGV_MAPERR or SEGV_ACCERR fault. */ + info.si_addr = (void *)address; + info.si_trapno = 0; + force_sig_info (SIGSEGV, &info, current); return; } unhandled_fault (address, current, regs); } return; +/* + * We ran out of memory, or some other thing happened to us that made + * us unable to handle the page fault gracefully. + */ +out_of_memory: + up(&mm->mmap_sem); + printk("VM: killing process %s\n", current->comm); + if (!(regs->tstate & TSTATE_PRIV)) + do_exit(SIGKILL); + goto do_kernel_fault; + do_sigbus: up(&mm->mmap_sem); - current->thread.sig_address = address; - current->thread.sig_desc = SUBSIG_MISCERROR; - force_sig(SIGBUS, current); + + /* + * Send a sigbus, regardless of whether we were in kernel + * or user mode. + */ + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = BUS_ADRERR; + info.si_addr = (void *)address; + info.si_trapno = 0; + force_sig_info (SIGBUS, &info, current); + + /* Kernel mode? Handle exceptions or die */ if (regs->tstate & TSTATE_PRIV) goto do_kernel_fault; } diff -ur --new-file old/linux/arch/sparc64/mm/init.c new/linux/arch/sparc64/mm/init.c --- old/linux/arch/sparc64/mm/init.c Tue Dec 21 07:05:52 1999 +++ new/linux/arch/sparc64/mm/init.c Tue Jan 25 19:26:04 2000 @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.143 1999/12/16 16:15:14 davem Exp $ +/* $Id: init.c,v 1.144 2000/01/23 07:16:11 davem Exp $ * arch/sparc64/mm/init.c * * Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu) @@ -40,8 +40,6 @@ /* Ugly, but necessary... -DaveM */ unsigned long phys_base; -static unsigned long totalram_pages = 0; - /* get_new_mmu_context() uses "cache + 1". */ spinlock_t ctx_alloc_lock = SPIN_LOCK_UNLOCKED; unsigned long tlb_context_cache = CTX_FIRST_VERSION - 1; @@ -125,7 +123,7 @@ show_free_areas(); printk("Free swap: %6dkB\n", nr_swap_pages << (PAGE_SHIFT-10)); - printk("%ld pages of RAM\n", totalram_pages); + printk("%ld pages of RAM\n", num_physpages); printk("%d free pages\n", nr_free_pages()); printk("%d pages in page table cache\n",pgtable_cache_size); #ifndef __SMP__ @@ -1088,7 +1086,6 @@ ClearPageReserved(mem_map + MAP_NR(first)); set_page_count(mem_map + MAP_NR(first), 1); free_page((unsigned long)first); - totalram_pages++; num_physpages++; first = (struct page *)((unsigned long)first + PAGE_SIZE); @@ -1180,7 +1177,7 @@ #ifdef DEBUG_BOOTMEM prom_printf("mem_init: Calling free_all_bootmem().\n"); #endif - num_physpages = totalram_pages = free_all_bootmem(); + num_physpages = free_all_bootmem(); #if 0 free_unused_mem_map(); #endif @@ -1202,7 +1199,6 @@ memset(empty_pg_dir, 0, sizeof(empty_pg_dir)); addr += alias_base; free_pgd_fast((pgd_t *)addr); - totalram_pages++; num_physpages++; } #endif @@ -1245,14 +1241,13 @@ ClearPageReserved(p); set_page_count(p, 1); __free_page(p); - totalram_pages++; num_physpages++; } } void si_meminfo(struct sysinfo *val) { - val->totalram = totalram_pages; + val->totalram = num_physpages; val->sharedram = 0; val->freeram = nr_free_pages(); val->bufferram = atomic_read(&buffermem_pages); diff -ur --new-file old/linux/arch/sparc64/solaris/misc.c new/linux/arch/sparc64/solaris/misc.c --- old/linux/arch/sparc64/solaris/misc.c Thu Jan 13 21:03:00 2000 +++ new/linux/arch/sparc64/solaris/misc.c Thu Jan 27 15:32:14 2000 @@ -242,8 +242,10 @@ /* Let's cheat */ set_utsfield(((struct sol_uname *)A(buf))->sysname, "SunOS", 1, 0); + down_read(&uts_sem); set_utsfield(((struct sol_uname *)A(buf))->nodename, system_utsname.nodename, 1, 1); + up_read(&uts_sem); set_utsfield(((struct sol_uname *)A(buf))->release, "2.6", 0, 0); set_utsfield(((struct sol_uname *)A(buf))->version, @@ -263,7 +265,7 @@ asmlinkage int solaris_utsname(u32 buf) { /* Why should we not lie a bit? */ - down(&uts_sem); + down_read(&uts_sem); set_utsfield(((struct sol_utsname *)A(buf))->sysname, "SunOS", 0, 0); set_utsfield(((struct sol_utsname *)A(buf))->nodename, @@ -274,7 +276,7 @@ "Generic", 0, 0); set_utsfield(((struct sol_utsname *)A(buf))->machine, machine(), 0, 0); - up(&uts_sem); + up_read(&uts_sem); return 0; } @@ -300,8 +302,10 @@ case SI_SYSNAME: r = "SunOS"; break; case SI_HOSTNAME: r = buffer + 256; + down_read(&uts_sem); for (p = system_utsname.nodename, q = buffer; q < r && *p && *p != '.'; *q++ = *p++); + up_read(&uts_sem); *q = 0; r = buffer; break; diff -ur --new-file old/linux/drivers/atm/Config.in new/linux/drivers/atm/Config.in --- old/linux/drivers/atm/Config.in Mon Jan 31 16:04:07 2000 +++ new/linux/drivers/atm/Config.in Mon Jan 31 16:05:40 2000 @@ -51,8 +51,7 @@ bool ' Enable debugging messages' CONFIG_ATM_IA_DEBUG fi fi -#if [ "$CONFIG_PCI" = "y" -o "$CONFIG_SBUS" = "y" ]; then -if [ "$CONFIG_PCI" = "y" ]; then +if [ "$CONFIG_PCI" = "y" -o "$CONFIG_SBUS" = "y" ]; then tristate 'FORE Systems 200E-series' CONFIG_ATM_FORE200E if [ "$CONFIG_ATM_FORE200E" != "n" ]; then if [ "$CONFIG_PCI" = "y" ]; then @@ -64,15 +63,15 @@ fi fi fi -# if [ "$CONFIG_SBUS" = "y" ]; then -# bool ' SBA-200E support' CONFIG_ATM_FORE200E_SBA y -# if [ "$CONFIG_ATM_FORE200E_SBA" = "y" ]; then -# bool ' Use default SBA-200E firmware (normally enabled)' CONFIG_ATM_FORE200E_SBA_DEFAULT_FW -# if [ "$CONFIG_ATM_FORE200E_SBA_DEFAULT_FW" = "n" ]; then -# string ' Pathname of user-supplied binary firmware' CONFIG_ATM_FORE200E_SBA_FW "" -# fi -# fi -# fi + if [ "$CONFIG_SBUS" = "y" ]; then + bool ' SBA-200E support' CONFIG_ATM_FORE200E_SBA y + if [ "$CONFIG_ATM_FORE200E_SBA" = "y" ]; then + bool ' Use default SBA-200E firmware (normally enabled)' CONFIG_ATM_FORE200E_SBA_DEFAULT_FW + if [ "$CONFIG_ATM_FORE200E_SBA_DEFAULT_FW" = "n" ]; then + string ' Pathname of user-supplied binary firmware' CONFIG_ATM_FORE200E_SBA_FW "" + fi + fi + fi int ' Maximum number of tx retries' CONFIG_ATM_FORE200E_TX_RETRY 16 int ' Debugging level (0-3)' CONFIG_ATM_FORE200E_DEBUG 0 fi diff -ur --new-file old/linux/drivers/atm/atmsar11.data new/linux/drivers/atm/atmsar11.data --- old/linux/drivers/atm/atmsar11.data Mon Aug 23 18:56:31 1999 +++ new/linux/drivers/atm/atmsar11.data Mon Jan 31 16:05:40 2000 @@ -2,12 +2,12 @@ Madge Ambassador ATM Adapter microcode. Copyright (C) 1995-1999 Madge Networks Ltd. - This is provided here for your convenience only. + This microcode data is placed under the terms of the GNU General + Public License. The GPL is contained in /usr/doc/copyright/GPL on a + Debian system and in the file COPYING in the Linux kernel source. - No restrictions are placed on its use, so long as this file remains - unchanged. - - You may not make, use or re-distribute modified versions of this code. + We would prefer you not to distribute modified versions without + consultation and not to ask for assembly/other microcode source. */ 0x401a6800, diff -ur --new-file old/linux/drivers/atm/atmsar11.regions new/linux/drivers/atm/atmsar11.regions --- old/linux/drivers/atm/atmsar11.regions Mon Aug 23 18:56:31 1999 +++ new/linux/drivers/atm/atmsar11.regions Mon Jan 31 16:05:40 2000 @@ -1,3 +1,6 @@ +/* + See copyright and licensing conditions in ambassador.* files. +*/ { 0x00000080, 993, }, { 0xa0d0d500, 80, }, { 0xa0d0f000, 978, }, diff -ur --new-file old/linux/drivers/atm/atmsar11.start new/linux/drivers/atm/atmsar11.start --- old/linux/drivers/atm/atmsar11.start Mon Aug 23 18:56:31 1999 +++ new/linux/drivers/atm/atmsar11.start Mon Jan 31 16:05:40 2000 @@ -1 +1,4 @@ +/* + See copyright and licensing conditions in ambassador.* files. +*/ 0xa0d0f000 diff -ur --new-file old/linux/drivers/atm/fore200e.c new/linux/drivers/atm/fore200e.c --- old/linux/drivers/atm/fore200e.c Mon Jan 31 16:04:07 2000 +++ new/linux/drivers/atm/fore200e.c Mon Jan 31 16:05:40 2000 @@ -2,14 +2,12 @@ $Id: $ A FORE Systems 200E-series driver for ATM on Linux. - Christophe Lizzi (lizzi@cnam.fr), October-December 1999. + Christophe Lizzi (lizzi@cnam.fr), October 1999-January 2000. Based on the PCA-200E driver from Uwe Dannowski (Uwe.Dannowski@inf.tu-dresden.de). This driver simultaneously supports PCA-200E and SBA-200E adapters - on i386, alpha (untested), powerpc, sparc and sparc64 (with additional - 64 bit fixes to the linux-atm core) hosts. - + on i386, alpha (untested), powerpc, sparc and sparc64 architectures. 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 @@ -68,7 +66,7 @@ #define FORE200E_52BYTE_AAL0_SDU #endif -#define FORE200E_VERSION "0.1e" +#define FORE200E_VERSION "0.2" #define FORE200E "fore200e: " @@ -81,17 +79,12 @@ #endif -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)) /* XXX 2.3.x? */ -#define FORE200E_PCI_BASE_ADDR base_address[0] -#else -#define FORE200E_PCI_BASE_ADDR resource[0].start -#endif - - #define FORE200E_ALIGN(addr, alignment) \ ((((unsigned long)(addr) + (alignment - 1)) & ~(alignment - 1)) - (unsigned long)(addr)) -#define FORE200E_DMA_INDEX(dma, type, index) ((dma) + (index) * sizeof(type)) +#define FORE200E_DMA_INDEX(dma_addr, type, index) ((dma_addr) + (index) * sizeof(type)) + +#define FORE200E_INDEX(virt_addr, type, index) (&((type *)(virt_addr))[ index ]) #define FORE200E_NEXT_ENTRY(index, modulo) (index = ++(index) % (modulo)) @@ -171,8 +164,6 @@ } -/* allocate and initialize a chunk of memory */ - static void* fore200e_kmalloc(int size, int flags) { @@ -187,51 +178,54 @@ } -/* free a chunk of memory */ - static void -fore200e_kfree(void** chunk) +fore200e_kfree(void* chunk) { - if (chunk && *chunk) { - void* tmp = *chunk; - *chunk = (void*) 0xDEADDEAD; /* XXX for debugging purposes */ - kfree(tmp); - } + kfree(chunk); } -/* allocate and align a chunk of memory */ +/* allocate and align a chunk of memory intended to hold the data behing exchanged + between the driver and the adapter (using streaming DVMA on SBUS hosts) */ static int -fore200e_align_alloc(void** aligned, void** raw, int size, int alignment) +fore200e_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int alignment) { unsigned long offset = 0; if (alignment <= sizeof(int)) alignment = 0; - *raw = fore200e_kmalloc(size + alignment, GFP_KERNEL | GFP_DMA); - if (*raw == NULL) + chunk->alloc_size = size + alignment; + chunk->align_size = size; + + chunk->alloc_addr = fore200e_kmalloc(chunk->alloc_size, GFP_KERNEL | GFP_DMA); + if (chunk->alloc_addr == NULL) return -ENOMEM; if (alignment > 0) - offset = FORE200E_ALIGN(*raw, alignment); + offset = FORE200E_ALIGN(chunk->alloc_addr, alignment); - *aligned = *raw + offset; + chunk->align_addr = chunk->alloc_addr + offset; + + chunk->dma_addr = fore200e->bus->dma_map(fore200e, chunk->align_addr, chunk->align_size); return 0; } -/* free and aligned chunk of memory */ +/* free a chunk of memory */ static void -fore200e_align_free(void** raw) +fore200e_chunk_free(struct fore200e* fore200e, struct chunk* chunk) { - fore200e_kfree(raw); + fore200e->bus->dma_unmap(fore200e, chunk->dma_addr, chunk->dma_size); + + fore200e_kfree(chunk->alloc_addr); } + #if 0 /* currently unused */ static int fore200e_checkup(struct fore200e* fore200e) @@ -268,8 +262,9 @@ unsigned long timeout = jiffies + MSECS(msecs); int ok; + mb(); do { - if ((ok = (fore200e->bus->read(addr) == val))) + if ((ok = (*addr == val)) || (*addr & STATUS_ERROR)) break; } while (jiffies < timeout); @@ -285,6 +280,29 @@ } +static int +fore200e_io_poll(struct fore200e* fore200e, volatile u32* addr, u32 val, int msecs) +{ + unsigned long timeout = jiffies + MSECS(msecs); + int ok; + + do { + if ((ok = (fore200e->bus->read(addr) == val))) + break; + + } while (jiffies < timeout); + +#if 1 + if (!ok) { + printk(FORE200E "I/O polling failed, got status 0x%x, expected 0x%x\n", + fore200e->bus->read(addr), val); + } +#endif + + return ok; +} + + static void fore200e_free_rx_buf(struct fore200e* fore200e) { @@ -297,8 +315,11 @@ if ((buffer = fore200e->host_bsq[ scheme ][ magn ].buffer) != NULL) { for (nbr = 0; nbr < fore200e_rx_buf_nbr[ scheme ][ magn ]; nbr++) { - if (buffer[ nbr ].data_raw != NULL) - fore200e_align_free((void**)&buffer[ nbr ].data_raw); + + struct chunk* data = &buffer[ nbr ].data; + + if (data->alloc_addr != NULL) + fore200e_chunk_free(fore200e, data); } } } @@ -310,16 +331,18 @@ fore200e_uninit_bs_queue(struct fore200e* fore200e) { int scheme, magn; - void *addr; for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) { for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) { - if ((addr = fore200e->host_bsq[ scheme ][ magn ].status_raw)) - fore200e->bus->dma_free((void**)&addr); + struct chunk* status = &fore200e->host_bsq[ scheme ][ magn ].status; + struct chunk* rbd_block = &fore200e->host_bsq[ scheme ][ magn ].rbd_block; + + if (status->alloc_addr) + fore200e->bus->dma_chunk_free(fore200e, status); - if ((addr = fore200e->host_bsq[ scheme ][ magn ].rbd_block_raw)) - fore200e->bus->dma_free((void**)&addr); + if (rbd_block->alloc_addr) + fore200e->bus->dma_chunk_free(fore200e, rbd_block); } } } @@ -337,7 +360,7 @@ fore200e->bus->reset(fore200e); if (diag) { - ok = fore200e_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_SELFTEST_OK, 1000); + ok = fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_SELFTEST_OK, 1000); if (ok == 0) { printk(FORE200E "device %s self-test failed\n", fore200e->name); @@ -369,8 +392,9 @@ switch(fore200e->state) { case FORE200E_STATE_COMPLETE: - if (fore200e->stats) + if (fore200e->stats) { kfree(fore200e->stats); + } case FORE200E_STATE_IRQ: free_irq(fore200e->irq, fore200e->atm_dev); @@ -382,15 +406,15 @@ fore200e_uninit_bs_queue(fore200e); case FORE200E_STATE_INIT_RXQ: - fore200e->bus->dma_free((void**)&fore200e->host_rxq.status_raw); - fore200e->bus->dma_free((void**)&fore200e->host_rxq.rpd_raw); + fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_rxq.status); + fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_rxq.rpd); case FORE200E_STATE_INIT_TXQ: - fore200e->bus->dma_free((void**)&fore200e->host_txq.status_raw); - fore200e->bus->dma_free((void**)&fore200e->host_txq.tpd_raw); + fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_txq.status); + fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_txq.tpd); case FORE200E_STATE_INIT_CMDQ: - fore200e->bus->dma_free((void**)&fore200e->host_cmdq.status_raw); + fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_cmdq.status); case FORE200E_STATE_INITIALIZE: /* nothing to do for that state */ @@ -425,12 +449,9 @@ static u32 fore200e_pca_read(volatile u32* addr) { #if defined(__BIG_ENDIAN) - /* on big-endian hosts, the board is configured to convert the endianess of - slave RAM accesses, so we do not use the regular readl()/writel() primitives */ -#if defined(__powerpc__) - eieio(); /* enforce in-order execution of I/O */ -#endif - return *addr; + /* on big-endian hosts, the board is configured to convert + the endianess of slave RAM accesses */ + return swab32(readl(addr)); #elif defined(__LITTLE_ENDIAN) return readl(addr); #else @@ -442,11 +463,9 @@ static void fore200e_pca_write(u32 val, volatile u32* addr) { #if defined(__BIG_ENDIAN) - /* same comment as above */ -#if defined(__powerpc__) - eieio(); /* enforce in-order execution of I/O */ -#endif - *addr = val; + /* on big-endian hosts, the board is configured to convert + the endianess of slave RAM accesses */ + writel(swab32(val), addr); #elif defined(__LITTLE_ENDIAN) writel(val, addr); #else @@ -455,31 +474,55 @@ } +/* make DMA mapping */ + static u32 -fore200e_pca_virt_to_dma(void* addr) +fore200e_pca_dma_map(struct fore200e* fore200e, void* virt_addr, int size) { - return (u32) virt_to_bus(addr); + u32 dma_addr = (u32) virt_to_bus(virt_addr); + + DPRINTK(3, "PCI DMA mapping: virt_addr = 0x%p, size = %d --> dma_addr = 0x%08x\n", + virt_addr, size, dma_addr); + + return dma_addr; } +/* remove DMA mapping */ + +static void +fore200e_pca_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size) +{ + DPRINTK(3, "PCI DMA unmapping: dma_addr = 0x%08x, size = %d\n", dma_addr, size); + + return; +} + + +/* allocate a DMA consistant chunk of memory intended to act as a communication mechanism + (to hold descriptors, status, queues, etc.) shared by the driver and the adapter */ static int -fore200e_pca_dma_alloc(void** aligned, void** raw, u32* dma, int size, int nbr, int alignment) +fore200e_pca_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, + int size, int nbr, int alignment) { - if (fore200e_align_alloc(aligned, raw, size * nbr, alignment) < 0) + if (fore200e_chunk_alloc(fore200e, chunk, size * nbr, alignment) < 0) return -ENOMEM; - *dma = fore200e_pca_virt_to_dma(*aligned); + chunk->dma_addr = fore200e_pca_dma_map(fore200e, chunk->align_addr, chunk->align_size); return 0; } +/* free a DMA consistant chunk of memory */ static void -fore200e_pca_dma_free(void** raw) +fore200e_pca_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk) { - fore200e_align_free(raw); + fore200e_pca_dma_unmap(fore200e, chunk->dma_addr, chunk->dma_size); + + fore200e_chunk_free(fore200e, chunk); } @@ -512,11 +555,7 @@ { DPRINTK(2, "device %s being mapped in memory\n", fore200e->name); -#if !defined(__sparc_v9__) fore200e->virt_base = ioremap(fore200e->phys_base, PCA200E_IOSPACE_LENGTH); -#else - fore200e->virt_base = (void*)fore200e->phys_base; -#endif if (fore200e->virt_base == NULL) { printk(FORE200E "can't map device %s\n", fore200e->name); @@ -540,8 +579,8 @@ { DPRINTK(2, "device %s being unmapped from memory\n", fore200e->name); - /* XXX iounmap() is empty on powerpc (at least in 2.2.12 and 2.3.18), so - we get a kernel panic if the module is loaded and unloaded several times */ + /* XXX iounmap() does nothing on powerpc (at least in 2.2.12 and 2.3.18), + this leads to a kernel panic if the module is loaded and unloaded several times */ if (fore200e->virt_base != NULL) iounmap(fore200e->virt_base); } @@ -556,21 +595,10 @@ DPRINTK(2, "device %s being configured\n", fore200e->name); -#if 0 && defined(__powerpc__) || defined(__sparc_v9__) /* XXX really required? */ - { - u16 command; - pci_read_config_word(pci_dev, PCI_COMMAND, &command); - command = PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER | - PCI_COMMAND_PARITY | - PCI_COMMAND_SERR; - pci_write_config_word(pci_dev, PCI_COMMAND, command); - } -#endif - #if defined(__powerpc__) if (pci_dev->irq == 0) { u8 intr_line; + pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &intr_line); /* pci_dev->irq is not set on my Motorola MTX (PReP PowerPC) running a 2.2.7 kernel */ @@ -585,7 +613,9 @@ #if defined(__BIG_ENDIAN) { u8 master_ctrl; + pci_read_config_byte(pci_dev, PCA200E_PCI_MASTER_CTRL, &master_ctrl); + /* request the PCA board to convert the endianess of slave RAM accesses */ master_ctrl = PCA200E_CTRL_DIS_CACHE_RD | PCA200E_CTRL_DIS_WRT_INVAL | @@ -625,7 +655,7 @@ fore200e->bus = bus; fore200e->bus_dev = pci_dev; fore200e->irq = pci_dev->irq; - fore200e->phys_base = (pci_dev->FORE200E_PCI_BASE_ADDR & PCI_BASE_ADDRESS_MEM_MASK); + fore200e->phys_base = (pci_dev->resource[0].start & PCI_BASE_ADDRESS_MEM_MASK); #if defined(__powerpc__) fore200e->phys_base += KERNELBASE; @@ -646,13 +676,16 @@ struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ]; struct prom_opcode opcode; int ok; + u32 prom_dma; FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD); opcode.opcode = OPCODE_GET_PROM; opcode.pad = 0; - fore200e->bus->write(fore200e->bus->virt_to_dma((void*) prom), &entry->cp_entry->cmd.prom_block.prom_haddr); + prom_dma = fore200e->bus->dma_map(fore200e, prom, sizeof(struct prom_data)); + + fore200e->bus->write(prom_dma, &entry->cp_entry->cmd.prom_block.prom_haddr); *entry->status = STATUS_PENDING; @@ -662,6 +695,8 @@ *entry->status = STATUS_FREE; + fore200e->bus->dma_unmap(fore200e, prom_dma, sizeof(struct prom_data)); + if (ok == 0) { printk(FORE200E "unable to get PROM data from device %s\n", fore200e->name); return -EIO; @@ -683,7 +718,7 @@ static int fore200e_pca_proc_read(struct fore200e* fore200e, char *page) { - struct pci_dev* pci_dev = fore200e->bus_dev; + struct pci_dev* pci_dev = (struct pci_dev*)fore200e->bus_dev; return sprintf(page, " PCI bus/slot/function:\t%d/%d/%d\n", pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn)); @@ -699,47 +734,79 @@ static u32 fore200e_sba_read(volatile u32* addr) { - return *addr; + return sbus_readl(addr); } static void fore200e_sba_write(u32 val, volatile u32* addr) { - *addr = val; + sbus_writel(val, addr); } static u32 -fore200e_sba_virt_to_dma(void* addr) +fore200e_sba_dma_map(struct fore200e* fore200e, void* virt_addr, int size) +{ + u32 dma_addr = sbus_map_single((struct sbus_dev*)fore200e->bus_dev, virt_addr, size); + + DPRINTK(3, "SBUS DVMA mapping: virt_addr = 0x%p, size = %d --> dma_addr = 0x%08x\n", virt_addr, size, dma_addr); + + return dma_addr; +} + + +static void +fore200e_sba_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size) { - return sbus_dvma_addr(addr); + DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d\n", dma_addr, size); + + sbus_unmap_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size); + + return; +} + + +static void +fore200e_sba_dma_sync(struct fore200e* fore200e, u32 dma_addr, int size) +{ + DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d\n", dma_addr, size); + + sbus_dma_sync_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size); } -/* allocate a DMA'able consistent chunk of memory */ +/* allocate a DVMA consistant chunk of memory intended to act as a communication mechanism + (to hold descriptors, status, queues, etc.) shared by the driver and the adapter */ static int -fore200e_sba_dma_alloc(void** aligned, void** raw, u32* dma, int size, int nbr, int alignment) +fore200e_sba_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int nbr, int alignment) { + chunk->alloc_size = chunk->align_size = size * nbr; + /* returned chunks are page-aligned */ - *aligned = sparc_dvma_malloc(size * nbr, "", dma); + chunk->alloc_addr = sbus_alloc_consistant((struct sbus_dev*)fore200e->bus_dev, + chunk->alloc_size, + &chunk->dma_addr); - if (*aligned == NULL || *dma == 0) + if (chunk->alloc_addr == NULL || chunk->dma_addr == 0) return -ENOMEM; - *raw = (void*)(unsigned long) *dma; /* XXX there is no sparc_dvma_free() anyway */ + chunk->align_addr = chunk->alloc_addr; return 0; } -/* free a DMA'able chunk of memory */ +/* free a DVMA consistant chunk of memory */ static void -fore200e_sba_dma_free(void** raw) +fore200e_sba_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk) { - /* XXX there is no sparc_dvma_free() */ + sbus_free_consistant((struct sbus_dev*)fore200e->bus_dev, + chunk->alloc_size, + chunk->alloc_addr, + chunk->dma_addr); } @@ -767,15 +834,6 @@ static void -fore200e_sba_dma_sync(struct fore200e* fore200e, u32 haddr, int len) -{ -#ifdef NEED_DMA_SYNCHRONIZATION - mmu_sync_dma(haddr, len, ((struct linux_sbus_device*)fore200e->bus_dev)->my_bus); -#endif -} - - -static void fore200e_sba_reset(struct fore200e* fore200e) { fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr); @@ -787,48 +845,17 @@ static int __init fore200e_sba_map(struct fore200e* fore200e) { - struct linux_sbus_device* sbus_dev = (struct linux_sbus_device*)fore200e->bus_dev; + struct sbus_dev* sbus_dev = (struct sbus_dev*)fore200e->bus_dev; /* gain access to the SBA-200E specific registers */ - prom_apply_sbus_ranges(sbus_dev->my_bus, &sbus_dev->reg_addrs[0], sbus_dev->num_registers, sbus_dev); - fore200e->regs.sba.hcr = (u32*)sparc_alloc_io(sbus_dev->reg_addrs[0].phys_addr, 0, - sbus_dev->reg_addrs[0].reg_size, - "SBA HCR", - sbus_dev->reg_addrs[0].which_io, 0); - if (fore200e->regs.sba.hcr == NULL) { - printk(FORE200E "unable to map HCR register of device %s\n", fore200e->name); - return -EFAULT; - } - - prom_apply_sbus_ranges(sbus_dev->my_bus, &sbus_dev->reg_addrs[1], sbus_dev->num_registers, sbus_dev); - fore200e->regs.sba.bsr = (u32*)sparc_alloc_io(sbus_dev->reg_addrs[1].phys_addr, 0, - sbus_dev->reg_addrs[1].reg_size, - "SBA BSR", - sbus_dev->reg_addrs[1].which_io, 0); - if (fore200e->regs.sba.bsr == NULL) { - printk(FORE200E "unable to map BSR register of device %s\n", fore200e->name); - return -EFAULT; - } - - prom_apply_sbus_ranges(sbus_dev->my_bus, &sbus_dev->reg_addrs[2], sbus_dev->num_registers, sbus_dev); - fore200e->regs.sba.isr = (u32*)sparc_alloc_io(sbus_dev->reg_addrs[2].phys_addr, 0, - sbus_dev->reg_addrs[2].reg_size, - "SBA ISR", - sbus_dev->reg_addrs[2].which_io, 0); - if (fore200e->regs.sba.isr == NULL) { - printk(FORE200E "unable to map ISR register of device %s\n", fore200e->name); - return -EFAULT; - } + fore200e->regs.sba.hcr = (u32*)sbus_ioremap(&sbus_dev->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR"); + fore200e->regs.sba.bsr = (u32*)sbus_ioremap(&sbus_dev->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR"); + fore200e->regs.sba.isr = (u32*)sbus_ioremap(&sbus_dev->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR"); + fore200e->virt_base = (u32*)sbus_ioremap(&sbus_dev->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM"); fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */ - - prom_apply_sbus_ranges(sbus_dev->my_bus, &sbus_dev->reg_addrs[3], sbus_dev->num_registers, sbus_dev); - fore200e->virt_base = (u32*)sparc_alloc_io(sbus_dev->reg_addrs[3].phys_addr, 0, - sbus_dev->reg_addrs[3].reg_size, - "SBA RAM", - sbus_dev->reg_addrs[3].which_io, 0); if (fore200e->virt_base == NULL) { printk(FORE200E "unable to map RAM of device %s\n", fore200e->name); return -EFAULT; @@ -844,12 +871,10 @@ static void fore200e_sba_unmap(struct fore200e* fore200e) { - struct linux_sbus_device* sbus_dev = (struct linux_sbus_device*)fore200e->bus_dev; - - sparc_free_io((void*)fore200e->regs.sba.hcr, sbus_dev->reg_addrs[0].reg_size); - sparc_free_io((void*)fore200e->regs.sba.bsr, sbus_dev->reg_addrs[1].reg_size); - sparc_free_io((void*)fore200e->regs.sba.isr, sbus_dev->reg_addrs[2].reg_size); - sparc_free_io((void*)fore200e->virt_base, sbus_dev->reg_addrs[3].reg_size); + sbus_iounmap((ulong)fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH); + sbus_iounmap((ulong)fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH); + sbus_iounmap((ulong)fore200e->regs.sba.isr, SBA200E_ISR_LENGTH); + sbus_iounmap((ulong)fore200e->virt_base, SBA200E_RAM_LENGTH); } @@ -865,16 +890,17 @@ fore200e_sba_detect(const struct fore200e_bus* bus, int index) { struct fore200e* fore200e; - struct linux_sbus* sbus; - struct linux_sbus_device* sbus_dev = 0; - unsigned int curr = 0; + struct sbus_bus* sbus_bus; + struct sbus_dev* sbus_dev = NULL; - for_each_sbus (sbus) { - for_each_sbusdev (sbus_dev, sbus) { + unsigned int count = 0; + + for_each_sbus (sbus_bus) { + for_each_sbusdev (sbus_dev, sbus_bus) { if (strcmp(sbus_dev->prom_name, SBA200E_PROM_NAME) == 0) { - if (curr >= index) + if (count >= index) goto found; - curr++; + count++; } } } @@ -908,11 +934,9 @@ static int __init fore200e_sba_prom_read(struct fore200e* fore200e, struct prom_data* prom) { - struct linux_sbus_device* sbus_dev; + struct sbus_dev* sbus_dev = (struct sbus_dev*) fore200e->bus_dev; int len; - sbus_dev = fore200e->bus_dev; - len = prom_getproperty(sbus_dev->prom_node, "macaddrlo2", &prom->mac_addr[ 4 ], 4); if (len < 0) return -EBUSY; @@ -934,7 +958,7 @@ static int fore200e_sba_proc_read(struct fore200e* fore200e, char *page) { - struct linux_sbus_device* sbus_dev = (struct linux_sbus_device*)fore200e->bus_dev; + struct sbus_dev* sbus_dev = (struct sbus_dev*)fore200e->bus_dev; return sprintf(page, " SBUS slot/device:\t\t%d/'%s'\n", sbus_dev->slot, sbus_dev->prom_name); } @@ -959,6 +983,9 @@ if (entry->data) kfree(entry->data); + /* remove DMA mapping */ + fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length); + /* notify tx completion */ if (entry->vcc->pop) entry->vcc->pop(entry->vcc, entry->skb); @@ -1009,7 +1036,7 @@ FORE200E_NEXT_ENTRY(bsq->free, fore200e_rx_buf_nbr[ scheme ][ magn ]); - entry->rbd_block->rbd[ i ].buffer_haddr = buffer->data_dma; + entry->rbd_block->rbd[ i ].buffer_haddr = buffer->data.dma_addr; entry->rbd_block->rbd[ i ].handle = FORE200E_BUF2HDL(buffer); } @@ -1102,9 +1129,9 @@ /* ensure DMA synchronisation */ if (fore200e->bus->dma_sync) - fore200e->bus->dma_sync(fore200e, buffer->data_dma, rpd->rsd[ i ].length); + fore200e->bus->dma_sync(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length); - memcpy(skb_put(skb, rpd->rsd[ i ].length), buffer->data_align, rpd->rsd[ i ].length); + memcpy(skb_put(skb, rpd->rsd[ i ].length), buffer->data.align_addr, rpd->rsd[ i ].length); } DPRINTK(3, "rx skb: len = %d, truesize = %d\n", skb->len, skb->truesize); @@ -1548,11 +1575,11 @@ if (skb_len < tx_len) memset(entry->data + skb_len, 0x00, tx_len - skb_len); - tpd->tsd[ 0 ].buffer = fore200e->bus->virt_to_dma(entry->data); + tpd->tsd[ 0 ].buffer = fore200e->bus->dma_map(fore200e, entry->data, tx_len); } else { entry->data = NULL; - tpd->tsd[ 0 ].buffer = fore200e->bus->virt_to_dma(skb_data); + tpd->tsd[ 0 ].buffer = fore200e->bus->dma_map(fore200e, skb_data, tx_len); } tpd->tsd[ 0 ].length = tx_len; @@ -1619,6 +1646,8 @@ { int ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 10); + fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length); + if (ok == 0) { printk(FORE200E "synchronous tx on %d:%d:%d failed\n", vcc->itf, vcc->vpi, vcc->vci); @@ -1652,6 +1681,7 @@ struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ]; struct stats_opcode opcode; int ok; + u32 stats_dma_addr; if (fore200e->stats == NULL) { fore200e->stats = fore200e_kmalloc(sizeof(struct stats), GFP_KERNEL | GFP_DMA); @@ -1659,13 +1689,14 @@ return -ENOMEM; } + stats_dma_addr = fore200e->bus->dma_map(fore200e, fore200e->stats, sizeof(struct stats)); + FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD); opcode.opcode = OPCODE_GET_STATS; opcode.pad = 0; - fore200e->bus->write(fore200e->bus->virt_to_dma((void*) fore200e->stats), - &entry->cp_entry->cmd.stats_block.stats_haddr); + fore200e->bus->write(stats_dma_addr, &entry->cp_entry->cmd.stats_block.stats_haddr); *entry->status = STATUS_PENDING; @@ -1675,6 +1706,8 @@ *entry->status = STATUS_FREE; + fore200e->bus->dma_unmap(fore200e, stats_dma_addr, sizeof(struct stats)); + if (ok == 0) { printk(FORE200E "unable to get statistics from device %s\n", fore200e->name); return -EIO; @@ -1716,6 +1749,9 @@ struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ]; struct oc3_opcode opcode; int ok; + u32 oc3_regs_dma_addr; + + oc3_regs_dma_addr = fore200e->bus->dma_map(fore200e, regs, sizeof(struct oc3_regs)); FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD); @@ -1724,8 +1760,7 @@ opcode.value = 0; opcode.mask = 0; - fore200e->bus->write(fore200e->bus->virt_to_dma((void*) regs), - &entry->cp_entry->cmd.oc3_block.regs_haddr); + fore200e->bus->write(oc3_regs_dma_addr, &entry->cp_entry->cmd.oc3_block.regs_haddr); *entry->status = STATUS_PENDING; @@ -1735,6 +1770,8 @@ *entry->status = STATUS_FREE; + fore200e->bus_dma_unmap(fore200e, oc3_regs_dma_addr, sizeof(struct oc3_regs)); + if (ok == 0) { printk(FORE200E "unable to get OC-3 regs of device %s\n", fore200e->name); return -EIO; @@ -1816,9 +1853,9 @@ static inline unsigned int -fore200e_dma_swap(unsigned int in) +fore200e_swap(unsigned int in) { -#if defined(__i386__) +#if defined(__LITTLE_ENDIAN) return swab32(in); #else return in; @@ -1834,19 +1871,19 @@ if (fore200e_getstats(fore200e) < 0) return -EIO; - tmp.section_bip = fore200e_dma_swap(fore200e->stats->oc3.section_bip8_errors); - tmp.line_bip = fore200e_dma_swap(fore200e->stats->oc3.line_bip24_errors); - tmp.path_bip = fore200e_dma_swap(fore200e->stats->oc3.path_bip8_errors); - tmp.line_febe = fore200e_dma_swap(fore200e->stats->oc3.line_febe_errors); - tmp.path_febe = fore200e_dma_swap(fore200e->stats->oc3.path_febe_errors); - tmp.corr_hcs = fore200e_dma_swap(fore200e->stats->oc3.corr_hcs_errors); - tmp.uncorr_hcs = fore200e_dma_swap(fore200e->stats->oc3.ucorr_hcs_errors); - tmp.tx_cells = fore200e_dma_swap(fore200e->stats->aal0.cells_transmitted) + - fore200e_dma_swap(fore200e->stats->aal34.cells_transmitted) + - fore200e_dma_swap(fore200e->stats->aal5.cells_transmitted); - tmp.rx_cells = fore200e_dma_swap(fore200e->stats->aal0.cells_received) + - fore200e_dma_swap(fore200e->stats->aal34.cells_received) + - fore200e_dma_swap(fore200e->stats->aal5.cells_received); + tmp.section_bip = fore200e_swap(fore200e->stats->oc3.section_bip8_errors); + tmp.line_bip = fore200e_swap(fore200e->stats->oc3.line_bip24_errors); + tmp.path_bip = fore200e_swap(fore200e->stats->oc3.path_bip8_errors); + tmp.line_febe = fore200e_swap(fore200e->stats->oc3.line_febe_errors); + tmp.path_febe = fore200e_swap(fore200e->stats->oc3.path_febe_errors); + tmp.corr_hcs = fore200e_swap(fore200e->stats->oc3.corr_hcs_errors); + tmp.uncorr_hcs = fore200e_swap(fore200e->stats->oc3.ucorr_hcs_errors); + tmp.tx_cells = fore200e_swap(fore200e->stats->aal0.cells_transmitted) + + fore200e_swap(fore200e->stats->aal34.cells_transmitted) + + fore200e_swap(fore200e->stats->aal5.cells_transmitted); + tmp.rx_cells = fore200e_swap(fore200e->stats->aal0.cells_received) + + fore200e_swap(fore200e->stats->aal34.cells_received) + + fore200e_swap(fore200e->stats->aal5.cells_received); if (arg) return copy_to_user(arg, &tmp, sizeof(struct sonet_stats)) ? -EFAULT : 0; @@ -1962,7 +1999,7 @@ fore200e->esi[ i ] = fore200e->atm_dev->esi[ i ] = prom->mac_addr[ i + 2 ]; } - fore200e_kfree((void**)&prom); + fore200e_kfree(prom); return 0; } @@ -1997,23 +2034,17 @@ buffer[ i ].scheme = scheme; buffer[ i ].magn = magn; - /* allocate and align the receive buffer body */ - if (fore200e_align_alloc((void**) &buffer[ i ].data_align, - (void**) &buffer[ i ].data_raw, - size, - fore200e->bus->buffer_alignment) < 0) { + /* allocate the receive buffer body */ + if (fore200e_chunk_alloc(fore200e, + &buffer[ i ].data, size, fore200e->bus->buffer_alignment) < 0) { while (i > 0) - fore200e_align_free((void**)&buffer[ --i ].data_raw); - fore200e_kfree((void**)&buffer); + fore200e_chunk_free(fore200e, &buffer[ --i ].data); + fore200e_kfree(buffer); return -ENOMEM; } - - /* finally get the physical base address of the buffer body */ - buffer[ i ].data_dma = fore200e->bus->virt_to_dma(buffer[ i ].data_align); } - /* set next free buffer index */ bsq->free = 0; } @@ -2031,8 +2062,6 @@ struct host_bsq* bsq; struct cp_bsq_entry* cp_entry; - u32 status_dma; - u32 rbd_block_dma; for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) { for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) { @@ -2042,9 +2071,8 @@ bsq = &fore200e->host_bsq[ scheme ][ magn ]; /* allocate and align the array of status words */ - if (fore200e->bus->dma_alloc((void**) &bsq->status_align, - (void**) &bsq->status_raw, - &status_dma, + if (fore200e->bus->dma_chunk_alloc(fore200e, + &bsq->status, sizeof(enum status), QUEUE_SIZE_BS, fore200e->bus->status_alignment) < 0) { @@ -2052,14 +2080,13 @@ } /* allocate and align the array of receive buffer descriptors */ - if (fore200e->bus->dma_alloc((void**) &bsq->rbd_block_align, - (void**) &bsq->rbd_block_raw, - &rbd_block_dma, + if (fore200e->bus->dma_chunk_alloc(fore200e, + &bsq->rbd_block, sizeof(struct rbd_block), QUEUE_SIZE_BS, fore200e->bus->descr_alignment) < 0) { - fore200e->bus->dma_free((void**)&bsq->status_raw); + fore200e->bus->dma_chunk_free(fore200e, &bsq->status); return -ENOMEM; } @@ -2070,14 +2097,18 @@ /* fill the host resident and cp resident buffer supply queue entries */ for (i = 0; i < QUEUE_SIZE_BS; i++) { - bsq->host_entry[ i ].status = &bsq->status_align[ i ]; - bsq->host_entry[ i ].rbd_block = &bsq->rbd_block_align[i]; - bsq->host_entry[ i ].rbd_block_dma = FORE200E_DMA_INDEX(rbd_block_dma, struct rbd, i); + bsq->host_entry[ i ].status = + FORE200E_INDEX(bsq->status.align_addr, enum status, i); + bsq->host_entry[ i ].rbd_block = + FORE200E_INDEX(bsq->rbd_block.align_addr, struct rbd_block, i); + bsq->host_entry[ i ].rbd_block_dma = + FORE200E_DMA_INDEX(bsq->rbd_block.dma_addr, struct rbd_block, i); bsq->host_entry[ i ].cp_entry = &cp_entry[ i ]; *bsq->host_entry[ i ].status = STATUS_FREE; - fore200e->bus->write(FORE200E_DMA_INDEX(status_dma, enum status, i), &cp_entry[ i ].status_haddr); + fore200e->bus->write(FORE200E_DMA_INDEX(bsq->status.dma_addr, enum status, i), + &cp_entry[ i ].status_haddr); } } } @@ -2092,16 +2123,13 @@ { struct host_rxq* rxq = &fore200e->host_rxq; struct cp_rxq_entry* cp_entry; - u32 status_dma; - u32 rpd_dma; int i; DPRINTK(2, "receive queue is being initialized\n"); /* allocate and align the array of status words */ - if (fore200e->bus->dma_alloc((void**) &rxq->status_align, - (void**) &rxq->status_raw, - &status_dma, + if (fore200e->bus->dma_chunk_alloc(fore200e, + &rxq->status, sizeof(enum status), QUEUE_SIZE_RX, fore200e->bus->status_alignment) < 0) { @@ -2109,14 +2137,13 @@ } /* allocate and align the array of receive PDU descriptors */ - if (fore200e->bus->dma_alloc((void**) &rxq->rpd_align, - (void**) &rxq->rpd_raw, - &rpd_dma, + if (fore200e->bus->dma_chunk_alloc(fore200e, + &rxq->rpd, sizeof(struct rpd), QUEUE_SIZE_RX, fore200e->bus->descr_alignment) < 0) { - fore200e->bus->dma_free((void**)&rxq->status_raw); + fore200e->bus->dma_chunk_free(fore200e, &rxq->status); return -ENOMEM; } @@ -2127,15 +2154,21 @@ /* fill the host resident and cp resident rx entries */ for (i=0; i < QUEUE_SIZE_RX; i++) { - rxq->host_entry[ i ].status = &rxq->status_align[ i ]; - rxq->host_entry[ i ].rpd = &rxq->rpd_align[ i ]; - rxq->host_entry[ i ].rpd_dma = FORE200E_DMA_INDEX(rpd_dma, struct rpd, i); + rxq->host_entry[ i ].status = + FORE200E_INDEX(rxq->status.align_addr, enum status, i); + rxq->host_entry[ i ].rpd = + FORE200E_INDEX(rxq->rpd.align_addr, struct rpd, i); + rxq->host_entry[ i ].rpd_dma = + FORE200E_DMA_INDEX(rxq->rpd.dma_addr, struct rpd, i); rxq->host_entry[ i ].cp_entry = &cp_entry[ i ]; *rxq->host_entry[ i ].status = STATUS_FREE; - fore200e->bus->write(FORE200E_DMA_INDEX(status_dma, enum status, i), &cp_entry[ i ].status_haddr); - fore200e->bus->write(FORE200E_DMA_INDEX(rpd_dma, struct rpd, i), &cp_entry[ i ].rpd_haddr); + fore200e->bus->write(FORE200E_DMA_INDEX(rxq->status.dma_addr, enum status, i), + &cp_entry[ i ].status_haddr); + + fore200e->bus->write(FORE200E_DMA_INDEX(rxq->rpd.dma_addr, struct rpd, i), + &cp_entry[ i ].rpd_haddr); } /* set the head entry of the queue */ @@ -2151,16 +2184,13 @@ { struct host_txq* txq = &fore200e->host_txq; struct cp_txq_entry* cp_entry; - u32 status_dma; - u32 tpd_dma; int i; DPRINTK(2, "transmit queue is being initialized\n"); /* allocate and align the array of status words */ - if (fore200e->bus->dma_alloc((void**) &txq->status_align, - (void**) &txq->status_raw, - &status_dma, + if (fore200e->bus->dma_chunk_alloc(fore200e, + &txq->status, sizeof(enum status), QUEUE_SIZE_TX, fore200e->bus->status_alignment) < 0) { @@ -2168,14 +2198,13 @@ } /* allocate and align the array of transmit PDU descriptors */ - if (fore200e->bus->dma_alloc((void**) &txq->tpd_align, - (void**) &txq->tpd_raw, - &tpd_dma, + if (fore200e->bus->dma_chunk_alloc(fore200e, + &txq->tpd, sizeof(struct tpd), QUEUE_SIZE_TX, fore200e->bus->descr_alignment) < 0) { - fore200e->bus->dma_free((void**)&txq->status_raw); + fore200e->bus->dma_chunk_free(fore200e, &txq->status); return -ENOMEM; } @@ -2186,20 +2215,24 @@ /* fill the host resident and cp resident tx entries */ for (i=0; i < QUEUE_SIZE_TX; i++) { - txq->host_entry[ i ].status = &txq->status_align[ i ]; - txq->host_entry[ i ].tpd = &txq->tpd_align[ i ]; - txq->host_entry[ i ].tpd_dma = FORE200E_DMA_INDEX(tpd_dma, struct tpd, i); + txq->host_entry[ i ].status = + FORE200E_INDEX(txq->status.align_addr, enum status, i); + txq->host_entry[ i ].tpd = + FORE200E_INDEX(txq->tpd.align_addr, struct tpd, i); + txq->host_entry[ i ].tpd_dma = + FORE200E_DMA_INDEX(txq->tpd.dma_addr, struct tpd, i); txq->host_entry[ i ].cp_entry = &cp_entry[ i ]; *txq->host_entry[ i ].status = STATUS_FREE; - fore200e->bus->write(FORE200E_DMA_INDEX(status_dma, enum status, i), &cp_entry[ i ].status_haddr); + fore200e->bus->write(FORE200E_DMA_INDEX(txq->status.dma_addr, enum status, i), + &cp_entry[ i ].status_haddr); /* although there is a one-to-one mapping of tx queue entries and tpds, - we do not write here the DMA (physical) base address of each tpd into the related - cp resident entry, because the cp relies on this write to detect that a new pdu - has been submitted for tx */ - } + we do not write here the DMA (physical) base address of each tpd into + the related cp resident entry, because the cp relies on this write + operation to detect that a new pdu has been submitted for tx */ +} /* set the head entry of the queue */ txq->head = 0; @@ -2214,15 +2247,13 @@ { struct host_cmdq* cmdq = &fore200e->host_cmdq; struct cp_cmdq_entry* cp_entry; - u32 status_dma; int i; DPRINTK(2, "command queue is being initialized\n"); /* allocate and align the array of status words */ - if (fore200e->bus->dma_alloc((void**) &cmdq->status_align, - (void**) &cmdq->status_raw, - &status_dma, + if (fore200e->bus->dma_chunk_alloc(fore200e, + &cmdq->status, sizeof(enum status), QUEUE_SIZE_CMD, fore200e->bus->status_alignment) < 0) { @@ -2236,12 +2267,14 @@ /* fill the host resident and cp resident cmd entries */ for (i=0; i < QUEUE_SIZE_CMD; i++) { - cmdq->host_entry[ i ].status = &cmdq->status_align[ i ]; + cmdq->host_entry[ i ].status = + FORE200E_INDEX(cmdq->status.align_addr, enum status, i); cmdq->host_entry[ i ].cp_entry = &cp_entry[ i ]; *cmdq->host_entry[ i ].status = STATUS_FREE; - fore200e->bus->write(FORE200E_DMA_INDEX(status_dma, enum status, i), &cp_entry[ i ].status_haddr); + fore200e->bus->write(FORE200E_DMA_INDEX(cmdq->status.dma_addr, enum status, i), + &cp_entry[ i ].status_haddr); } /* set the head entry of the queue */ @@ -2281,12 +2314,7 @@ DPRINTK(2, "device %s being initialized\n", fore200e->name); spin_lock_init(&fore200e->tx_lock); - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)) - fore200e->rate_sf = MUTEX; -#else init_MUTEX(&fore200e->rate_sf); -#endif cpq = fore200e->cp_queues = (struct cp_queues*) (fore200e->virt_base + FORE200E_CP_QUEUES_OFFSET); @@ -2316,7 +2344,7 @@ fore200e->bus->write(STATUS_PENDING, &cpq->init.status); fore200e->bus->write(OPCODE_INITIALIZE, &cpq->init.opcode); - ok = fore200e_poll(fore200e, &cpq->init.status, STATUS_COMPLETE, 3000); + ok = fore200e_io_poll(fore200e, &cpq->init.status, STATUS_COMPLETE, 3000); if (ok == 0) { printk(FORE200E "device %s initialization failed\n", fore200e->name); return -ENODEV; @@ -2394,7 +2422,7 @@ fore200e_monitor_puts(fore200e, cmd); - ok = fore200e_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_CP_RUNNING, 1000); + ok = fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_CP_RUNNING, 1000); if (ok == 0) { printk(FORE200E "device %s firmware didn't start\n", fore200e->name); return -ENODEV; @@ -2690,8 +2718,8 @@ " 4b5b:\n" " crc_header_errors:\t\t%10u\n" " framing_errors:\t\t%10u\n", - fore200e_dma_swap(fore200e->stats->phy.crc_header_errors), - fore200e_dma_swap(fore200e->stats->phy.framing_errors)); + fore200e_swap(fore200e->stats->phy.crc_header_errors), + fore200e_swap(fore200e->stats->phy.framing_errors)); if (!left--) return sprintf(page, "\n" @@ -2703,13 +2731,13 @@ " path_febe_errors:\t\t%10u\n" " corr_hcs_errors:\t\t%10u\n" " ucorr_hcs_errors:\t\t%10u\n", - fore200e_dma_swap(fore200e->stats->oc3.section_bip8_errors), - fore200e_dma_swap(fore200e->stats->oc3.path_bip8_errors), - fore200e_dma_swap(fore200e->stats->oc3.line_bip24_errors), - fore200e_dma_swap(fore200e->stats->oc3.line_febe_errors), - fore200e_dma_swap(fore200e->stats->oc3.path_febe_errors), - fore200e_dma_swap(fore200e->stats->oc3.corr_hcs_errors), - fore200e_dma_swap(fore200e->stats->oc3.ucorr_hcs_errors)); + fore200e_swap(fore200e->stats->oc3.section_bip8_errors), + fore200e_swap(fore200e->stats->oc3.path_bip8_errors), + fore200e_swap(fore200e->stats->oc3.line_bip24_errors), + fore200e_swap(fore200e->stats->oc3.line_febe_errors), + fore200e_swap(fore200e->stats->oc3.path_febe_errors), + fore200e_swap(fore200e->stats->oc3.corr_hcs_errors), + fore200e_swap(fore200e->stats->oc3.ucorr_hcs_errors)); if (!left--) return sprintf(page,"\n" @@ -2720,12 +2748,12 @@ " vpi no conn:\t\t%10u\n" " vci out of range:\t\t%10u\n" " vci no conn:\t\t%10u\n", - fore200e_dma_swap(fore200e->stats->atm.cells_transmitted), - fore200e_dma_swap(fore200e->stats->atm.cells_received), - fore200e_dma_swap(fore200e->stats->atm.vpi_bad_range), - fore200e_dma_swap(fore200e->stats->atm.vpi_no_conn), - fore200e_dma_swap(fore200e->stats->atm.vci_bad_range), - fore200e_dma_swap(fore200e->stats->atm.vci_no_conn)); + fore200e_swap(fore200e->stats->atm.cells_transmitted), + fore200e_swap(fore200e->stats->atm.cells_received), + fore200e_swap(fore200e->stats->atm.vpi_bad_range), + fore200e_swap(fore200e->stats->atm.vpi_no_conn), + fore200e_swap(fore200e->stats->atm.vci_bad_range), + fore200e_swap(fore200e->stats->atm.vci_no_conn)); if (!left--) return sprintf(page,"\n" @@ -2733,9 +2761,9 @@ " TX:\t\t\t%10u\n" " RX:\t\t\t%10u\n" " dropped:\t\t\t%10u\n", - fore200e_dma_swap(fore200e->stats->aal0.cells_transmitted), - fore200e_dma_swap(fore200e->stats->aal0.cells_received), - fore200e_dma_swap(fore200e->stats->aal0.cells_dropped)); + fore200e_swap(fore200e->stats->aal0.cells_transmitted), + fore200e_swap(fore200e->stats->aal0.cells_received), + fore200e_swap(fore200e->stats->aal0.cells_dropped)); if (!left--) return sprintf(page,"\n" @@ -2751,15 +2779,15 @@ " RX:\t\t\t%10u\n" " dropped:\t\t\t%10u\n" " protocol errors:\t\t%10u\n", - fore200e_dma_swap(fore200e->stats->aal34.cells_transmitted), - fore200e_dma_swap(fore200e->stats->aal34.cells_received), - fore200e_dma_swap(fore200e->stats->aal34.cells_dropped), - fore200e_dma_swap(fore200e->stats->aal34.cells_crc_errors), - fore200e_dma_swap(fore200e->stats->aal34.cells_protocol_errors), - fore200e_dma_swap(fore200e->stats->aal34.cspdus_transmitted), - fore200e_dma_swap(fore200e->stats->aal34.cspdus_received), - fore200e_dma_swap(fore200e->stats->aal34.cspdus_dropped), - fore200e_dma_swap(fore200e->stats->aal34.cspdus_protocol_errors)); + fore200e_swap(fore200e->stats->aal34.cells_transmitted), + fore200e_swap(fore200e->stats->aal34.cells_received), + fore200e_swap(fore200e->stats->aal34.cells_dropped), + fore200e_swap(fore200e->stats->aal34.cells_crc_errors), + fore200e_swap(fore200e->stats->aal34.cells_protocol_errors), + fore200e_swap(fore200e->stats->aal34.cspdus_transmitted), + fore200e_swap(fore200e->stats->aal34.cspdus_received), + fore200e_swap(fore200e->stats->aal34.cspdus_dropped), + fore200e_swap(fore200e->stats->aal34.cspdus_protocol_errors)); if (!left--) return sprintf(page,"\n" @@ -2775,15 +2803,15 @@ " dropped:\t\t\t%10u\n" " CRC errors:\t\t%10u\n" " protocol errors:\t\t%10u\n", - fore200e_dma_swap(fore200e->stats->aal5.cells_transmitted), - fore200e_dma_swap(fore200e->stats->aal5.cells_received), - fore200e_dma_swap(fore200e->stats->aal5.cells_dropped), - fore200e_dma_swap(fore200e->stats->aal5.congestion_experienced), - fore200e_dma_swap(fore200e->stats->aal5.cspdus_transmitted), - fore200e_dma_swap(fore200e->stats->aal5.cspdus_received), - fore200e_dma_swap(fore200e->stats->aal5.cspdus_dropped), - fore200e_dma_swap(fore200e->stats->aal5.cspdus_crc_errors), - fore200e_dma_swap(fore200e->stats->aal5.cspdus_protocol_errors)); + fore200e_swap(fore200e->stats->aal5.cells_transmitted), + fore200e_swap(fore200e->stats->aal5.cells_received), + fore200e_swap(fore200e->stats->aal5.cells_dropped), + fore200e_swap(fore200e->stats->aal5.congestion_experienced), + fore200e_swap(fore200e->stats->aal5.cspdus_transmitted), + fore200e_swap(fore200e->stats->aal5.cspdus_received), + fore200e_swap(fore200e->stats->aal5.cspdus_dropped), + fore200e_swap(fore200e->stats->aal5.cspdus_crc_errors), + fore200e_swap(fore200e->stats->aal5.cspdus_protocol_errors)); if (!left--) return sprintf(page,"\n" @@ -2793,11 +2821,11 @@ " small b2:\t\t\t%10u\n" " large b2:\t\t\t%10u\n" " RX PDUs:\t\t\t%10u\n", - fore200e_dma_swap(fore200e->stats->aux.small_b1_failed), - fore200e_dma_swap(fore200e->stats->aux.large_b1_failed), - fore200e_dma_swap(fore200e->stats->aux.small_b2_failed), - fore200e_dma_swap(fore200e->stats->aux.large_b2_failed), - fore200e_dma_swap(fore200e->stats->aux.rpd_alloc_failed)); + fore200e_swap(fore200e->stats->aux.small_b1_failed), + fore200e_swap(fore200e->stats->aux.large_b1_failed), + fore200e_swap(fore200e->stats->aux.small_b2_failed), + fore200e_swap(fore200e->stats->aux.large_b2_failed), + fore200e_swap(fore200e->stats->aux.rpd_alloc_failed)); if (!left--) return sprintf(page,"\n" @@ -2854,14 +2882,21 @@ static const struct atmdev_ops fore200e_ops = { - open: fore200e_open, - close: fore200e_close, - ioctl: fore200e_ioctl, - getsockopt: fore200e_getsockopt, - setsockopt: fore200e_setsockopt, - send: fore200e_send, - change_qos: fore200e_change_qos, - proc_read: fore200e_proc_read + NULL, /* fore200e_dev_close */ + fore200e_open, + fore200e_close, + fore200e_ioctl, + fore200e_getsockopt, + fore200e_setsockopt, + fore200e_send, + NULL, /* fore200e_sg_send, */ + NULL, /* fore200e_send_oam, */ + NULL, /* fore200e_phy_put, */ + NULL, /* fore200e_phy_get, */ + NULL, /* fore200e_feedback, */ + fore200e_change_qos, + NULL, /* free_rx_skb */ + fore200e_proc_read }; @@ -2880,9 +2915,11 @@ _fore200e_pca_fw_data, &_fore200e_pca_fw_size, fore200e_pca_read, fore200e_pca_write, - fore200e_pca_virt_to_dma, - fore200e_pca_dma_alloc, - fore200e_pca_dma_free, + fore200e_pca_dma_map, + fore200e_pca_dma_unmap, + NULL, + fore200e_pca_dma_chunk_alloc, + fore200e_pca_dma_chunk_free, fore200e_pca_detect, fore200e_pca_configure, fore200e_pca_map, @@ -2892,7 +2929,6 @@ NULL, fore200e_pca_irq_check, fore200e_pca_irq_ack, - NULL, fore200e_pca_proc_read, }, #endif @@ -2901,9 +2937,11 @@ _fore200e_sba_fw_data, &_fore200e_sba_fw_size, fore200e_sba_read, fore200e_sba_write, - fore200e_sba_virt_to_dma, - fore200e_sba_dma_alloc, - fore200e_sba_dma_free, + fore200e_sba_dma_map, + fore200e_sba_dma_unmap, + fore200e_sba_dma_sync, + fore200e_sba_dma_chunk_alloc, + fore200e_sba_dma_chunk_free, fore200e_sba_detect, fore200e_sba_configure, fore200e_sba_map, @@ -2913,7 +2951,6 @@ fore200e_sba_irq_enable, fore200e_sba_irq_check, fore200e_sba_irq_ack, - fore200e_sba_dma_sync, fore200e_sba_proc_read, }, #endif diff -ur --new-file old/linux/drivers/atm/fore200e.h new/linux/drivers/atm/fore200e.h --- old/linux/drivers/atm/fore200e.h Mon Jan 31 16:04:08 2000 +++ new/linux/drivers/atm/fore200e.h Mon Jan 31 16:05:40 2000 @@ -553,15 +553,26 @@ } host_cmdq_entry_t; +/* chunk of memory */ + +typedef struct chunk { + void* alloc_addr; /* base address of allocated chunk */ + void* align_addr; /* base address of aligned chunk */ + u32 dma_addr; /* DMA address of aligned chunk */ + u32 alloc_size; /* length of allocated chunk */ + u32 align_size; /* length of aligned chunk */ +} chunk_t; + +#define dma_size align_size /* DMA useable size */ + + /* host resident receive buffer */ typedef struct buffer { struct buffer* next; /* next receive buffer */ enum buffer_scheme scheme; /* buffer scheme */ enum buffer_magn magn; /* buffer magnitude */ - void* data_raw; /* raw buffer data */ - void* data_align; /* DMA aligned buffer data */ - u32 data_dma; /* DMA address of data */ + struct chunk data; /* data buffer */ } buffer_t; @@ -579,9 +590,7 @@ typedef struct host_cmdq { struct host_cmdq_entry host_entry[ QUEUE_SIZE_CMD ]; /* host resident cmd queue entries */ int head; /* head of cmd queue */ - enum status* status_raw; /* raw array of completion status */ - enum status* status_align; /* DMA aligned array of completion status */ - + struct chunk status; /* array of completion status */ } host_cmdq_t; @@ -590,10 +599,8 @@ typedef struct host_txq { struct host_txq_entry host_entry[ QUEUE_SIZE_TX ]; /* host resident tx queue entries */ int head; /* head of tx queue */ - struct tpd* tpd_raw; /* raw array of tpds */ - struct tpd* tpd_align; /* DMA aligned array of tpds */ - enum status* status_raw; /* raw array of completion status */ - enum status* status_align; /* DMA aligned array of completion status */ + struct chunk tpd; /* array of tpds */ + struct chunk status; /* arry of completion status */ int txing; /* number of pending PDUs in tx queue */ } host_txq_t; @@ -603,10 +610,8 @@ typedef struct host_rxq { struct host_rxq_entry host_entry[ QUEUE_SIZE_RX ]; /* host resident rx queue entries */ int head; /* head of rx queue */ - struct rpd* rpd_raw; /* raw array of rpds */ - struct rpd* rpd_align; /* DMA aligned array of rpds */ - enum status* status_raw; /* raw array of completion status */ - enum status* status_align; /* DMA aligned array of completion status */ + struct chunk rpd; /* array of rpds */ + struct chunk status; /* array of completion status */ } host_rxq_t; @@ -615,10 +620,8 @@ typedef struct host_bsq { struct host_bsq_entry host_entry[ QUEUE_SIZE_BS ]; /* host resident buffer supply queue entries */ int head; /* head of buffer supply queue */ - struct rbd_block* rbd_block_raw; /* raw array of rbds */ - struct rbd_block* rbd_block_align; /* DMA aligned array fo rbds */ - enum status* status_raw; /* raw array of completion status */ - enum status* status_align; /* DMA aligned array of completion status */ + struct chunk rbd_block; /* array of rbds */ + struct chunk status; /* array of completion status */ struct buffer* buffer; /* array of rx buffers */ int free; /* index of first free rx buffer */ volatile int count; /* count of supplied rx buffers */ @@ -793,9 +796,11 @@ const unsigned int* fw_size; /* address of firmware data size */ u32 (*read)(volatile u32*); void (*write)(u32, volatile u32*); - u32 (*virt_to_dma)(void*); - int (*dma_alloc)(void**, void**, u32*, int, int, int); - void (*dma_free)(void**); + u32 (*dma_map)(struct fore200e*, void*, int); + void (*dma_unmap)(struct fore200e*, u32, int); + void (*dma_sync)(struct fore200e*, u32, int); + int (*dma_chunk_alloc)(struct fore200e*, struct chunk*, int, int, int); + void (*dma_chunk_free)(struct fore200e*, struct chunk*); struct fore200e* (*detect)(const struct fore200e_bus*, int); int (*configure)(struct fore200e*); int (*map)(struct fore200e*); @@ -805,7 +810,6 @@ void (*irq_enable)(struct fore200e*); int (*irq_check)(struct fore200e*); void (*irq_ack)(struct fore200e*); - void (*dma_sync)(struct fore200e*, u32, int); int (*proc_read)(struct fore200e*, char*); } fore200e_bus_t; @@ -910,6 +914,15 @@ #define SBA200E_PROM_NAME "FORE,sba-200e" /* device name in openprom tree */ + + +/* size of SBA-200E registers */ + +#define SBA200E_HCR_LENGTH 4 +#define SBA200E_BSR_LENGTH 4 +#define SBA200E_ISR_LENGTH 4 +#define SBA200E_RAM_LENGTH 0x40000 + /* SBA-200E host control register */ diff -ur --new-file old/linux/drivers/block/Config.in new/linux/drivers/block/Config.in --- old/linux/drivers/block/Config.in Tue Jan 18 00:24:03 2000 +++ new/linux/drivers/block/Config.in Mon Jan 24 20:24:50 2000 @@ -59,18 +59,20 @@ if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a "$CONFIG_BLK_DEV_AEC6210" = "y" ]; then bool ' AEC6210 Tuning support (EXPERIMENTAL)' CONFIG_BLK_DEV_AEC6210_TUNING fi + if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then + bool ' ALI M15x3 chipset support' CONFIG_BLK_DEV_ALI15X3 + if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then + bool ' AMD Viper support (EXPERIMENTAL)' CONFIG_BLK_DEV_AMD7409 + fi + fi bool ' CMD64X chipset support' CONFIG_BLK_DEV_CMD64X - if [ "$CONFIG_BLK_DEV_CMD64X" = "y" -a "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then + if [ "$CONFIG_BLK_DEV_CMD64X" = "y" -a "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then bool ' CMD64X chipset RAID support (EXPERIMENTAL) (WIP)' CONFIG_BLK_DEV_CMD64X_RAID fi if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then bool ' CY82C693 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CY82C693 fi if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then - bool ' ALI M15x3 chipset support' CONFIG_BLK_DEV_ALI15X3 - if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then - bool ' AMD Viper support (EXPERIMENTAL)' CONFIG_BLK_DEV_AMD7409 - fi bool ' HPT34X chipset support' CONFIG_BLK_DEV_HPT34X if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a "$CONFIG_BLK_DEV_HPT34X" = "y" ]; then bool ' HPT34X DMA support (EXPERIMENTAL)' CONFIG_BLK_DEV_HPT34X_DMA @@ -218,15 +220,6 @@ tristate 'Mylex DAC960/DAC1100 PCI RAID Controller support' CONFIG_BLK_DEV_DAC960 fi -# PARIDE doesn't need PARPORT, but if PARPORT is configured as a module, -# PARIDE must also be a module. The bogus CONFIG_PARIDE_PARPORT option -# controls the choices given to the user ... - -if [ "$CONFIG_PARPORT" = "y" -o "$CONFIG_PARPORT" = "n" ]; then - define_tristate CONFIG_PARIDE_PARPORT y -else - define_tristate CONFIG_PARIDE_PARPORT m -fi dep_tristate 'Parallel port IDE device support' CONFIG_PARIDE $CONFIG_PARIDE_PARPORT if [ "$CONFIG_PARIDE" = "y" -o "$CONFIG_PARIDE" = "m" ]; then source drivers/block/paride/Config.in diff -ur --new-file old/linux/drivers/block/DAC960.c new/linux/drivers/block/DAC960.c --- old/linux/drivers/block/DAC960.c Wed Jan 19 03:54:20 2000 +++ new/linux/drivers/block/DAC960.c Wed Jan 26 21:43:03 2000 @@ -1009,6 +1009,45 @@ } +static int DAC_merge_fn(request_queue_t *q, struct request *req, + struct buffer_head *bh) +{ + int max_segments; + DAC960_Controller_T * Controller = q->queuedata; + + max_segments = Controller->MaxSegmentsPerRequest[MINOR(req->rq_dev)]; + + if (req->bhtail->b_data + req->bhtail->b_size != bh->b_data) { + if (req->nr_segments < max_segments) { + req->nr_segments++; + return 1; + } + return 0; + } + + return 1; +} + +static int DAC_merge_requests_fn(request_queue_t *q, + struct request *req, + struct request *next) +{ + int max_segments; + DAC960_Controller_T * Controller = q->queuedata; + int total_segments = req->nr_segments + next->nr_segments; + + max_segments = Controller->MaxSegmentsPerRequest[MINOR(req->rq_dev)]; + + if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) + total_segments--; + + if (total_segments > max_segments) + return 0; + + req->nr_segments = total_segments; + return 1; +} + /* DAC960_RegisterBlockDevice registers the Block Device structures associated with Controller. @@ -1016,6 +1055,8 @@ static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller) { + request_queue_t * q; + static void (*RequestFunctions[DAC960_MaxControllers])(request_queue_t *) = { DAC960_RequestFunction0, DAC960_RequestFunction1, DAC960_RequestFunction2, DAC960_RequestFunction3, @@ -1036,8 +1077,13 @@ /* Initialize the I/O Request Function. */ - blk_init_queue(BLK_DEFAULT_QUEUE(MajorNumber), - RequestFunctions[Controller->ControllerNumber]); + q = BLK_DEFAULT_QUEUE(MajorNumber); + blk_init_queue(q, RequestFunctions[Controller->ControllerNumber]); + blk_queue_headactive(q, 0); + q->merge_fn = DAC_merge_fn; + q->merge_requests_fn = DAC_merge_requests_fn; + q->queuedata = (void *) Controller; + /* Initialize the Disk Partitions array, Partition Sizes array, Block Sizes array, Max Sectors per Request array, and Max Segments per Request array. @@ -1054,7 +1100,6 @@ Controller->GenericDiskInfo.sizes = Controller->PartitionSizes; blksize_size[MajorNumber] = Controller->BlockSizes; max_sectors[MajorNumber] = Controller->MaxSectorsPerRequest; - max_segments[MajorNumber] = Controller->MaxSegmentsPerRequest; /* Initialize Read Ahead to 128 sectors. */ diff -ur --new-file old/linux/drivers/block/alim15x3.c new/linux/drivers/block/alim15x3.c --- old/linux/drivers/block/alim15x3.c Tue Jan 18 00:23:11 2000 +++ new/linux/drivers/block/alim15x3.c Mon Jan 24 20:24:50 2000 @@ -411,7 +411,11 @@ { struct hd_driveid *id = drive->id; +#if 0 + if (m5229_revision < 0x20) { +#else if (m5229_revision <= 0x20) { +#endif return 0; } else if ((m5229_revision < 0xC2) && ((drive->media!=ide_disk) || diff -ur --new-file old/linux/drivers/block/amiflop.c new/linux/drivers/block/amiflop.c --- old/linux/drivers/block/amiflop.c Sun Jan 9 02:41:16 2000 +++ new/linux/drivers/block/amiflop.c Wed Jan 26 21:45:20 2000 @@ -1795,7 +1795,8 @@ return -EBUSY; } - if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE)) == NULL) { + if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE, "Floppy")) == + NULL) { printk("fd: cannot get chip mem buffer\n"); unregister_blkdev(MAJOR_NR,"fd"); return -ENOMEM; diff -ur --new-file old/linux/drivers/block/buddha.c new/linux/drivers/block/buddha.c --- old/linux/drivers/block/buddha.c Thu May 13 20:04:54 1999 +++ new/linux/drivers/block/buddha.c Wed Jan 26 21:45:20 2000 @@ -111,24 +111,28 @@ static int find_buddha(void) { - u_int key; - const struct ConfigDev *cd; + struct zorro_dev *z = NULL; buddha_num_hwifs = 0; - if ((key = zorro_find(ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA, 0, 0))) - buddha_num_hwifs = BUDDHA_NUM_HWIFS; - else if ((key = zorro_find(ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL, 0, - 0))) - buddha_num_hwifs = CATWEASEL_NUM_HWIFS; - if (key) { - cd = zorro_get_board(key); - buddha_board = (u_long)cd->cd_BoardAddr; - if (buddha_board) { - buddha_board = ZTWO_VADDR(buddha_board); - /* write to BUDDHA_IRQ_MR to enable the board IRQ */ - *(char *)(buddha_board+BUDDHA_IRQ_MR) = 0; - zorro_config_board(key, 0); - } + while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { + unsigned long board; + const char *name; + if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) { + buddha_num_hwifs = BUDDHA_NUM_HWIFS; + name = "Buddha IDE Interface"; + } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL) { + buddha_num_hwifs = CATWEASEL_NUM_HWIFS; + name = "Catweasel IDE Interface and Floppy Controller"; + } else + continue; + board = z->resource.start; + if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE")) + continue; + strcpy(z->name, name); + buddha_board = ZTWO_VADDR(board); + /* write to BUDDHA_IRQ_MR to enable the board IRQ */ + *(char *)(buddha_board+BUDDHA_IRQ_MR) = 0; + break; } return buddha_num_hwifs; } diff -ur --new-file old/linux/drivers/block/cmd64x.c new/linux/drivers/block/cmd64x.c --- old/linux/drivers/block/cmd64x.c Fri Jan 14 09:50:53 2000 +++ new/linux/drivers/block/cmd64x.c Thu Jan 27 17:58:15 2000 @@ -228,6 +228,7 @@ dma_stat = inb(dma_base+2); /* get DMA status */ outb(inb(dma_base)&~1, dma_base); /* stop DMA */ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ + ide_destroy_dmatable(drive); /* and free any DMA resources */ return (dma_stat & 7) != 4; /* verify good DMA status */ } diff -ur --new-file old/linux/drivers/block/hpt34x.c new/linux/drivers/block/hpt34x.c --- old/linux/drivers/block/hpt34x.c Fri Jan 14 09:50:53 2000 +++ new/linux/drivers/block/hpt34x.c Thu Jan 27 17:58:15 2000 @@ -292,7 +292,7 @@ case ide_dma_write: if (!(count = ide_build_dmatable(drive, func))) return 1; /* try PIO instead of DMA */ - outl(virt_to_bus(hwif->dmatable), dma_base + 4); /* PRD table */ + outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */ reading |= 0x01; outb(reading, dma_base); /* specify r/w */ outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */ @@ -307,6 +307,7 @@ outb(inb(dma_base)&~1, dma_base); /* stop DMA */ dma_stat = inb(dma_base+2); /* get DMA status */ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ + ide_destroy_dmatable(drive); /* purge DMA mappings */ return (dma_stat & 7) != 4; /* verify good DMA status */ default: break; diff -ur --new-file old/linux/drivers/block/hpt366.c new/linux/drivers/block/hpt366.c --- old/linux/drivers/block/hpt366.c Fri Jan 14 09:50:53 2000 +++ new/linux/drivers/block/hpt366.c Mon Jan 24 20:24:50 2000 @@ -30,7 +30,6 @@ #include "ide_modes.h" const char *bad_ata66_4[] = { - "QUANTUM FIREBALLP KA9.1", "WDC AC310200R", NULL }; @@ -423,30 +422,17 @@ int hpt366_dmaproc (ide_dma_action_t func, ide_drive_t *drive) { + byte reg50h = 0; + switch (func) { case ide_dma_check: return config_drive_xfer_rate(drive); + case ide_dma_lostirq: + pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, ®50h); + pci_write_config_byte(HWIF(drive)->pci_dev, 0x50, reg50h|0x03); + pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, ®50h); + /* ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); */ case ide_dma_timeout: - /* ide_do_reset(drive); */ - - if (0) { - byte reg50h = 0, reg52h = 0; - (void) ide_dmaproc(ide_dma_off_quietly, drive); - pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, ®50h); - pci_read_config_byte(HWIF(drive)->pci_dev, 0x52, ®52h); - printk("%s: (ide_dma_timeout) reg52h=0x%02x\n", drive->name, reg52h); - if (reg52h & 0x04) { - pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, ®50h); - pci_write_config_byte(HWIF(drive)->pci_dev, 0x50, reg50h|0xff); - pci_write_config_byte(HWIF(drive)->pci_dev, 0x50, reg50h); - } - pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, ®50h); - pci_read_config_byte(HWIF(drive)->pci_dev, 0x52, ®52h); - printk("%s: (ide_dma_timeout) reg50h=0x%02x reg52h=0x%02x :: again\n", drive->name, reg50h, reg52h); - (void) ide_dmaproc(ide_dma_on, drive); - if (reg52h & 0x04) - (void) ide_dmaproc(ide_dma_off, drive); - } break; default: break; diff -ur --new-file old/linux/drivers/block/icside.c new/linux/drivers/block/icside.c --- old/linux/drivers/block/icside.c Tue Dec 14 01:26:27 1999 +++ new/linux/drivers/block/icside.c Thu Jan 27 17:58:15 2000 @@ -226,7 +226,7 @@ unsigned long addr, size; unsigned char *virt_addr; unsigned int count = 0; - dmasg_t *sg = (dmasg_t *)HWIF(drive)->dmatable; + dmasg_t *sg = (dmasg_t *)HWIF(drive)->dmatable_cpu; do { if (bh == NULL) { @@ -393,7 +393,7 @@ */ set_dma_speed(hwif->hw.dma, drive->drive_data); - set_dma_sg(hwif->hw.dma, (dmasg_t *)hwif->dmatable, count); + set_dma_sg(hwif->hw.dma, (dmasg_t *)hwif->dmatable_cpu, count); set_dma_mode(hwif->hw.dma, reading ? DMA_MODE_READ : DMA_MODE_WRITE); @@ -458,7 +458,7 @@ if (!table) printk(" -- ERROR, unable to allocate DMA table\n"); else { - hwif->dmatable = (void *)table; + hwif->dmatable_cpu = (void *)table; hwif->dmaproc = icside_dmaproc; hwif->autodma = autodma; @@ -466,7 +466,7 @@ ", auto-enable" : ""); } - return hwif->dmatable != NULL; + return hwif->dmatable_cpu != NULL; } #endif diff -ur --new-file old/linux/drivers/block/ide-disk.c new/linux/drivers/block/ide-disk.c --- old/linux/drivers/block/ide-disk.c Fri Jan 14 09:50:53 2000 +++ new/linux/drivers/block/ide-disk.c Mon Jan 24 20:24:50 2000 @@ -572,7 +572,7 @@ drive->special.b.recalibrate = 1; if (OK_TO_RESET_CONTROLLER) drive->mult_count = 0; - if (!drive->keep_settings) + if (!drive->keep_settings && !drive->using_dma) drive->mult_req = 0; if (drive->mult_req != drive->mult_count) drive->special.b.set_multmode = 1; diff -ur --new-file old/linux/drivers/block/ide-dma.c new/linux/drivers/block/ide-dma.c --- old/linux/drivers/block/ide-dma.c Fri Jan 14 09:50:53 2000 +++ new/linux/drivers/block/ide-dma.c Thu Jan 27 17:58:15 2000 @@ -208,6 +208,31 @@ return ide_error(drive, "dma_intr", stat); } +static int ide_build_sglist (ide_hwif_t *hwif, struct request *rq) +{ + struct buffer_head *bh; + struct scatterlist *sg = hwif->sg_table; + int nents = 0; + + bh = rq->bh; + do { + unsigned char *virt_addr = bh->b_data; + unsigned int size = bh->b_size; + + while ((bh = bh->b_reqnext) != NULL) { + if ((virt_addr + size) != (unsigned char *) bh->b_data) + break; + size += bh->b_size; + } + memset(&sg[nents], 0, sizeof(*sg)); + sg[nents].address = virt_addr; + sg[nents].length = size; + nents++; + } while (bh != NULL); + + return pci_map_sg(hwif->pci_dev, sg, nents); +} + /* * ide_build_dmatable() prepares a dma request. * Returns 0 if all went okay, returns 1 otherwise. @@ -215,95 +240,70 @@ */ int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func) { - struct request *rq = HWGROUP(drive)->rq; - struct buffer_head *bh = rq->bh; - unsigned int size, addr, *table = (unsigned int *)HWIF(drive)->dmatable; - unsigned char *virt_addr; + unsigned int *table = HWIF(drive)->dmatable_cpu; #ifdef CONFIG_BLK_DEV_TRM290 unsigned int is_trm290_chipset = (HWIF(drive)->chipset == ide_trm290); #else const int is_trm290_chipset = 0; #endif unsigned int count = 0; + int i; + struct scatterlist *sg; - do { - /* - * Determine addr and size of next buffer area. We assume that - * individual virtual buffers are always composed linearly in - * physical memory. For example, we assume that any 8kB buffer - * is always composed of two adjacent physical 4kB pages rather - * than two possibly non-adjacent physical 4kB pages. - */ - if (bh == NULL) { /* paging requests have (rq->bh == NULL) */ - virt_addr = rq->buffer; - addr = virt_to_bus (virt_addr); - size = rq->nr_sectors << 9; - } else { - /* group sequential buffers into one large buffer */ - virt_addr = bh->b_data; - addr = virt_to_bus (virt_addr); - size = bh->b_size; - while ((bh = bh->b_reqnext) != NULL) { - if ((addr + size) != virt_to_bus (bh->b_data)) - break; - size += bh->b_size; - } - } - /* - * Fill in the dma table, without crossing any 64kB boundaries. - * Most hardware requires 16-bit alignment of all blocks, - * but the trm290 requires 32-bit alignment. - */ - if ((addr & 3)) { - printk("%s: misaligned DMA buffer\n", drive->name); - return 0; - } + HWIF(drive)->sg_nents = i = ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq); - /* - * Some CPUs without cache snooping need to invalidate/write - * back their caches before DMA transfers to guarantee correct - * data. -- rmk - */ - if (size) { - if (func == ide_dma_read) { - dma_cache_inv((unsigned int)virt_addr, size); - } else { - dma_cache_wback((unsigned int)virt_addr, size); - } - } + sg = HWIF(drive)->sg_table; + while (i && sg_dma_len(sg)) { + u32 cur_addr; + u32 cur_len; - while (size) { + cur_addr = sg_dma_address(sg); + cur_len = sg_dma_len(sg); + + while (cur_len) { if (++count >= PRD_ENTRIES) { printk("%s: DMA table too small\n", drive->name); + pci_unmap_sg(HWIF(drive)->pci_dev, + HWIF(drive)->sg_table, + HWIF(drive)->sg_nents); return 0; /* revert to PIO for this request */ } else { - unsigned int xcount, bcount = 0x10000 - (addr & 0xffff); - if (bcount > size) - bcount = size; - *table++ = cpu_to_le32(addr); + u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff); + + if (bcount > cur_len) + bcount = cur_len; + *table++ = cpu_to_le32(cur_addr); xcount = bcount & 0xffff; if (is_trm290_chipset) xcount = ((xcount >> 2) - 1) << 16; *table++ = cpu_to_le32(xcount); - addr += bcount; - size -= bcount; + cur_addr += bcount; + cur_len -= bcount; } } - } while (bh != NULL); - if (!count) { - printk("%s: empty DMA table?\n", drive->name); - } else { - if (!is_trm290_chipset) - *--table |= cpu_to_le32(0x80000000); /* set End-Of-Table (EOT) bit */ - /* - * Some CPUs need to flush the DMA table to physical RAM - * before DMA can start. -- rmk - */ - dma_cache_wback((unsigned long)HWIF(drive)->dmatable, count * sizeof(unsigned int) * 2); + + sg++; + i--; } + + if (!count) + printk("%s: empty DMA table?\n", drive->name); + else if (!is_trm290_chipset) + *--table |= cpu_to_le32(0x80000000); + return count; } +/* Teardown mappings after DMA has completed. */ +void ide_destroy_dmatable (ide_drive_t *drive) +{ + struct pci_dev *dev = HWIF(drive)->pci_dev; + struct scatterlist *sg = HWIF(drive)->sg_table; + int nents = HWIF(drive)->sg_nents; + + pci_unmap_sg(dev, sg, nents); +} + /* * For both Blacklisted and Whitelisted drives. * This is setup to be called as an extern for future support @@ -413,7 +413,7 @@ case ide_dma_write: if (!(count = ide_build_dmatable(drive, func))) return 1; /* try PIO instead of DMA */ - outl(virt_to_bus(hwif->dmatable), dma_base + 4); /* PRD table */ + outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */ outb(reading, dma_base); /* specify r/w */ outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */ drive->waiting_for_dma = 1; @@ -434,6 +434,7 @@ outb(inb(dma_base)&~1, dma_base); /* stop DMA */ dma_stat = inb(dma_base+2); /* get DMA status */ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ + ide_destroy_dmatable(drive); /* purge DMA mappings */ return (dma_stat & 7) != 4; /* verify good DMA status */ case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */ dma_stat = inb(dma_base+2); @@ -458,9 +459,16 @@ */ int ide_release_dma (ide_hwif_t *hwif) { - if (hwif->dmatable) { - clear_page((void *)hwif->dmatable); /* clear PRD 1st */ - free_page((unsigned long)hwif->dmatable); /* free PRD 2nd */ + if (hwif->dmatable_cpu) { + pci_free_consistent(hwif->pci_dev, + PRD_ENTRIES * PRD_BYTES, + hwif->dmatable_cpu, + hwif->dmatable_dma); + hwif->dmatable_cpu = NULL; + } + if (hwif->sg_table) { + kfree(hwif->sg_table); + hwif->sg_table = NULL; } if ((hwif->dma_extra) && (hwif->channel == 0)) release_region((hwif->dma_base + 16), hwif->dma_extra); @@ -474,9 +482,6 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_ports) { - static unsigned long dmatable = 0; - static unsigned leftover = 0; - printk(" %s: BM-DMA at 0x%04lx-0x%04lx", hwif->name, dma_base, dma_base + num_ports - 1); if (check_region(dma_base, num_ports)) { printk(" -- ERROR, PORT ADDRESSES ALREADY IN USE\n"); @@ -484,31 +489,33 @@ } request_region(dma_base, num_ports, hwif->name); hwif->dma_base = dma_base; - if (leftover < (PRD_ENTRIES * PRD_BYTES)) { - /* - * The BM-DMA uses full 32bit addr, so we can - * safely use __get_free_page() here instead - * of __get_dma_pages() -- no ISA limitations. - */ - dmatable = __get_free_pages(GFP_KERNEL,1); - leftover = dmatable ? PAGE_SIZE : 0; + hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev, + PRD_ENTRIES * PRD_BYTES, + &hwif->dmatable_dma); + if (hwif->dmatable_cpu == NULL) + goto dma_alloc_failure; + + hwif->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES, + GFP_KERNEL); + if (hwif->sg_table == NULL) { + pci_free_consistent(hwif->pci_dev, PRD_ENTRIES * PRD_BYTES, + hwif->dmatable_cpu, hwif->dmatable_dma); + goto dma_alloc_failure; } - if (!dmatable) { - printk(" -- ERROR, UNABLE TO ALLOCATE PRD TABLE\n"); - } else { - hwif->dmatable = (unsigned long *) dmatable; - dmatable += (PRD_ENTRIES * PRD_BYTES); - leftover -= (PRD_ENTRIES * PRD_BYTES); - hwif->dmaproc = &ide_dmaproc; - - if (hwif->chipset != ide_trm290) { - byte dma_stat = inb(dma_base+2); - printk(", BIOS settings: %s:%s, %s:%s", - hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio", - hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio"); - } - printk("\n"); + + hwif->dmaproc = &ide_dmaproc; + + if (hwif->chipset != ide_trm290) { + byte dma_stat = inb(dma_base+2); + printk(", BIOS settings: %s:%s, %s:%s", + hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio", + hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio"); } + printk("\n"); + return; + +dma_alloc_failure: + printk(" -- ERROR, UNABLE TO ALLOCATE DMA TABLES\n"); } /* diff -ur --new-file old/linux/drivers/block/ide-pci.c new/linux/drivers/block/ide-pci.c --- old/linux/drivers/block/ide-pci.c Fri Jan 14 09:50:53 2000 +++ new/linux/drivers/block/ide-pci.c Mon Jan 24 20:24:50 2000 @@ -29,8 +29,8 @@ #define DEVID_PIIXb ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_1}) #define DEVID_PIIX3 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1}) #define DEVID_PIIX4 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB}) -#define DEVID_PIIX4E ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1}) -#define DEVID_PIIX4U ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1}) +#define DEVID_PIIX4E ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1}) +#define DEVID_PIIX4U ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1}) #define DEVID_VIA_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561}) #define DEVID_VP_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1}) #define DEVID_PDC20246 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246}) @@ -696,70 +696,45 @@ * ide_scan_pcibus() gets invoked at boot time from ide.c. * It finds all PCI IDE controllers and calls ide_setup_pci_device for them. */ -void __init ide_forward_scan_pcibus (void) +void __init ide_scan_pcidev (struct pci_dev *dev) { - struct pci_dev *dev; ide_pci_devid_t devid; ide_pci_device_t *d; - pci_for_each_dev(dev) { - devid.vid = dev->vendor; - devid.did = dev->device; - for (d = ide_pci_chipsets; d->devid.vid && !IDE_PCI_DEVID_EQ(d->devid, devid); ++d); - if (d->init_hwif == IDE_IGNORE) - printk("%s: ignored by ide_scan_pci_device() (uses own driver)\n", d->name); - else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_OPTI621V) && !(PCI_FUNC(dev->devfn) & 1)) - continue; /* OPTI Viper-M uses same devid for functions 0 and 1 */ - else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) && (!(PCI_FUNC(dev->devfn) & 1) || !((dev->class >> 8) == PCI_CLASS_STORAGE_IDE))) - continue; /* CY82C693 is more than only a IDE controller */ - else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886A) && !(PCI_FUNC(dev->devfn) & 1)) - continue; /* UM8886A/BF pair */ - else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366)) - hpt366_device_order_fixup(dev, d); - else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) { - if (IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL)) - printk("%s: unknown IDE controller on PCI bus %02x device %02x, VID=%04x, DID=%04x\n", - d->name, dev->bus->number, dev->devfn, devid.vid, devid.did); - else - printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); - ide_setup_pci_device(dev, d); - } + devid.vid = dev->vendor; + devid.did = dev->device; + for (d = ide_pci_chipsets; d->devid.vid && !IDE_PCI_DEVID_EQ(d->devid, devid); ++d); + if (d->init_hwif == IDE_IGNORE) + printk("%s: ignored by ide_scan_pci_device() (uses own driver)\n", d->name); + else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_OPTI621V) && !(PCI_FUNC(dev->devfn) & 1)) + return; + else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) && (!(PCI_FUNC(dev->devfn) & 1) || !((dev->class >> 8) == PCI_CLASS_STORAGE_IDE))) + return; /* CY82C693 is more than only a IDE controller */ + else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886A) && !(PCI_FUNC(dev->devfn) & 1)) + return; /* UM8886A/BF pair */ + else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366)) + hpt366_device_order_fixup(dev, d); + else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) { + if (IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL)) + printk("%s: unknown IDE controller on PCI bus %02x device %02x, VID=%04x, DID=%04x\n", + d->name, dev->bus->number, dev->devfn, devid.vid, devid.did); + else + printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); + ide_setup_pci_device(dev, d); } } -void __init ide_reverse_scan_pcibus (void) +void __init ide_scan_pcibus (int scan_direction) { - struct pci_dev *dev; - ide_pci_devid_t devid; - ide_pci_device_t *d; + struct pci_dev *dev; - pci_for_each_dev_reverse(dev) { - devid.vid = dev->vendor; - devid.did = dev->device; - for (d = ide_pci_chipsets; d->devid.vid && !IDE_PCI_DEVID_EQ(d->devid, devid); ++d); - if (d->init_hwif == IDE_IGNORE) - printk("%s: ignored by ide_scan_pci_device() (uses own driver)\n", d->name); - else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_OPTI621V) && !(PCI_FUNC(dev->devfn) & 1)) - continue; /* OPTI Viper-M uses same devid for functions 0 and 1 */ - else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) && (!(PCI_FUNC(dev->devfn) & 1) || !((dev->class >> 8) == PCI_CLASS_STORAGE_IDE))) - continue; /* CY82C693 is more than only a IDE controller */ - else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886A) && !(PCI_FUNC(dev->devfn) & 1)) - continue; /* UM8886A/BF pair */ - else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366)) - hpt366_device_order_fixup(dev, d); - else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) { - if (IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL)) - printk("%s: unknown IDE controller on PCI bus %02x device %02x, VID=%04x, DID=%04x\n", - d->name, dev->bus->number, dev->devfn, devid.vid, devid.did); - else - printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); - ide_setup_pci_device(dev, d); + if (!scan_direction) { + pci_for_each_dev(dev) { + ide_scan_pcidev(dev); + } + } else { + pci_for_each_dev_reverse(dev) { + ide_scan_pcidev(dev); } } -} - -void __init ide_scan_pcibus (int scan_direction) -{ - if (!scan_direction) ide_forward_scan_pcibus(); - else ide_reverse_scan_pcibus(); } diff -ur --new-file old/linux/drivers/block/ide-pmac.c new/linux/drivers/block/ide-pmac.c --- old/linux/drivers/block/ide-pmac.c Fri Nov 5 19:40:23 1999 +++ new/linux/drivers/block/ide-pmac.c Thu Jan 27 17:58:15 2000 @@ -241,9 +241,9 @@ * The +2 is +1 for the stop command and +1 to allow for * aligning the start address to a multiple of 16 bytes. */ - hwif->dmatable = (unsigned long *) + hwif->dmatable_cpu = (unsigned long *) kmalloc((MAX_DCMDS + 2) * sizeof(struct dbdma_cmd), GFP_KERNEL); - if (hwif->dmatable == 0) { + if (hwif->dmatable_cpu == 0) { printk(KERN_ERR "%s: unable to allocate DMA command list\n", hwif->name); return; @@ -271,7 +271,7 @@ volatile struct dbdma_regs *dma = (volatile struct dbdma_regs *) hwif->dma_base; - table = tstart = (struct dbdma_cmd *) DBDMA_ALIGN(hwif->dmatable); + table = tstart = (struct dbdma_cmd *) DBDMA_ALIGN(hwif->dmatable_cpu); out_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16); do { diff -ur --new-file old/linux/drivers/block/ide-probe.c new/linux/drivers/block/ide-probe.c --- old/linux/drivers/block/ide-probe.c Mon Jan 17 04:34:28 2000 +++ new/linux/drivers/block/ide-probe.c Mon Jan 24 20:24:50 2000 @@ -285,6 +285,7 @@ drive->name, drive->present, drive->media, (cmd == WIN_IDENTIFY) ? "ATA" : "ATAPI"); #endif + ide_delay_50ms(); /* needed for some systems (e.g. crw9624 as drive0 with disk as slave) */ SELECT_DRIVE(hwif,drive); ide_delay_50ms(); if (IN_BYTE(IDE_SELECT_REG) != drive->select.all && !drive->present) { diff -ur --new-file old/linux/drivers/block/ide-tape.c new/linux/drivers/block/ide-tape.c --- old/linux/drivers/block/ide-tape.c Fri Jan 14 09:50:53 2000 +++ new/linux/drivers/block/ide-tape.c Thu Jan 27 17:58:15 2000 @@ -384,7 +384,7 @@ * sharing a (fast) ATA-2 disk with any (slow) new ATAPI device. */ -#define IDETAPE_VERSION "1.16e" +#define IDETAPE_VERSION "1.16f" #include #include @@ -409,6 +409,9 @@ #include #include + +#define NO_LONGER_REQUIRE (1) + /* * OnStream support */ @@ -1735,7 +1738,7 @@ aux = stage->aux; p = stage->bh->b_data; if (ntohl(aux->logical_blk_num) < 11300 && ntohl(aux->logical_blk_num) > 11100) - printk(KERN_INFO "ide-tape: finished writing logical blk %lu (data %x %x %x %x)\n", ntohl(aux->logical_blk_num), *p++, *p++, *p++, *p++); + printk(KERN_INFO "ide-tape: finished writing logical blk %u (data %x %x %x %x)\n", ntohl(aux->logical_blk_num), *p++, *p++, *p++, *p++); } } #endif @@ -2695,14 +2698,14 @@ goto abort; if (clear) memset(b_data, 0, PAGE_SIZE); - if (bh->b_data == b_data + PAGE_SIZE && virt_to_bus (bh->b_data) == virt_to_bus (b_data) + PAGE_SIZE) { + if (bh->b_data == b_data + PAGE_SIZE) { bh->b_size += PAGE_SIZE; bh->b_data -= PAGE_SIZE; if (full) atomic_add(PAGE_SIZE, &bh->b_count); continue; } - if (b_data == bh->b_data + bh->b_size && virt_to_bus (b_data) == virt_to_bus (bh->b_data) + bh->b_size) { + if (b_data == bh->b_data + bh->b_size) { bh->b_size += PAGE_SIZE; if (full) atomic_add(PAGE_SIZE, &bh->b_count); @@ -2851,7 +2854,7 @@ /* * Initialize the OnStream AUX */ -static void idetape_init_stage(ide_drive_t *drive, idetape_stage_t *stage, int frame_type, int logical_blk_num) +static void idetape_init_stage (ide_drive_t *drive, idetape_stage_t *stage, int frame_type, int logical_blk_num) { idetape_tape_t *tape = drive->driver_data; os_aux_t *aux = stage->aux; @@ -2965,7 +2968,7 @@ } else { #if IDETAPE_DEBUG_LOG if (tape->debug_level >= 2) - printk (KERN_INFO "ide-tape: Block Location - %lu\n", ntohl (result->first_block)); + printk (KERN_INFO "ide-tape: Block Location - %u\n", ntohl (result->first_block)); #endif /* IDETAPE_DEBUG_LOG */ tape->partition = result->partition; tape->first_frame_position = ntohl (result->first_block); @@ -3358,7 +3361,7 @@ unsigned int block; if (tape->onstream_write_error == 1) { - printk(KERN_ERR "ide-tape: %s: detected physical bad block at %lu\n", tape->name, ntohl(tape->sense.information)); + printk(KERN_ERR "ide-tape: %s: detected physical bad block at %u\n", tape->name, ntohl(tape->sense.information)); block = ntohl(tape->sense.information) + 80; idetape_update_stats(drive); printk(KERN_ERR "ide-tape: %s: relocating %d buffered logical blocks to physical block %u\n", tape->name, tape->cur_frames, block); @@ -3490,7 +3493,7 @@ return 0; } if (ntohl(aux->format_id) != 0) { - printk(KERN_INFO "ide-tape: %s: skipping frame, format_id %lu\n", tape->name, ntohl(aux->format_id)); + printk(KERN_INFO "ide-tape: %s: skipping frame, format_id %u\n", tape->name, ntohl(aux->format_id)); return 0; } if (memcmp(aux->application_sig, tape->application_sig, 4) != 0) { @@ -3514,7 +3517,7 @@ return 0; } if (ntohs(par->wrt_pass_cntr) != tape->wrt_pass_cntr) { - printk(KERN_INFO "ide-tape: %s: skipping frame, wrt_pass_cntr %d (expected %d)(logical_blk_num %lu)\n", tape->name, ntohs(par->wrt_pass_cntr), tape->wrt_pass_cntr, ntohl(aux->logical_blk_num)); + printk(KERN_INFO "ide-tape: %s: skipping frame, wrt_pass_cntr %d (expected %d)(logical_blk_num %u)\n", tape->name, ntohs(par->wrt_pass_cntr), tape->wrt_pass_cntr, ntohl(aux->logical_blk_num)); return 0; } if (aux->frame_seq_num != aux->logical_blk_num) { @@ -3523,7 +3526,7 @@ } if (logical_blk_num != -1 && ntohl(aux->logical_blk_num) != logical_blk_num) { if (!quiet) - printk(KERN_INFO "ide-tape: %s: skipping frame, logical_blk_num %lu (expected %d)\n", tape->name, ntohl(aux->logical_blk_num), logical_blk_num); + printk(KERN_INFO "ide-tape: %s: skipping frame, logical_blk_num %u (expected %d)\n", tape->name, ntohl(aux->logical_blk_num), logical_blk_num); return 0; } if (aux->frame_type == OS_FRAME_TYPE_MARKER) { @@ -4492,7 +4495,8 @@ idetape_position_tape(drive, block, 0, 0); memset(&header, 0, sizeof(header)); strcpy(header.ident_str, "ADR_SEQ"); - header.major_rev = header.minor_rev = 2; + header.major_rev = 1; + header.minor_rev = 2; header.par_num = 1; header.partition.partition_num = OS_DATA_PARTITION; header.partition.par_desc_ver = OS_PARTITION_VERSION; @@ -5113,7 +5117,11 @@ for (block = 5; block < 10; block++) if (__idetape_analyze_headers(drive, block)) goto ok; +#if 0 + for (block = 0xbae; block < 0xbb8; block++) +#else for (block = 0xbae; block < 0xbb3; block++) +#endif if (__idetape_analyze_headers(drive, block)) goto ok; printk(KERN_ERR "ide-tape: %s: failed to find valid ADRL header\n", tape->name); @@ -5866,8 +5874,7 @@ ide_register_module (&idetape_module); MOD_DEC_USE_COUNT; #if ONSTREAM_DEBUG - if (tape->debug_level >= 6) - printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_init\n"); + printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_init\n"); #endif return 0; } diff -ur --new-file old/linux/drivers/block/ide.c new/linux/drivers/block/ide.c --- old/linux/drivers/block/ide.c Wed Jan 19 03:54:21 2000 +++ new/linux/drivers/block/ide.c Mon Jan 24 20:24:50 2000 @@ -655,14 +655,17 @@ static void pre_reset (ide_drive_t *drive) { + if (drive->driver != NULL) + DRIVER(drive)->pre_reset(drive); + if (!drive->keep_settings) { - drive->unmask = 0; - drive->io_32bit = 0; - if (drive->using_dma) + if (drive->using_dma) { (void) HWIF(drive)->dmaproc(ide_dma_off, drive); + } else { + drive->unmask = 0; + drive->io_32bit = 0; + } } - if (drive->driver != NULL) - DRIVER(drive)->pre_reset(drive); } /* @@ -901,7 +904,7 @@ try_to_flush_leftover_data(drive); } if (GET_STAT() & (BUSY_STAT|DRQ_STAT)) - rq->errors |= ERROR_RESET; /* Mmmm.. timing problem */ + OUT_BYTE(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); /* force an abort */ if (rq->errors >= ERROR_MAX) { if (drive->driver != NULL) @@ -1825,7 +1828,7 @@ revalidate_drives(); #ifdef CONFIG_KMOD if (!found && type == IDE_PROBE_MODULE) - (void) request_module("ide-probe"); + (void) request_module("ide-probe-mod"); #endif /* CONFIG_KMOD */ } diff -ur --new-file old/linux/drivers/block/ll_rw_blk.c new/linux/drivers/block/ll_rw_blk.c --- old/linux/drivers/block/ll_rw_blk.c Mon Dec 13 07:55:54 1999 +++ new/linux/drivers/block/ll_rw_blk.c Thu Jan 27 22:17:15 2000 @@ -118,11 +118,6 @@ */ int * max_sectors[MAX_BLKDEV] = { NULL, NULL, }; -/* - * Max number of segments per request - */ -int * max_segments[MAX_BLKDEV] = { NULL, NULL, }; - static inline int get_max_sectors(kdev_t dev) { if (!max_sectors[MAJOR(dev)]) @@ -130,13 +125,6 @@ return max_sectors[MAJOR(dev)][MINOR(dev)]; } -static inline int get_max_segments(kdev_t dev) -{ - if (!max_segments[MAJOR(dev)]) - return MAX_SEGMENTS; - return max_segments[MAJOR(dev)][MINOR(dev)]; -} - /* * Is called with the request spinlock aquired. * NOTE: the device-specific queue() functions @@ -167,24 +155,52 @@ q->use_plug = use_plug; } +static int ll_merge_fn(request_queue_t *q, struct request *req, + struct buffer_head *bh) +{ + if (req->bhtail->b_data + req->bhtail->b_size != bh->b_data) { + if (req->nr_segments < MAX_SEGMENTS) { + req->nr_segments++; + return 1; + } + return 0; + } + return 1; +} + +static int ll_merge_requests_fn(request_queue_t *q, struct request *req, + struct request *next) +{ + int total_segments = req->nr_segments + next->nr_segments; + + if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) + total_segments--; + + if (total_segments > MAX_SEGMENTS) + return 0; + + req->nr_segments = total_segments; + return 1; +} + void blk_init_queue(request_queue_t * q, request_fn_proc * rfn) { - q->request_fn = rfn; - q->current_request = NULL; - q->merge_fn = NULL; - q->merge_requests_fn = NULL; - q->plug_tq.sync = 0; - q->plug_tq.routine = &unplug_device; - q->plug_tq.data = q; - q->plugged = 0; + q->request_fn = rfn; + q->current_request = NULL; + q->merge_fn = ll_merge_fn; + q->merge_requests_fn = ll_merge_requests_fn; + q->plug_tq.sync = 0; + q->plug_tq.routine = unplug_device; + q->plug_tq.data = q; + q->plugged = 0; /* * These booleans describe the queue properties. We set the * default (and most common) values here. Other drivers can * use the appropriate functions to alter the queue properties. * as appropriate. */ - q->use_plug = 1; - q->head_active = 1; + q->use_plug = 1; + q->head_active = 1; } /* @@ -427,11 +443,9 @@ */ static inline void attempt_merge (request_queue_t * q, struct request *req, - int max_sectors, - int max_segments) + int max_sectors) { struct request *next = req->next; - int total_segments; if (!next) return; @@ -439,29 +453,15 @@ return; if (next->sem || req->cmd != next->cmd || req->rq_dev != next->rq_dev || req->nr_sectors + next->nr_sectors > max_sectors) return; - total_segments = req->nr_segments + next->nr_segments; - if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) - total_segments--; - if (total_segments > max_segments) - return; - if( q->merge_requests_fn != NULL ) - { - /* - * If we are not allowed to merge these requests, then - * return. If we are allowed to merge, then the count - * will have been updated to the appropriate number, - * and we shouldn't do it here too. - */ - if( !(q->merge_requests_fn)(q, req, next) ) - { - return; - } - } - else - { - req->nr_segments = total_segments; - } + /* + * If we are not allowed to merge these requests, then + * return. If we are allowed to merge, then the count + * will have been updated to the appropriate number, + * and we shouldn't do it here too. + */ + if(!(q->merge_requests_fn)(q, req, next)) + return; req->bhtail->b_reqnext = next->bh; req->bhtail = next->bhtail; @@ -478,7 +478,7 @@ { unsigned int sector, count; struct request * req; - int rw_ahead, max_req, max_sectors, max_segments; + int rw_ahead, max_req, max_sectors; unsigned long flags; count = bh->b_size >> 9; @@ -570,7 +570,6 @@ * Try to coalesce the new request with old requests */ max_sectors = get_max_sectors(bh->b_rdev); - max_segments = get_max_segments(bh->b_rdev); /* * Now we acquire the request spinlock, we have to be mega careful @@ -584,162 +583,88 @@ major != DDV_MAJOR && major != NBD_MAJOR && q->use_plug) plug_device(q); /* is atomic */ - } else switch (major) { - /* - * FIXME(eric) - this entire switch statement is going away - * soon, and we will instead key off of q->head_active to decide - * whether the top request in the queue is active on the device - * or not. - */ - case IDE0_MAJOR: /* same as HD_MAJOR */ - case IDE1_MAJOR: - case FLOPPY_MAJOR: - case IDE2_MAJOR: - case IDE3_MAJOR: - case IDE4_MAJOR: - case IDE5_MAJOR: - case IDE6_MAJOR: - case IDE7_MAJOR: - case IDE8_MAJOR: - case IDE9_MAJOR: - case ACSI_MAJOR: - case MFM_ACORN_MAJOR: + goto get_rq; + } + + if (q->head_active && !q->plugged) { /* * The scsi disk and cdrom drivers completely remove the request * from the queue when they start processing an entry. For this - * reason it is safe to continue to add links to the top entry for - * those devices. + * reason it is safe to continue to add links to the top entry + * for those devices. * * All other drivers need to jump over the first entry, as that - * entry may be busy being processed and we thus can't change it. + * entry may be busy being processed and we thus can't change + * it. */ - if (req == q->current_request) - req = req->next; - if (!req) - break; - /* fall through */ - - case SCSI_DISK0_MAJOR: - case SCSI_DISK1_MAJOR: - case SCSI_DISK2_MAJOR: - case SCSI_DISK3_MAJOR: - case SCSI_DISK4_MAJOR: - case SCSI_DISK5_MAJOR: - case SCSI_DISK6_MAJOR: - case SCSI_DISK7_MAJOR: - case SCSI_CDROM_MAJOR: - case DAC960_MAJOR+0: - case DAC960_MAJOR+1: - case DAC960_MAJOR+2: - case DAC960_MAJOR+3: - case DAC960_MAJOR+4: - case DAC960_MAJOR+5: - case DAC960_MAJOR+6: - case DAC960_MAJOR+7: - case I2O_MAJOR: - case COMPAQ_SMART2_MAJOR+0: - case COMPAQ_SMART2_MAJOR+1: - case COMPAQ_SMART2_MAJOR+2: - case COMPAQ_SMART2_MAJOR+3: - case COMPAQ_SMART2_MAJOR+4: - case COMPAQ_SMART2_MAJOR+5: - case COMPAQ_SMART2_MAJOR+6: - case COMPAQ_SMART2_MAJOR+7: + if ((req = req->next) == NULL) + goto get_rq; + } - do { - if (req->sem) - continue; - if (req->cmd != rw) - continue; - if (req->nr_sectors + count > max_sectors) - continue; - if (req->rq_dev != bh->b_rdev) + do { + if (req->sem) + continue; + if (req->cmd != rw) + continue; + if (req->nr_sectors + count > max_sectors) + continue; + if (req->rq_dev != bh->b_rdev) + continue; + /* Can we add it to the end of this request? */ + if (req->sector + req->nr_sectors == sector) { + /* + * The merge_fn is a more advanced way + * of accomplishing the same task. Instead + * of applying a fixed limit of some sort + * we instead define a function which can + * determine whether or not it is safe to + * merge the request or not. + * + * See if this queue has rules that + * may suggest that we shouldn't merge + * this + */ + if(!(q->merge_fn)(q, req, bh)) continue; - /* Can we add it to the end of this request? */ - if (req->sector + req->nr_sectors == sector) { - /* - * The merge_fn is a more advanced way - * of accomplishing the same task. Instead - * of applying a fixed limit of some sort - * we instead define a function which can - * determine whether or not it is safe to - * merge the request or not. - */ - if( q->merge_fn == NULL ) - { - if (req->bhtail->b_data + req->bhtail->b_size - != bh->b_data) { - if (req->nr_segments < max_segments) - req->nr_segments++; - else continue; - } - } - else - { - /* - * See if this queue has rules that - * may suggest that we shouldn't merge - * this - */ - if( !(q->merge_fn)(q, req, bh) ) - { - continue; - } - } - req->bhtail->b_reqnext = bh; - req->bhtail = bh; - req->nr_sectors += count; - drive_stat_acct(req, count, 0); - /* Can we now merge this req with the next? */ - attempt_merge(q, req, max_sectors, max_segments); - /* or to the beginning? */ - } else if (req->sector - count == sector) { - /* - * The merge_fn is a more advanced way - * of accomplishing the same task. Instead - * of applying a fixed limit of some sort - * we instead define a function which can - * determine whether or not it is safe to - * merge the request or not. - */ - if( q->merge_fn == NULL ) - { - if (bh->b_data + bh->b_size - != req->bh->b_data) { - if (req->nr_segments < max_segments) - req->nr_segments++; - else continue; - } - } - else - { - /* - * See if this queue has rules that - * may suggest that we shouldn't merge - * this - */ - if( !(q->merge_fn)(q, req, bh) ) - { - continue; - } - } - bh->b_reqnext = req->bh; - req->bh = bh; - req->buffer = bh->b_data; - req->current_nr_sectors = count; - req->sector = sector; - req->nr_sectors += count; - drive_stat_acct(req, count, 0); - } else + req->bhtail->b_reqnext = bh; + req->bhtail = bh; + req->nr_sectors += count; + drive_stat_acct(req, count, 0); + /* Can we now merge this req with the next? */ + attempt_merge(q, req, max_sectors); + /* or to the beginning? */ + } else if (req->sector - count == sector) { + /* + * The merge_fn is a more advanced way + * of accomplishing the same task. Instead + * of applying a fixed limit of some sort + * we instead define a function which can + * determine whether or not it is safe to + * merge the request or not. + * + * See if this queue has rules that + * may suggest that we shouldn't merge + * this + */ + if(!(q->merge_fn)(q, req, bh)) continue; + bh->b_reqnext = req->bh; + req->bh = bh; + req->buffer = bh->b_data; + req->current_nr_sectors = count; + req->sector = sector; + req->nr_sectors += count; + drive_stat_acct(req, count, 0); + } else + continue; - spin_unlock_irqrestore(&io_request_lock,flags); - return; + spin_unlock_irqrestore(&io_request_lock,flags); + return; - } while ((req = req->next) != NULL); - } + } while ((req = req->next) != NULL); /* find an unused request. */ +get_rq: req = get_request(max_req, bh->b_rdev); spin_unlock_irqrestore(&io_request_lock,flags); @@ -758,6 +683,7 @@ req->nr_sectors = count; req->current_nr_sectors = count; req->nr_segments = 1; /* Always 1 for a new request. */ + req->nr_hw_segments = 1; /* Always 1 for a new request. */ req->buffer = bh->b_data; req->sem = NULL; req->bh = bh; diff -ur --new-file old/linux/drivers/block/ns87415.c new/linux/drivers/block/ns87415.c --- old/linux/drivers/block/ns87415.c Wed Dec 15 08:03:50 1999 +++ new/linux/drivers/block/ns87415.c Thu Jan 27 17:58:15 2000 @@ -89,6 +89,7 @@ dma_stat = inb(hwif->dma_base+2); outb(inb(hwif->dma_base)&~1, hwif->dma_base); /* stop DMA */ outb(inb(hwif->dma_base)|6, hwif->dma_base); /* from ERRATA: clear the INTR & ERROR bits */ + ide_destroy_dmatable(drive); /* and free any DMA resources */ return (dma_stat & 7) != 4; /* verify good DMA status */ case ide_dma_write: case ide_dma_read: diff -ur --new-file old/linux/drivers/block/paride/Config.in new/linux/drivers/block/paride/Config.in --- old/linux/drivers/block/paride/Config.in Tue Dec 22 17:29:00 1998 +++ new/linux/drivers/block/paride/Config.in Mon Jan 24 20:21:47 2000 @@ -1,6 +1,17 @@ # # PARIDE configuration # + +# PARIDE doesn't need PARPORT, but if PARPORT is configured as a module, +# PARIDE must also be a module. The bogus CONFIG_PARIDE_PARPORT option +# controls the choices given to the user ... + +if [ "$CONFIG_PARPORT" = "y" -o "$CONFIG_PARPORT" = "n" ]; then + define_tristate CONFIG_PARIDE_PARPORT y +else + define_tristate CONFIG_PARIDE_PARPORT m +fi + comment 'Parallel IDE high-level drivers' dep_tristate ' Parallel port IDE disks' CONFIG_PARIDE_PD $CONFIG_PARIDE dep_tristate ' Parallel port ATAPI CD-ROMs' CONFIG_PARIDE_PCD $CONFIG_PARIDE diff -ur --new-file old/linux/drivers/block/piix.c new/linux/drivers/block/piix.c --- old/linux/drivers/block/piix.c Fri Jan 14 09:50:53 2000 +++ new/linux/drivers/block/piix.c Mon Jan 24 20:24:50 2000 @@ -33,11 +33,16 @@ * * 4a 84|21 hdb|hda * 4b 84|21 hdd|hdc - * - * 00|00 udma 0 - * 01|01 udma 1 - * 10|10 udma 2 - * 11|11 reserved + * + * ata-33/82371AB + * ata-33/82371EB + * ata-33/82801AB ata-66/82801AA + * 00|00 udma 0 00|00 reserved + * 01|01 udma 1 01|01 udma 3 + * 10|10 udma 2 10|10 udma 4 + * 11|11 reserved 11|11 reserved + * + * 54 8421|8421 ata66 drive|ata66 enable * * pci_read_config_word(HWIF(drive)->pci_dev, 0x40, ®40); * pci_read_config_word(HWIF(drive)->pci_dev, 0x42, ®42); @@ -195,71 +200,78 @@ struct pci_dev *dev = hwif->pci_dev; int sitre; - short reg4042, reg44, reg48, reg4a; + short reg4042, reg44, reg48, reg4a, reg54; byte speed; - int u_speed; byte maslave = hwif->channel ? 0x42 : 0x40; byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; int ultra = ((dev->device == PCI_DEVICE_ID_INTEL_82371AB) || - (dev->device == PCI_DEVICE_ID_INTEL_82801AA_1)) ? 1 : 0; - int ultra66 = (dev->device == PCI_DEVICE_ID_INTEL_82801AB_1) ? 1 : 0; + (dev->device == PCI_DEVICE_ID_INTEL_82801AB_1)) ? 1 : 0; + int ultra66 = (dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) ? 1 : 0; int drive_number = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01)); int a_speed = 2 << (drive_number * 4); int u_flag = 1 << drive_number; + int u_speed = 0; pci_read_config_word(dev, maslave, ®4042); - sitre = (reg4042 & 0x4000) ? 1 : 0; + sitre = (reg4042 & 0x4000) ? 1 : 0; pci_read_config_word(dev, 0x44, ®44); pci_read_config_word(dev, 0x48, ®48); pci_read_config_word(dev, 0x4a, ®4a); + pci_read_config_word(dev, 0x54, ®54); - if (id->dma_ultra && (ultra)) { - if (!(reg48 & u_flag)) { - pci_write_config_word(dev, 0x48, reg48|u_flag); - } - } else { - if (reg48 & u_flag) { - pci_write_config_word(dev, 0x48, reg48 & ~u_flag); - } - } - - if (((id->dma_ultra & 0x0010) || (id->dma_ultra & 0x0008) || (id->dma_ultra & 0x0004)) && (ultra)) { + if ((id->dma_ultra & 0x0010) && (ultra)) { + u_speed = 2 << (drive_number * 4); + speed = ((udma_66) && (ultra66)) ? XFER_UDMA_4 : XFER_UDMA_2; + } else if ((id->dma_ultra & 0x0008) && (ultra)) { + u_speed = 1 << (drive_number * 4); + speed = ((udma_66) && (ultra66)) ? XFER_UDMA_3 : XFER_UDMA_1; + } else if ((id->dma_ultra & 0x0004) && (ultra)) { u_speed = 2 << (drive_number * 4); - if (!(reg4a & u_speed)) { - pci_write_config_word(dev, 0x4a, reg4a|u_speed); - } speed = XFER_UDMA_2; } else if ((id->dma_ultra & 0x0002) && (ultra)) { u_speed = 1 << (drive_number * 4); - if (!(reg4a & u_speed)) { - pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); - pci_write_config_word(dev, 0x4a, reg4a|u_speed); - } speed = XFER_UDMA_1; } else if ((id->dma_ultra & 0x0001) && (ultra)) { u_speed = 0 << (drive_number * 4); - if (!(reg4a & u_speed)) { - pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); - pci_write_config_word(dev, 0x4a, reg4a|u_speed); - } speed = XFER_UDMA_0; } else if (id->dma_mword & 0x0004) { - if (reg4a & a_speed) - pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); speed = XFER_MW_DMA_2; } else if (id->dma_mword & 0x0002) { - if (reg4a & a_speed) - pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); speed = XFER_MW_DMA_1; } else if (id->dma_1word & 0x0004) { - if (reg4a & a_speed) - pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); speed = XFER_SW_DMA_2; } else { speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); } + /* + * This is !@#$% ugly and stupid............. + * But ugly harware generates ugly code......... + */ + if (speed >= XFER_UDMA_0) { + if (!(reg48 & u_flag)) + pci_write_config_word(dev, 0x48, reg48|u_flag); + if (!(reg4a & u_speed)) { + pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + pci_write_config_word(dev, 0x4a, reg4a|u_speed); + } + if ((speed > XFER_UDMA_2) && (!(reg54 & u_flag))) { + pci_write_config_word(dev, 0x54, reg54|u_flag); + } else { + pci_write_config_word(dev, 0x54, reg54 & ~u_flag); + } + } + + if (speed < XFER_UDMA_0) { + if (reg48 & u_flag) + pci_write_config_word(dev, 0x48, reg48 & ~u_flag); + if (reg4a & a_speed) + pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + if (reg54 & u_flag) + pci_write_config_word(dev, 0x54, reg54 & ~u_flag); + } + piix_tune_drive(drive, piix_dma_2_pio(speed)); (void) ide_config_drive_speed(drive, speed); @@ -301,11 +313,21 @@ return 0; } +/* + * Sheesh, someone at Intel needs to go read the ATA-4/5 T13 standards. + * It does not specify device detection, but channel!!! + * You determine later if bit 13 of word93 is set... + */ unsigned int __init ata66_piix (ide_hwif_t *hwif) { - if (0) - return 1; - return 0; + byte reg54h = 0, reg55h = 0, ata66 = 0; + byte mask = hwif->channel ? 0x0c : 0x03; + + pci_read_config_byte(hwif->pci_dev, 0x54, ®54h); + pci_read_config_byte(hwif->pci_dev, 0x55, ®55h); + ata66 = (reg54h & mask) ? 0 : 1; + + return ata66; } void __init ide_init_piix (ide_hwif_t *hwif) diff -ur --new-file old/linux/drivers/block/trm290.c new/linux/drivers/block/trm290.c --- old/linux/drivers/block/trm290.c Fri Nov 5 19:40:23 1999 +++ new/linux/drivers/block/trm290.c Thu Jan 27 17:58:15 2000 @@ -187,7 +187,7 @@ if (!(count = ide_build_dmatable(drive, func))) break; /* try PIO instead of DMA */ trm290_prepare_drive(drive, 1); /* select DMA xfer */ - outl(virt_to_bus(hwif->dmatable)|reading|writing, hwif->dma_base); + outl(hwif->dmatable_dma|reading|writing, hwif->dma_base); drive->waiting_for_dma = 1; outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */ if (drive->media != ide_disk) @@ -199,6 +199,7 @@ return 0; case ide_dma_end: drive->waiting_for_dma = 0; + ide_destroy_dmatable(drive); /* purge DMA mappings */ return (inw(hwif->dma_base+2) != 0x00ff); case ide_dma_test_irq: return (inw(hwif->dma_base+2) == 0x00ff); diff -ur --new-file old/linux/drivers/block/z2ram.c new/linux/drivers/block/z2ram.c --- old/linux/drivers/block/z2ram.c Sun Jan 9 02:41:16 2000 +++ new/linux/drivers/block/z2ram.c Wed Jan 26 21:45:20 2000 @@ -144,7 +144,7 @@ { chip_count++; z2ram_map[ z2ram_size ] = - (u_long)amiga_chip_alloc( Z2RAM_CHUNKSIZE ); + (u_long)amiga_chip_alloc( Z2RAM_CHUNKSIZE, "z2ram" ); if ( z2ram_map[ z2ram_size ] == 0 ) { diff -ur --new-file old/linux/drivers/cdrom/Config.in new/linux/drivers/cdrom/Config.in --- old/linux/drivers/cdrom/Config.in Sat Oct 2 16:35:15 1999 +++ new/linux/drivers/cdrom/Config.in Mon Jan 24 20:04:37 2000 @@ -7,9 +7,9 @@ if [ "$CONFIG_SBPCD" = "y" ]; then bool ' Matsushita/Panasonic, ... second CDROM controller support' CONFIG_SBPCD2 if [ "$CONFIG_SBPCD2" = "y" ]; then - bool ' Matsushita/Panasonic, ... third CDROM controller support' CONFIG_SBPCD3 + bool ' Matsushita/Panasonic, ... third CDROM controller support' CONFIG_SBPCD3 if [ "$CONFIG_SBPCD3" = "y" ]; then - bool ' Matsushita/Panasonic, ... fourth CDROM controller support' CONFIG_SBPCD4 + bool ' Matsushita/Panasonic, ... fourth CDROM controller support' CONFIG_SBPCD4 fi fi fi diff -ur --new-file old/linux/drivers/cdrom/cdrom.c new/linux/drivers/cdrom/cdrom.c --- old/linux/drivers/cdrom/cdrom.c Wed Jan 19 03:54:21 2000 +++ new/linux/drivers/cdrom/cdrom.c Wed Jan 26 21:25:56 2000 @@ -227,6 +227,7 @@ #include #include #include + #include #include #include @@ -353,8 +354,6 @@ cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name); cdi->next = topCdromPtr; topCdromPtr = cdi; - /*FIXME:as soon as we'll switch to real thing, pass device number here*/ - register_disk(NULL, cdi->dev, 1, &cdrom_fops, 0); return 0; } #undef ENSURE @@ -382,7 +381,6 @@ prev->next = cdi->next; else topCdromPtr = cdi->next; -/* unregister_disk(); */ cdi->ops->n_minors--; cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name); return 0; @@ -407,12 +405,10 @@ while (cdi != NULL && cdi->dev != cd_dev) cdi = cdi->next; } - + return cdi; } -static int cdrom_setup_writemode(struct cdrom_device_info *cdi); - /* We use the open-option O_NONBLOCK to indicate that the * purpose of opening is only for subsequent ioctl() calls; no device * integrity checks are performed. @@ -446,9 +442,6 @@ if (!ret) cdi->use_count++; - if (fp->f_mode & FMODE_WRITE && !cdi->write.writeable) - cdi->write.writeable = !cdrom_setup_writemode(cdi); - cdinfo(CD_OPEN, "Use count for \"/dev/%s\" now %d\n", cdi->name, cdi->use_count); /* Do this on open. Don't wait for mount, because they might not be mounting, but opening with O_NONBLOCK */ @@ -2095,8 +2088,8 @@ return -ENOTTY; } -static int cdrom_get_track_info(kdev_t dev, __u16 track, __u8 type, - track_information *ti) +int cdrom_get_track_info(kdev_t dev, __u16 track, __u8 type, + track_information *ti) { struct cdrom_device_info *cdi = cdrom_find_device(dev); struct cdrom_device_ops *cdo = cdi->ops; @@ -2118,7 +2111,7 @@ return cdo->generic_packet(cdi, &cgc); } -static int cdrom_get_disc_info(kdev_t dev, disc_information *di) +int cdrom_get_disc_info(kdev_t dev, disc_information *di) { struct cdrom_device_info *cdi = cdrom_find_device(dev); struct cdrom_device_ops *cdo = cdi->ops; @@ -2230,98 +2223,8 @@ } } -/* return the buffer size of writeable drives */ -static int cdrom_read_buffer_capacity(struct cdrom_device_info *cdi) -{ - struct cdrom_device_ops *cdo = cdi->ops; - struct cdrom_generic_command cgc; - struct { - unsigned int pad; - unsigned int buffer_size; - unsigned int buffer_free; - } buf; - int ret; - - init_cdrom_command(&cgc, &buf, 12); - cgc.cmd[0] = 0x5c; - cgc.cmd[8] = 12; - - if ((ret = cdo->generic_packet(cdi, &cgc))) - return ret; - - return be32_to_cpu(buf.buffer_size); -} - -/* return 0 if succesful and the disc can be considered writeable. */ -static int cdrom_setup_writemode(struct cdrom_device_info *cdi) -{ - struct cdrom_generic_command cgc; - write_param_page wp; - disc_information di; - track_information ti; - int ret, last_track; - - memset(&di, 0, sizeof(disc_information)); - memset(&ti, 0, sizeof(track_information)); - memset(&cdi->write, 0, sizeof(struct cdrom_write_settings)); - - if ((ret = cdrom_get_disc_info(cdi->dev, &di))) - return ret; - - last_track = (di.last_track_msb << 8) | di.last_track_lsb; - if ((ret = cdrom_get_track_info(cdi->dev, last_track, 1, &ti))) - return ret; - - /* if the media is erasable, then it is either CD-RW or - * DVD-RW - use fixed packets for those. non-erasable media - * indicated CD-R or DVD-R media, use varible sized packets for - * those (where the packet size is a bit less than the buffer - * capacity of the drive. */ - if (di.erasable) { - cdi->write.fpacket = 1; - /* FIXME: DVD-RW is 16, should get the packet size instead */ - cdi->write.packet_size = 32; - } else { - int buf_size; - cdi->write.fpacket = 0; - buf_size = cdrom_read_buffer_capacity(cdi); - buf_size -= 100*1024; - cdi->write.packet_size = buf_size / CD_FRAMESIZE; - } - - init_cdrom_command(&cgc, &wp, 0x3c); - if ((ret = cdrom_mode_sense(cdi, &cgc, GPMODE_WRITE_PARMS_PAGE, 0))) - return ret; - - /* sanity checks */ - if ((ti.damage && !ti.nwa_v) || ti.blank) { - cdinfo(CD_WARNING, "can't write to this disc\n"); - return 1; - } - - /* NWA is only for CD-R and DVD-R. -RW media is randomly - * writeable once it has been formatted. */ - cdi->write.nwa = ti.nwa_v ? be32_to_cpu(ti.next_writable) : 0; - - wp.fp = cdi->write.fpacket ? 1 : 0; - wp.track_mode = 0; - wp.write_type = 0; - wp.data_block_type = 8; - wp.session_format = 0; - wp.multi_session = 3; - wp.audio_pause = cpu_to_be16(0x96); - wp.packet_size = cdi->write.fpacket ? cpu_to_be32(cdi->write.packet_size) : 0; - wp.track_mode = 5; /* should be ok with both CD and DVD */ - - if ((ret = cdrom_mode_select(cdi, &cgc))) - return ret; - - cdinfo(CD_WARNING, "%s: writeable with %lu block %s packets\n", - cdi->name, cdi->write.packet_size, - cdi->write.fpacket ? "fixed" : "variable"); - return 0; -} - +EXPORT_SYMBOL(cdrom_get_disc_info); +EXPORT_SYMBOL(cdrom_get_track_info); EXPORT_SYMBOL(cdrom_get_next_writable); EXPORT_SYMBOL(cdrom_get_last_written); EXPORT_SYMBOL(cdrom_count_tracks); diff -ur --new-file old/linux/drivers/char/Config.in new/linux/drivers/char/Config.in --- old/linux/drivers/char/Config.in Thu Jan 20 19:44:46 2000 +++ new/linux/drivers/char/Config.in Mon Jan 24 20:04:37 2000 @@ -33,8 +33,8 @@ tristate ' Digiboard PC/Xx Support' CONFIG_DIGI fi tristate ' Hayes ESP serial port support' CONFIG_ESPSERIAL - tristate 'Moxa Intellio support' CONFIG_MOXA_INTELLIO - tristate 'Moxa SmartIO support' CONFIG_MOXA_SMARTIO + tristate ' Moxa Intellio support' CONFIG_MOXA_INTELLIO + tristate ' Moxa SmartIO support' CONFIG_MOXA_SMARTIO if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then dep_tristate ' Multi-Tech multiport card support (EXPERIMENTAL)' CONFIG_ISI m fi @@ -115,6 +115,7 @@ tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT + tristate ' Mixcom Watchdog' CONFIG_MIXCOMWD fi endmenu diff -ur --new-file old/linux/drivers/char/Makefile new/linux/drivers/char/Makefile --- old/linux/drivers/char/Makefile Thu Jan 20 19:44:46 2000 +++ new/linux/drivers/char/Makefile Wed Jan 26 21:44:21 2000 @@ -20,8 +20,8 @@ O_TARGET := char.o M_OBJS := -O_OBJS := tty_io.o n_tty.o tty_ioctl.o mem.o random.o raw.o -OX_OBJS := pty.o misc.o +O_OBJS := tty_io.o n_tty.o tty_ioctl.o mem.o raw.o +OX_OBJS := pty.o misc.o random.o KEYMAP =defkeymap.o KEYBD =pc_keyb.o @@ -29,8 +29,8 @@ SERIAL =serial.o ifeq ($(ARCH),m68k) - KEYMAP = KEYBD = + SERIAL = endif ifeq ($(ARCH),arm) @@ -312,6 +312,14 @@ else ifeq ($(CONFIG_ACQUIRE_WDT),m) M_OBJS += acquirewdt.o + endif +endif + +ifeq ($(CONFIG_MIXCOMWD),y) +O_OBJS += mixcomwd.o +else + ifeq ($(CONFIG_MIXCOMWD),m) + M_OBJS += mixcomwd.o endif endif diff -ur --new-file old/linux/drivers/char/console.c new/linux/drivers/char/console.c --- old/linux/drivers/char/console.c Tue Dec 21 00:43:01 1999 +++ new/linux/drivers/char/console.c Wed Jan 26 22:34:37 2000 @@ -92,7 +92,7 @@ #include #include #include -#include +#include #include #include @@ -205,10 +205,8 @@ #define DO_UPDATE IS_VISIBLE #endif -static int acpi_con_transition(struct acpi_dev *dev, acpi_dstate_t state); -static struct acpi_dev_info acpi_con_info - = {ACPI_SYS_DEV, ACPI_VGA_HID, acpi_con_transition}; -static struct acpi_dev *acpi_con = NULL; +static int pm_con_request(struct pm_dev *dev, pm_request_t rqst, void *data); +static struct pm_dev *pm_con = NULL; static inline unsigned short *screenpos(int currcons, int offset, int viewed) { @@ -664,8 +662,11 @@ kmalloced = 1; vc_init(currcons, video_num_lines, video_num_columns, 1); - if (!acpi_con) - acpi_con = acpi_register(&acpi_con_info, 0); + if (!pm_con) { + pm_con = pm_register(PM_SYS_DEV, + PM_SYS_VGA, + pm_con_request); + } } return 0; } @@ -2003,7 +2004,7 @@ if (!printable || test_and_set_bit(0, &printing)) return; - acpi_access(acpi_con); + pm_access(pm_con); if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1)) currcons = kmsg_redirect - 1; @@ -2162,7 +2163,7 @@ { int retval; - acpi_access(acpi_con); + pm_access(pm_con); retval = do_con_write(tty, from_user, buf, count); con_flush_chars(tty); @@ -2171,7 +2172,7 @@ static void con_put_char(struct tty_struct *tty, unsigned char ch) { - acpi_access(acpi_con); + pm_access(pm_con); do_con_write(tty, 0, &ch, 1); } @@ -2237,7 +2238,7 @@ { struct vt_struct *vt = (struct vt_struct *)tty->driver_data; - acpi_access(acpi_con); + pm_access(pm_con); set_cursor(vt->vc_num); } @@ -2820,16 +2821,14 @@ } } -static int acpi_con_transition(struct acpi_dev *dev, acpi_dstate_t state) +static int pm_con_request(struct pm_dev *dev, pm_request_t rqst, void *data) { - switch (state) + switch (rqst) { - case ACPI_D0: + case PM_RESUME: unblank_screen(); break; - case ACPI_D1: - case ACPI_D2: - case ACPI_D3: + case PM_SUSPEND: do_blank_screen(0); break; } @@ -2847,6 +2846,7 @@ EXPORT_SYMBOL(video_font_height); EXPORT_SYMBOL(video_scan_lines); EXPORT_SYMBOL(vc_resize); +EXPORT_SYMBOL(fg_console); #ifndef VT_SINGLE_DRIVER EXPORT_SYMBOL(take_over_console); diff -ur --new-file old/linux/drivers/char/dtlk.c new/linux/drivers/char/dtlk.c --- old/linux/drivers/char/dtlk.c Fri Jan 7 20:43:09 2000 +++ new/linux/drivers/char/dtlk.c Tue Jan 25 23:13:47 2000 @@ -47,13 +47,8 @@ #include #endif -#ifdef MODULE #include #include -#else -#define MOD_INC_USE_COUNT -#define MOD_DEC_USE_COUNT -#endif #define KERNEL #include @@ -66,7 +61,7 @@ #include /* for inb_p, outb_p, inb, outb, etc. */ #include /* for get_user, etc. */ #include /* for wait_queue */ -#include /* for __init */ +#include /* for __init, module_{init,exit} */ #include /* for POLLIN, etc. */ #include /* local header file for DoubleTalk values */ @@ -364,7 +359,7 @@ return 0; } -int __init dtlk_init(void) +static int __init dtlk_init(void) { dtlk_port_lpc = 0; dtlk_port_tts = 0; @@ -385,13 +380,7 @@ return 0; } -#ifdef MODULE -int init_module(void) -{ - return dtlk_init(); -} - -void cleanup_module(void) +static void __exit dtlk_cleanup (void) { dtlk_write_bytes("goodbye", 8); current->state = TASK_INTERRUPTIBLE; @@ -405,7 +394,8 @@ release_region(dtlk_port_lpc, DTLK_IO_EXTENT); } -#endif +module_init(dtlk_init); +module_exit(dtlk_cleanup); /* ------------------------------------------------------------------------ */ diff -ur --new-file old/linux/drivers/char/ftape/Config.in new/linux/drivers/char/ftape/Config.in --- old/linux/drivers/char/ftape/Config.in Wed Nov 3 23:43:54 1999 +++ new/linux/drivers/char/ftape/Config.in Mon Jan 24 20:04:37 2000 @@ -34,5 +34,9 @@ int ' Default FIFO threshold (EXPERIMENTAL)' CONFIG_FT_FDC_THR 8 int ' Maximal data rate to use (EXPERIMENTAL)' CONFIG_FT_FDC_MAX_RATE 2000 fi -comment 'ONLY for DEC Alpha architectures' -int ' CPU clock frequency of your DEC Alpha' CONFIG_FT_ALPHA_CLOCK 0 + +if [ "$ARCH" = "alpha" ]; then + int ' CPU clock frequency of your DEC Alpha' CONFIG_FT_ALPHA_CLOCK 0 +else + define_int CONFIG_FT_ALPHA_CLOCK 0 +fi diff -ur --new-file old/linux/drivers/char/h8.c new/linux/drivers/char/h8.c --- old/linux/drivers/char/h8.c Fri Jan 7 20:43:09 2000 +++ new/linux/drivers/char/h8.c Tue Jan 25 23:13:47 2000 @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -27,6 +26,8 @@ #include #include #include +#include +#include #define __KERNEL_SYSCALLS__ #include @@ -294,35 +295,7 @@ return; } -#ifdef MODULE - -int init_module(void) -{ - printk("H8 module at %X(Interrupt %d)\n", h8_base, h8_irq); - if(request_irq(h8_irq, h8_intr, SA_INTERRUPT, "h8", NULL)) - { - printk("H8: error: IRQ %d is not free.\n", h8_irq); - return -EIO; - } - - misc_register(&h8_device); - request_region(h8_base, 8, "h8"); - - create_proc_info_entry("driver/h8", 0, NULL, h8_get_info); - - QUEUE_INIT(&h8_actq, link, h8_cmd_q_t *); - QUEUE_INIT(&h8_cmdq, link, h8_cmd_q_t *); - QUEUE_INIT(&h8_freeq, link, h8_cmd_q_t *); - h8_alloc_queues(); - - h8_hw_init(); - - kernel_thread(h8_monitor_thread, NULL, 0); - - return 0; -} - -void cleanup_module(void) +static void __exit h8_cleanup (void) { remove_proc_entry("driver/h8", NULL); misc_deregister(&h8_device); @@ -330,16 +303,14 @@ free_irq(h8_irq, NULL); } -#else /* MODULE */ - -int h8_init(void) +static int __init h8_init(void) { if(request_irq(h8_irq, h8_intr, SA_INTERRUPT, "h8", NULL)) { - printk("H8: error: IRQ %d is not free\n", h8_irq); + printk(KERN_ERR "H8: error: IRQ %d is not free\n", h8_irq); return -EIO; } - printk("H8 at 0x%x IRQ %d\n", h8_base, h8_irq); + printk(KERN_INFO "H8 at 0x%x IRQ %d\n", h8_base, h8_irq); create_proc_info_entry("driver/h8", 0, NULL, h8_get_info); @@ -357,9 +328,11 @@ return 0; } -#endif /* MODULE */ -void h8_hw_init(void) +module_init(h8_init); +module_exit(h8_cleanup); + +static void __init h8_hw_init(void) { u_char buf[H8_MAX_CMD_SIZE]; diff -ur --new-file old/linux/drivers/char/keyboard.c new/linux/drivers/char/keyboard.c --- old/linux/drivers/char/keyboard.c Thu Jan 20 18:48:48 2000 +++ new/linux/drivers/char/keyboard.c Wed Jan 26 22:34:37 2000 @@ -41,7 +41,7 @@ #include #include #include -#include +#include #define SIZE(x) (sizeof(x)/sizeof((x)[0])) @@ -161,8 +161,7 @@ int sysrq_enabled = 1; #endif -static struct acpi_dev_info acpi_kbd_info = {ACPI_SYS_DEV, ACPI_KBC_HID, NULL}; -static struct acpi_dev *acpi_kbd = NULL; +static struct pm_dev *pm_kbd = NULL; /* * Many other routines do put_queue, but I think either @@ -206,7 +205,7 @@ char up_flag = down ? 0 : 0200; char raw_mode; - acpi_access(acpi_kbd); + pm_access(pm_kbd); do_poke_blanked_console = 1; mark_bh(CONSOLE_BH); @@ -932,7 +931,7 @@ init_bh(KEYBOARD_BH, kbd_bh); mark_bh(KEYBOARD_BH); - acpi_kbd = acpi_register(&acpi_kbd_info, 0); + pm_kbd = pm_register(PM_SYS_DEV, PM_SYS_KBC, NULL); return 0; } diff -ur --new-file old/linux/drivers/char/mem.c new/linux/drivers/char/mem.c --- old/linux/drivers/char/mem.c Thu Dec 30 02:13:02 1999 +++ new/linux/drivers/char/mem.c Wed Jan 26 21:44:21 2000 @@ -159,10 +159,12 @@ #elif defined(__powerpc__) prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; #elif defined(__mc68000__) - if (CPU_IS_020_OR_030) + if (MMU_IS_SUN3) + prot |= SUN3_PAGE_NOCACHE; + else if (MMU_IS_851 || MMU_IS_030) prot |= _PAGE_NOCACHE030; /* Use no-cache mode, serialized */ - if (CPU_IS_040_OR_060) + else if (MMU_IS_040 || MMU_IS_060) prot = (prot & _CACHEMASK040) | _PAGE_NOCACHE_S; #elif defined(__mips__) prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED; diff -ur --new-file old/linux/drivers/char/misc.c new/linux/drivers/char/misc.c --- old/linux/drivers/char/misc.c Tue Dec 14 01:26:27 1999 +++ new/linux/drivers/char/misc.c Tue Jan 25 23:21:07 2000 @@ -67,9 +67,6 @@ #endif extern void streamable_init(void); extern void watchdog_init(void); -extern void wdt_init(void); -extern void acq_init(void); -extern void dtlk_init(void); extern void pcwatchdog_init(void); extern int rtc_sun_init(void); /* Combines MK48T02 and MK48T08 */ extern int rtc_DP8570A_init(void); @@ -196,20 +193,8 @@ #ifdef CONFIG_PCWATCHDOG pcwatchdog_init(); #endif -#ifdef CONFIG_WDT - wdt_init(); -#endif -#ifdef CONFIG_ACQUIRE_WDT - acq_init(); -#endif #ifdef CONFIG_SOFT_WATCHDOG watchdog_init(); -#endif -#ifdef CONFIG_DTLK - dtlk_init(); -#endif -#ifdef CONFIG_H8 - h8_init(); #endif #ifdef CONFIG_MVME16x rtc_MK48T08_init(); diff -ur --new-file old/linux/drivers/char/mixcomwd.c new/linux/drivers/char/mixcomwd.c --- old/linux/drivers/char/mixcomwd.c Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/char/mixcomwd.c Sat Jan 22 21:31:10 2000 @@ -0,0 +1,250 @@ +/* + * MixCom Watchdog: A Simple Hardware Watchdog Device + * Based on Softdog driver by Alan Cox and PC Watchdog driver by Ken Hollis + * + * Author: Gergely Madarasz + * + * Copyright (c) 1999 ITConsult-Pro Co. + * + * 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. + * + * Version 0.1 (99/04/15): + * - first version + * + * Version 0.2 (99/06/16): + * - added kernel timer watchdog ping after close + * since the hardware does not support watchdog shutdown + * + * Version 0.3 (99/06/21): + * - added WDIOC_GETSTATUS and WDIOC_GETSUPPORT ioctl calls + * + * Version 0.3.1 (99/06/22): + * - allow module removal while internal timer is active, + * print warning about probable reset + * + */ + +#define VERSION "0.3.1" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int mixcomwd_ioports[] = { 0x180, 0x280, 0x380, 0x000 }; + +#define MIXCOM_WATCHDOG_OFFSET 0xc10 +#define MIXCOM_ID1 0x11 +#define MIXCOM_ID2 0x13 + +static int mixcomwd_opened; +static int mixcomwd_port; + +#ifndef CONFIG_WATCHDOG_NOWAYOUT +static int mixcomwd_timer_alive; +static struct timer_list mixcomwd_timer; +#endif + +static void mixcomwd_ping(void) +{ + outb_p(55,mixcomwd_port+MIXCOM_WATCHDOG_OFFSET); + return; +} + +#ifndef CONFIG_WATCHDOG_NOWAYOUT +static void mixcomwd_timerfun(unsigned long d) +{ + mixcomwd_ping(); + + mod_timer(&mixcomwd_timer,jiffies+ 5*HZ); +} +#endif + +/* + * Allow only one person to hold it open + */ + +static int mixcomwd_open(struct inode *inode, struct file *file) +{ + if(test_and_set_bit(0,&mixcomwd_opened)) { + return -EBUSY; + } + mixcomwd_ping(); + +#ifndef CONFIG_WATCHDOG_NOWAYOUT + if(mixcomwd_timer_alive) { + del_timer(&mixcomwd_timer); + mixcomwd_timer_alive=0; + } +#endif + MOD_INC_USE_COUNT; + + return 0; +} + +static int mixcomwd_release(struct inode *inode, struct file *file) +{ + +#ifndef CONFIG_WATCHDOG_NOWAYOUT + if(mixcomwd_timer_alive) { + printk(KERN_ERR "mixcomwd: release called while internal timer alive"); + return -EBUSY; + } + init_timer(&mixcomwd_timer); + mixcomwd_timer.expires=jiffies + 5 * HZ; + mixcomwd_timer.function=mixcomwd_timerfun; + mixcomwd_timer.data=0; + mixcomwd_timer_alive=1; + add_timer(&mixcomwd_timer); +#endif + MOD_DEC_USE_COUNT; + + clear_bit(0,&mixcomwd_opened); + return 0; +} + + +static ssize_t mixcomwd_write(struct file *file, const char *data, size_t len, loff_t *ppos) +{ + if (ppos != &file->f_pos) { + return -ESPIPE; + } + + if(len) + { + mixcomwd_ping(); + return 1; + } + return 0; +} + +static int mixcomwd_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int status; + static struct watchdog_info ident = { + WDIOF_KEEPALIVEPING, 1, "MixCOM watchdog" + }; + + switch(cmd) + { + case WDIOC_GETSTATUS: + status=mixcomwd_opened; +#ifndef CONFIG_WATCHDOG_NOWAYOUT + status|=mixcomwd_timer_alive; +#endif + if (copy_to_user((int *)arg, &status, sizeof(int))) { + return -EFAULT; + } + break; + case WDIOC_GETSUPPORT: + if (copy_to_user((struct watchdog_info *)arg, &ident, + sizeof(ident))) { + return -EFAULT; + } + break; + case WDIOC_KEEPALIVE: + mixcomwd_ping(); + break; + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static struct file_operations mixcomwd_fops= +{ + NULL, /* Seek */ + NULL, /* Read */ + mixcomwd_write, /* Write */ + NULL, /* Readdir */ + NULL, /* Select */ + mixcomwd_ioctl, /* Ioctl */ + NULL, /* MMap */ + mixcomwd_open, + NULL, /* flush */ + mixcomwd_release, + NULL, + NULL /* Fasync */ +}; + +static struct miscdevice mixcomwd_miscdev= +{ + WATCHDOG_MINOR, + "watchdog", + &mixcomwd_fops +}; + +static int __init mixcomwd_checkcard(int port) +{ + int id; + + if(check_region(port,1)) { + return 0; + } + + id=inb_p(port + MIXCOM_WATCHDOG_OFFSET) & 0x3f; + if(id!=MIXCOM_ID1 && id!=MIXCOM_ID2) { + return 0; + } + return 1; +} + + +void __init mixcomwd_init(void) +{ + int i; + int found=0; + + for (i = 0; mixcomwd_ioports[i] != 0; i++) { + if (mixcomwd_checkcard(mixcomwd_ioports[i])) { + found = 1; + mixcomwd_port = mixcomwd_ioports[i]; + break; + } + } + + if (!found) { + printk("mixcomwd: No card detected, or port not available.\n"); + return; + } + + request_region(mixcomwd_port+MIXCOM_WATCHDOG_OFFSET,1,"MixCOM watchdog"); + + misc_register(&mixcomwd_miscdev); + printk("MixCOM watchdog driver v%s, MixCOM card at 0x%3x\n",VERSION,mixcomwd_port); +} + +#ifdef MODULE +int init_module(void) +{ + mixcomwd_init(); + return 0; +} + +void cleanup_module(void) +{ +#ifndef CONFIG_WATCHDOG_NOWAYOUT + if(mixcomwd_timer_alive) { + printk(KERN_WARNING "mixcomwd: I quit now, hardware will" + " probably reboot!\n"); + del_timer(&mixcomwd_timer); + mixcomwd_timer_alive=0; + } +#endif + release_region(mixcomwd_port+MIXCOM_WATCHDOG_OFFSET,1); + misc_deregister(&mixcomwd_miscdev); +} +#endif diff -ur --new-file old/linux/drivers/char/moxa.c new/linux/drivers/char/moxa.c --- old/linux/drivers/char/moxa.c Thu Jan 20 19:44:46 2000 +++ new/linux/drivers/char/moxa.c Tue Jan 25 20:41:20 2000 @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include diff -ur --new-file old/linux/drivers/char/pc_keyb.c new/linux/drivers/char/pc_keyb.c --- old/linux/drivers/char/pc_keyb.c Wed Dec 22 19:53:57 1999 +++ new/linux/drivers/char/pc_keyb.c Fri Jan 21 22:03:02 2000 @@ -412,8 +412,11 @@ #endif } +static unsigned char kbd_exists = 1; + static inline void handle_keyboard_event(unsigned char scancode) { + kbd_exists = 1; #ifdef CONFIG_VT if (do_acknowledge(scancode)) handle_scancode(scancode, !(scancode & 0x80)); @@ -482,6 +485,8 @@ { int retries = 3; + if (!kbd_exists) return 0; + do { unsigned long timeout = KBD_TIMEOUT; @@ -497,8 +502,9 @@ mdelay(1); if (!--timeout) { #ifdef KBD_REPORT_TIMEOUTS - printk(KERN_WARNING "Keyboard timeout[2]\n"); + printk(KERN_WARNING "keyboard: Timeout - AT keyboard not present?\n"); #endif + kbd_exists = 0; return 0; } } @@ -506,6 +512,7 @@ #ifdef KBD_REPORT_TIMEOUTS printk(KERN_WARNING "keyboard: Too many NACKs -- noisy kbd cable?\n"); #endif + kbd_exists = 0; return 0; } diff -ur --new-file old/linux/drivers/char/random.c new/linux/drivers/char/random.c --- old/linux/drivers/char/random.c Thu Jan 6 19:14:36 2000 +++ new/linux/drivers/char/random.c Tue Jan 25 23:13:46 2000 @@ -235,6 +235,7 @@ #include #include +#include #include #include #include @@ -626,7 +627,7 @@ return 0; } -static void batch_entropy_store(__u32 a, __u32 b, int num) +void batch_entropy_store(u32 a, u32 b, int num) { int new; @@ -2238,3 +2239,12 @@ return (cookie - tmp[17]) & COOKIEMASK; /* Leaving the data behind */ } #endif + + + +EXPORT_SYMBOL(add_keyboard_randomness); +EXPORT_SYMBOL(add_mouse_randomness); +EXPORT_SYMBOL(add_interrupt_randomness); +EXPORT_SYMBOL(add_blkdev_randomness); +EXPORT_SYMBOL(batch_entropy_store); + diff -ur --new-file old/linux/drivers/char/rtc.c new/linux/drivers/char/rtc.c --- old/linux/drivers/char/rtc.c Tue Nov 23 21:15:29 1999 +++ new/linux/drivers/char/rtc.c Tue Jan 25 23:13:47 2000 @@ -5,8 +5,8 @@ * * This driver allows use of the real time clock (built into * nearly all computers) from user space. It exports the /dev/rtc - * interface supporting various ioctl() and also the /proc/rtc - * pseudo-file for status information. + * interface supporting various ioctl() and also the + * /proc/driver/rtc pseudo-file for status information. * * The ioctls can be used to set the interrupt behaviour and * generation rate from the RTC via IRQ 8. Then the /dev/rtc @@ -60,6 +60,7 @@ #include #include #include +#include #include #include @@ -81,6 +82,8 @@ static DECLARE_WAIT_QUEUE_HEAD(rtc_wait); +static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; + static struct timer_list rtc_irq_timer; static long long rtc_llseek(struct file *file, loff_t offset, int origin); @@ -103,7 +106,7 @@ static inline unsigned char rtc_is_updating(void); static int rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data); + int count, int *eof, void *data); /* * Bits in rtc_status. (6 bits of room for future expansion) @@ -112,7 +115,7 @@ #define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ #define RTC_TIMER_ON 0x02 /* missed irq timer active */ -static unsigned char rtc_status = 0; /* bitmapped status byte. */ +static atomic_t rtc_status = ATOMIC_INIT(0); /* bitmapped status byte. */ static unsigned long rtc_freq = 0; /* Current periodic IRQ rate */ static unsigned long rtc_irq_data = 0; /* our output to the world */ @@ -142,12 +145,15 @@ * the last read in the remainder of rtc_irq_data. */ + spin_lock (&rtc_lock); rtc_irq_data += 0x100; rtc_irq_data &= ~0xff; rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0); + spin_unlock (&rtc_lock); + wake_up_interruptible(&rtc_wait); - if (rtc_status & RTC_TIMER_ON) + if (atomic_read(&rtc_status) & RTC_TIMER_ON) mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100); } @@ -217,9 +223,10 @@ case RTC_PIE_OFF: /* Mask periodic int. enab. bit */ { mask_rtc_irq_bit(RTC_PIE); - if (rtc_status & RTC_TIMER_ON) { + if (atomic_read(&rtc_status) & RTC_TIMER_ON) { del_timer(&rtc_irq_timer); - rtc_status &= ~RTC_TIMER_ON; + atomic_set(&rtc_status, + atomic_read(&rtc_status) & ~RTC_TIMER_ON); } return 0; } @@ -233,8 +240,9 @@ if ((rtc_freq > 64) && (!capable(CAP_SYS_RESOURCE))) return -EACCES; - if (!(rtc_status & RTC_TIMER_ON)) { - rtc_status |= RTC_TIMER_ON; + if (!(atomic_read(&rtc_status) & RTC_TIMER_ON)) { + atomic_set(&rtc_status, + atomic_read(&rtc_status) | RTC_TIMER_ON); rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100; add_timer(&rtc_irq_timer); } @@ -289,8 +297,7 @@ if (sec >= 60) sec = 0xff; - save_flags(flags); - cli(); + spin_lock_irqsave(&rtc_lock, flags); if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { @@ -301,7 +308,7 @@ CMOS_WRITE(hrs, RTC_HOURS_ALARM); CMOS_WRITE(min, RTC_MINUTES_ALARM); CMOS_WRITE(sec, RTC_SECONDS_ALARM); - restore_flags(flags); + spin_unlock_irqrestore(&rtc_lock, flags); return 0; } @@ -349,8 +356,7 @@ if ((yrs -= epoch) > 255) /* They are unsigned */ return -EINVAL; - save_flags(flags); - cli(); + spin_lock_irqsave(&rtc_lock, flags); if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { if (yrs > 169) { @@ -383,7 +389,7 @@ CMOS_WRITE(save_control, RTC_CONTROL); CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - restore_flags(flags); + spin_unlock_irqrestore(&rtc_lock, flags); return 0; } case RTC_IRQP_READ: /* Read the periodic IRQ rate. */ @@ -418,12 +424,11 @@ rtc_freq = arg; - save_flags(flags); - cli(); + spin_lock_irqsave(&rtc_lock, flags); val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0; val |= (16 - tmp); CMOS_WRITE(val, RTC_FREQ_SELECT); - restore_flags(flags); + spin_unlock_irqrestore(&rtc_lock, flags); return 0; } #ifdef __alpha__ @@ -460,13 +465,18 @@ static int rtc_open(struct inode *inode, struct file *file) { - if(rtc_status & RTC_IS_OPEN) + unsigned long flags; + + if(atomic_read(&rtc_status) & RTC_IS_OPEN) return -EBUSY; MOD_INC_USE_COUNT; - rtc_status |= RTC_IS_OPEN; + atomic_set(&rtc_status, atomic_read(&rtc_status) | RTC_IS_OPEN); + + spin_lock_irqsave (&rtc_lock, flags); rtc_irq_data = 0; + spin_unlock_irqrestore (&rtc_lock, flags); return 0; } @@ -480,32 +490,40 @@ unsigned char tmp; unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&rtc_lock, flags); tmp = CMOS_READ(RTC_CONTROL); tmp &= ~RTC_PIE; tmp &= ~RTC_AIE; tmp &= ~RTC_UIE; CMOS_WRITE(tmp, RTC_CONTROL); CMOS_READ(RTC_INTR_FLAGS); - restore_flags(flags); + spin_unlock_irqrestore(&rtc_lock, flags); - if (rtc_status & RTC_TIMER_ON) { - rtc_status &= ~RTC_TIMER_ON; + if (atomic_read(&rtc_status) & RTC_TIMER_ON) { + atomic_set(&rtc_status, atomic_read(&rtc_status) & ~RTC_TIMER_ON); del_timer(&rtc_irq_timer); } MOD_DEC_USE_COUNT; + spin_lock_irqsave (&rtc_lock, flags); rtc_irq_data = 0; - rtc_status &= ~RTC_IS_OPEN; + spin_unlock_irqrestore (&rtc_lock, flags); + atomic_set(&rtc_status, atomic_read(&rtc_status) & ~RTC_IS_OPEN); return 0; } static unsigned int rtc_poll(struct file *file, poll_table *wait) { + unsigned long l, flags; + poll_wait(file, &rtc_wait, wait); - if (rtc_irq_data != 0) + + spin_lock_irqsave (&rtc_lock, flags); + l = rtc_irq_data; + spin_unlock_irqrestore (&rtc_lock, flags); + + if (l != 0) return POLLIN | POLLRDNORM; return 0; } @@ -547,7 +565,6 @@ struct linux_ebus_device *edev; #endif - printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION); #ifdef __sparc__ for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { @@ -575,20 +592,26 @@ printk("rtc: cannot register IRQ %d\n", rtc_irq); return -EIO; } - misc_register(&rtc_dev); #else + if (check_region (RTC_PORT (0), RTC_IO_EXTENT)) + { + printk(KERN_ERR "rtc: I/O port %d is not free.\n", RTC_PORT (0)); + return -EIO; + } + if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL)) { /* Yeah right, seeing as irq 8 doesn't even hit the bus. */ printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ); return -EIO; } - misc_register(&rtc_dev); - create_proc_read_entry ("rtc", 0, NULL, rtc_read_proc, NULL); - /* Check region? Naaah! Just snarf it up. */ request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc"); #endif /* __sparc__ vs. others */ + + misc_register(&rtc_dev); + create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL); + #ifdef __alpha__ rtc_freq = HZ; @@ -600,11 +623,10 @@ while (jiffies - uip_watchdog < 2*HZ/100) barrier(); - save_flags(flags); - cli(); + spin_lock_irqsave(&rtc_lock, flags); year = CMOS_READ(RTC_YEAR); ctrl = CMOS_READ(RTC_CONTROL); - restore_flags(flags); + spin_unlock_irqrestore(&rtc_lock, flags); if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) BCD_TO_BIN(year); /* This should never happen... */ @@ -621,20 +643,25 @@ #endif init_timer(&rtc_irq_timer); rtc_irq_timer.function = rtc_dropped_irq; - save_flags(flags); - cli(); + spin_lock_irqsave(&rtc_lock, flags); /* Initialize periodic freq. to CMOS reset default, which is 1024Hz */ CMOS_WRITE(((CMOS_READ(RTC_FREQ_SELECT) & 0xF0) | 0x06), RTC_FREQ_SELECT); - restore_flags(flags); + spin_unlock_irqrestore(&rtc_lock, flags); rtc_freq = 1024; + + printk(KERN_INFO "Real Time Clock Driver v" RTC_VERSION "\n"); + return 0; } static void __exit rtc_exit (void) { - /* interrupts and timer disabled at this point by rtc_release */ + /* interrupts and maybe timer disabled at this point by rtc_release */ + + if (atomic_read(&rtc_status) & RTC_TIMER_ON) + del_timer(&rtc_irq_timer); - remove_proc_entry ("rtc", NULL); + remove_proc_entry ("driver/rtc", NULL); misc_deregister(&rtc_dev); #ifdef __sparc__ @@ -668,30 +695,30 @@ printk(KERN_INFO "rtc: lost some interrupts at %ldHz.\n", rtc_freq); mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100); - save_flags(flags); - cli(); + spin_lock_irqsave(&rtc_lock, flags); rtc_irq_data += ((rtc_freq/HZ)<<8); rtc_irq_data &= ~0xff; rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0); /* restart */ - restore_flags(flags); + spin_unlock_irqrestore(&rtc_lock, flags); } /* - * Info exported via "/proc/rtc". + * Info exported via "/proc/driver/rtc". */ -static int rtc_get_status(char *buf) +static int rtc_proc_output (char *buf) { +#define YN(bit) ((ctrl & bit) ? "yes" : "no") +#define NY(bit) ((ctrl & bit) ? "no" : "yes") char *p; struct rtc_time tm; unsigned char batt, ctrl; unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&rtc_lock, flags); batt = CMOS_READ(RTC_VALID) & RTC_VRT; ctrl = CMOS_READ(RTC_CONTROL); - restore_flags(flags); + spin_unlock_irqrestore(&rtc_lock, flags); p = buf; @@ -741,23 +768,25 @@ "periodic_IRQ\t: %s\n" "periodic_freq\t: %ld\n" "batt_status\t: %s\n", - (ctrl & RTC_DST_EN) ? "yes" : "no", - (ctrl & RTC_DM_BINARY) ? "no" : "yes", - (ctrl & RTC_24H) ? "yes" : "no", - (ctrl & RTC_SQWE) ? "yes" : "no", - (ctrl & RTC_AIE) ? "yes" : "no", - (ctrl & RTC_UIE) ? "yes" : "no", - (ctrl & RTC_PIE) ? "yes" : "no", + YN(RTC_DST_EN), + NY(RTC_DM_BINARY), + YN(RTC_24H), + YN(RTC_SQWE), + YN(RTC_AIE), + YN(RTC_UIE), + YN(RTC_PIE), rtc_freq, batt ? "okay" : "dead"); return p - buf; +#undef YN +#undef NY } static int rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) + int count, int *eof, void *data) { - int len = rtc_get_status(page); + int len = rtc_proc_output (page); if (len <= off+count) *eof = 1; *start = page + off; len -= off; @@ -774,10 +803,9 @@ unsigned long flags; unsigned char uip; - save_flags(flags); - cli(); + spin_lock_irqsave(&rtc_lock, flags); uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP); - restore_flags(flags); + spin_unlock_irqrestore(&rtc_lock, flags); return uip; } @@ -807,8 +835,7 @@ * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated * by the RTC when initially set to a non-zero value. */ - save_flags(flags); - cli(); + spin_lock_irqsave(&rtc_lock, flags); rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); rtc_tm->tm_hour = CMOS_READ(RTC_HOURS); @@ -816,7 +843,7 @@ rtc_tm->tm_mon = CMOS_READ(RTC_MONTH); rtc_tm->tm_year = CMOS_READ(RTC_YEAR); ctrl = CMOS_READ(RTC_CONTROL); - restore_flags(flags); + spin_unlock_irqrestore(&rtc_lock, flags); if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { @@ -847,13 +874,12 @@ * Only the values that we read from the RTC are set. That * means only tm_hour, tm_min, and tm_sec. */ - save_flags(flags); - cli(); + spin_lock_irqsave(&rtc_lock, flags); alm_tm->tm_sec = CMOS_READ(RTC_SECONDS_ALARM); alm_tm->tm_min = CMOS_READ(RTC_MINUTES_ALARM); alm_tm->tm_hour = CMOS_READ(RTC_HOURS_ALARM); ctrl = CMOS_READ(RTC_CONTROL); - restore_flags(flags); + spin_unlock_irqrestore(&rtc_lock, flags); if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { @@ -873,19 +899,18 @@ * meddles with the interrupt enable/disable bits. */ -void mask_rtc_irq_bit(unsigned char bit) +static void mask_rtc_irq_bit(unsigned char bit) { unsigned char val; unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&rtc_lock, flags); val = CMOS_READ(RTC_CONTROL); val &= ~bit; CMOS_WRITE(val, RTC_CONTROL); CMOS_READ(RTC_INTR_FLAGS); - restore_flags(flags); rtc_irq_data = 0; + spin_unlock_irqrestore(&rtc_lock, flags); } static void set_rtc_irq_bit(unsigned char bit) @@ -893,12 +918,11 @@ unsigned char val; unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&rtc_lock, flags); val = CMOS_READ(RTC_CONTROL); val |= bit; CMOS_WRITE(val, RTC_CONTROL); CMOS_READ(RTC_INTR_FLAGS); rtc_irq_data = 0; - restore_flags(flags); + spin_unlock_irqrestore(&rtc_lock, flags); } diff -ur --new-file old/linux/drivers/char/saa5249.c new/linux/drivers/char/saa5249.c --- old/linux/drivers/char/saa5249.c Thu Dec 16 22:59:38 1999 +++ new/linux/drivers/char/saa5249.c Sat Jan 22 21:31:10 2000 @@ -50,7 +50,7 @@ #include #include #include -#include +#include #include #include @@ -101,7 +101,7 @@ int is_searching[NUM_DAUS]; int disp_mode; int virtual_mode; - struct i2c_bus *bus; + struct i2c_client *client; }; @@ -109,7 +109,6 @@ #define CCTRD 35 #define NOACK_REPEAT 10 /* Retry access this many times on failure */ #define CLEAR_DELAY (HZ/20) /* Time required to clear a page */ -#define I2C_TIMEOUT (3*HZ) /* open/close/SDA-check timeout */ #define READY_TIMEOUT (30*HZ/1000) /* Time to wait for ready signal of I²C-bus interface */ #define INIT_DELAY 500 /* Time in usec to wait at initialization of CEA interface */ #define START_DELAY 10 /* Time in usec to wait before starting write-cycle (CEA) */ @@ -135,45 +134,60 @@ static struct video_device saa_template; /* Declared near bottom */ -/* - * We do most of the hard work when we become a device on the i2c. - */ - -static int saa5249_attach(struct i2c_device *device) +/* Addresses to scan */ +static unsigned short normal_i2c[] = {34>>1,I2C_CLIENT_END}; +static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; +static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; + +static struct i2c_client_address_data addr_data = { + normal_i2c, normal_i2c_range, + probe, probe_range, + ignore, ignore_range, + force +}; + +static struct i2c_client client_template; + +static int saa5249_attach(struct i2c_adapter *adap, int addr, unsigned short flags, int kind) { int pgbuf; int err; + struct i2c_client *client; struct video_device *vd; struct saa5249_device *t; - /* Only attach these chips to the BT848 bus for now */ - - if(device->bus->id!=I2C_BUSID_BT848) - return -EINVAL; - - strcpy(device->name, IF_NAME); + + printk(KERN_INFO "saa5249: teletext chip found.\n"); + client=kmalloc(sizeof(*client), GFP_KERNEL); + if(client==NULL) + return -ENOMEM; + client_template.adapter = adap; + client_template.addr = addr; + memcpy(client, &client_template, sizeof(*client)); + t = kmalloc(sizeof(*t), GFP_KERNEL); + if(t==NULL) + { + kfree(client); + return -ENOMEM; + } + memset(t, 0, sizeof(*t)); + strcpy(client->name, IF_NAME); /* * Now create a video4linux device */ - vd=(struct video_device *)kmalloc(sizeof(struct video_device), GFP_KERNEL); + client->data = vd=(struct video_device *)kmalloc(sizeof(struct video_device), GFP_KERNEL); if(vd==NULL) - return -ENOMEM; - - memcpy(vd, &saa_template, sizeof(*vd)); - - /* - * Attach an saa5249 device - */ - - t=(struct saa5249_device *)kmalloc(sizeof(struct saa5249_device), GFP_KERNEL); - if(t==NULL) { - kfree(vd); + kfree(t); + kfree(client); return -ENOMEM; } - - memset(t, 0, sizeof(*t)); + memcpy(vd, &saa_template, sizeof(*vd)); for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { @@ -186,7 +200,6 @@ t->is_searching[pgbuf] = FALSE; } vd->priv=t; - device->data=vd; /* * Register it @@ -196,22 +209,43 @@ { kfree(t); kfree(vd); + kfree(client); return err; } - t->bus = device->bus; + t->client = client; + i2c_attach_client(client); + MOD_INC_USE_COUNT; + return 0; +} + +/* + * We do most of the hard work when we become a device on the i2c. + */ + +static int saa5249_probe(struct i2c_adapter *adap) +{ + /* Only attach these chips to the BT848 bus for now */ + + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) + { + return i2c_probe(adap, &addr_data, saa5249_attach); + } return 0; } -static int saa5249_detach(struct i2c_device *device) +static int saa5249_detach(struct i2c_client *client) { - struct video_device *vd=device->data; + struct video_device *vd=client->data; + i2c_detach_client(client); video_unregister_device(vd); kfree(vd->priv); kfree(vd); + kfree(client); + MOD_DEC_USE_COUNT; return 0; } -static int saa5249_command(struct i2c_device *device, +static int saa5249_command(struct i2c_client *device, unsigned int cmd, void *arg) { return -EINVAL; @@ -223,12 +257,21 @@ { IF_NAME, /* name */ I2C_DRIVERID_VIDEOTEXT, /* in i2c.h */ - 34, 35, /* Addr range */ - saa5249_attach, + I2C_DF_NOTIFY, + saa5249_probe, saa5249_detach, saa5249_command }; +static struct i2c_client client_template = { + "(unset)", + -1, + 0, + 0, + NULL, + &i2c_driver_videotext +}; + /* * Wait the given number of jiffies (10ms). This calls the scheduler, so the actual * delay may be longer. @@ -252,109 +295,46 @@ } -/* Send arbitrary number of bytes to I²C-bus. Start & stop handshaking is done by this routine. - * adr should be address of I²C-device, varargs-list of values to send must be terminated by -1 - * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise +/* + * I2C interfaces */ - -static int i2c_senddata(struct saa5249_device *t, int adr, ...) + +static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data) { - int val, loop; - va_list argp; - - for (loop = 0; loop <= NOACK_REPEAT; loop++) - { - i2c_start(t->bus); - if (i2c_sendbyte(t->bus, adr, 0) != 0) - goto loopend; - - va_start(argp, adr); - while ((val = va_arg(argp, int)) != -1) - { - if (val < 0 || val > 255) - { - printk(KERN_ERR "vtx: internal error in i2c_senddata\n"); - break; - } - if (i2c_sendbyte(t->bus, val, 0) != 0) - goto loopend; - } - va_end(argp); - i2c_stop(t->bus); + char buf[64]; + + buf[0] = reg; + memcpy(buf+1, data, count); + + if(i2c_master_send(t->client, buf, count+1)==count+1) return 0; -loopend: - i2c_stop(t->bus); - } - va_end(argp); return -1; } - -/* Send count number of bytes from buffer buf to I²C-device adr. Start & stop handshaking is - * done by this routine. If uaccess is TRUE, data is read from user-space with get_user. - * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise - */ - -static int i2c_sendbuf(struct saa5249_device *t, int adr, int reg, int count, u8 *buf, int uaccess) +static int i2c_senddata(struct saa5249_device *t, ...) { - int pos, loop; - u8 val; - - for (loop = 0; loop <= NOACK_REPEAT; loop++) - { - i2c_start(t->bus); - if (i2c_sendbyte(t->bus, adr, 0) != 0 || i2c_sendbyte(t->bus, reg, 0) != 0) - goto loopend; - for (pos = 0; pos < count; pos++) - { - /* FIXME: FAULT WITH CLI/SPINLOCK ?? */ - if (uaccess) - get_user(val, buf + pos); - else - val = buf[pos]; - if (i2c_sendbyte(t->bus, val, 0) != 0) - goto loopend; - RESCHED; - } - i2c_stop(t->bus); - return 0; -loopend: - i2c_stop(t->bus); - } - return -1; + unsigned char buf[64]; + int v; + int ct=0; + va_list argp; + va_start(argp,t); + + while((v=va_arg(argp,int))!=-1) + buf[ct++]=v; + return i2c_sendbuf(t, buf[0], ct-1, buf+1); } - /* Get count number of bytes from I²C-device at address adr, store them in buf. Start & stop * handshaking is done by this routine, ack will be sent after the last byte to inhibit further * sending of data. If uaccess is TRUE, data is written to user-space with put_user. * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise */ -static int i2c_getdata(struct saa5249_device *t, int adr, int count, u8 *buf, int uaccess) +static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf) { - int pos, loop, val; - - for (loop = 0; loop <= NOACK_REPEAT; loop++) - { - i2c_start(t->bus); - if (i2c_sendbyte(t->bus, adr, 1) != 0) - goto loopend; - for (pos = 0; pos < count; pos++) - { - val = i2c_readbyte(t->bus, (pos==count-1) ? 1 : 0); - if (uaccess) - put_user(val, buf + pos); - else - buf[pos] = val; - RESCHED; - } - i2c_stop(t->bus); - return 0; -loopend: - i2c_stop(t->bus); - } - return -1; + if(i2c_master_recv(t->client, buf, count)!=count) + return -1; + return 0; } @@ -449,41 +429,41 @@ return -EINVAL; if (!t->vdau[req.pgbuf].stopped) { - if (i2c_senddata(t, CCTWR, 2, 0, -1) || - i2c_sendbuf(t, CCTWR, 3, sizeof(t->vdau[0].sregs), t->vdau[req.pgbuf].sregs, FALSE) || - i2c_senddata(t, CCTWR, 8, 0, 25, 0, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', -1) || - i2c_senddata(t, CCTWR, 2, 0, t->vdau[req.pgbuf].sregs[0] | 8, -1) || - i2c_senddata(t, CCTWR, 8, 0, 25, 0, -1)) + if (i2c_senddata(t, 2, 0, -1) || + i2c_sendbuf(t, 3, sizeof(t->vdau[0].sregs), t->vdau[req.pgbuf].sregs) || + i2c_senddata(t, 8, 0, 25, 0, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', -1) || + i2c_senddata(t, 2, 0, t->vdau[req.pgbuf].sregs[0] | 8, -1) || + i2c_senddata(t, 8, 0, 25, 0, -1)) return -EIO; jdelay(PAGE_WAIT); - if (i2c_getdata(t, CCTRD, 10, infobits, FALSE)) + if (i2c_getdata(t, 10, infobits)) return -EIO; if (!(infobits[8] & 0x10) && !(infobits[7] & 0xf0) && /* check FOUND-bit */ (memcmp(infobits, t->vdau[req.pgbuf].laststat, sizeof(infobits)) || time_after_eq(jiffies, t->vdau[req.pgbuf].expire))) { /* check if new page arrived */ - if (i2c_senddata(t, CCTWR, 8, 0, 0, 0, -1) || - i2c_getdata(t, CCTRD, VTX_PAGESIZE, t->vdau[req.pgbuf].pgbuf, FALSE)) + if (i2c_senddata(t, 8, 0, 0, 0, -1) || + i2c_getdata(t, VTX_PAGESIZE, t->vdau[req.pgbuf].pgbuf)) return -EIO; t->vdau[req.pgbuf].expire = jiffies + PGBUF_EXPIRE; memset(t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE, ' ', VTX_VIRTUALSIZE - VTX_PAGESIZE); if (t->virtual_mode) { /* Packet X/24 */ - if (i2c_senddata(t, CCTWR, 8, 0, 0x20, 0, -1) || - i2c_getdata(t, CCTRD, 40, t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE + 20 * 40, FALSE)) + if (i2c_senddata(t, 8, 0, 0x20, 0, -1) || + i2c_getdata(t, 40, t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE + 20 * 40)) return -EIO; /* Packet X/27/0 */ - if (i2c_senddata(t, CCTWR, 8, 0, 0x21, 0, -1) || - i2c_getdata(t, CCTRD, 40, t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE + 16 * 40, FALSE)) + if (i2c_senddata(t, 8, 0, 0x21, 0, -1) || + i2c_getdata(t, 40, t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE + 16 * 40)) return -EIO; /* Packet 8/30/0...8/30/15 * FIXME: AFAIK, the 5249 does hamming-decoding for some bytes in packet 8/30, * so we should undo this here. */ - if (i2c_senddata(t, CCTWR, 8, 0, 0x22, 0, -1) || - i2c_getdata(t, CCTRD, 40, t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE + 23 * 40, FALSE)) + if (i2c_senddata(t, 8, 0, 0x22, 0, -1) || + i2c_getdata(t, 40, t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE + 23 * 40)) return -EIO; } t->vdau[req.pgbuf].clrfound = FALSE; @@ -554,20 +534,30 @@ if (req.start <= 39 && req.end >= 32) { + int len; + char buf[16]; start = MAX(req.start, 32); end = MIN(req.end, 39); - if (i2c_senddata(t, CCTWR, 8, 0, 0, start, -1) || - i2c_getdata(t, CCTRD, end - start + 1, req.buffer + start - req.start, TRUE)) + len=end-start+1; + if (i2c_senddata(t, 8, 0, 0, start, -1) || + i2c_getdata(t, len, buf)) return -EIO; + if(copy_to_user(req.buffer+start-req.start, buf, len)) + return -EFAULT; } /* Insert the current header if DAU is still searching for a page */ if (req.start <= 31 && req.end >= 7 && t->is_searching[req.pgbuf]) { + char buf[32]; + int len; start = MAX(req.start, 7); end = MIN(req.end, 31); - if (i2c_senddata(t, CCTWR, 8, 0, 0, start, -1) || - i2c_getdata(t, CCTRD, end - start + 1, req.buffer + start - req.start, TRUE)) + len=end-start+1; + if (i2c_senddata(t, 8, 0, 0, start, -1) || + i2c_getdata(t, len, buf)) return -EIO; + if(copy_to_user(req.buffer+start-req.start, buf, len)) + return -EFAULT; } return 0; } @@ -592,11 +582,11 @@ case VTXIOCCLRCACHE: { - if (i2c_senddata(t ,CCTWR, 0, NUM_DAUS, 0, 8, -1) || i2c_senddata(t, CCTWR, 11, + if (i2c_senddata(t, 0, NUM_DAUS, 0, 8, -1) || i2c_senddata(t, 11, ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', -1)) return -EIO; - if (i2c_senddata(t, CCTWR, 3, 0x20, -1)) + if (i2c_senddata(t, 3, 0x20, -1)) return -EIO; jdelay(10 * CLEAR_DELAY); /* I have no idea how long we have to wait here */ return 0; @@ -618,14 +608,14 @@ struct saa5249_device *t=vd->priv; int pgbuf; - if (t->bus==NULL) + if (t->client==NULL) return -ENODEV; - if (i2c_senddata(t, CCTWR, 0, 0, -1) || /* Select R11 */ + if (i2c_senddata(t, 0, 0, -1) || /* Select R11 */ /* Turn off parity checks (we do this ourselves) */ - i2c_senddata(t, CCTWR, 1, disp_modes[t->disp_mode][0], 0, -1) || + i2c_senddata(t, 1, disp_modes[t->disp_mode][0], 0, -1) || /* Display TV-picture, no virtual rows */ - i2c_senddata(t, CCTWR, 4, NUM_DAUS, disp_modes[t->disp_mode][1], disp_modes[t->disp_mode][2], 7, -1)) /* Set display to page 4 */ + i2c_senddata(t, 4, NUM_DAUS, disp_modes[t->disp_mode][1], disp_modes[t->disp_mode][2], 7, -1)) /* Set display to page 4 */ { return -EIO; @@ -651,8 +641,8 @@ static void saa5249_release(struct video_device *vd) { struct saa5249_device *t=vd->priv; - i2c_senddata(t, CCTWR, 1, 0x20, -1); /* Turn off CCT */ - i2c_senddata(t, CCTWR, 5, 3, 3, -1); /* Turn off TV-display */ + i2c_senddata(t, 1, 0x20, -1); /* Turn off CCT */ + i2c_senddata(t, 5, 3, 3, -1); /* Turn off TV-display */ MOD_DEC_USE_COUNT; return; } @@ -666,12 +656,12 @@ { printk(KERN_INFO "SAA5249 driver (" IF_NAME " interface) for VideoText version %d.%d\n", VTX_VER_MAJ, VTX_VER_MIN); - return i2c_register_driver(&i2c_driver_videotext); + return i2c_add_driver(&i2c_driver_videotext); } static void __exit cleanup_saa_5249 (void) { - i2c_unregister_driver(&i2c_driver_videotext); + i2c_del_driver(&i2c_driver_videotext); } module_init(init_saa_5249); diff -ur --new-file old/linux/drivers/char/serial.c new/linux/drivers/char/serial.c --- old/linux/drivers/char/serial.c Fri Jan 7 20:43:09 2000 +++ new/linux/drivers/char/serial.c Fri Jan 28 01:40:09 2000 @@ -44,8 +44,8 @@ * int rs_init(void); */ -static char *serial_version = "4.91"; -static char *serial_revdate = "1999-11-17"; +static char *serial_version = "4.92"; +static char *serial_revdate = "2000-1-27"; /* * Serial driver configuration section. Here are the various options: @@ -74,12 +74,10 @@ #include #include -#include #undef SERIAL_PARANOIA_CHECK #define CONFIG_SERIAL_NOPAUSE_IO #define SERIAL_DO_RESTART -#define CONFIG_SERIAL_PCI_MEMMAPPED #if 0 /* These defines are normally controlled by the autoconf.h */ @@ -100,6 +98,12 @@ #endif #endif +#ifdef CONFIG_ISAPNP +#ifndef ENABLE_SERIAL_PNP +#define ENABLE_SERIAL_PNP +#endif +#endif + /* Set of debugging defines */ #undef SERIAL_DEBUG_INTR @@ -133,31 +137,13 @@ #define SERIAL_INLINE #endif -#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) -#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ - kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s) -#else -#define DBG_CNT(s) -#endif - /* * End of serial driver configuration section. */ -#define NEW_MODULES -#ifdef LOCAL_HEADERS /* We're building standalone */ -#define MODULE -#endif - -#ifdef NEW_MODULES #ifdef MODVERSIONS #include #endif -#else /* !NEW_MODULES */ -#ifdef MODVERSIONS -#define MODULE -#endif -#endif /* NEW_MODULES */ #include #include @@ -198,13 +184,19 @@ #ifdef ENABLE_SERIAL_PCI #include #endif +#ifdef ENABLE_SERIAL_PNP +#include +#endif +#ifdef CONFIG_MAGIC_SYSRQ +#include +#endif /* * All of the compatibilty code so we can compile serial.c against * older kernels is hidden in serial_compat.h */ -#if (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */ -#include "serial_compat.h" +#if defined(LOCAL_HEADERS) || (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */ +#include "serial_compat.h" #endif #include @@ -276,7 +268,7 @@ UART_STARTECH }, { "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO}, { "Startech", 1, 0}, /* usurped by cyclades.c */ - { "16C950", 128, UART_CLEAR_FIFO | UART_USE_FIFO}, + { "16C950/954", 128, UART_CLEAR_FIFO | UART_USE_FIFO}, { "ST16654", 64, UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH }, { "XR16850", 128, UART_CLEAR_FIFO | UART_USE_FIFO | @@ -290,16 +282,35 @@ #define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) -#ifdef ENABLE_SERIAL_PCI +#if (defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)) #define NR_PCI_BOARDS 8 +#ifdef MODULE +/* We don't unregister PCI boards right now */ static struct pci_board_inst serial_pci_board[NR_PCI_BOARDS]; static int serial_pci_board_idx = 0; -#ifdef PCI_NUM_RESOURCES +#endif +#ifndef PCI_BASE_ADDRESS #define PCI_BASE_ADDRESS(dev, r) ((dev)->resource[r].start) -#else -#define PCI_BASE_ADDRESS(dev, r) ((dev)->base_address[r]) +#define PCI_BASE_REGION_SIZE(dev, r) ((dev)->resource[r].end - \ + (dev)->resource[r].start) +#define IS_PCI_REGION_IOPORT(dev, r) ((dev)->resource[r].flags & \ + IORESOURCE_IO) +#endif +#ifndef PCI_IRQ_RESOURCE +#define PCI_IRQ_RESOURCE(dev, r) ((dev)->irq_resource[r].start) +#endif +#ifndef pci_get_subvendor +#define pci_get_subvendor(dev) ((dev)->subsystem_vendor) +#define pci_get_subdevice(dev) ((dev)->subsystem_device) +#endif +#endif /* ENABLE_SERIAL_PCI || ENABLE_SERIAL_PNP */ + +#ifndef PREPARE_FUNC +#define PREPARE_FUNC(dev) (dev->prepare) +#define ACTIVATE_FUNC(dev) (dev->activate) +#define DEACTIVATE_FUNC(dev) (dev->deactivate) #endif -#endif /* ENABLE_SERIAL_PCI */ + static struct tty_struct *serial_table[NR_PORTS]; static struct termios *serial_termios[NR_PORTS]; @@ -309,6 +320,13 @@ #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif +#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) +#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ + kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s) +#else +#define DBG_CNT(s) +#endif + /* * tmp_buf is used as a temporary buffer by serial_write. We need to * lock it in case the copy_from_user blocks while swapping in a page, @@ -355,11 +373,9 @@ outb(info->hub6 - 1 + offset, info->port); return inb(info->port+1); #endif -#ifdef CONFIG_SERIAL_PCI_MEMMAPPED case SERIAL_IO_MEM: return readb(info->iomem_base + (offset<iomem_reg_shift)); -#endif #ifdef CONFIG_SERIAL_GSC case SERIAL_IO_GSC: return gsc_readb(info->iomem_base + offset); @@ -379,12 +395,10 @@ outb(value, info->port+1); break; #endif -#ifdef CONFIG_SERIAL_PCI_MEMMAPPED case SERIAL_IO_MEM: writeb(value, info->iomem_base + (offset<iomem_reg_shift)); break; -#endif #ifdef CONFIG_SERIAL_GSC case SERIAL_IO_GSC: gsc_writeb(value, info->iomem_base + offset); @@ -905,11 +919,16 @@ continue; info = IRQ_ports[irq]; + /* + * The user was a bonehead, and misconfigured their + * multiport info. Rather than lock up the kernel + * in an infinite loop, if we loop too many times, + * print a message and break out of the loop. + */ if (pass_counter++ > RS_ISR_PASS_LIMIT) { -#if 1 - printk("rs_multi loop break\n"); -#endif - break; /* Prevent infinite loops */ + printk("Misconfigured multiport serial info " + "for irq %d. Breaking out irq loop\n", irq); + break; } if (multi->port_monitor) printk("rs port monitor irq %d: 0x%x, 0x%x\n", @@ -1540,6 +1559,15 @@ /* As a last resort, if the quotient is zero, default to 9600 bps */ if (!quot) quot = baud_base / 9600; + /* + * Work around a bug in the Oxford Semiconductor 952 rev B + * chip which causes it to seriously miscalculate baud rates + * when DLL is 0. + */ + if (((quot & 0xFF) == 0) && (info->state->type == PORT_16C950) && + (info->state->revision == 0x5202)) + quot++; + info->quot = quot; info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base); info->timeout += HZ/50; /* Add .02 seconds of slop */ @@ -2090,6 +2118,8 @@ if (arg & TIOCM_OUT2) info->MCR |= UART_MCR_OUT2; #endif + if (arg & TIOCM_LOOP) + info->MCR |= UART_MCR_LOOP; break; case TIOCMBIC: if (arg & TIOCM_RTS) @@ -2102,6 +2132,8 @@ if (arg & TIOCM_OUT2) info->MCR &= ~UART_MCR_OUT2; #endif + if (arg & TIOCM_LOOP) + info->MCR &= ~UART_MCR_LOOP; break; case TIOCMSET: info->MCR = ((info->MCR & ~(UART_MCR_RTS | @@ -2109,12 +2141,14 @@ UART_MCR_OUT1 | UART_MCR_OUT2 | #endif + UART_MCR_LOOP | UART_MCR_DTR)) | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0) #ifdef TIOCM_OUT1 | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0) | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0) #endif + | ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0) | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0)); break; default: @@ -2579,6 +2613,7 @@ return; } info->flags |= ASYNC_CLOSING; + restore_flags(flags); /* * Save the termios structure, since this port may have * separate termios for callout and dialin. @@ -2630,7 +2665,6 @@ ASYNC_CLOSING); wake_up_interruptible(&info->close_wait); MOD_DEC_USE_COUNT; - restore_flags(flags); } /* @@ -2712,6 +2746,8 @@ state = info->state; rs_flush_buffer(tty); + if (info->flags & ASYNC_CLOSING) + return; shutdown(info); info->event = 0; state->count = 0; @@ -2884,10 +2920,8 @@ info->port = sstate->port; info->flags = sstate->flags; info->io_type = sstate->io_type; -#ifdef CONFIG_SERIAL_PCI_MEMMAPPED info->iomem_base = sstate->iomem_base; info->iomem_reg_shift = sstate->iomem_reg_shift; -#endif info->xmit_fifo_size = sstate->xmit_fifo_size; info->line = line; info->tqueue.routine = do_softint; @@ -3123,43 +3157,47 @@ * number, and identifies which options were configured into this * driver. */ -static _INLINE_ void show_serial_version(void) -{ - printk(KERN_INFO "%s version %s%s (%s) with", serial_name, - serial_version, LOCAL_VERSTRING, serial_revdate); +static char serial_options[] __initdata = #ifdef CONFIG_HUB6 - printk(" HUB-6"); + " HUB-6" #define SERIAL_OPT #endif #ifdef CONFIG_SERIAL_MANY_PORTS - printk(" MANY_PORTS"); + " MANY_PORTS" #define SERIAL_OPT #endif #ifdef CONFIG_SERIAL_MULTIPORT - printk(" MULTIPORT"); + " MULTIPORT" #define SERIAL_OPT #endif #ifdef CONFIG_SERIAL_SHARE_IRQ - printk(" SHARE_IRQ"); + " SHARE_IRQ" #define SERIAL_OPT #endif #ifdef CONFIG_SERIAL_DETECT_IRQ - printk(" DETECT_IRQ"); + " DETECT_IRQ" #define SERIAL_OPT #endif #ifdef ENABLE_SERIAL_PCI - printk(" SERIAL_PCI"); -#ifdef CONFIG_SERIAL_PCI_MEMMAPPED - printk(" PCI_IOMEM"); + " SERIAL_PCI" +#define SERIAL_OPT #endif +#ifdef ENABLE_SERIAL_PNP + " ISAPNP" #define SERIAL_OPT #endif #ifdef SERIAL_OPT - printk(" enabled\n"); + " enabled\n"; #else - printk(" no serial options enabled\n"); + " no serial options enabled\n"; #endif #undef SERIAL_OPT + +static _INLINE_ void show_serial_version(void) +{ + printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name, + serial_version, LOCAL_VERSTRING, serial_revdate, + serial_options); } /* @@ -3188,11 +3226,15 @@ } #endif scr_info.magic = SERIAL_MAGIC; + scr_info.state = state; scr_info.port = state->port; scr_info.flags = state->flags; #ifdef CONFIG_HUB6 scr_info.hub6 = state->hub6; #endif + scr_info.io_type = state->io_type; + scr_info.iomem_base = state->iomem_base; + scr_info.iomem_reg_shift = state->iomem_reg_shift; /* forget possible initially masked and pending IRQ */ probe_irq_off(probe_irq_on()); @@ -3296,7 +3338,8 @@ (scratch3 == 0x50 || scratch3 == 0x52 || scratch3 == 0x54)) { state->type = PORT_16C950; - state->revision = serial_icr_read(info, UART_REV); + state->revision = serial_icr_read(info, UART_REV) | + (scratch3 << 8); return; } } @@ -3367,10 +3410,8 @@ info->hub6 = state->hub6; #endif info->io_type = state->io_type; -#ifdef CONFIG_SERIAL_PCI_MEMMAPPED info->iomem_base = state->iomem_base; info->iomem_reg_shift = state->iomem_reg_shift; -#endif save_flags(flags); cli(); @@ -3536,18 +3577,151 @@ }; #endif + +#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP) + +static void __init printk_pnp_dev_id(unsigned short vendor, + unsigned short device) +{ + printk("%c%c%c%x%x%x%x", + 'A' + ((vendor >> 2) & 0x3f) - 1, + 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1, + 'A' + ((vendor >> 8) & 0x1f) - 1, + (device >> 4) & 0x0f, + device & 0x0f, + (device >> 12) & 0x0f, + (device >> 8) & 0x0f); +} + +static _INLINE_ int get_pci_port(struct pci_dev *dev, + struct pci_board *board, + struct serial_struct *state, + int idx) +{ + unsigned long port; + int base_idx; + int max_port; + + base_idx = SPCI_FL_GET_BASE(board->flags); + if (board->flags & SPCI_FL_BASE_TABLE) + base_idx += idx; + + if (board->flags & SPCI_FL_REGION_SZ_CAP) { + max_port = PCI_BASE_REGION_SIZE(dev, base_idx) / 8; + if (idx >= max_port) + return 1; + } + + port = PCI_BASE_ADDRESS(dev, base_idx) + board->first_uart_offset; + + if ((board->flags & SPCI_FL_BASE_TABLE) == 0) + port += idx * (board->uart_offset ? board->uart_offset : 8); + + if (IS_PCI_REGION_IOPORT(dev, base_idx)) { + state->port = port; + return 0; + } + state->io_type = SERIAL_IO_MEM; + state->iomem_base = ioremap(port, board->uart_offset); + state->iomem_reg_shift = board->reg_shift; + state->port = 0; + return 0; +} + +static _INLINE_ int get_pci_irq(struct pci_dev *dev, + struct pci_board *board, + int idx) +{ + int base_idx; + + if ((board->flags & SPCI_FL_IRQRESOURCE) == 0) + return dev->irq; + + base_idx = SPCI_FL_GET_IRQBASE(board->flags); + if (board->flags & SPCI_FL_IRQ_TABLE) + base_idx += idx; + + return PCI_IRQ_RESOURCE(dev, base_idx); +} + +/* + * Common enabler code shared by both PCI and ISAPNP probes + */ +static void __init start_pci_pnp_board(struct pci_dev *dev, + struct pci_board *board) +{ + int k, line; + struct serial_struct fake_state; + int base_baud; + + if (PREPARE_FUNC(dev) && (PREPARE_FUNC(dev))(dev) < 0) { + printk("SERIAL: PNP device '"); + printk_pnp_dev_id(board->vendor, board->device); + printk("' prepare failed\n"); + return; + } + + if (ACTIVATE_FUNC(dev) && (ACTIVATE_FUNC(dev))(dev) < 0) { + printk("SERIAL: PNP device '"); + printk_pnp_dev_id(board->vendor, board->device); + printk("' activate failed\n"); + return; + } + + /* + * Run the initialization function, if any + */ + if (board->init_fn && ((board->init_fn)(dev, board, 1) != 0)) + return; + +#ifdef MODULE + /* + * Register the serial board in the array if we need to + * shutdown the board on a module unload. + */ + if (DEACTIVATE_FUNC(dev) || board->init_fn) { + if (serial_pci_board_idx >= NR_PCI_BOARDS) + return; + serial_pci_board[serial_pci_board_idx].board = *board; + serial_pci_board[serial_pci_board_idx].dev = dev; + serial_pci_board_idx++; + } +#endif + + base_baud = board->base_baud; + if (!base_baud) + base_baud = BASE_BAUD; + memset(&fake_state, 0, sizeof(fake_state)); + + for (k=0; k < board->num_ports; k++) { + fake_state.irq = get_pci_irq(dev, board, k); + if (get_pci_port(dev, board, &fake_state, k)) + break; + fake_state.flags = ASYNC_SKIP_TEST; +#ifdef SERIAL_DEBUG_PCI + printk("Setup PCI/PNP port: port %x, irq %d, type %d\n", + fake_state.port, fake_state.irq, fake_state.io_type); +#endif + line = register_serial(&fake_state); + if (line < 0) + break; + rs_table[line].baud_base = base_baud; + } +} +#endif /* ENABLE_SERIAL_PCI || ENABLE_SERIAL_PNP */ + #ifdef ENABLE_SERIAL_PCI /* * Some PCI serial cards using the PLX 9050 PCI interface chip require * that the card interrupt be explicitly enabled or disabled. This * seems to be mainly needed on card using the PLX which also use I/O * mapped memory. - * - * Note that __init is a no-op if MODULE is defined; we depend on this. */ -static int __init pci_plx9050_fn(struct pci_dev *dev, - struct pci_board *board, - int enable) +static int +#ifndef MODULE +__init +#endif +pci_plx9050_fn(struct pci_dev *dev, struct pci_board *board, int enable) { u8 data, *p, scratch; @@ -3559,7 +3733,7 @@ /* enable/disable interrupts */ p = ioremap(PCI_BASE_ADDRESS(dev, 0), 0x80); - if (board->vendor == PCI_VENDOR_ID_PANACOM) { + if (dev->vendor == PCI_VENDOR_ID_PANACOM) { scratch = readl(p + 0x4c); if (enable) scratch |= 0x40; @@ -3598,9 +3772,11 @@ #define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc) #define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8) -static int __init pci_siig10x_fn(struct pci_dev *dev, - struct pci_board *board, - int enable) +static int +#ifndef MODULE +__init +#endif +pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable) { u16 data, *p; @@ -3628,9 +3804,11 @@ #define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc) #define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc) -static int __init pci_siig20x_fn(struct pci_dev *dev, - struct pci_board *board, - int enable) +static int +#ifndef MODULE +__init +#endif +pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable) { u8 data; @@ -3649,11 +3827,12 @@ return 0; } + /* * This is the configuration table for all of the PCI serial boards * which we support. */ -static struct pci_board pci_boards[] = { +static struct pci_board pci_boards[] __initdata = { /* * Vendor ID, Device ID, * Subvendor ID, Subdevice ID, @@ -3752,7 +3931,7 @@ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_SUBVENDOR_ID_KEYSPAN, PCI_SUBDEVICE_ID_KEYSPAN_SX2, - SPCI_FL_BASE2 | SPCI_FL_IOMEM, 2, 921600, + SPCI_FL_BASE2, 2, 921600, /* IOMEM */ 0x400, 7, pci_plx9050_fn }, { PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_QUADMODEM, PCI_ANY_ID, PCI_ANY_ID, @@ -3798,18 +3977,47 @@ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M, PCI_ANY_ID, PCI_ANY_ID, SPCI_FL_BASE1, 8, 115200 }, - { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, - PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, - SPCI_FL_BASE0 , 4, 115200 }, { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954, PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, SPCI_FL_BASE0 , 4, 921600 }, + { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, + PCI_ANY_ID, PCI_ANY_ID, + SPCI_FL_BASE0 , 4, 115200 }, + { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952, + PCI_ANY_ID, PCI_ANY_ID, + SPCI_FL_BASE0 , 2, 115200 }, + /* This board uses the size of PCI Base region 0 to + * signal now many ports are available */ + { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI95N, + PCI_ANY_ID, PCI_ANY_ID, + SPCI_FL_BASE0 | SPCI_FL_REGION_SZ_CAP, 32, 115200 }, { PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889, PCI_ANY_ID, PCI_ANY_ID, SPCI_FL_BASE0 , 2, 921600 }, - { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DUAL_SERIAL, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DSERIAL, + PCI_ANY_ID, PCI_ANY_ID, + SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_A, PCI_ANY_ID, PCI_ANY_ID, SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B, + PCI_ANY_ID, PCI_ANY_ID, + SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_PLUS, + PCI_ANY_ID, PCI_ANY_ID, + SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 }, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_A, + PCI_ANY_ID, PCI_ANY_ID, + SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 }, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B, + PCI_ANY_ID, PCI_ANY_ID, + SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 }, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL, + PCI_ANY_ID, PCI_ANY_ID, + SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_650, + PCI_ANY_ID, PCI_ANY_ID, + SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 460800 }, { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550, PCI_ANY_ID, PCI_ANY_ID, SPCI_FL_BASE2, 1, 460800, @@ -3945,60 +4153,105 @@ /* Computone devices submitted by Doug McNash dmcnash@computone.com */ { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG, PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG4, - SPCI_FL_IOMEM | SPCI_FL_BASE0, 4, 921600, + SPCI_FL_BASE0, 4, 921600, /* IOMEM */ 0x40, 2, NULL, 0x200 }, { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG, PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG8, - SPCI_FL_IOMEM | SPCI_FL_BASE0, 8, 921600, + SPCI_FL_BASE0, 8, 921600, /* IOMEM */ 0x40, 2, NULL, 0x200 }, { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG, PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG6, - SPCI_FL_IOMEM | SPCI_FL_BASE0, 6, 921600, + SPCI_FL_BASE0, 6, 921600, /* IOMEM */ 0x40, 2, NULL, 0x200 }, - /* - * Untested PCI modems, sent in from various folks... - */ - /* at+t zoom 56K faxmodem, from dougd@shieldsbag.com */ - { PCI_VENDOR_ID_ATT, 0x442, + /* Digitan DS560-558, from jimd@esoft.com */ + { PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_ATT_VENUS_MODEM, PCI_ANY_ID, PCI_ANY_ID, SPCI_FL_BASE1, 1, 115200 }, - /* at&t unknown modem, from jimd@esoft.com */ - { PCI_VENDOR_ID_ATT, 0x480, + /* 3Com US Robotics 56k Voice Internal PCI model 5610 */ + { PCI_VENDOR_ID_USR, 0x1008, PCI_ANY_ID, PCI_ANY_ID, - SPCI_FL_BASE1, 1, 115200 }, + SPCI_FL_BASE0, 1, 115200 }, + /* + * Untested PCI modems, sent in from various folks... + */ /* Elsa Model 56K PCI Modem, from Andreas Rath */ { PCI_VENDOR_ID_ROCKWELL, 0x1004, 0x1048, 0x1500, SPCI_FL_BASE1, 1, 115200 }, - /* 3Com US Robotics 56k* Voice Internal PCI, model# 2884 */ - /* from evidal@iti.upv.es */ - /* XXX complete guess this may not work!!! */ - { PCI_VENDOR_ID_USR, 0x1006, - 0x12b9, 0x0060, - SPCI_FL_BASE1 | SPCI_FL_IOMEM, 1, 115200 }, - { 0, } + /* Generic serial board */ + { 0, 0, + 0, 0, + SPCI_FL_BASE0, 1, 115200 }, }; /* + * Given a complete unknown PCI device, try to use some hueristics to + * guess what the configuration might be, based on the pitiful PCI + * serial specs. Returns 0 on success, 1 on failure. + */ +static int _INLINE_ serial_guess_board(struct pci_dev *dev, + struct pci_board *board) +{ + int num_iomem = 0, num_port = 0, first_port = -1; + int i; + + /* + * If it is not a communications device or the programming + * interface is greater than 6, give up. + * + * (Should we try to make guesses for multiport serial devices + * later?) + */ + if ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL || + (dev->class & 0xff) > 6) + return 1; + + for (i=0; i < 6; i++) { + if (IS_PCI_REGION_IOPORT(dev, i)) { + num_port = 0; + if (first_port == -1) + first_port = i; + } else { + num_iomem++; + } + } + + /* + * If there is 1 or 0 iomem regions, and exactly one port, use + * it. + */ + if (num_iomem <= 1 && num_port == 1) { + board->flags = first_port; + return 0; + } + return 1; +} + + + +/* * Query PCI space for known serial boards * If found, add them to the PCI device space in rs_table[] * * Accept a maximum of eight boards * */ -static void probe_serial_pci(void) +static void __init probe_serial_pci(void) { - int k, line; struct pci_dev *dev = NULL; struct pci_board *board; - struct serial_struct fake_state; - int uart_offset, base_baud, base_idx; - unsigned long port; #ifdef SERIAL_DEBUG_PCI printk(KERN_DEBUG "Entered probe_serial_pci()\n"); #endif + if (!pcibios_present()) { +#ifdef SERIAL_DEBUG_PCI + printk(KERN_DEBUG "Leaving probe_serial_pci() (no pcibios)\n"); +#endif + return; + } + pci_for_each_dev(dev) { for (board = pci_boards; board->vendor; board++) { if (board->vendor != (unsigned short) PCI_ANY_ID && @@ -4008,121 +4261,87 @@ dev->device != board->device) continue; if (board->subvendor != (unsigned short) PCI_ANY_ID && - dev->subsystem_vendor != board->subvendor) + pci_get_subvendor(dev) != board->subvendor) continue; if (board->subdevice != (unsigned short) PCI_ANY_ID && - dev->subsystem_device != board->subdevice) + pci_get_subdevice(dev) != board->subdevice) continue; break; } - if (board->vendor == 0) { + if (board->vendor == 0 && serial_guess_board(dev, board)) + continue; + + start_pci_pnp_board(dev, board); + } + #ifdef SERIAL_DEBUG_PCI - printk(KERN_DEBUG - "Found unknown serial board: %x:%x, %x:%x, %x\n", - dev->vendor, dev->device, subvendor, subdevice, - dev->class); - printk(KERN_DEBUG - " Addresses: %lx, %lx, %lx, %lx\n", - PCI_BASE_ADDRESS(dev, 0), PCI_BASE_ADDRESS(dev, 1), - PCI_BASE_ADDRESS(dev, 2), PCI_BASE_ADDRESS(dev, 3)); + printk(KERN_DEBUG "Leaving probe_serial_pci() (probe finished)\n"); #endif - continue; - } + return; +} - /* - * Run the initialization function, if any - */ - if (board->init_fn) - if ((board->init_fn)(dev, board, 1) != 0) - continue; +#endif /* ENABLE_SERIAL_PCI */ - /* - * Register the serial board in the array so we can - * shutdown the board later, if necessary. - */ - if (serial_pci_board_idx >= NR_PCI_BOARDS) - continue; - serial_pci_board[serial_pci_board_idx].board = board; - serial_pci_board[serial_pci_board_idx].dev = dev; - serial_pci_board_idx++; +#ifdef ENABLE_SERIAL_PNP - base_idx = board->flags & SPCI_FL_BASE_MASK; - port = PCI_BASE_ADDRESS(dev, base_idx) + - board->first_uart_offset; - if (board->flags & SPCI_FL_IOMEM) - port &= PCI_BASE_ADDRESS_MEM_MASK; - else - port &= PCI_BASE_ADDRESS_IO_MASK; +static struct pci_board pnp_devices[] __initdata = { + /* Rockwell 56K ACF II Fax+Data+Voice Modem */ + { ISAPNP_VENDOR('A', 'K', 'Y'), ISAPNP_DEVICE(0x1021), 0, 0, + SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, + /* Boca Research 33,600 ACF Modem */ + { ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x1400), 0, 0, + SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, + /* Best Data Products Inc. Smart One 336F PnP Modem */ + { ISAPNP_VENDOR('B', 'D', 'P'), ISAPNP_DEVICE(0x3336), 0, 0, + SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, + /* These ID's are taken from M$ documentation */ + /* Compaq 14400 Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC000), 0, 0, + SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, + /* Compaq 2400/9600 Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC001), 0, 0, + SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, + /* Generic standard PC COM port */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0500), 0, 0, + SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, + /* Generic 16550A-compatible COM port */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0501), 0, 0, + SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, + { 0, } +}; - /* - * Set some defaults for the loop below, which - * actually registers each serial port belonging to - * the card. - */ - uart_offset = board->uart_offset; - if (!uart_offset) - uart_offset = 8; - base_baud = board->base_baud; - if (!base_baud) - base_baud = BASE_BAUD; -#ifndef CONFIG_SERIAL_PCI_MEMMAPPED - if (board->flags & SPCI_FL_IOMEM) { -#ifdef SERIAL_DEBUG_PCI - printk(KERN_DEBUG - "Can't support memory mapped PCI serial device\n"); +static void __init probe_serial_pnp(void) +{ + struct pci_dev *dev = NULL; + struct pci_board *board; + +#ifdef SERIAL_DEBUG_PNP + printk("Entered probe_serial_pnp()\n"); #endif - continue; - } + if (!isapnp_present()) { +#ifdef SERIAL_DEBUG_PNP + printk("Leaving probe_serial_pnp() (no isapnp)\n"); #endif - memset(&fake_state, 0, sizeof(fake_state)); + return; + } -#ifdef SERIAL_DEBUG_PCI - printk(KERN_DEBUG - "Found Serial PCI device: %x:%x, %x:%x, %x\n", - dev->vendor, dev->device, subvendor, subdevice, - dev->class); - printk(KERN_DEBUG - " IRQ: %d, base: %lx (%s), num_ports: %d\n", - dev->irq, port, board->flags & SPCI_FL_IOMEM ? - "iomem" : "port", board->num_ports); -#endif + for (board = pnp_devices; board->vendor; board++) { + while ((dev = isapnp_find_dev(NULL, board->vendor, + board->device, dev))) { + + start_pci_pnp_board(dev, board); - for (k=0; k < board->num_ports; k++) { - if (board->flags & SPCI_FL_BASE_TABLE) { - port = PCI_BASE_ADDRESS(dev, base_idx++); - if (board->flags & SPCI_FL_IOMEM) - port &= PCI_BASE_ADDRESS_MEM_MASK; - else - port &= PCI_BASE_ADDRESS_IO_MASK; - } - fake_state.irq = dev->irq; - fake_state.port = port; -#ifdef CONFIG_SERIAL_PCI_MEMMAPPED - if (board->flags & SPCI_FL_IOMEM) { - fake_state.io_type = SERIAL_IO_MEM; - fake_state.iomem_base = - ioremap(port, board->uart_offset); - fake_state.iomem_reg_shift = board->reg_shift; - fake_state.port = 0; - } -#endif - port += uart_offset; - fake_state.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ; - line = register_serial(&fake_state); - if (line < 0) - break; - rs_table[line].baud_base = base_baud; - } - } - -#ifdef SERIAL_DEBUG_PCI - printk(KERN_DEBUG "Leaving probe_serial_pci() (probe finished)\n"); + } + } + +#ifdef SERIAL_DEBUG_PNP + printk("Leaving probe_serial_pnp() (probe finished)\n"); #endif - return; + return; } -#endif /* ENABLE_SERIAL_PCI */ +#endif /* ENABLE_SERIAL_PNP */ /* * The serial driver boot-time initialization code! @@ -4270,6 +4489,9 @@ #ifdef ENABLE_SERIAL_PCI probe_serial_pci(); #endif +#ifdef ENABLE_SERIAL_PNP + probe_serial_pnp(); +#endif return 0; } @@ -4282,6 +4504,7 @@ int i; unsigned long flags; struct serial_state *state; + struct async_struct *info; save_flags(flags); cli(); @@ -4311,13 +4534,17 @@ state->port = req->port; state->flags = req->flags; state->io_type = req->io_type; -#ifdef CONFIG_SERIAL_PCI_MEMMAPPED state->iomem_base = req->iomem_base; state->iomem_reg_shift = req->iomem_reg_shift; -#endif if (req->baud_base) state->baud_base = req->baud_base; - + if ((info = state->info) != NULL) { + info->port = req->port; + info->flags = req->flags; + info->io_type = req->io_type; + info->iomem_base = req->iomem_base; + info->iomem_reg_shift = req->iomem_reg_shift; + } autoconfig(state); if (state->type == PORT_UNKNOWN) { restore_flags(flags); @@ -4387,17 +4614,20 @@ } if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) release_region(rs_table[i].port, 8); -#if defined(ENABLE_SERIAL_PCI) && defined (CONFIG_SERIAL_PCI_MEMMAPPED) +#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP) if (rs_table[i].iomem_base) iounmap(rs_table[i].iomem_base); #endif } -#ifdef ENABLE_SERIAL_PCI +#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP) for (i=0; i < serial_pci_board_idx; i++) { struct pci_board_inst *brd = &serial_pci_board[i]; - if (brd->board->init_fn) - (brd->board->init_fn)(brd->dev, brd->board, 0); + if (brd->board.init_fn) + (brd->board.init_fn)(brd->dev, &brd->board, 0); + + if (DEACTIVATE_FUNC(brd->dev)) + (DEACTIVATE_FUNC(brd->dev))(brd->dev); } #endif if (tmp_buf) { @@ -4599,10 +4829,8 @@ info->hub6 = state->hub6; #endif info->io_type = state->io_type; -#ifdef CONFIG_SERIAL_PCI_MEMMAPPED info->iomem_base = state->iomem_base; info->iomem_reg_shift = state->iomem_reg_shift; -#endif quot = state->baud_base / baud; cval = cflag & (CSIZE | CSTOPB); #if defined(__powerpc__) || defined(__alpha__) diff -ur --new-file old/linux/drivers/char/sx.c new/linux/drivers/char/sx.c --- old/linux/drivers/char/sx.c Fri Jan 7 20:43:09 2000 +++ new/linux/drivers/char/sx.c Sat Jan 22 21:31:10 2000 @@ -2457,20 +2457,20 @@ { unsigned int hwbase; unsigned long rebase; - int t; + unsigned int t; -#define CNTRL_REG_OFFSET 0x14 +#define CNTRL_REG_OFFSET 0x50 +#define CNTRL_REG_GOODVALUE 0x00260000 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase); hwbase &= PCI_BASE_ADDRESS_MEM_MASK; rebase = (ulong) ioremap(hwbase, 0x80); - t = readb (rebase + CNTRL_REG_OFFSET*4 + 2); - if (t != 0x06) { - printk (KERN_DEBUG "sx: performing cntrl reg fix: %02x -> 06\n", t); - writeb (0x06, rebase + CNTRL_REG_OFFSET*4+2); + t = readl (rebase + CNTRL_REG_OFFSET); + if (t != CNTRL_REG_GOODVALUE) { + printk (KERN_DEBUG "sx: performing cntrl reg fix: %08x -> %08x\n", t, CNTRL_REG_GOODVALUE); + writel (CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET); } my_iounmap (hwbase, rebase); - } #endif diff -ur --new-file old/linux/drivers/char/wdt.c new/linux/drivers/char/wdt.c --- old/linux/drivers/char/wdt.c Thu Aug 26 22:53:47 1999 +++ new/linux/drivers/char/wdt.c Wed Jan 26 21:24:41 2000 @@ -60,19 +60,31 @@ #define WD_TIMO (100*60) /* 1 minute */ +#ifndef MODULE + /* * Setup options */ -void __init wdt_setup(char *str, int *ints) +static int __init wdt_setup(char *str) { - if(ints[0]>0) + int ints[4]; + + str = get_options (str, ARRAY_SIZE(ints), ints); + + if (ints[0] > 0) { - io=ints[1]; - if(ints[0]>1) - irq=ints[2]; + io = ints[1]; + if(ints[0] > 1) + irq = ints[2]; } + + return 1; } + +__setup("wdt=", wdt_setup); + +#endif /* !MODULE */ /* * Programming support @@ -367,10 +379,10 @@ int __init wdt_init(void) { - printk("WDT500/501-P driver 0.07 at %X (Interrupt %d)\n", io,irq); + printk(KERN_INFO "WDT500/501-P driver 0.07 at %X (Interrupt %d)\n", io,irq); if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", NULL)) { - printk("IRQ %d is not free.\n", irq); + printk(KERN_ERR "IRQ %d is not free.\n", irq); return -EIO; } misc_register(&wdt_miscdev); diff -ur --new-file old/linux/drivers/fc4/fc.c new/linux/drivers/fc4/fc.c --- old/linux/drivers/fc4/fc.c Tue Dec 21 07:06:42 1999 +++ new/linux/drivers/fc4/fc.c Thu Jan 27 17:58:15 2000 @@ -54,32 +54,19 @@ #endif #ifdef __sparc__ -static inline void *fc_dma_alloc(long size, dma_handle *dma, fc_channel *fc) -{ - return sbus_alloc_consistant(fc->dev, size, dma); -} - -static inline dma_handle fc_sync_dma_entry(void *buf, long len, fc_channel *fc) -{ - return sbus_map_single(fc->dev, buf, len); -} - -static inline void fc_sync_dma_exit(dma_handle dmh, long size, fc_channel *fc) -{ - sbus_unmap_single(fc->dev, dmh, size); -} - -static inline void fc_sync_dma_entry_sg(struct scatterlist *list, int count, fc_channel *fc) -{ - sbus_map_sg(fc->dev, list, count); -} - -static inline void fc_sync_dma_exit_sg(struct scatterlist *list, int count, fc_channel *fc) -{ - sbus_unmap_sg(fc->dev, list, count); -} +#define dma_alloc_consistent(d,s,p) sbus_alloc_consistent(d,s,p) +#define dma_free_consistent(d,s,v,h) sbus_free_consistent(d,s,v,h) +#define dma_map_single(d,v,s) sbus_map_single(d,v,s) +#define dma_unmap_single(d,h,s) sbus_unmap_single(d,h,s) +#define dma_map_sg(d,s,n) sbus_map_sg(d,s,n) +#define dma_unmap_sg(d,s,n) sbus_unmap_sg(d,s,n) #else -#error Port this +#define dma_alloc_consistent(d,s,p) pci_alloc_consistent(d,s,p) +#define dma_free_consistent(d,s,v,h) pci_free_consistent(d,s,v,h) +#define dma_map_single(d,v,s) pci_map_single(d,v,s) +#define dma_unmap_single(d,h,s) pci_unmap_single(d,h,s) +#define dma_map_sg(d,s,n) pci_map_sg(d,s,n) +#define dma_unmap_sg(d,s,n) pci_unmap_sg(d,s,n) #endif #define FCP_CMND(SCpnt) ((fcp_cmnd *)&(SCpnt->SCp)) @@ -176,7 +163,7 @@ fc->state = FC_STATE_FPORT_OK; fcmd = l->fcmds + i; plogi = l->logi + 3 * i; - fc_sync_dma_exit (fcmd->cmd, 3 * sizeof(logi), fc); + dma_unmap_single (fc->dev, fcmd->cmd, 3 * sizeof(logi)); plogi->code = LS_PLOGI; memcpy (&plogi->nport_wwn, &fc->wwn_nport, sizeof(fc_wwn)); memcpy (&plogi->node_wwn, &fc->wwn_node, sizeof(fc_wwn)); @@ -196,7 +183,7 @@ printk ("\n"); } #endif - fcmd->cmd = fc_sync_dma_entry (plogi, 3 * sizeof(logi), fc); + fcmd->cmd = dma_map_single (fc->dev, plogi, 3 * sizeof(logi)); fcmd->rsp = fcmd->cmd + 2 * sizeof(logi); if (fc->hw_enque (fc, fcmd)) printk ("FC: Cannot enque PLOGI packet on %s\n", fc->name); @@ -219,7 +206,7 @@ switch (status) { case FC_STATUS_OK: plogi = l->logi + 3 * i; - fc_sync_dma_exit (l->fcmds[i].cmd, 3 * sizeof(logi), fc); + dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi)); if (!fc->wwn_dest.lo && !fc->wwn_dest.hi) { memcpy (&fc->wwn_dest, &plogi[1].node_wwn, sizeof(fc_wwn)); FCD(("Dest WWN %08x%08x\n", *(u32 *)&fc->wwn_dest, fc->wwn_dest.lo)) @@ -237,7 +224,7 @@ break; case FC_STATUS_ERR_OFFLINE: fc->state = FC_STATE_OFFLINE; - fc_sync_dma_exit (l->fcmds[i].cmd, 3 * sizeof(logi), fc); + dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi)); printk ("%s: FC is offline\n", fc->name); if (atomic_dec_and_test (&l->todo)) up(&l->sem); @@ -261,7 +248,7 @@ FCD(("Report map done %d %d\n", i, status)) switch (status) { case FC_STATUS_OK: /* Ok, let's have a fun on a loop */ - fc_sync_dma_exit (l->fcmds[i].cmd, 3 * sizeof(logi), fc); + dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi)); p = (fc_al_posmap *)(l->logi + 3 * i); #ifdef FCDEBUG { @@ -310,7 +297,7 @@ case FC_STATUS_POINTTOPOINT: /* We're Point-to-Point, no AL... */ FCD(("SID %d DID %d\n", fc->sid, fc->did)) fcmd = l->fcmds + i; - fc_sync_dma_exit(fcmd->cmd, 3 * sizeof(logi), fc); + dma_unmap_single(fc->dev, fcmd->cmd, 3 * sizeof(logi)); fch = &fcmd->fch; memset(l->logi + 3 * i, 0, 3 * sizeof(logi)); FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, FS_FABRIC_F_PORT); @@ -320,11 +307,11 @@ FILL_FCHDR_OXRX(fch, 0xffff, 0xffff); fch->param = 0; l->logi [3 * i].code = LS_FLOGI; - fcmd->cmd = fc_sync_dma_entry (l->logi + 3 * i, 3 * sizeof(logi), fc); + fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi)); fcmd->rsp = fcmd->cmd + sizeof(logi); fcmd->cmdlen = sizeof(logi); fcmd->rsplen = sizeof(logi); - fcmd->data = (dma_handle)NULL; + fcmd->data = (dma_addr_t)NULL; fcmd->class = FC_CLASS_SIMPLE; fcmd->proto = TYPE_EXTENDED_LS; if (fc->hw_enque (fc, fcmd)) @@ -350,9 +337,10 @@ if (type == TYPE_SCSI_FCP) { if (!unregister) { - fc->scsi_cmd_pool = - (fcp_cmd *) fc_dma_alloc (slots * (sizeof (fcp_cmd) + fc->rsp_size), - &fc->dma_scsi_cmd, fc); + fc->scsi_cmd_pool = (fcp_cmd *) + dma_alloc_consistent (fc->dev, + slots * (sizeof (fcp_cmd) + fc->rsp_size), + &fc->dma_scsi_cmd); fc->scsi_rsp_pool = (char *)(fc->scsi_cmd_pool + slots); fc->dma_scsi_rsp = fc->dma_scsi_cmd + slots * sizeof (fcp_cmd); fc->scsi_bitmap_end = (slots + 63) & ~63; @@ -436,9 +424,9 @@ if (fcmd->data) { if (SCpnt->use_sg) - fc_sync_dma_exit_sg((struct scatterlist *)SCpnt->buffer, SCpnt->use_sg, fc); + dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->buffer, SCpnt->use_sg); else - fc_sync_dma_exit(fcmd->data, SCpnt->request_bufflen, fc); + dma_unmap_single(fc->dev, fcmd->data, SCpnt->request_bufflen); } break; default: @@ -577,7 +565,7 @@ fc->login = fcmd; fc->ls = (void *)l; /* Assumes sizeof(fc_al_posmap) < 3 * sizeof(logi), which is true */ - fcmd->cmd = fc_sync_dma_entry (l->logi + 3 * i, 3 * sizeof(logi), fc); + fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi)); fcmd->proto = PROTO_REPORT_AL_MAP; fcmd->token = i; fcmd->fc = fc; @@ -596,7 +584,7 @@ } else { fc->state = FC_STATE_OFFLINE; enable_irq(fc->irq); - fc_sync_dma_exit (l->fcmds[i].cmd, 3 * sizeof(logi), fc); + dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi)); if (atomic_dec_and_test (&l->todo)) goto all_done; } @@ -613,7 +601,7 @@ FCD(("SID %d DID %d\n", fc->sid, fc->did)) fcmd = l->fcmds + i; - fc_sync_dma_exit(fcmd->cmd, 3 * sizeof(logi), fc); + dma_unmap_single(fc->dev, fcmd->cmd, 3 * sizeof(logi)); fch = &fcmd->fch; FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, FS_FABRIC_F_PORT); FILL_FCHDR_SID(fch, 0); @@ -622,11 +610,11 @@ FILL_FCHDR_OXRX(fch, 0xffff, 0xffff); fch->param = 0; l->logi [3 * i].code = LS_FLOGI; - fcmd->cmd = fc_sync_dma_entry (l->logi + 3 * i, 3 * sizeof(logi), fc); + fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi)); fcmd->rsp = fcmd->cmd + sizeof(logi); fcmd->cmdlen = sizeof(logi); fcmd->rsplen = sizeof(logi); - fcmd->data = (dma_handle)NULL; + fcmd->data = (dma_addr_t)NULL; fcmd->class = FC_CLASS_SIMPLE; fcmd->proto = TYPE_EXTENDED_LS; } else @@ -650,7 +638,7 @@ switch (fc->state) { case FC_STATE_ONLINE: break; case FC_STATE_OFFLINE: break; - default: fc_sync_dma_exit (l->fcmds[i].cmd, 3 * sizeof(logi), fc); + default: dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi)); break; } } @@ -800,7 +788,7 @@ fcp_cntl = FCP_CNTL_QTYPE_UNTAGGED; if (!SCpnt->request_bufflen && !SCpnt->use_sg) { cmd->fcp_cntl = fcp_cntl; - fcmd->data = (dma_handle)NULL; + fcmd->data = (dma_addr_t)NULL; } else { switch (SCpnt->cmnd[0]) { case WRITE_6: @@ -812,16 +800,17 @@ } if (!SCpnt->use_sg) { cmd->fcp_data_len = SCpnt->request_bufflen; - fcmd->data = fc_sync_dma_entry ((char *)SCpnt->request_buffer, - SCpnt->request_bufflen, fc); + fcmd->data = dma_map_single (fc->dev, (char *)SCpnt->request_buffer, + SCpnt->request_bufflen); } else { struct scatterlist *sg = (struct scatterlist *)SCpnt->buffer; + int nents; FCD(("XXX: Use_sg %d %d\n", SCpnt->use_sg, sg->length)) - if (SCpnt->use_sg > 1) printk ("%s: SG for use_sg > 1 not handled yet\n", fc->name); - fc_sync_dma_entry_sg (sg, SCpnt->use_sg, fc); - fcmd->data = sg->dvma_address; - cmd->fcp_data_len = sg->dvma_length; + nents = dma_map_sg (fc->dev, sg, SCpnt->use_sg); + if (nents > 1) printk ("%s: SG for nents %d (use_sg %d) not handled yet\n", fc->name, nents, SCpnt->use_sg); + fcmd->data = sg_dma_address(sg); + cmd->fcp_data_len = sg_dma_len(sg); } } memcpy (cmd->fcp_cdb, SCpnt->cmnd, SCpnt->cmd_len); @@ -954,7 +943,7 @@ fc->cmd_slots[0] = fcmd; cmd->fcp_cntl = FCP_CNTL_QTYPE_ORDERED | FCP_CNTL_RESET; - fcmd->data = (dma_handle)NULL; + fcmd->data = (dma_addr_t)NULL; fcmd->proto = TYPE_SCSI_FCP; memcpy (cmd->fcp_cdb, SCpnt->cmnd, SCpnt->cmd_len); @@ -1059,11 +1048,11 @@ FILL_FCHDR_SEQ_DF_SEQ(fch, 0, 0, 0); FILL_FCHDR_OXRX(fch, 0xffff, 0xffff); fch->param = 0; - fcmd->cmd = fc_sync_dma_entry (data, 2 * len, fc); + fcmd->cmd = dma_map_single (fc->dev, data, 2 * len); fcmd->rsp = fcmd->cmd + len; fcmd->cmdlen = len; fcmd->rsplen = len; - fcmd->data = (dma_handle)NULL; + fcmd->data = (dma_addr_t)NULL; fcmd->fc = fc; fcmd->class = FC_CLASS_SIMPLE; fcmd->proto = TYPE_EXTENDED_LS; @@ -1094,7 +1083,7 @@ clear_bit(fcmd->token, fc->scsi_bitmap); fc->scsi_free++; - fc_sync_dma_exit (fcmd->cmd, 2 * len, fc); + dma_unmap_single (fc->dev, fcmd->cmd, 2 * len); return l.status; } diff -ur --new-file old/linux/drivers/fc4/fcp_impl.h new/linux/drivers/fc4/fcp_impl.h --- old/linux/drivers/fc4/fcp_impl.h Tue Dec 21 07:06:42 1999 +++ new/linux/drivers/fc4/fcp_impl.h Thu Jan 27 17:58:15 2000 @@ -15,13 +15,9 @@ #include "fcp.h" #include "fc-al.h" +#include #ifdef __sparc__ - #include -typedef u32 dma_handle; - -#else -#error Need to port FC layer to your architecture #endif /* 0 or 1 */ @@ -49,11 +45,11 @@ unsigned short token; unsigned int did; /* FCP SCSI stuff */ - dma_handle data; + dma_addr_t data; /* From now on this cannot be touched for proto == TYPE_SCSI_FCP */ fc_hdr fch; - dma_handle cmd; - dma_handle rsp; + dma_addr_t cmd; + dma_addr_t rsp; int cmdlen; int rsplen; int class; @@ -85,6 +81,8 @@ svc_parm *class_svcs; #ifdef __sparc__ struct sbus_dev *dev; +#else + struct pci_dev *dev; #endif struct module *module; /* FCP SCSI stuff */ @@ -93,7 +91,7 @@ int rsp_size; fcp_cmd *scsi_cmd_pool; char *scsi_rsp_pool; - dma_handle dma_scsi_cmd, dma_scsi_rsp; + dma_addr_t dma_scsi_cmd, dma_scsi_rsp; long *scsi_bitmap; long scsi_bitmap_end; int scsi_free; diff -ur --new-file old/linux/drivers/fc4/soc.c new/linux/drivers/fc4/soc.c --- old/linux/drivers/fc4/soc.c Tue Jan 4 20:17:47 2000 +++ new/linux/drivers/fc4/soc.c Thu Jan 27 17:58:15 2000 @@ -668,7 +668,7 @@ memset (cq, 0, sizeof(cq)); size = (SOC_CQ_REQ0_SIZE + SOC_CQ_REQ1_SIZE) * sizeof(soc_req); - s->req_cpu = sbus_alloc_consistant(sdev, size, &s->req_dvma); + s->req_cpu = sbus_alloc_consistent(sdev, size, &s->req_dvma); s->req[0].pool = s->req_cpu; cq[0].address = s->req_dvma; s->req[1].pool = s->req[0].pool + SOC_CQ_REQ0_SIZE; @@ -765,7 +765,7 @@ sbus_iounmap(s->xram, sdev->reg_addrs[1].reg_size); sbus_iounmap(s->regs, sdev->reg_addrs[2].reg_size); } - sbus_free_consistant(sdev, + sbus_free_consistent(sdev, (SOC_CQ_REQ0_SIZE+SOC_CQ_REQ1_SIZE)*sizeof(soc_req), s->req_cpu, s->req_dvma); } diff -ur --new-file old/linux/drivers/fc4/socal.c new/linux/drivers/fc4/socal.c --- old/linux/drivers/fc4/socal.c Tue Jan 4 20:17:47 2000 +++ new/linux/drivers/fc4/socal.c Thu Jan 27 17:58:15 2000 @@ -794,7 +794,7 @@ size = (SOCAL_CQ_REQ0_SIZE + SOCAL_CQ_REQ1_SIZE + SOCAL_CQ_RSP0_SIZE + SOCAL_CQ_RSP1_SIZE + SOCAL_CQ_RSP2_SIZE) * sizeof(socal_req); - s->req_cpu = sbus_alloc_consistant(sdev, size, &s->req_dvma); + s->req_cpu = sbus_alloc_consistent(sdev, size, &s->req_dvma); s->req[0].pool = s->req_cpu; cq[0].address = s->req_dvma; s->req[1].pool = s->req[0].pool + SOCAL_CQ_REQ0_SIZE; @@ -903,7 +903,7 @@ sbus_iounmap(s->xram, sdev->reg_addrs[1].reg_size); sbus_iounmap(s->regs, sdev->reg_addrs[2].reg_size); } - sbus_free_consistant(sdev, + sbus_free_consistent(sdev, (SOCAL_CQ_REQ0_SIZE + SOCAL_CQ_REQ1_SIZE + SOCAL_CQ_RSP0_SIZE + SOCAL_CQ_RSP1_SIZE + SOCAL_CQ_RSP2_SIZE) * sizeof(socal_req), diff -ur --new-file old/linux/drivers/i2o/i2o_core.c new/linux/drivers/i2o/i2o_core.c --- old/linux/drivers/i2o/i2o_core.c Fri Jan 14 01:53:52 2000 +++ new/linux/drivers/i2o/i2o_core.c Wed Jan 26 22:16:05 2000 @@ -1411,24 +1411,30 @@ } memset(status, 0, 4); - msg[0]= EIGHT_WORD_MSG_SIZE| TRL_OFFSET_6; + msg[0]= EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6; msg[1]= I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID; msg[2]= core_context; msg[3]= 0x0106; /* Transaction context */ msg[4]= 4096; /* Host page frame size */ - msg[5]= MSG_FRAME_SIZE<<16|0x80; /* Outbound msg frame size and Initcode */ + /* Frame size is in words. Pick 128, its what everyone elses uses and + other sizes break some adapters. */ + msg[5]= (MSG_FRAME_SIZE>>2)<<16|0x80; /* Outbound msg frame size and Initcode */ msg[6]= 0xD0000004; /* Simple SG LE, EOB */ - msg[7]= virt_to_phys(status); + msg[7]= virt_to_bus(status); i2o_post_message(c,m); barrier(); time=jiffies; - while(status[0]!=I2O_CMD_OUTBOUND_INIT_COMPLETE) + while(status[0]<0x02) { if((jiffies-time)>=5*HZ) { - printk(KERN_ERR "%s: Outbound Q initialize timeout.\n", + if(status[0]==0x00) + printk(KERN_ERR "%s: Ignored queue initialize request.\n", + c->name); + else + printk(KERN_ERR "%s: Outbound queue initialize timeout.\n", c->name); kfree(status); return -ETIMEDOUT; @@ -1437,6 +1443,13 @@ barrier(); } + if(status[0] != I2O_CMD_OUTBOUND_INIT_COMPLETE) + { + printk(KERN_ERR "%s: Outbound queue initialize rejected (%d).\n", + c->name, status[0]); + kfree(status); + return -EINVAL; + } /* Alloc space for IOP's outbound queue message frames */ c->page_frame = kmalloc(MSG_POOL_SIZE, GFP_KERNEL); diff -ur --new-file old/linux/drivers/net/Space.c new/linux/drivers/net/Space.c --- old/linux/drivers/net/Space.c Fri Jan 7 00:01:56 2000 +++ new/linux/drivers/net/Space.c Wed Jan 26 22:16:05 2000 @@ -569,7 +569,6 @@ /* Token-ring device probe */ extern int ibmtr_probe(struct net_device *); extern int olympic_probe(struct net_device *); -extern int tms380tr_probe(struct net_device *); extern int smctr_probe(struct net_device *); static int @@ -581,9 +580,6 @@ #endif #ifdef CONFIG_IBMOL && olympic_probe(dev) -#endif -#ifdef CONFIG_SKTR - && tms380tr_probe(dev) #endif #ifdef CONFIG_SMCTR && smctr_probe(dev) diff -ur --new-file old/linux/drivers/net/a2065.c new/linux/drivers/net/a2065.c --- old/linux/drivers/net/a2065.c Thu Aug 19 19:54:10 1999 +++ new/linux/drivers/net/a2065.c Wed Jan 26 21:45:20 2000 @@ -127,9 +127,6 @@ int auto_select; /* cable-selection by carrier */ unsigned short busmaster_regval; -#ifdef CONFIG_AMIGA - unsigned int key; -#endif #ifdef CONFIG_SUNLANCE struct Linux_SBus_DMA *ledma; /* if set this points to ledma and arch=4m */ int burst_sizes; /* ledma SBus burst sizes */ @@ -740,78 +737,92 @@ int __init a2065_probe(struct net_device *dev) { - unsigned int key, is_cbm; - const struct ConfigDev *cd; - u_long board; - u_long sn; - struct lance_private *priv; - struct A2065Board *a2065; - - if ((key = is_cbm = zorro_find(ZORRO_PROD_CBM_A2065_1, 0, 0)) || - (key = is_cbm = zorro_find(ZORRO_PROD_CBM_A2065_2, 0, 0)) || - (key = zorro_find(ZORRO_PROD_AMERISTAR_A2065, 0, 0))) { - cd = zorro_get_board(key); - if ((board = (u_long)cd->cd_BoardAddr)) { - sn = cd->cd_Rom.er_SerialNumber; - if (is_cbm) { /* Commodore */ - dev->dev_addr[0] = 0x00; - dev->dev_addr[1] = 0x80; - dev->dev_addr[2] = 0x10; - } else { /* Ameristar */ - dev->dev_addr[0] = 0x00; - dev->dev_addr[1] = 0x00; - dev->dev_addr[2] = 0x9f; - } - dev->dev_addr[3] = (sn>>16) & 0xff; - dev->dev_addr[4] = (sn>>8) & 0xff; - dev->dev_addr[5] = sn & 0xff; - printk("%s: A2065 at 0x%08lx, Ethernet Address %02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, board, dev->dev_addr[0], - dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], - dev->dev_addr[5]); - - init_etherdev(dev, 0); - - dev->priv = kmalloc(sizeof(struct - lance_private), - GFP_KERNEL); - if (dev->priv == NULL) - return -ENOMEM; - priv = (struct lance_private *)dev->priv; - memset(priv, 0, sizeof(struct lance_private)); - - a2065 = (struct A2065Board *)ZTWO_VADDR(board); - priv->ll = &a2065->Lance; - priv->init_block = - (struct lance_init_block *)&a2065->RAM; - priv->lance_init_block = (struct lance_init_block *) - offsetof(struct A2065Board, RAM); - priv->auto_select = 0; - priv->key = key; - priv->busmaster_regval = LE_C3_BSWP; - - priv->lance_log_rx_bufs = LANCE_LOG_RX_BUFFERS; - priv->lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS; - priv->rx_ring_mod_mask = RX_RING_MOD_MASK; - priv->tx_ring_mod_mask = TX_RING_MOD_MASK; - - dev->open = &lance_open; - dev->stop = &lance_close; - dev->hard_start_xmit = &lance_start_xmit; - dev->get_stats = &lance_get_stats; - dev->set_multicast_list = &lance_set_multicast; - dev->dma = 0; - - ether_setup(dev); - init_timer(&priv->multicast_timer); - priv->multicast_timer.data = (unsigned long) dev; - priv->multicast_timer.function = - (void (*)(unsigned long)) &lance_set_multicast; + struct zorro_dev *z = NULL; + + while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { + unsigned long board, base_addr, ram_start; + int is_cbm; + struct lance_private *priv; + + if (z->id == ZORRO_PROD_CBM_A2065_1 || + z->id == ZORRO_PROD_CBM_A2065_2) + is_cbm = 1; + else if (z->id == ZORRO_PROD_AMERISTAR_A2065) + is_cbm = 0; + else + continue; + + board = z->resource.start; + base_addr = board+A2065_LANCE; + ram_start = board+A2065_RAM; - zorro_config_board(key, 0); - return(0); + if (!request_mem_region(base_addr, sizeof(struct lance_regs), + "Am7990")) + continue; + if (!request_mem_region(ram_start, A2065_RAM_SIZE, "RAM")) { + release_mem_region(base_addr, + sizeof(struct lance_regs)); + continue; + } + strcpy(z->name, "A2065 Ethernet Card"); + if (is_cbm) { /* Commodore */ + dev->dev_addr[0] = 0x00; + dev->dev_addr[1] = 0x80; + dev->dev_addr[2] = 0x10; + } else { /* Ameristar */ + dev->dev_addr[0] = 0x00; + dev->dev_addr[1] = 0x00; + dev->dev_addr[2] = 0x9f; } + dev->dev_addr[3] = (z->rom.er_SerialNumber>>16) & 0xff; + dev->dev_addr[4] = (z->rom.er_SerialNumber>>8) & 0xff; + dev->dev_addr[5] = z->rom.er_SerialNumber & 0xff; + printk("%s: A2065 at 0x%08lx, Ethernet Address " + "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, board, + dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], + dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + + init_etherdev(dev, 0); + + dev->priv = kmalloc(sizeof(struct lance_private), GFP_KERNEL); + if (dev->priv == NULL) { + release_mem_region(base_addr, + sizeof(struct lance_regs)); + release_mem_region(ram_start, A2065_RAM_SIZE); + return -ENOMEM; + } + priv = (struct lance_private *)dev->priv; + memset(priv, 0, sizeof(struct lance_private)); + + dev->base_addr = ZTWO_VADDR(base_addr); + dev->mem_start = ZTWO_VADDR(ram_start); + dev->mem_end = dev->mem_start+A2065_RAM_SIZE; + + priv->ll = (volatile struct lance_regs *)dev->base_addr; + priv->init_block = (struct lance_init_block *)dev->mem_start; + priv->lance_init_block = (struct lance_init_block *)A2065_RAM; + priv->auto_select = 0; + priv->busmaster_regval = LE_C3_BSWP; + + priv->lance_log_rx_bufs = LANCE_LOG_RX_BUFFERS; + priv->lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS; + priv->rx_ring_mod_mask = RX_RING_MOD_MASK; + priv->tx_ring_mod_mask = TX_RING_MOD_MASK; + + dev->open = &lance_open; + dev->stop = &lance_close; + dev->hard_start_xmit = &lance_start_xmit; + dev->get_stats = &lance_get_stats; + dev->set_multicast_list = &lance_set_multicast; + dev->dma = 0; + + ether_setup(dev); + init_timer(&priv->multicast_timer); + priv->multicast_timer.data = (unsigned long) dev; + priv->multicast_timer.function = + (void (*)(unsigned long)) &lance_set_multicast; + + return(0); } return(-ENODEV); } @@ -845,7 +856,9 @@ struct lance_private *priv = (struct lance_private *)a2065_dev.priv; unregister_netdev(&a2065_dev); - zorro_unconfig_board(priv->key, 0); + release_mem_region(ZTWO_PADDR(a2065_dev.base_addr), + sizeof(struct lance_regs)); + release_mem_region(ZTWO_PADDR(a2065_dev.mem_start), A2065_RAM_SIZE); kfree(priv); } diff -ur --new-file old/linux/drivers/net/a2065.h new/linux/drivers/net/a2065.h --- old/linux/drivers/net/a2065.h Thu Aug 19 19:54:10 1999 +++ new/linux/drivers/net/a2065.h Wed Jan 26 21:45:20 2000 @@ -169,9 +169,8 @@ * A2065 Expansion Board Structure */ -struct A2065Board { - u_char Pad1[0x4000]; - volatile struct lance_regs Lance; - u_char Pad2[0x3ffc]; - volatile u_char RAM[0x8000]; -}; +#define A2065_LANCE 0x4000 + +#define A2065_RAM 0x8000 +#define A2065_RAM_SIZE 0x8000 + diff -ur --new-file old/linux/drivers/net/ariadne.c new/linux/drivers/net/ariadne.c --- old/linux/drivers/net/ariadne.c Sat Sep 4 22:08:32 1999 +++ new/linux/drivers/net/ariadne.c Wed Jan 26 21:45:20 2000 @@ -96,17 +96,15 @@ */ struct ariadne_private { - struct AriadneBoard *board; - struct TDRE *tx_ring[TX_RING_SIZE]; - struct RDRE *rx_ring[RX_RING_SIZE]; - u_short *tx_buff[TX_RING_SIZE]; - u_short *rx_buff[RX_RING_SIZE]; + volatile struct TDRE *tx_ring[TX_RING_SIZE]; + volatile struct RDRE *rx_ring[RX_RING_SIZE]; + volatile u_short *tx_buff[TX_RING_SIZE]; + volatile u_short *rx_buff[RX_RING_SIZE]; int cur_tx, cur_rx; /* The next free ring entry */ int dirty_tx; /* The ring entries to be free()ed. */ struct net_device_stats stats; char tx_full; unsigned long lock; - unsigned int key; }; @@ -134,7 +132,7 @@ #endif -static void memcpyw(u_short *dest, u_short *src, int len) +static void memcpyw(volatile u_short *dest, u_short *src, int len) { while (len >= 2) { *(dest++) = *(src++); @@ -147,71 +145,76 @@ int __init ariadne_probe(struct net_device *dev) { - unsigned int key; - const struct ConfigDev *cd; - u_long board; - struct ariadne_private *priv; - - /* Ethernet is part 0, Parallel is part 1 */ - if ((key = zorro_find(ZORRO_PROD_VILLAGE_TRONIC_ARIADNE, 0, 0))) { - cd = zorro_get_board(key); - if ((board = (u_long)cd->cd_BoardAddr)) { - dev->dev_addr[0] = 0x00; - dev->dev_addr[1] = 0x60; - dev->dev_addr[2] = 0x30; - dev->dev_addr[3] = (cd->cd_Rom.er_SerialNumber>>16)&0xff; - dev->dev_addr[4] = (cd->cd_Rom.er_SerialNumber>>8)&0xff; - dev->dev_addr[5] = cd->cd_Rom.er_SerialNumber&0xff; - printk("%s: Ariadne at 0x%08lx, Ethernet Address " - "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, board, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); - - init_etherdev(dev, 0); - - dev->priv = kmalloc(sizeof(struct ariadne_private), GFP_KERNEL); - if (dev->priv == NULL) - return -ENOMEM; - priv = (struct ariadne_private *)dev->priv; - memset(priv, 0, sizeof(struct ariadne_private)); - - priv->board = (struct AriadneBoard *)ZTWO_VADDR(board); - priv->key = key; - - dev->open = &ariadne_open; - dev->stop = &ariadne_close; - dev->hard_start_xmit = &ariadne_start_xmit; - dev->get_stats = &ariadne_get_stats; - dev->set_multicast_list = &set_multicast_list; + struct zorro_dev *z = NULL; - zorro_config_board(key, 0); - return(0); + while ((z = zorro_find_device(ZORRO_PROD_VILLAGE_TRONIC_ARIADNE, z))) { + unsigned long board = z->resource.start; + unsigned long base_addr = board+ARIADNE_LANCE; + unsigned long ram_start = board+ARIADNE_RAM; + + if (!request_mem_region(base_addr, sizeof(struct Am79C960), + "Am79C960")) + continue; + if (!request_mem_region(ram_start, ARIADNE_RAM_SIZE, "RAM")) { + release_mem_region(base_addr, sizeof(struct Am79C960)); + continue; } + strcpy(z->name, "Ariadne Ethernet Card and Parallel Ports"); + dev->dev_addr[0] = 0x00; + dev->dev_addr[1] = 0x60; + dev->dev_addr[2] = 0x30; + dev->dev_addr[3] = (z->rom.er_SerialNumber>>16)&0xff; + dev->dev_addr[4] = (z->rom.er_SerialNumber>>8)&0xff; + dev->dev_addr[5] = z->rom.er_SerialNumber&0xff; + printk("%s: Ariadne at 0x%08lx, Ethernet Address " + "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, board, + dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], + dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + + init_etherdev(dev, 0); + + dev->priv = kmalloc(sizeof(struct ariadne_private), GFP_KERNEL); + if (dev->priv == NULL) { + release_mem_region(base_addr, sizeof(struct Am79C960)); + release_mem_region(ram_start, ARIADNE_RAM_SIZE); + return -ENOMEM; + } + memset(dev->priv, 0, sizeof(struct ariadne_private)); + + dev->base_addr = ZTWO_VADDR(base_addr); + dev->mem_start = ZTWO_VADDR(ram_start); + dev->mem_end = dev->mem_start+ARIADNE_RAM_SIZE; + + dev->open = &ariadne_open; + dev->stop = &ariadne_close; + dev->hard_start_xmit = &ariadne_start_xmit; + dev->get_stats = &ariadne_get_stats; + dev->set_multicast_list = &set_multicast_list; + + return 0; } - return(ENODEV); + return -ENODEV; } static int ariadne_open(struct net_device *dev) { - struct ariadne_private *priv = (struct ariadne_private *)dev->priv; - struct AriadneBoard *board = priv->board; - struct lancedata *lancedata; + volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; u_short in; u_long version; /* Reset the LANCE */ - in = board->Lance.Reset; + in = lance->Reset; /* Stop the LANCE */ - board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */ - board->Lance.RDP = STOP; + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RDP = STOP; /* Check the LANCE version */ - board->Lance.RAP = CSR88; /* Chip ID */ - version = swapw(board->Lance.RDP); - board->Lance.RAP = CSR89; /* Chip ID */ - version |= swapw(board->Lance.RDP)<<16; + lance->RAP = CSR88; /* Chip ID */ + version = swapw(lance->RDP); + lance->RAP = CSR89; /* Chip ID */ + version |= swapw(lance->RDP)<<16; if ((version & 0x00000fff) != 0x00000003) { printk("ariadne_open: Couldn't find AMD Ethernet Chip\n"); return(-EAGAIN); @@ -229,64 +232,62 @@ ariadne_init_ring(dev); /* Miscellaneous Stuff */ - board->Lance.RAP = CSR3; /* Interrupt Masks and Deferral Control */ - board->Lance.RDP = 0x0000; - board->Lance.RAP = CSR4; /* Test and Features Control */ - board->Lance.RDP = DPOLL|APAD_XMT|MFCOM|RCVCCOM|TXSTRTM|JABM; + lance->RAP = CSR3; /* Interrupt Masks and Deferral Control */ + lance->RDP = 0x0000; + lance->RAP = CSR4; /* Test and Features Control */ + lance->RDP = DPOLL|APAD_XMT|MFCOM|RCVCCOM|TXSTRTM|JABM; /* Set the Multicast Table */ - board->Lance.RAP = CSR8; /* Logical Address Filter, LADRF[15:0] */ - board->Lance.RDP = 0x0000; - board->Lance.RAP = CSR9; /* Logical Address Filter, LADRF[31:16] */ - board->Lance.RDP = 0x0000; - board->Lance.RAP = CSR10; /* Logical Address Filter, LADRF[47:32] */ - board->Lance.RDP = 0x0000; - board->Lance.RAP = CSR11; /* Logical Address Filter, LADRF[63:48] */ - board->Lance.RDP = 0x0000; + lance->RAP = CSR8; /* Logical Address Filter, LADRF[15:0] */ + lance->RDP = 0x0000; + lance->RAP = CSR9; /* Logical Address Filter, LADRF[31:16] */ + lance->RDP = 0x0000; + lance->RAP = CSR10; /* Logical Address Filter, LADRF[47:32] */ + lance->RDP = 0x0000; + lance->RAP = CSR11; /* Logical Address Filter, LADRF[63:48] */ + lance->RDP = 0x0000; /* Set the Ethernet Hardware Address */ - board->Lance.RAP = CSR12; /* Physical Address Register, PADR[15:0] */ - board->Lance.RDP = ((u_short *)&dev->dev_addr[0])[0]; - board->Lance.RAP = CSR13; /* Physical Address Register, PADR[31:16] */ - board->Lance.RDP = ((u_short *)&dev->dev_addr[0])[1]; - board->Lance.RAP = CSR14; /* Physical Address Register, PADR[47:32] */ - board->Lance.RDP = ((u_short *)&dev->dev_addr[0])[2]; + lance->RAP = CSR12; /* Physical Address Register, PADR[15:0] */ + lance->RDP = ((u_short *)&dev->dev_addr[0])[0]; + lance->RAP = CSR13; /* Physical Address Register, PADR[31:16] */ + lance->RDP = ((u_short *)&dev->dev_addr[0])[1]; + lance->RAP = CSR14; /* Physical Address Register, PADR[47:32] */ + lance->RDP = ((u_short *)&dev->dev_addr[0])[2]; /* Set the Init Block Mode */ - board->Lance.RAP = CSR15; /* Mode Register */ - board->Lance.RDP = 0x0000; - - lancedata = (struct lancedata *)offsetof(struct AriadneBoard, RAM); + lance->RAP = CSR15; /* Mode Register */ + lance->RDP = 0x0000; /* Set the Transmit Descriptor Ring Pointer */ - board->Lance.RAP = CSR30; /* Base Address of Transmit Ring */ - board->Lance.RDP = swloww((u_long)&lancedata->tx_ring); - board->Lance.RAP = CSR31; /* Base Address of transmit Ring */ - board->Lance.RDP = swhighw((u_long)&lancedata->tx_ring); + lance->RAP = CSR30; /* Base Address of Transmit Ring */ + lance->RDP = swloww(ARIADNE_RAM+offsetof(struct lancedata, tx_ring)); + lance->RAP = CSR31; /* Base Address of transmit Ring */ + lance->RDP = swhighw(ARIADNE_RAM+offsetof(struct lancedata, tx_ring)); /* Set the Receive Descriptor Ring Pointer */ - board->Lance.RAP = CSR24; /* Base Address of Receive Ring */ - board->Lance.RDP = swloww((u_long)&lancedata->rx_ring); - board->Lance.RAP = CSR25; /* Base Address of Receive Ring */ - board->Lance.RDP = swhighw((u_long)&lancedata->rx_ring); + lance->RAP = CSR24; /* Base Address of Receive Ring */ + lance->RDP = swloww(ARIADNE_RAM+offsetof(struct lancedata, rx_ring)); + lance->RAP = CSR25; /* Base Address of Receive Ring */ + lance->RDP = swhighw(ARIADNE_RAM+offsetof(struct lancedata, rx_ring)); /* Set the Number of RX and TX Ring Entries */ - board->Lance.RAP = CSR76; /* Receive Ring Length */ - board->Lance.RDP = swapw(((u_short)-RX_RING_SIZE)); - board->Lance.RAP = CSR78; /* Transmit Ring Length */ - board->Lance.RDP = swapw(((u_short)-TX_RING_SIZE)); + lance->RAP = CSR76; /* Receive Ring Length */ + lance->RDP = swapw(((u_short)-RX_RING_SIZE)); + lance->RAP = CSR78; /* Transmit Ring Length */ + lance->RDP = swapw(((u_short)-TX_RING_SIZE)); /* Enable Media Interface Port Auto Select (10BASE-2/10BASE-T) */ - board->Lance.RAP = ISACSR2; /* Miscellaneous Configuration */ - board->Lance.IDP = ASEL; + lance->RAP = ISACSR2; /* Miscellaneous Configuration */ + lance->IDP = ASEL; /* LED Control */ - board->Lance.RAP = ISACSR5; /* LED1 Status */ - board->Lance.IDP = PSE|XMTE; - board->Lance.RAP = ISACSR6; /* LED2 Status */ - board->Lance.IDP = PSE|COLE; - board->Lance.RAP = ISACSR7; /* LED3 Status */ - board->Lance.IDP = PSE|RCVE; + lance->RAP = ISACSR5; /* LED1 Status */ + lance->IDP = PSE|XMTE; + lance->RAP = ISACSR6; /* LED2 Status */ + lance->IDP = PSE|COLE; + lance->RAP = ISACSR7; /* LED3 Status */ + lance->IDP = PSE|RCVE; dev->tbusy = 0; dev->interrupt = 0; @@ -296,8 +297,8 @@ "Ariadne Ethernet", dev)) return(-EAGAIN); - board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */ - board->Lance.RDP = INEA|STRT; + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RDP = INEA|STRT; MOD_INC_USE_COUNT; @@ -308,45 +309,42 @@ static void ariadne_init_ring(struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; - struct AriadneBoard *board = priv->board; - struct lancedata *lancedata; /* LANCE point of view */ - struct lancedata *alancedata; /* Amiga point of view */ + volatile struct lancedata *lancedata = (struct lancedata *)dev->mem_start; int i; priv->lock = 0, priv->tx_full = 0; priv->cur_rx = priv->cur_tx = 0; priv->dirty_tx = 0; - lancedata = (struct lancedata *)offsetof(struct AriadneBoard, RAM); - alancedata = (struct lancedata *)board->RAM; - /* Set up TX Ring */ for (i = 0; i < TX_RING_SIZE; i++) { - alancedata->tx_ring[i].TMD0 = swloww((u_long)lancedata->tx_buff[i]); - alancedata->tx_ring[i].TMD1 = swhighw((u_long)lancedata->tx_buff[i])|TF_STP|TF_ENP; - alancedata->tx_ring[i].TMD2 = swapw((u_short)-PKT_BUF_SIZE); - alancedata->tx_ring[i].TMD3 = 0; - priv->tx_ring[i] = &alancedata->tx_ring[i]; - priv->tx_buff[i] = alancedata->tx_buff[i]; + volatile struct TDRE *t = &lancedata->tx_ring[i]; + t->TMD0 = swloww(ARIADNE_RAM+offsetof(struct lancedata, tx_buff[i])); + t->TMD1 = swhighw(ARIADNE_RAM+offsetof(struct lancedata, tx_buff[i])) | + TF_STP | TF_ENP; + t->TMD2 = swapw((u_short)-PKT_BUF_SIZE); + t->TMD3 = 0; + priv->tx_ring[i] = &lancedata->tx_ring[i]; + priv->tx_buff[i] = lancedata->tx_buff[i]; #if 0 - printk("TX Entry %2d @ 0x%08x (LANCE 0x%08x), Buf @ 0x%08x (LANCE 0x%08x)\n", - i, (int)&alancedata->tx_ring[i], (int)&lancedata->tx_ring[i], - (int)alancedata->tx_buff[i], (int)lancedata->tx_buff[i]); + printk("TX Entry %2d at %p, Buf at %p\n", i, &lancedata->tx_ring[i], + lancedata->tx_buff[i]); #endif } /* Set up RX Ring */ for (i = 0; i < RX_RING_SIZE; i++) { - alancedata->rx_ring[i].RMD0 = swloww((u_long)lancedata->rx_buff[i]); - alancedata->rx_ring[i].RMD1 = swhighw((u_long)lancedata->rx_buff[i])|RF_OWN; - alancedata->rx_ring[i].RMD2 = swapw((u_short)-PKT_BUF_SIZE); - alancedata->rx_ring[i].RMD3 = 0x0000; - priv->rx_ring[i] = &alancedata->rx_ring[i]; - priv->rx_buff[i] = alancedata->rx_buff[i]; + volatile struct RDRE *r = &lancedata->rx_ring[i]; + r->RMD0 = swloww(ARIADNE_RAM+offsetof(struct lancedata, rx_buff[i])); + r->RMD1 = swhighw(ARIADNE_RAM+offsetof(struct lancedata, rx_buff[i])) | + RF_OWN; + r->RMD2 = swapw((u_short)-PKT_BUF_SIZE); + r->RMD3 = 0x0000; + priv->rx_ring[i] = &lancedata->rx_ring[i]; + priv->rx_buff[i] = lancedata->rx_buff[i]; #if 0 - printk("RX Entry %2d @ 0x%08x (LANCE 0x%08x), Buf @ 0x%08x (LANCE 0x%08x)\n", - i, (int)&alancedata->rx_ring[i], (int)&lancedata->rx_ring[i], - (int)alancedata->rx_buff[i], (int)lancedata->rx_buff[i]); + printk("RX Entry %2d at %p, Buf at %p\n", i, &lancedata->rx_ring[i], + lancedata->rx_buff[i]); #endif } } @@ -355,24 +353,24 @@ static int ariadne_close(struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; - struct AriadneBoard *board = priv->board; + volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; dev->start = 0; dev->tbusy = 1; - board->Lance.RAP = CSR112; /* Missed Frame Count */ - priv->stats.rx_missed_errors = swapw(board->Lance.RDP); - board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RAP = CSR112; /* Missed Frame Count */ + priv->stats.rx_missed_errors = swapw(lance->RDP); + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ if (ariadne_debug > 1) { printk("%s: Shutting down ethercard, status was %2.2x.\n", dev->name, - board->Lance.RDP); + lance->RDP); printk("%s: %lu packets missed\n", dev->name, priv->stats.rx_missed_errors); } /* We stop the LANCE here -- it occasionally polls memory if we don't. */ - board->Lance.RDP = STOP; + lance->RDP = STOP; free_irq(IRQ_AMIGA_PORTS, dev); @@ -385,21 +383,18 @@ static void ariadne_interrupt(int irq, void *data, struct pt_regs *fp) { struct net_device *dev = (struct net_device *)data; + volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; struct ariadne_private *priv; - struct AriadneBoard *board; - int csr0, boguscnt = 10; + int csr0, boguscnt; if (dev == NULL) { printk("ariadne_interrupt(): irq for unknown device.\n"); return; } - priv = (struct ariadne_private *)dev->priv; - board = priv->board; - - board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ - if (!(board->Lance.RDP & INTR)) /* Check if any interrupt has been */ + if (!(lance->RDP & INTR)) /* Check if any interrupt has been */ return; /* generated by the board. */ if (dev->interrupt) @@ -407,14 +402,17 @@ dev->interrupt = 1; - while ((csr0 = board->Lance.RDP) & (ERR|RINT|TINT) && --boguscnt >= 0) { + priv = (struct ariadne_private *)dev->priv; + + boguscnt = 10; + while ((csr0 = lance->RDP) & (ERR|RINT|TINT) && --boguscnt >= 0) { /* Acknowledge all of the current interrupt sources ASAP. */ - board->Lance.RDP = csr0 & ~(INEA|TDMD|STOP|STRT|INIT); + lance->RDP = csr0 & ~(INEA|TDMD|STOP|STRT|INIT); #if 0 if (ariadne_debug > 5) { printk("%s: interrupt csr0=%#2.2x new csr=%#2.2x.", dev->name, - csr0, board->Lance.RDP); + csr0, lance->RDP); printk("["); if (csr0 & INTR) printk(" INTR"); @@ -484,7 +482,7 @@ printk("%s: Tx FIFO error! Status %4.4x.\n", dev->name, csr0); /* Restart the chip. */ - board->Lance.RDP = STRT; + lance->RDP = STRT; } } else { if (status & (TF_MORE|TF_ONE)) @@ -522,18 +520,18 @@ printk("%s: Bus master arbitration failure, status %4.4x.\n", dev->name, csr0); /* Restart the chip. */ - board->Lance.RDP = STRT; + lance->RDP = STRT; } } /* Clear any other interrupt, and set interrupt enable. */ - board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */ - board->Lance.RDP = INEA|BABL|CERR|MISS|MERR|IDON; + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RDP = INEA|BABL|CERR|MISS|MERR|IDON; #if 0 if (ariadne_debug > 4) - printk("%s: exiting interrupt, csr%d=%#4.4x.\n", dev->name, - board->Lance.RAP, board->Lance.RDP); + printk("%s: exiting interrupt, csr%d=%#4.4x.\n", dev->name, lance->RAP, + lance->RDP); #endif dev->interrupt = 0; @@ -544,7 +542,7 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; - struct AriadneBoard *board = priv->board; + volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; int entry; unsigned long flags; @@ -553,10 +551,10 @@ int tickssofar = jiffies - dev->trans_start; if (tickssofar < 20) return(1); - board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ printk("%s: transmit timed out, status %4.4x, resetting.\n", dev->name, - board->Lance.RDP); - board->Lance.RDP = STOP; + lance->RDP); + lance->RDP = STOP; priv->stats.tx_errors++; #ifndef final_version { @@ -566,17 +564,20 @@ priv->cur_rx); for (i = 0 ; i < RX_RING_SIZE; i++) printk("%s %08x %04x %04x", i & 0x3 ? "" : "\n ", - (swapw((priv->rx_ring[i]->RMD1))<<16)|swapw(priv->rx_ring[i]->RMD0), - swapw(-priv->rx_ring[i]->RMD2), swapw(priv->rx_ring[i]->RMD3)); + (swapw((priv->rx_ring[i]->RMD1))<<16) | + swapw(priv->rx_ring[i]->RMD0), + swapw(-priv->rx_ring[i]->RMD2), + swapw(priv->rx_ring[i]->RMD3)); for (i = 0 ; i < TX_RING_SIZE; i++) printk("%s %08x %04x %04x", i & 0x3 ? "" : "\n ", - (swapw((priv->tx_ring[i]->TMD1))<<16)|swapw(priv->tx_ring[i]->TMD0), + (swapw((priv->tx_ring[i]->TMD1))<<16) | + swapw(priv->tx_ring[i]->TMD0), swapw(-priv->tx_ring[i]->TMD2), priv->tx_ring[i]->TMD3); printk("\n"); } #endif ariadne_init_ring(dev); - board->Lance.RDP = INEA|STRT; + lance->RDP = INEA|STRT; dev->tbusy = 0; dev->trans_start = jiffies; @@ -586,10 +587,10 @@ #if 0 if (ariadne_debug > 3) { - board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ printk("%s: ariadne_start_xmit() called, csr0 %4.4x.\n", dev->name, - board->Lance.RDP); - board->Lance.RDP = 0x0000; + lance->RDP); + lance->RDP = 0x0000; } #endif @@ -675,8 +676,8 @@ } /* Trigger an immediate send poll. */ - board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */ - board->Lance.RDP = INEA|TDMD; + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RDP = INEA|TDMD; dev->trans_start = jiffies; @@ -782,16 +783,16 @@ static struct net_device_stats *ariadne_get_stats(struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; - struct AriadneBoard *board = priv->board; + volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; short saved_addr; unsigned long flags; save_flags(flags); cli(); - saved_addr = board->Lance.RAP; - board->Lance.RAP = CSR112; /* Missed Frame Count */ - priv->stats.rx_missed_errors = swapw(board->Lance.RDP); - board->Lance.RAP = saved_addr; + saved_addr = lance->RAP; + lance->RAP = CSR112; /* Missed Frame Count */ + priv->stats.rx_missed_errors = swapw(lance->RDP); + lance->RAP = saved_addr; restore_flags(flags); return(&priv->stats); @@ -806,18 +807,18 @@ */ static void set_multicast_list(struct net_device *dev) { - struct ariadne_private *priv = (struct ariadne_private *)dev->priv; - struct AriadneBoard *board = priv->board; + volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; /* We take the simple way out and always enable promiscuous mode. */ - board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */ - board->Lance.RDP = STOP; /* Temporarily stop the lance. */ + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RDP = STOP; /* Temporarily stop the lance. */ + ariadne_init_ring(dev); if (dev->flags & IFF_PROMISC) { /* Log any net taps. */ printk("%s: Promiscuous mode enabled.\n", dev->name); - board->Lance.RAP = CSR15; /* Mode Register */ - board->Lance.RDP = PROM; /* Set promiscuous mode */ + lance->RAP = CSR15; /* Mode Register */ + lance->RDP = PROM; /* Set promiscuous mode */ } else { short multicast_table[4]; int num_addrs = dev->mc_count; @@ -826,15 +827,15 @@ memset(multicast_table, (num_addrs == 0) ? 0 : -1, sizeof(multicast_table)); for (i = 0; i < 4; i++) { - board->Lance.RAP = CSR8+(i<<8); /* Logical Address Filter */ - board->Lance.RDP = swapw(multicast_table[i]); + lance->RAP = CSR8+(i<<8); /* Logical Address Filter */ + lance->RDP = swapw(multicast_table[i]); } - board->Lance.RAP = CSR15; /* Mode Register */ - board->Lance.RDP = 0x0000; /* Unset promiscuous mode */ + lance->RAP = CSR15; /* Mode Register */ + lance->RDP = 0x0000; /* Unset promiscuous mode */ } - board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */ - board->Lance.RDP = INEA|STRT|IDON; /* Resume normal operation. */ + lance->RAP = CSR0; /* PCnet-ISA Controller Status */ + lance->RDP = INEA|STRT|IDON; /* Resume normal operation. */ } @@ -866,7 +867,9 @@ struct ariadne_private *priv = (struct ariadne_private *)ariadne_dev.priv; unregister_netdev(&ariadne_dev); - zorro_unconfig_board(priv->key, 0); + release_mem_region(ZTWO_PADDR(ariadne_dev.base_addr), + sizeof(struct Am79C960)); + release_mem_region(ZTWO_PADDR(ariadne_dev.mem_start), ARIADNE_RAM_SIZE); kfree(priv); } diff -ur --new-file old/linux/drivers/net/ariadne.h new/linux/drivers/net/ariadne.h --- old/linux/drivers/net/ariadne.h Thu Aug 19 19:54:10 1999 +++ new/linux/drivers/net/ariadne.h Wed Jan 26 21:45:20 2000 @@ -403,12 +403,13 @@ * Ariadne Expansion Board Structure */ -struct AriadneBoard { - u_char Pad1[0x360]; - struct Am79C960 Lance; - u_char Pad2[0xc88]; - struct MC68230 PiT; - u_char Pad3[0x2fc0]; - volatile u_short BootPROM[0x2000]; /* I guess it's here :-) */ - volatile u_short RAM[0x4000]; /* Always access WORDs!! */ -}; +#define ARIADNE_LANCE 0x360 + +#define ARIADNE_PIT 0x1000 + +#define ARIADNE_BOOTPROM 0x4000 /* I guess it's here :-) */ +#define ARIADNE_BOOTPROM_SIZE 0x4000 + +#define ARIADNE_RAM 0x8000 /* Always access WORDs!! */ +#define ARIADNE_RAM_SIZE 0x8000 + diff -ur --new-file old/linux/drivers/net/ariadne2.c new/linux/drivers/net/ariadne2.c --- old/linux/drivers/net/ariadne2.c Wed Aug 18 20:36:41 1999 +++ new/linux/drivers/net/ariadne2.c Wed Jan 26 21:45:20 2000 @@ -66,8 +66,7 @@ #define WORDSWAP(a) ((((a)>>8)&0xff) | ((a)<<8)) int ariadne2_probe(struct net_device *dev); -static int ariadne2_init(struct net_device *dev, unsigned int key, - unsigned long board); +static int ariadne2_init(struct net_device *dev, unsigned long board); static int ariadne2_open(struct net_device *dev); static int ariadne2_close(struct net_device *dev); @@ -83,25 +82,26 @@ int __init ariadne2_probe(struct net_device *dev) { - unsigned int key; - const struct ConfigDev *cd; - u_long board; + struct zorro_dev *z = NULL; + unsigned long board, ioaddr; int err; - if ((key = zorro_find(ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, 0, 0))) { - cd = zorro_get_board(key); - if ((board = (u_long)cd->cd_BoardAddr)) { - if ((err = ariadne2_init(dev, key, ZTWO_VADDR(board)))) - return err; - zorro_config_board(key, 0); - return 0; + while ((z = zorro_find_device(ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, z))) { + board = z->resource.start; + ioaddr = board+ARIADNE2_BASE*2; + if (!request_mem_region(ioaddr, NE_IO_EXTENT*2, "RTL8019AS")) + continue; + if ((err = ariadne2_init(dev, ZTWO_VADDR(board)))) { + release_mem_region(ioaddr, NE_IO_EXTENT*2); + return err; } + strcpy(z->name, "AriadNE2 Ethernet"); + return 0; } return -ENODEV; } -static int __init ariadne2_init(struct net_device *dev, unsigned int key, - unsigned long board) +static int __init ariadne2_init(struct net_device *dev, unsigned long board) { int i; unsigned char SA_prom[32]; @@ -111,7 +111,7 @@ 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, }; - int ioaddr = board+ARIADNE2_BASE*2; + unsigned long ioaddr = board+ARIADNE2_BASE*2; if (load_8390_module("ariadne2.c")) return -ENOSYS; @@ -189,7 +189,6 @@ printk("Unable to get memory for dev->priv.\n"); return -ENOMEM; } - ((struct ei_device *)dev->priv)->priv = key; for(i = 0; i < ETHER_ADDR_LEN; i++) { #ifdef DEBUG @@ -417,10 +416,9 @@ void cleanup_module(void) { - unsigned int key = ((struct ei_device *)ariadne2_dev.priv)->priv; free_irq(IRQ_AMIGA_PORTS, &ariadne2_dev); + release_mem_region(ZTWO_PADDR(ariadne2_dev.base_addr), NE_IO_EXTENT*2); unregister_netdev(&ariadne2_dev); - zorro_unconfig_board(key, 0); unlock_8390_module(); } diff -ur --new-file old/linux/drivers/net/eexpress.c new/linux/drivers/net/eexpress.c --- old/linux/drivers/net/eexpress.c Wed Sep 8 20:51:22 1999 +++ new/linux/drivers/net/eexpress.c Wed Jan 26 22:16:05 2000 @@ -9,6 +9,7 @@ * Many modifications, and currently maintained, by * Philip Blundell * Added the Compaq LTE Alan Cox + * Added MCA support Adam Fritzler * * Note - this driver is experimental still - it has problems on faster * machines. Someone needs to sit down and go through it line by line with @@ -120,6 +121,7 @@ #include #include #include +#include #include @@ -232,6 +234,16 @@ /* maps irq number to EtherExpress magic value */ static char irqrmap[] = { 0,0,1,2,3,4,0,0,0,1,5,6,0,0,0,0 }; +#ifdef CONFIG_MCA +/* mapping of the first four bits of the second POS register */ +static unsigned short mca_iomap[] = { + 0x270, 0x260, 0x250, 0x240, 0x230, 0x220, 0x210, 0x200, + 0x370, 0x360, 0x350, 0x340, 0x330, 0x320, 0x310, 0x300 +}; +/* bits 5-7 of the second POS register */ +static char mca_irqmap[] = { 12, 9, 3, 4, 5, 10, 11, 15 }; +#endif + /* * Prototypes for Linux interface */ @@ -331,6 +343,55 @@ static unsigned short ports[] = { 0x300,0x310,0x270,0x320,0x340,0 }; unsigned short ioaddr = dev->base_addr; + dev->if_port = 0xff; /* not set */ + +#ifdef CONFIG_MCA + if (MCA_bus) { + int slot = 0; + + /* + * Only find one card at a time. Subsequent calls + * will find others, however, proper multicard MCA + * probing and setup can't be done with the + * old-style Space.c init routines. -- ASF + */ + while (slot != MCA_NOTFOUND) { + int pos0, pos1; + + slot = mca_find_unused_adapter(0x628B, slot); + if (slot == MCA_NOTFOUND) + break; + + pos0 = mca_read_stored_pos(slot, 2); + pos1 = mca_read_stored_pos(slot, 3); + ioaddr = mca_iomap[pos1&0xf]; + + dev->irq = mca_irqmap[(pos1>>4)&0x7]; + + /* + * XXX: Transciever selection is done + * differently on the MCA version. + * How to get it to select something + * other than external/AUI is currently + * unknown. This code is just for looks. -- ASF + */ + if ((pos0 & 0x7) == 0x1) + dev->if_port = AUI; + else if ((pos0 & 0x7) == 0x5) { + if (pos1 & 0x80) + dev->if_port = BNC; + else + dev->if_port = TPE; + } + + mca_set_adapter_name(slot, "Intel EtherExpress 16 MCA"); + mca_set_adapter_procfn(slot, NULL, dev); + mca_mark_as_used(slot); + + break; + } + } +#endif if (ioaddr&0xfe00) return eexp_hw_probe(dev,ioaddr); else if (ioaddr) @@ -522,7 +583,9 @@ static int eexp_xmit(struct sk_buff *buf, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; +#ifdef CONFIG_SMP unsigned long flags; +#endif #if NET_DEBUG > 6 printk(KERN_DEBUG "%s: eexp_xmit()\n", dev->name); @@ -1010,8 +1073,10 @@ if (!dev->irq) dev->irq = irqmap[setupval>>13]; - dev->if_port = !(setupval & 0x1000) ? AUI : - eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TPE : BNC; + if (dev->if_port == 0xff) { + dev->if_port = !(setupval & 0x1000) ? AUI : + eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TPE : BNC; + } buswidth = !((setupval & 0x400) >> 10); } diff -ur --new-file old/linux/drivers/net/hydra.c new/linux/drivers/net/hydra.c --- old/linux/drivers/net/hydra.c Thu Aug 19 19:54:10 1999 +++ new/linux/drivers/net/hydra.c Wed Jan 26 21:45:20 2000 @@ -80,14 +80,11 @@ */ struct hydra_private { - u8 *hydra_base; - u8 *hydra_nic_base; u16 tx_page_start; u16 rx_page_start; u16 rx_page_stop; u16 next_pkt; struct net_device_stats stats; - unsigned int key; }; static int hydra_open(struct net_device *dev); @@ -159,52 +156,53 @@ int __init hydra_probe(struct net_device *dev) { - struct hydra_private *priv; - u32 board; - unsigned int key; - const struct ConfigDev *cd; + struct zorro_dev *z = NULL; int j; #ifdef HYDRA_DEBUG printk("hydra_probe(%x)\n", dev); #endif - if ((key = zorro_find(ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET, 0, 0))) - { - cd = zorro_get_board(key); - if((board = (u32) cd->cd_BoardAddr)) - { - for(j = 0; j < ETHER_ADDR_LEN; j++) - dev->dev_addr[j] = *((u8 *)ZTWO_VADDR(board + HYDRA_ADDRPROM + 2*j)); - - printk("%s: hydra at 0x%08x, address %02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n", - dev->name, (int)board, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); - init_etherdev(dev, 0); - - dev->priv = kmalloc(sizeof(struct hydra_private), GFP_KERNEL); - priv = (struct hydra_private *)dev->priv; - memset(priv, 0, sizeof(struct hydra_private)); - - priv->hydra_base = (u8 *) ZTWO_VADDR(board); - priv->hydra_nic_base = (u8 *) ZTWO_VADDR(board) + HYDRA_NIC_BASE; - priv->key = key; - - dev->open = &hydra_open; - dev->stop = &hydra_close; - dev->hard_start_xmit = &hydra_start_xmit; - dev->get_stats = &hydra_get_stats; + while ((z = zorro_find_device(ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET, z))) { + unsigned long board = z->resource.start; + unsigned long base_addr = board+HYDRA_NIC_BASE; + + if (!request_mem_region(base_addr, 0x20, "NS8390")) + continue; + if (!request_mem_region(board, 0x4000, "RAM")) { + release_mem_region(base_addr, 0x20); + continue; + } + strcpy(z->name, "Hydra Ethernet Card"); + + for(j = 0; j < ETHER_ADDR_LEN; j++) + dev->dev_addr[j] = *((u8 *)ZTWO_VADDR(board + HYDRA_ADDRPROM + 2*j)); + + printk("%s: hydra at 0x%08x, address %02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n", + dev->name, (int)board, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], + dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + init_etherdev(dev, 0); + + dev->priv = kmalloc(sizeof(struct hydra_private), GFP_KERNEL); + memset(dev->priv, 0, sizeof(struct hydra_private)); + + dev->base_addr = ZTWO_VADDR(base_addr); + dev->mem_start = ZTWO_VADDR(board); + dev->mem_end = dev->mem_start+0x4000; + + dev->open = &hydra_open; + dev->stop = &hydra_close; + dev->hard_start_xmit = &hydra_start_xmit; + dev->get_stats = &hydra_get_stats; #ifdef HAVE_MULTICAST - dev->set_multicast_list = &set_multicast_list; + dev->set_multicast_list = &set_multicast_list; #endif - - /* - * Cannot yet do multicast - */ - dev->flags&=~IFF_MULTICAST; - zorro_config_board(key, 0); - return(0); - } + + /* + * Cannot yet do multicast + */ + dev->flags&=~IFF_MULTICAST; + return(0); } return(-ENODEV); } @@ -213,7 +211,7 @@ static int hydra_open(struct net_device *dev) { struct hydra_private *priv = (struct hydra_private *)dev->priv; - volatile u8 *nicbase = priv->hydra_nic_base; + volatile u8 *nicbase = (u8 *)dev->base_addr; int i; #ifdef HYDRA_DEBUG @@ -295,7 +293,7 @@ static int hydra_close(struct net_device *dev) { struct hydra_private *priv = (struct hydra_private *)dev->priv; - volatile u8 *nicbase = priv->hydra_nic_base; + volatile u8 *nicbase = (u8 *)dev->base_addr; int n = 5000; dev->start = 0; @@ -340,7 +338,7 @@ dev->interrupt = 1; priv = (struct hydra_private *) dev->priv; - nicbase = (u8 *) priv->hydra_nic_base; + nicbase = (u8 *)dev->base_addr; /* select page 0 */ WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA); @@ -437,7 +435,7 @@ static int hydra_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct hydra_private *priv = (struct hydra_private *)dev->priv; - volatile u8 *nicbase = priv->hydra_nic_base; + volatile u8 *nicbase = (u8 *)dev->base_addr; int len, len1; /* Transmitter timeout, serious problems. */ @@ -491,16 +489,17 @@ /* make sure we've got an even number of bytes to copy to hydra's mem */ if(len & 1) len++; - if((u32)(priv->hydra_base + (priv->tx_page_start << 8)) < 0x80000000) - printk("weirdness: memcpyw(txbuf, skbdata, len): txbuf = 0x%x\n", (u_int)(priv->hydra_base+(priv->tx_page_start<<8))); + if((u32)(dev->mem_start + (priv->tx_page_start << 8)) < 0x80000000) + printk("weirdness: memcpyw(txbuf, skbdata, len): txbuf = 0x%x\n", (u_int)(dev->mem_start+(priv->tx_page_start<<8))); /* copy the packet data to the transmit buffer in the ethernet card RAM */ - memcpyw((u16 *)(priv->hydra_base + (priv->tx_page_start << 8)), + memcpyw((u16 *)(dev->mem_start + (priv->tx_page_start << 8)), (u16 *)skb->data, len); /* clear the unused space */ for(; len1hydra_base + (priv->tx_page_start<<8) + len1) = 0; + (u16)*((u8 *)dev->mem_start + (priv->tx_page_start<<8) + len1) + = 0; dev_kfree_skb(skb); priv->stats.tx_packets++; @@ -536,7 +535,7 @@ WRITE_REG(NIC_CR, CR_PAGE1 | CR_NODMA | CR_START); /* page 1 */ while(priv->next_pkt != READ_REG(NIC_CURR)) /* should read this only once? */ { - board_ram_ptr = (u16 *)(priv->hydra_base + (priv->next_pkt << 8)); + board_ram_ptr = (u16 *)(dev->mem_start + (priv->next_pkt << 8)); #ifdef HYDRA_DEBUG printk("next_pkt = 0x%x, board_ram_ptr = 0x%x\n", priv->next_pkt, board_ram_ptr); @@ -577,7 +576,7 @@ len1 = ((priv->rx_page_stop - priv->next_pkt)<<8)-4; memcpyw((u16 *)skb_put(skb, len1), (u16 *)(board_ram_ptr+2), len1); - memcpyw((u16 *)skb_put(skb, pkt_len-len1), (u16 *)(priv->hydra_base+(priv->rx_page_start<<8)), pkt_len-len1); + memcpyw((u16 *)skb_put(skb, pkt_len-len1), (u16 *)(dev->mem_start+(priv->rx_page_start<<8)), pkt_len-len1); #ifdef HYDRA_DEBUG printk("wrapped packet: %d/%d bytes\n", len1, pkt_len-len1); @@ -638,7 +637,7 @@ { struct hydra_private *priv = (struct hydra_private *)dev->priv; #if 0 - u8 *board = priv->hydra_base; + u8 *board = (u8 *)dev->mem_start; short saved_addr; #endif @@ -651,7 +650,7 @@ static void set_multicast_list(struct net_device *dev, int num_addrs, void *addrs) { struct hydra_private *priv = (struct hydra_private *)dev->priv; - u8 *board = priv->hydra_base; + u8 *board = (u8 *)dev->mem_start; /* yes, this code is also waiting for someone to complete.. :) */ /* (personally i don't care about multicasts at all :) */ @@ -688,7 +687,8 @@ struct hydra_private *priv = (struct hydra_private *)hydra_dev.priv; unregister_netdev(&hydra_dev); - zorro_unconfig_board(priv->key, 0); + release_mem_region(ZTWO_PADDR(hydra_dev.base_addr), 0x20); + release_mem_region(ZTWO_PADDR(hydra_dev.mem_start), 0x4000); kfree(priv); } diff -ur --new-file old/linux/drivers/net/pcmcia/Config.in new/linux/drivers/net/pcmcia/Config.in --- old/linux/drivers/net/pcmcia/Config.in Tue Jan 18 07:22:52 2000 +++ new/linux/drivers/net/pcmcia/Config.in Wed Jan 26 21:35:07 2000 @@ -31,8 +31,6 @@ fi fi -endmenu - if [ "$CONFIG_PCMCIA_3C589" = "y" -o "$CONFIG_PCMCIA_3C574" = "y" -o \ "$CONFIG_PCMCIA_FMVJ18X" = "y" -o "$CONFIG_PCMCIA_PCNET" = "y" -o \ "$CONFIG_PCMCIA_NMCLAN" = "y" -o "$CONFIG_PCMCIA_SMC91C92" = "y" -o \ @@ -40,3 +38,5 @@ "$CONFIG_PCMCIA_NETWAVE" = "y" -o "$CONFIG_PCMCIA_WAVELAN" = "y" ]; then define_bool CONFIG_PCMCIA_NETCARD y fi + +endmenu diff -ur --new-file old/linux/drivers/net/pcnet32.c new/linux/drivers/net/pcnet32.c --- old/linux/drivers/net/pcnet32.c Thu Jan 20 19:44:46 2000 +++ new/linux/drivers/net/pcnet32.c Wed Jan 26 22:16:05 2000 @@ -13,7 +13,7 @@ * This driver is for PCnet32 and PCnetPCI based ethercards */ -static const char *version = "pcnet32.c:v1.23ac 21.9.1999 tsbogend@alpha.franken.de\n"; +static const char *version = "pcnet32.c:v1.25kf 26.9.1999 tsbogend@alpha.franken.de\n"; #include #include @@ -41,12 +41,13 @@ static unsigned int pcnet32_portlist[] __initdata = {0x300, 0x320, 0x340, 0x360, 0}; static int pcnet32_debug = 1; +static int tx_start = 1; /* Mapping -- 0:20, 1:64, 2:128, 3:~220 (depends on chip vers) */ #ifdef MODULE static struct net_device *pcnet32_dev = NULL; #endif -static const int max_interrupt_work = 20; +static const int max_interrupt_work = 80; static const int rx_copybreak = 200; #define PORT_AUI 0x00 @@ -154,7 +155,12 @@ * Michael Richard ) * added chip id for 79c973/975 (thanks to Zach Brown ) * v1.23 fixed small bug, when manual selecting MII speed/duplex - * v1.23ac Added SMP spinlocking - Alan Cox + * v1.24 Applied Thomas' patch to use TxStartPoint and thus decrease TxFIFO + * underflows. Added tx_start_pt module parameter. Increased + * TX_RING_SIZE from 16 to 32. Added #ifdef'd code to use DXSUFLO + * for FAST[+] chipsets. + * v1.24ac Added SMP spinlocking - Alan Cox + * v1.25kf Added No Interrupt on successful Tx for some Tx's */ @@ -165,7 +171,7 @@ */ #ifndef PCNET32_LOG_TX_BUFFERS #define PCNET32_LOG_TX_BUFFERS 4 -#define PCNET32_LOG_RX_BUFFERS 4 +#define PCNET32_LOG_RX_BUFFERS 5 #endif #define TX_RING_SIZE (1 << (PCNET32_LOG_TX_BUFFERS)) @@ -255,12 +261,16 @@ struct pcnet32_access a; void *origmem; spinlock_t lock; /* Guard lock */ - int cur_rx, cur_tx; /* The next free ring entry */ - int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ + unsigned int cur_rx, cur_tx; /* The next free ring entry */ + unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ struct net_device_stats stats; char tx_full; int options; int shared_irq:1, /* shared irq possible */ + ltint:1, +#ifdef DO_DXSUFLO + dxsuflo:1, /* disable transmit stop on uflo */ +#endif full_duplex:1, /* full duplex possible */ mii:1; /* mii port available */ #ifdef MODULE @@ -299,6 +309,10 @@ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, 0, 0, PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE, pcnet32_probe1}, + { "AMD PCnetPCI series (IBM)", + PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, 0x1014, 0x2000, + PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE, + pcnet32_probe1}, { "AMD PCnetHome series", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_PCNETHOME, 0, 0, PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE, @@ -448,8 +462,8 @@ int chip_idx; u16 sdid,svid; - pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &sdid); - pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &svid); + pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &svid); + pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &sdid); for (chip_idx = 0; pcnet32_tbl[chip_idx].vendor_id; chip_idx++) if ((pdev->vendor == pcnet32_tbl[chip_idx].vendor_id) && (pdev->device == pcnet32_tbl[chip_idx].device_id) && @@ -510,6 +524,10 @@ { struct pcnet32_private *lp; int i,media,fdx = 0, mii = 0, fset = 0; +#ifdef DO_DXSUFLO + int dxsuflo = 0; +#endif + int ltint = 0; int chip_version; char *chipname; char *priv; @@ -552,6 +570,7 @@ case 0x2623: chipname = "PCnet/FAST 79C971"; fdx = 1; mii = 1; fset = 1; + ltint = 1; break; case 0x2624: chipname = "PCnet/FAST+ 79C972"; @@ -600,7 +619,11 @@ if(fset) { a->write_bcr(ioaddr, 18, (a->read_bcr(ioaddr, 18) | 0x0800)); - a->write_csr(ioaddr, 80, a->read_csr(ioaddr, 80) | 0x0c00); + a->write_csr(ioaddr, 80, (a->read_csr(ioaddr, 80) & 0x0C00) | 0x0c00); +#ifdef DO_DXSUFLO + dxsuflo = 1; +#endif + ltint = 1; } dev = init_etherdev(NULL, 0); @@ -614,6 +637,29 @@ for (i = 0; i < 6; i++) printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i)); + if (((chip_version + 1) & 0xfffe) == 0x2624) { /* Version 0x2623 or 0x2624 */ + i = a->read_csr(ioaddr, 80) & 0x0C00; /* Check tx_start_pt */ + printk("\n tx_start_pt(0x%04x):",i); + switch(i>>10) { + case 0: printk(" 20 bytes,"); break; + case 1: printk(" 64 bytes,"); break; + case 2: printk(" 128 bytes,"); break; + case 3: printk("~220 bytes,"); break; + } + i = a->read_bcr(ioaddr, 18); /* Check Burst/Bus control */ + printk(" BCR18(%x):",i&0xffff); + if (i & (1<<5)) printk("BurstWrEn "); + if (i & (1<<6)) printk("BurstRdEn "); + if (i & (1<<7)) printk("DWordIO "); + if (i & (1<<11)) printk("NoUFlow "); + i = a->read_bcr(ioaddr, 25); + printk("\n SRAMSIZE=0x%04x,",i<<8); + i = a->read_bcr(ioaddr, 26); + printk(" SRAM_BND=0x%04x,",i<<8); + i = a->read_bcr(ioaddr, 27); + if (i & (1<<14)) printk("LowLatRx,"); + } + dev->base_addr = ioaddr; request_region(ioaddr, PCNET32_TOTAL_SIZE, chipname); @@ -634,6 +680,10 @@ lp->name = chipname; lp->shared_irq = shared; lp->full_duplex = fdx; +#ifdef DO_DXSUFLO + lp->dxsuflo = dxsuflo; +#endif + lp->ltint = ltint; lp->mii = mii; if (options[card_idx] > sizeof (options_mapping)) lp->options = PORT_ASEL; @@ -775,7 +825,20 @@ val |= 0x08; lp->a.write_bcr (ioaddr, 32, val); } - + +#ifdef DO_DXSUFLO + if (lp->dxsuflo) { /* Disable transmit stop on underflow */ + val = lp->a.read_csr (ioaddr, 3); + val |= 0x40; + lp->a.write_csr (ioaddr, 3, val); + } +#endif + if (lp->ltint) { /* Enable TxDone-intr inhibitor */ + val = lp->a.read_csr (ioaddr, 5); + val |= (1<<14); + lp->a.write_csr (ioaddr, 5, val); + } + lp->init_block.mode = le16_to_cpu((lp->options & PORT_PORTSEL) << 7); lp->init_block.filter[0] = 0x00000000; lp->init_block.filter[1] = 0x00000000; @@ -905,6 +968,7 @@ { struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; unsigned int ioaddr = dev->base_addr; + u16 status; int entry; unsigned long flags; @@ -953,11 +1017,28 @@ } spin_lock_irqsave(&lp->lock, flags); - /* Fill in a Tx ring entry */ + /* Default status -- will not enable Successful-TxDone + * interrupt when that option is available to us. + */ + status = 0x8300; + if ((lp->ltint) && + ((lp->cur_tx - lp->dirty_tx == TX_RING_SIZE/2) || + (lp->cur_tx - lp->dirty_tx >= TX_RING_SIZE-2))) + { + /* Enable Successful-TxDone interrupt if we have + * 1/2 of, or nearly all of, our ring buffer Tx'd + * but not yet cleaned up. Thus, most of the time, + * we will not enable Successful-TxDone interrupts. + */ + status = 0x9300; + } + + /* Fill in a Tx ring entry */ + /* Mask to ring buffer boundary. */ entry = lp->cur_tx & TX_RING_MOD_MASK; - + /* Caution: the write order is important here, set the base address with the "ownership" bits last. */ @@ -967,7 +1048,7 @@ lp->tx_skbuff[entry] = skb; lp->tx_ring[entry].base = (u32)le32_to_cpu(virt_to_bus(skb->data)); - lp->tx_ring[entry].status = le16_to_cpu(0x8300); + lp->tx_ring[entry].status = le16_to_cpu(status); lp->cur_tx++; lp->stats.tx_bytes += skb->len; @@ -1026,7 +1107,7 @@ pcnet32_rx(dev); if (csr0 & 0x0200) { /* Tx-done interrupt */ - int dirty_tx = lp->dirty_tx; + unsigned int dirty_tx = lp->dirty_tx; while (dirty_tx < lp->cur_tx) { int entry = dirty_tx & TX_RING_MOD_MASK; @@ -1044,14 +1125,27 @@ if (err_status & 0x04000000) lp->stats.tx_aborted_errors++; if (err_status & 0x08000000) lp->stats.tx_carrier_errors++; if (err_status & 0x10000000) lp->stats.tx_window_errors++; - if (err_status & 0x40000000) { +#ifndef DO_DXSUFLO + if (err_status & 0x40000000) { + lp->stats.tx_fifo_errors++; /* Ackk! On FIFO errors the Tx unit is turned off! */ + /* Remove this verbosity later! */ + printk("%s: Tx FIFO error! CSR0=%4.4x\n", + dev->name, csr0); + must_restart = 1; + } +#else + if (err_status & 0x40000000) { lp->stats.tx_fifo_errors++; - /* Remove this verbosity later! */ - printk("%s: Tx FIFO error! Status %4.4x.\n", - dev->name, csr0); - must_restart = 1; - } + if (! lp->dxsuflo) { /* If controller doesn't recover ... */ + /* Ackk! On FIFO errors the Tx unit is turned off! */ + /* Remove this verbosity later! */ + printk("%s: Tx FIFO error! CSR0=%4.4x\n", + dev->name, csr0); + must_restart = 1; + } + } +#endif } else { if (status & 0x1800) lp->stats.collisions++; @@ -1388,18 +1482,22 @@ MODULE_PARM(debug, "i"); MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(rx_copybreak, "i"); +MODULE_PARM(tx_start_pt, "i"); MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); /* An additional parameter that may be passed in... */ static int debug = -1; +static int tx_start_pt = -1; int init_module(void) { if (debug > 0) pcnet32_debug = debug; + if ((tx_start_pt >= 0) && (tx_start_pt <= 3)) + tx_start = tx_start_pt; pcnet32_dev = NULL; return pcnet32_probe(); diff -ur --new-file old/linux/drivers/net/setup.c new/linux/drivers/net/setup.c --- old/linux/drivers/net/setup.c Fri Jan 14 03:03:58 2000 +++ new/linux/drivers/net/setup.c Wed Jan 26 22:16:05 2000 @@ -48,6 +48,7 @@ extern int rr_hippi_probe(void); extern int rtl8139_probe(void); extern int sdla_setup(void); +extern int sdla_c_setup(void); extern int sis900_probe(void); extern int skge_probe(void); extern int sparc_lance_probe(void); @@ -57,6 +58,10 @@ extern int via_rhine_probe(void); extern int yellowfin_probe(void); +extern int abyss_probe(void); +extern int madgemc_probe(void); +extern int tms_pci_probe(void); + /* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is tring of 9 zeros. */ #define __PAD6 "\0\0\0\0\0\0\0\0\0" #define __PAD5 __PAD6 "\0" @@ -94,7 +99,7 @@ {dlci_setup, 0}, #endif #if defined(CONFIG_SDLA) - {sdla_setup, 0}, + {sdla_c_setup, 0}, #endif #if defined(CONFIG_LAPBETHER) {lapbeth_init, 0}, @@ -249,7 +254,19 @@ #ifdef CONFIG_YAM {yam_init, 0}, #endif /* CONFIG_YAM */ - + +/* + * Token Ring Drivers + */ +#ifdef CONFIG_ABYSS + {abyss_probe, 0}, +#endif +#ifdef CONFIG_MADGEMC + {madgemc_probe, 0}, +#endif +#ifdef CONFIG_TMSPCI + {tms_pci_probe, 0}, +#endif {NULL, 0}, }; diff -ur --new-file old/linux/drivers/net/sunbmac.c new/linux/drivers/net/sunbmac.c --- old/linux/drivers/net/sunbmac.c Tue Dec 21 07:06:42 1999 +++ new/linux/drivers/net/sunbmac.c Thu Jan 27 17:58:15 2000 @@ -1165,11 +1165,11 @@ bigmac_stop(bp); /* Allocate transmit/receive descriptor DVMA block. */ - bp->bmac_block = sbus_alloc_consistant(bp->bigmac_sdev, + bp->bmac_block = sbus_alloc_consistent(bp->bigmac_sdev, PAGE_SIZE, &bp->bblock_dvma); if (bp->bmac_block == NULL || bp->bblock_dvma == 0) { - printk(KERN_ERR "BIGMAC: Cannot allocate consistant DMA.\n"); + printk(KERN_ERR "BIGMAC: Cannot allocate consistent DMA.\n"); goto fail_and_cleanup; } @@ -1220,7 +1220,7 @@ sbus_iounmap(bp->tregs, TCVR_REG_SIZE); if (bp->bmac_block) - sbus_free_consistant(bp->bigmac_sdev, + sbus_free_consistent(bp->bigmac_sdev, PAGE_SIZE, bp->bmac_block, bp->bblock_dvma); @@ -1301,7 +1301,7 @@ sbus_iounmap(bp->creg, CREG_REG_SIZE); sbus_iounmap(bp->bregs, BMAC_REG_SIZE); sbus_iounmap(bp->tregs, TCVR_REG_SIZE); - sbus_free_consistant(bp->bigmac_sdev, + sbus_free_consistent(bp->bigmac_sdev, PAGE_SIZE, bp->bmac_block, bp->bblock_dvma); diff -ur --new-file old/linux/drivers/net/sunhme.c new/linux/drivers/net/sunhme.c --- old/linux/drivers/net/sunhme.c Tue Dec 21 07:06:42 1999 +++ new/linux/drivers/net/sunhme.c Thu Jan 27 17:58:15 2000 @@ -207,42 +207,6 @@ return cpu_to_le32(*p); } -/* XXX Convert these to direct function hookup once new - * XXX PCI dvma interfaces are propagated and in use everywhere. - */ -static u32 pci_hme_dma_map(void *device, void *ptr, long size) -{ -#if 1 - return virt_to_bus(ptr); -#else - struct pci_dev *pdev = device; - - return pci_map_single(pdev, ptr, size); -#endif -} - -static void pci_hme_dma_unmap(void *device, u32 dma_addr, long size) -{ -#if 1 - return; -#else - struct pci_dev *pdev = device; - - pci_unmap_single(pdev, dma_addr, size); -#endif -} - -static void pci_hme_dma_sync(void *device, u32 dma_addr, long size) -{ -#if 1 - return; -#else - struct pci_dev *pdev = device; - - pci_dma_sync_single(pdev, dma_addr, size); -#endif -} - #define hme_write32(__hp, __reg, __val) \ ((__hp)->write32((__reg), (__val))) #define hme_read32(__hp, __reg) \ @@ -296,21 +260,12 @@ (__txd)->tx_flags = cpu_to_le32(__flags); \ } while(0) #define hme_read_desc32(__hp, __p) cpu_to_le32(*(__p)) -#if 0 /* XXX Once new PCI interfaces are in place... XXX */ #define hme_dma_map(__hp, __ptr, __size) \ pci_map_single((__hp)->happy_dev, (__ptr), (__size)) #define hme_dma_unmap(__hp, __addr, __size) \ pci_unmap_single((__hp)->happy_dev, (__addr), (__size)) #define hme_dma_sync(__hp, __addr, __size) \ pci_dma_sync_single((__hp)->happy_dev, (__addr), (__size)) -#else -#define hme_dma_map(__hp, __ptr, __size) \ - (virt_to_bus(__ptr)) -#define hme_dma_unmap(__hp, __addr, __size) \ - do { } while(0) -#define hme_dma_sync(__hp, __addr, __size) \ - do { } while(0) -#endif #endif #endif @@ -2663,7 +2618,7 @@ hp->happy_bursts = prom_getintdefault(sdev->bus->prom_node, "burst-sizes", 0x00); - hp->happy_block = sbus_alloc_consistant(hp->happy_dev, + hp->happy_block = sbus_alloc_consistent(hp->happy_dev, PAGE_SIZE, &hp->hblock_dvma); @@ -2835,20 +2790,14 @@ /* Assume PCI happy meals can handle all burst sizes. */ hp->happy_bursts = DMA_BURSTBITS; - hp->happy_block = (struct hmeal_init_block *) get_free_page(GFP_ATOMIC); + hp->happy_block = (struct hmeal_init_block *) + pci_alloc_consistent(pdev, PAGE_SIZE, &hp->hblock_dvma); + if (!hp->happy_block) { printk(KERN_ERR "happymeal(PCI): Cannot get hme init block.\n"); return ENODEV; } - hp->hblock_dvma = (u32) virt_to_bus(hp->happy_block); -#ifndef __sparc_v9__ - /* - * P3: Dirty trick to get uncacheable memory as we have no dma_sync. - */ - hp->happy_block = ioremap(virt_to_phys(hp->happy_block), PAGE_SIZE); -#endif - hp->linkcheck = 0; hp->timer_state = asleep; hp->timer_ticks = 0; @@ -2870,9 +2819,9 @@ hp->read_desc32 = pci_hme_read_desc32; hp->write_txd = pci_hme_write_txd; hp->write_rxd = pci_hme_write_rxd; - hp->dma_map = pci_hme_dma_map; - hp->dma_unmap = pci_hme_dma_unmap; - hp->dma_sync = pci_hme_dma_sync; + hp->dma_map = (u32 (*)(void *, void *, long))pci_map_single; + hp->dma_unmap = (void (*)(void *, u32, long))pci_unmap_single; + hp->dma_sync = (void (*)(void *, u32, long))pci_dma_sync_single; hp->read32 = pci_hme_read32; hp->write32 = pci_hme_write32; #endif @@ -3011,10 +2960,18 @@ sbus_iounmap(hp->erxregs, ERX_REG_SIZE); sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE); sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE); - sbus_free_consistant(hp->happy_dev, + sbus_free_consistent(hp->happy_dev, PAGE_SIZE, hp->happy_block, hp->hblock_dvma); + } +#endif +#ifdef CONFIG_PCI + if ((hp->happy_flags & HFLAG_PCI)) { + pci_free_consistent(hp->happy_dev, + PAGE_SIZE, + hp->happy_block, + hp->hblock_dvma); } #endif unregister_netdev(hp->dev); diff -ur --new-file old/linux/drivers/net/sunlance.c new/linux/drivers/net/sunlance.c --- old/linux/drivers/net/sunlance.c Tue Dec 21 07:06:42 1999 +++ new/linux/drivers/net/sunlance.c Thu Jan 27 17:58:15 2000 @@ -1305,7 +1305,7 @@ sbus_iounmap((unsigned long)lp->init_block, sizeof(struct lance_init_block)); } else { - sbus_free_consistant(lp->sdev, + sbus_free_consistent(lp->sdev, sizeof(struct lance_init_block), (void *)lp->init_block, lp->init_block_dvma); @@ -1375,11 +1375,11 @@ lp->tx = lance_tx_pio; } else { lp->init_block = (volatile struct lance_init_block *) - sbus_alloc_consistant(sdev, sizeof(struct lance_init_block), + sbus_alloc_consistent(sdev, sizeof(struct lance_init_block), &lp->init_block_dvma); if (lp->init_block == NULL || lp->init_block_dvma == 0) { - printk(KERN_ERR "%s: Cannot allocate consistant DMA memory.\n", + printk(KERN_ERR "%s: Cannot allocate consistent DMA memory.\n", dev->name); goto fail; } diff -ur --new-file old/linux/drivers/net/sunqe.c new/linux/drivers/net/sunqe.c --- old/linux/drivers/net/sunqe.c Tue Dec 21 07:06:42 1999 +++ new/linux/drivers/net/sunqe.c Thu Jan 27 17:58:15 2000 @@ -833,10 +833,10 @@ goto qec_free_devs; } - qeps[i]->qe_block = sbus_alloc_consistant(qesdevs[i], + qeps[i]->qe_block = sbus_alloc_consistent(qesdevs[i], PAGE_SIZE, &qeps[i]->qblock_dvma); - qeps[i]->buffers = sbus_alloc_consistant(qesdevs[i], + qeps[i]->buffers = sbus_alloc_consistent(qesdevs[i], sizeof(struct sunqe_buffers), &qeps[i]->buffers_dvma); if (qeps[i]->qe_block == NULL || @@ -907,12 +907,12 @@ if (qe->mregs) sbus_iounmap(qe->mregs, MREGS_REG_SIZE); if (qe->qe_block != NULL) - sbus_free_consistant(qe->qe_sdev, + sbus_free_consistent(qe->qe_sdev, PAGE_SIZE, qe->qe_block, qe->qblock_dvma); if (qe->buffers != NULL) - sbus_free_consistant(qe->qe_sdev, + sbus_free_consistent(qe->qe_sdev, sizeof(struct sunqe_buffers), qe->buffers, qe->buffers_dvma); @@ -1006,11 +1006,11 @@ unregister_netdev(root_qec_dev->qes[i]->dev); sbus_iounmap(root_qec_dev->qes[i]->qcregs, CREG_REG_SIZE); sbus_iounmap(root_qec_dev->qes[i]->mregs, MREGS_REG_SIZE); - sbus_free_consistant(root_qec_dev->qes[i]->qe_sdev, + sbus_free_consistent(root_qec_dev->qes[i]->qe_sdev, PAGE_SIZE, root_qec_dev->qes[i]->qe_block, root_qec_dev->qes[i]->qblock_dvma); - sbus_free_consistant(root_qec_dev->qes[i]->qe_sdev, + sbus_free_consistent(root_qec_dev->qes[i]->qe_sdev, sizeof(struct sunqe_buffers), root_qec_dev->qes[i]->buffers, root_qec_dev->qes[i]->buffers_dvma); diff -ur --new-file old/linux/drivers/net/tokenring/Config.in new/linux/drivers/net/tokenring/Config.in --- old/linux/drivers/net/tokenring/Config.in Fri Jan 7 00:01:56 2000 +++ new/linux/drivers/net/tokenring/Config.in Wed Jan 26 22:16:05 2000 @@ -6,11 +6,16 @@ comment 'Token Ring driver support' bool 'Token Ring driver support' CONFIG_TR -if [ "$CONFIG_TR" = "y" ]; then - tristate ' IBM Tropic chipset based adapter support' CONFIG_IBMTR - tristate ' IBM Olympic chipset PCI adapter support' CONFIG_IBMOL - tristate ' Generic TMS380 Token Ring ISA/PCI adapter support' CONFIG_TMS380TR - tristate ' SMC ISA adapter support' CONFIG_SMCTR +if [ "$CONFIG_TR" != "n" ]; then + dep_tristate ' IBM Tropic chipset based adapter support' CONFIG_IBMTR $CONFIG_TR + dep_tristate ' IBM Olympic chipset PCI adapter support' CONFIG_IBMOL $CONFIG_TR + dep_tristate ' Generic TMS380 Token Ring ISA/PCI adapter support' CONFIG_TMS380TR $CONFIG_TR + if [ "$CONFIG_TMS380TR" != "n" ]; then + dep_tristate ' Generic TMS380 PCI support' CONFIG_TMSPCI $CONFIG_TMS380TR + dep_tristate ' Madge Smart 16/4 PCI Mk2 support' CONFIG_ABYSS $CONFIG_TMS380TR + dep_tristate ' Madge Smart 16/4 Ringnode MicroChannel' CONFIG_MADGEMC $CONFIG_TMS380TR + fi + dep_tristate ' SMC ISA/MCA adapter support' CONFIG_SMCTR $CONFIG_TR fi endmenu diff -ur --new-file old/linux/drivers/net/tokenring/Makefile new/linux/drivers/net/tokenring/Makefile --- old/linux/drivers/net/tokenring/Makefile Fri Jan 7 00:01:56 2000 +++ new/linux/drivers/net/tokenring/Makefile Wed Jan 26 22:16:05 2000 @@ -41,9 +41,27 @@ ifeq ($(CONFIG_TMS380TR),y) L_OBJS += tms380tr.o + ifeq ($(CONFIG_ABYSS),y) + L_OBJS += abyss.o + endif + ifeq ($(CONFIG_MADGEMC),y) + L_OBJS += madgemc.o + endif + ifeq ($(CONFIG_TMSPCI),y) + L_OBJS += tmspci.o + endif else ifeq ($(CONFIG_TMS380TR),m) M_OBJS += tms380tr.o + ifeq ($(CONFIG_ABYSS),m) + M_OBJS += abyss.o + endif + ifeq ($(CONFIG_MADGEMC),m) + M_OBJS += madgemc.o + endif + ifeq ($(CONFIG_TMSPCI),m) + M_OBJS += tmspci.o + endif endif endif diff -ur --new-file old/linux/drivers/net/tokenring/abyss.c new/linux/drivers/net/tokenring/abyss.c --- old/linux/drivers/net/tokenring/abyss.c Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/net/tokenring/abyss.c Wed Jan 26 22:16:05 2000 @@ -0,0 +1,512 @@ +/* + * abyss.c: Network driver for the Madge Smart 16/4 PCI Mk2 token ring card. + * + * Written 1999-2000 by Adam Fritzler + * + * This software may be used and distributed according to the terms + * of the GNU Public License, incorporated herein by reference. + * + * This driver module supports the following cards: + * - Madge Smart 16/4 PCI Mk2 + * + * Maintainer(s): + * AF Adam Fritzler mid@auk.cx + * + * Modification History: + * 30-Dec-99 AF Split off from the tms380tr driver. + * 22-Jan-00 AF Updated to use indirect read/writes + * + * + * TODO: + * 1. See if we can use MMIO instead of inb/outb/inw/outw + * 2. Add support for Mk1 (has AT24 attached to the PCI + * config registers) + * + */ +static const char *version = "abyss.c: v1.01 22/01/2000 by Adam Fritzler\n"; + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include "tms380tr.h" +#include "abyss.h" /* Madge-specific constants */ + +#define ABYSS_IO_EXTENT 64 + +int abyss_probe(void); +static int abyss_open(struct net_device *dev); +static int abyss_close(struct net_device *dev); +static void abyss_enable(struct net_device *dev); +static int abyss_chipset_init(struct net_device *dev); +static void abyss_read_eeprom(struct net_device *dev); +static unsigned short abyss_setnselout_pins(struct net_device *dev); + +void at24_writedatabyte(unsigned long regaddr, unsigned char byte); +int at24_sendfullcmd(unsigned long regaddr, unsigned char cmd, unsigned char addr); +int at24_sendcmd(unsigned long regaddr, unsigned char cmd); +unsigned char at24_readdatabit(unsigned long regaddr); +unsigned char at24_readdatabyte(unsigned long regaddr); +int at24_waitforack(unsigned long regaddr); +int at24_waitfornack(unsigned long regaddr); +void at24_setlines(unsigned long regaddr, unsigned char clock, unsigned char data); +void at24_start(unsigned long regaddr); +void at24_stop(unsigned long regaddr); +unsigned char at24_readb(unsigned long regaddr, unsigned char addr); + +static unsigned short abyss_sifreadb(struct net_device *dev, unsigned short reg) +{ + return inb(dev->base_addr + reg); +} + +static unsigned short abyss_sifreadw(struct net_device *dev, unsigned short reg) +{ + return inw(dev->base_addr + reg); +} + +static void abyss_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg) +{ + outb(val, dev->base_addr + reg); +} + +static void abyss_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg) +{ + outw(val, dev->base_addr + reg); +} + +struct tms_abyss_card { + struct net_device *dev; + struct pci_dev *pci_dev; + struct tms_abyss_card *next; +}; +static struct tms_abyss_card *abyss_card_list = NULL; + +int __init abyss_probe(void) +{ + static int versionprinted = 0; + struct pci_dev *pdev = NULL ; + struct net_device *dev; + struct net_local *tp; + int i; + + if (!pci_present()) + return (-1); /* No PCI present. */ + + while ( (pdev=pci_find_class(PCI_CLASS_NETWORK_TOKEN_RING<<8, pdev))) { + unsigned int pci_irq_line; + unsigned long pci_ioaddr; + struct tms_abyss_card *card; + + /* We only support Madge Smart 16/4 PCI Mk2 (Abyss) cards */ + if ( (pdev->vendor != PCI_VENDOR_ID_MADGE) || + (pdev->device != PCI_DEVICE_ID_MADGE_MK2) ) + continue; + + if (versionprinted++ == 0) + printk("%s", version); + + pci_enable_device(pdev); + + /* Remove I/O space marker in bit 0. */ + pci_irq_line = pdev->irq; + pci_ioaddr = pdev->resource[0].start ; + + if(check_region(pci_ioaddr, ABYSS_IO_EXTENT)) + continue; + + /* At this point we have found a valid card. */ + + dev = init_trdev(NULL, 0); + + request_region(pci_ioaddr, ABYSS_IO_EXTENT, "abyss"); + if(request_irq(pdev->irq, tms380tr_interrupt, SA_SHIRQ, + "abyss", dev)) { + release_region(pci_ioaddr, ABYSS_IO_EXTENT) ; + continue; /*return (-ENODEV);*/ /* continue; ?? */ + } + + /* + if (load_tms380_module("abyss.c")) { + return 0; + } + */ + + pci_ioaddr &= ~3 ; + dev->base_addr = pci_ioaddr; + dev->irq = pci_irq_line; + dev->dma = 0; + + printk("%s: Madge Smart 16/4 PCI Mk2 (Abyss)\n", dev->name); + printk("%s: IO: %#4lx IRQ: %d\n", + dev->name, pci_ioaddr, dev->irq); + /* + * The TMS SIF registers lay 0x10 above the card base address. + */ + dev->base_addr += 0x10; + + if (tmsdev_init(dev)) { + printk("%s: unable to get memory for dev->priv.\n", + dev->name); + return 0; + } + + abyss_read_eeprom(dev); + + printk("%s: Ring Station Address: ", dev->name); + printk("%2.2x", dev->dev_addr[0]); + for (i = 1; i < 6; i++) + printk(":%2.2x", dev->dev_addr[i]); + printk("\n"); + + tp = (struct net_local *)dev->priv; + tp->dmalimit = 0; /* XXX: should be the max PCI32 DMA max */ + tp->setnselout = abyss_setnselout_pins; + tp->sifreadb = abyss_sifreadb; + tp->sifreadw = abyss_sifreadw; + tp->sifwriteb = abyss_sifwriteb; + tp->sifwritew = abyss_sifwritew; + + memcpy(tp->ProductID, "Madge PCI 16/4 Mk2", PROD_ID_SIZE + 1); + + dev->open = abyss_open; + dev->stop = abyss_close; + + if (register_trdev(dev) == 0) { + /* Enlist in the card list */ + card = kmalloc(sizeof(struct tms_abyss_card), + GFP_KERNEL); + card->next = abyss_card_list; + abyss_card_list = card; + card->dev = dev; + card->pci_dev = pdev; + } else { + printk("abyss: register_trdev() returned non-zero.\n"); + kfree(dev->priv); + kfree(dev); + return -1; + } + } + + if (abyss_card_list) + return 0; + return (-1); +} + +unsigned short abyss_setnselout_pins(struct net_device *dev) +{ + unsigned short val = 0; + struct net_local *tp = (struct net_local *)dev->priv; + + if(tp->DataRate == SPEED_4) + val |= 0x01; /* Set 4Mbps */ + else + val |= 0x00; /* Set 16Mbps */ + + return val; +} + +/* + * The following Madge boards should use this code: + * - Smart 16/4 PCI Mk2 (Abyss) + * - Smart 16/4 PCI Mk1 (PCI T) + * - Smart 16/4 Client Plus PnP (Big Apple) + * - Smart 16/4 Cardbus Mk2 + * + * These access an Atmel AT24 SEEPROM using their glue chip registers. + * + */ +void at24_writedatabyte(unsigned long regaddr, unsigned char byte) +{ + int i; + + for (i = 0; i < 8; i++) { + at24_setlines(regaddr, 0, (byte >> (7-i))&0x01); + at24_setlines(regaddr, 1, (byte >> (7-i))&0x01); + at24_setlines(regaddr, 0, (byte >> (7-i))&0x01); + } +} + +int at24_sendfullcmd(unsigned long regaddr, unsigned char cmd, unsigned char addr) +{ + if (at24_sendcmd(regaddr, cmd)) { + at24_writedatabyte(regaddr, addr); + return at24_waitforack(regaddr); + } + return 0; +} + +int at24_sendcmd(unsigned long regaddr, unsigned char cmd) +{ + int i; + + for (i = 0; i < 10; i++) { + at24_start(regaddr); + at24_writedatabyte(regaddr, cmd); + if (at24_waitforack(regaddr)) + return 1; + } + return 0; +} + +unsigned char at24_readdatabit(unsigned long regaddr) +{ + unsigned char val; + + at24_setlines(regaddr, 0, 1); + at24_setlines(regaddr, 1, 1); + val = (inb(regaddr) & AT24_DATA)?1:0; + at24_setlines(regaddr, 1, 1); + at24_setlines(regaddr, 0, 1); + return val; +} + +unsigned char at24_readdatabyte(unsigned long regaddr) +{ + unsigned char data = 0; + int i; + + for (i = 0; i < 8; i++) { + data <<= 1; + data |= at24_readdatabit(regaddr); + } + + return data; +} + +int at24_waitforack(unsigned long regaddr) +{ + int i; + + for (i = 0; i < 10; i++) { + if ((at24_readdatabit(regaddr) & 0x01) == 0x00) + return 1; + } + return 0; +} + +int at24_waitfornack(unsigned long regaddr) +{ + int i; + for (i = 0; i < 10; i++) { + if ((at24_readdatabit(regaddr) & 0x01) == 0x01) + return 1; + } + return 0; +} + +void at24_setlines(unsigned long regaddr, unsigned char clock, unsigned char data) +{ + unsigned char val; + val = AT24_ENABLE; + if (clock) + val |= AT24_CLOCK; + if (data) + val |= AT24_DATA; + + outb(val, regaddr); + tms380tr_wait(20); /* Very necessary. */ +} + +void at24_start(unsigned long regaddr) +{ + at24_setlines(regaddr, 0, 1); + at24_setlines(regaddr, 1, 1); + at24_setlines(regaddr, 1, 0); + at24_setlines(regaddr, 0, 1); + return; +} + +void at24_stop(unsigned long regaddr) +{ + at24_setlines(regaddr, 0, 0); + at24_setlines(regaddr, 1, 0); + at24_setlines(regaddr, 1, 1); + at24_setlines(regaddr, 0, 1); + return; +} + +unsigned char at24_readb(unsigned long regaddr, unsigned char addr) +{ + unsigned char data = 0xff; + + if (at24_sendfullcmd(regaddr, AT24_WRITE, addr)) { + if (at24_sendcmd(regaddr, AT24_READ)) { + data = at24_readdatabyte(regaddr); + if (!at24_waitfornack(regaddr)) + data = 0xff; + } + } + return data; +} + + +/* + * Enable basic functions of the Madge chipset needed + * for initialization. + */ +static void abyss_enable(struct net_device *dev) +{ + unsigned char reset_reg; + unsigned long ioaddr; + + ioaddr = dev->base_addr; + reset_reg = inb(ioaddr + PCIBM2_RESET_REG); + reset_reg |= PCIBM2_RESET_REG_CHIP_NRES; + outb(reset_reg, ioaddr + PCIBM2_RESET_REG); + tms380tr_wait(100); + return; +} + +/* + * Enable the functions of the Madge chipset needed for + * full working order. + */ +static int abyss_chipset_init(struct net_device *dev) +{ + unsigned char reset_reg; + unsigned long ioaddr; + + ioaddr = dev->base_addr; + + reset_reg = inb(ioaddr + PCIBM2_RESET_REG); + + reset_reg |= PCIBM2_RESET_REG_CHIP_NRES; + outb(reset_reg, ioaddr + PCIBM2_RESET_REG); + + reset_reg &= ~(PCIBM2_RESET_REG_CHIP_NRES | + PCIBM2_RESET_REG_FIFO_NRES | + PCIBM2_RESET_REG_SIF_NRES); + outb(reset_reg, ioaddr + PCIBM2_RESET_REG); + + tms380tr_wait(100); + + reset_reg |= PCIBM2_RESET_REG_CHIP_NRES; + outb(reset_reg, ioaddr + PCIBM2_RESET_REG); + + reset_reg |= PCIBM2_RESET_REG_SIF_NRES; + outb(reset_reg, ioaddr + PCIBM2_RESET_REG); + + reset_reg |= PCIBM2_RESET_REG_FIFO_NRES; + outb(reset_reg, ioaddr + PCIBM2_RESET_REG); + + outb(PCIBM2_INT_CONTROL_REG_SINTEN | + PCIBM2_INT_CONTROL_REG_PCI_ERR_ENABLE, + ioaddr + PCIBM2_INT_CONTROL_REG); + + outb(30, ioaddr + PCIBM2_FIFO_THRESHOLD); + + return 0; +} + +void abyss_chipset_close(struct net_device *dev) +{ + unsigned long ioaddr; + + ioaddr = dev->base_addr; + outb(0, ioaddr + PCIBM2_RESET_REG); + + return; +} + +/* + * Read configuration data from the AT24 SEEPROM on Madge cards. + * + */ +static void abyss_read_eeprom(struct net_device *dev) +{ + struct net_local *tp; + unsigned long ioaddr; + unsigned short val; + int i; + + tp = (struct net_local *)dev->priv; + ioaddr = dev->base_addr; + + /* Must enable glue chip first */ + abyss_enable(dev); + + val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, + PCIBM2_SEEPROM_RING_SPEED); + tp->DataRate = val?SPEED_4:SPEED_16; /* set open speed */ + printk("%s: SEEPROM: ring speed: %dMb/sec\n", dev->name, tp->DataRate); + + val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, + PCIBM2_SEEPROM_RAM_SIZE) * 128; + printk("%s: SEEPROM: adapter RAM: %dkb\n", dev->name, val); + + dev->addr_len = 6; + for (i = 0; i < 6; i++) + dev->dev_addr[i] = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, + PCIBM2_SEEPROM_BIA+i); + + return; +} + +static int abyss_open(struct net_device *dev) +{ + abyss_chipset_init(dev); + tms380tr_open(dev); + MOD_INC_USE_COUNT; + return 0; +} + +static int abyss_close(struct net_device *dev) +{ + tms380tr_close(dev); + abyss_chipset_close(dev); + MOD_DEC_USE_COUNT; + return 0; +} + +#ifdef MODULE + +int init_module(void) +{ + /* Probe for cards. */ + if (abyss_probe()) { + printk(KERN_NOTICE "abyss.c: No cards found.\n"); + } + /* lock_tms380_module(); */ + return (0); +} + +void cleanup_module(void) +{ + struct net_device *dev; + struct tms_abyss_card *this_card; + + while (abyss_card_list) { + dev = abyss_card_list->dev; + unregister_netdev(dev); + release_region(dev->base_addr-0x10, ABYSS_IO_EXTENT); + free_irq(dev->irq, dev); + kfree(dev->priv); + kfree(dev); + this_card = abyss_card_list; + abyss_card_list = this_card->next; + kfree(this_card); + } + /* unlock_tms380_module(); */ +} +#endif /* MODULE */ + + +/* + * Local variables: + * compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c abyss.c" + * alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c abyss.c" + * c-set-style "K&R" + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -ur --new-file old/linux/drivers/net/tokenring/abyss.h new/linux/drivers/net/tokenring/abyss.h --- old/linux/drivers/net/tokenring/abyss.h Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/net/tokenring/abyss.h Wed Jan 26 22:16:05 2000 @@ -0,0 +1,58 @@ +/* + * abyss.h: Header for the abyss tms380tr module + * + * Authors: + * - Adam Fritzler + */ + +#ifndef __LINUX_MADGETR_H +#define __LINUX_MADGETR_H + +#ifdef __KERNEL__ + +/* + * For Madge Smart 16/4 PCI Mk2. Since we increment the base address + * to get everything correct for the TMS SIF, we do these as negatives + * as they fall below the SIF in addressing. + */ +#define PCIBM2_INT_STATUS_REG ((short)-15)/* 0x01 */ +#define PCIBM2_INT_CONTROL_REG ((short)-14)/* 0x02 */ +#define PCIBM2_RESET_REG ((short)-12)/* 0x04 */ +#define PCIBM2_SEEPROM_REG ((short)-9) /* 0x07 */ + +#define PCIBM2_INT_CONTROL_REG_SINTEN 0x02 +#define PCIBM2_INT_CONTROL_REG_PCI_ERR_ENABLE 0x80 +#define PCIBM2_INT_STATUS_REG_PCI_ERR 0x80 + +#define PCIBM2_RESET_REG_CHIP_NRES 0x01 +#define PCIBM2_RESET_REG_FIFO_NRES 0x02 +#define PCIBM2_RESET_REG_SIF_NRES 0x04 + +#define PCIBM2_FIFO_THRESHOLD 0x21 +#define PCIBM2_BURST_LENGTH 0x22 + +/* + * Bits in PCIBM2_SEEPROM_REG. + */ +#define AT24_ENABLE 0x04 +#define AT24_DATA 0x02 +#define AT24_CLOCK 0x01 + +/* + * AT24 Commands. + */ +#define AT24_WRITE 0xA0 +#define AT24_READ 0xA1 + +/* + * Addresses in AT24 SEEPROM. + */ +#define PCIBM2_SEEPROM_BIA 0x12 +#define PCIBM2_SEEPROM_RING_SPEED 0x18 +#define PCIBM2_SEEPROM_RAM_SIZE 0x1A +#define PCIBM2_SEEPROM_HWF1 0x1C +#define PCIBM2_SEEPROM_HWF2 0x1E + + +#endif /* __KERNEL__ */ +#endif /* __LINUX_MADGETR_H */ diff -ur --new-file old/linux/drivers/net/tokenring/madgemc.c new/linux/drivers/net/tokenring/madgemc.c --- old/linux/drivers/net/tokenring/madgemc.c Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/net/tokenring/madgemc.c Wed Jan 26 22:16:05 2000 @@ -0,0 +1,806 @@ +/* + * madgemc.c: Driver for the Madge Smart 16/4 MC16 MCA token ring card. + * + * Written 2000 by Adam Fritzler + * + * This software may be used and distributed according to the terms + * of the GNU Public License, incorporated herein by reference. + * + * This driver module supports the following cards: + * - Madge Smart 16/4 Ringnode MC16 + * - Madge Smart 16/4 Ringnode MC32 (??) + * + * Maintainer(s): + * AF Adam Fritzler mid@auk.cx + * + * Modification History: + * 16-Jan-00 AF Created + * + */ +static const char *version = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n"; + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include "tms380tr.h" +#include "madgemc.h" /* Madge-specific constants */ + +#define MADGEMC_IO_EXTENT 32 +#define MADGEMC_SIF_OFFSET 0x08 + +struct madgemc_card { + struct net_device *dev; + + /* + * These are read from the BIA ROM. + */ + unsigned int manid; + unsigned int cardtype; + unsigned int cardrev; + unsigned int ramsize; + + /* + * These are read from the MCA POS registers. + */ + unsigned int burstmode:2; + unsigned int fairness:1; /* 0 = Fair, 1 = Unfair */ + unsigned int arblevel:4; + unsigned int ringspeed:2; /* 0 = 4mb, 1 = 16, 2 = Auto/none */ + unsigned int cabletype:1; /* 0 = RJ45, 1 = DB9 */ + + struct madgemc_card *next; +}; +static struct madgemc_card *madgemc_card_list = NULL; + + +int madgemc_probe(void); +static int madgemc_open(struct net_device *dev); +static int madgemc_close(struct net_device *dev); +static int madgemc_chipset_init(struct net_device *dev); +static void madgemc_read_rom(struct madgemc_card *card); +static unsigned short madgemc_setnselout_pins(struct net_device *dev); +static void madgemc_setcabletype(struct net_device *dev, int type); + +static int madgemc_mcaproc(char *buf, int slot, void *d); + +static void madgemc_setregpage(struct net_device *dev, int page); +static void madgemc_setsifsel(struct net_device *dev, int val); +static void madgemc_setint(struct net_device *dev, int val); + +static void madgemc_interrupt(int irq, void *dev_id, struct pt_regs *regs); + +/* + * These work around paging, however they dont guarentee you're on the + * right page. + */ +#define SIFREADB(reg) (inb(dev->base_addr + ((reg<0x8)?reg:reg-0x8))) +#define SIFWRITEB(val, reg) (outb(val, dev->base_addr + ((reg<0x8)?reg:reg-0x8))) +#define SIFREADW(reg) (inw(dev->base_addr + ((reg<0x8)?reg:reg-0x8))) +#define SIFWRITEW(val, reg) (outw(val, dev->base_addr + ((reg<0x8)?reg:reg-0x8))) + +/* + * Read a byte-length value from the register. + */ +static unsigned short madgemc_sifreadb(struct net_device *dev, unsigned short reg) +{ + unsigned short ret; + if (reg<0x8) + ret = SIFREADB(reg); + else { + madgemc_setregpage(dev, 1); + ret = SIFREADB(reg); + madgemc_setregpage(dev, 0); + } + return ret; +} + +/* + * Write a byte-length value to a register. + */ +static void madgemc_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg) +{ + if (reg<0x8) + SIFWRITEB(val, reg); + else { + madgemc_setregpage(dev, 1); + SIFWRITEB(val, reg); + madgemc_setregpage(dev, 0); + } + return; +} + +/* + * Read a word-length value from a register + */ +static unsigned short madgemc_sifreadw(struct net_device *dev, unsigned short reg) +{ + unsigned short ret; + if (reg<0x8) + ret = SIFREADW(reg); + else { + madgemc_setregpage(dev, 1); + ret = SIFREADW(reg); + madgemc_setregpage(dev, 0); + } + return ret; +} + +/* + * Write a word-length value to a register. + */ +static void madgemc_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg) +{ + if (reg<0x8) + SIFWRITEW(val, reg); + else { + madgemc_setregpage(dev, 1); + SIFWRITEW(val, reg); + madgemc_setregpage(dev, 0); + } + return; +} + + + +int __init madgemc_probe(void) +{ + static int versionprinted = 0; + struct net_device *dev; + struct net_local *tp; + struct madgemc_card *card; + int i,slot = 0; + __u8 posreg[4]; + + if (!MCA_bus) + return -1; + + while (slot != MCA_NOTFOUND) { + /* + * Currently we only support the MC16/32 (MCA ID 002d) + */ + slot = mca_find_unused_adapter(0x002d, slot); + if (slot == MCA_NOTFOUND) + break; + + /* + * If we get here, we have an adapter. + */ + if (versionprinted++ == 0) + printk("%s", version); + + if ((dev = init_trdev(NULL, 0))==NULL) { + printk("madgemc: unable to allocate dev space\n"); + return -1; + } + dev->dma = 0; + + /* + * Fetch MCA config registers + */ + for(i=0;i<4;i++) + posreg[i] = mca_read_stored_pos(slot, i+2); + + card = kmalloc(sizeof(struct madgemc_card), GFP_KERNEL); + if (card==NULL) { + printk("madgemc: unable to allocate card struct\n"); + return -1; + } + card->dev = dev; + + /* + * Parse configuration information. This all comes + * directly from the publicly available @002d.ADF. + * Get it from Madge or your local ADF library. + */ + + /* + * Base address + */ + dev->base_addr = 0x0a20 + + ((posreg[2] & MC16_POS2_ADDR2)?0x0400:0) + + ((posreg[0] & MC16_POS0_ADDR1)?0x1000:0) + + ((posreg[3] & MC16_POS3_ADDR3)?0x2000:0); + + /* + * Interrupt line + */ + switch(posreg[0] >> 6) { /* upper two bits */ + case 0x1: dev->irq = 3; break; + case 0x2: dev->irq = 9; break; /* IRQ 2 = IRQ 9 */ + case 0x3: dev->irq = 10; break; + default: dev->irq = 0; break; + } + + if (dev->irq == 0) { + printk("%s: invalid IRQ\n", dev->name); + goto getout; + } + + request_region(dev->base_addr, MADGEMC_IO_EXTENT, "madgemc"); +#if 0 + /* why is this not working? */ + if (request_region(dev->base_addr, MADGEMC_IO_EXTENT, + "madgemc")) { + printk(KERN_INFO "madgemc: unable to setup Smart MC in slot %d because of I/O base conflict at 0x%04lx\n", slot, dev->base_addr); + dev->base_addr += MADGEMC_SIF_OFFSET; + goto getout; + } +#endif + dev->base_addr += MADGEMC_SIF_OFFSET; + + /* + * Arbitration Level + */ + card->arblevel = ((posreg[0] >> 1) & 0x7) + 8; + + /* + * Burst mode and Fairness + */ + card->burstmode = ((posreg[2] >> 6) & 0x3); + card->fairness = ((posreg[2] >> 4) & 0x1); + + /* + * Ring Speed + */ + if ((posreg[1] >> 2)&0x1) + card->ringspeed = 2; /* not selected */ + else if ((posreg[2] >> 5) & 0x1) + card->ringspeed = 1; /* 16Mb */ + else + card->ringspeed = 0; /* 4Mb */ + + /* + * Cable type + */ + if ((posreg[1] >> 6)&0x1) + card->cabletype = 1; /* STP/DB9 */ + else + card->cabletype = 0; /* UTP/RJ-45 */ + + + /* + * ROM Info. This requires us to actually twiddle + * bits on the card, so we must ensure above that + * the base address is free of conflict (request_region above). + */ + madgemc_read_rom(card); + + if (card->manid != 0x4d) { /* something went wrong */ + printk(KERN_INFO "%s: Madge MC ROM read failed (unknown manufacturer ID %02x)\n", dev->name, card->manid); + goto getout; + } + + if ((card->cardtype != 0x08) && (card->cardtype != 0x0d)) { + printk(KERN_INFO "%s: Madge MC ROM read failed (unknown card ID %02x)\n", dev->name, card->cardtype); + goto getout; + } + + /* All cards except Rev 0 and 1 MC16's have 256kb of RAM */ + if ((card->cardtype == 0x08) && (card->cardrev <= 0x01)) + card->ramsize = 128; + else + card->ramsize = 256; + + printk("%s: %s Rev %d at 0x%04lx IRQ %d\n", + dev->name, + (card->cardtype == 0x08)?MADGEMC16_CARDNAME: + MADGEMC32_CARDNAME, card->cardrev, + dev->base_addr, dev->irq); + + if (card->cardtype == 0x0d) + printk("%s: Warning: MC32 support is experimental and highly untested\n", dev->name); + + if (card->ringspeed==2) { /* Unknown */ + printk("%s: Warning: Ring speed not set in POS -- Please run the reference disk and set it!\n", dev->name); + card->ringspeed = 1; /* default to 16mb */ + } + + printk("%s: RAM Size: %dKB\n", dev->name, card->ramsize); + + printk("%s: Ring Speed: %dMb/sec on %s\n", dev->name, + (card->ringspeed)?16:4, + card->cabletype?"STP/DB9":"UTP/RJ-45"); + printk("%s: Arbitration Level: %d\n", dev->name, + card->arblevel); + + printk("%s: Burst Mode: ", dev->name); + switch(card->burstmode) { + case 0: printk("Cycle steal"); break; + case 1: printk("Limited burst"); break; + case 2: printk("Delayed release"); break; + case 3: printk("Immediate release"); break; + } + printk(" (%s)\n", (card->fairness)?"Unfair":"Fair"); + + + /* + * Enable SIF before we assign the interrupt handler, + * just in case we get spurious interrupts that need + * handling. + */ + outb(0, dev->base_addr + MC_CONTROL_REG0); /* sanity */ + madgemc_setsifsel(dev, 1); + if(request_irq(dev->irq, madgemc_interrupt, SA_SHIRQ, + "madgemc", dev)) + goto getout; + + madgemc_chipset_init(dev); /* enables interrupts! */ + madgemc_setcabletype(dev, card->cabletype); + + /* Setup MCA structures */ + mca_set_adapter_name(slot, (card->cardtype == 0x08)?MADGEMC16_CARDNAME:MADGEMC32_CARDNAME); + mca_set_adapter_procfn(slot, madgemc_mcaproc, dev); + mca_mark_as_used(slot); + + printk("%s: Ring Station Address: ", dev->name); + printk("%2.2x", dev->dev_addr[0]); + for (i = 1; i < 6; i++) + printk(":%2.2x", dev->dev_addr[i]); + printk("\n"); + + if (tmsdev_init(dev)) { + printk("%s: unable to get memory for dev->priv.\n", + dev->name); + return -1; + } + tp = (struct net_local *)dev->priv; + + /* + * The MC16 is physically a 32bit card. However, Madge + * insists on calling it 16bit, so I'll assume here that + * they know what they're talking about. Cut off DMA + * at 16mb. + */ + tp->dmalimit = ISA_MAX_ADDRESS; /* XXX: ?? */ + tp->setnselout = madgemc_setnselout_pins; + tp->sifwriteb = madgemc_sifwriteb; + tp->sifreadb = madgemc_sifreadb; + tp->sifwritew = madgemc_sifwritew; + tp->sifreadw = madgemc_sifreadw; + tp->DataRate = (card->ringspeed)?SPEED_16:SPEED_4; + + memcpy(tp->ProductID, "Madge MCA 16/4 ", PROD_ID_SIZE + 1); + + dev->open = madgemc_open; + dev->stop = madgemc_close; + + if (register_trdev(dev) == 0) { + /* Enlist in the card list */ + card->next = madgemc_card_list; + madgemc_card_list = card; + } else { + printk("madgemc: register_trdev() returned non-zero.\n"); + + kfree(card); + kfree(dev->priv); + kfree(dev); + return -1; + } + + slot++; + continue; /* successful, try to find another */ + + getout: + release_region(dev->base_addr-MADGEMC_SIF_OFFSET, + MADGEMC_IO_EXTENT); + kfree(card); + kfree(dev); /* release_trdev? */ + slot++; + } + + if (madgemc_card_list) + return 0; + return -1; +} + +/* + * Handle interrupts generated by the card + * + * The MicroChannel Madge cards need slightly more handling + * after an interrupt than other TMS380 cards do. + * + * First we must make sure it was this card that generated the + * interrupt (since interrupt sharing is allowed). Then, + * because we're using level-triggered interrupts (as is + * standard on MCA), we must toggle the interrupt line + * on the card in order to claim and acknowledge the interrupt. + * Once that is done, the interrupt should be handlable in + * the normal tms380tr_interrupt() routine. + * + * There's two ways we can check to see if the interrupt is ours, + * both with their own disadvantages... + * + * 1) Read in the SIFSTS register from the TMS controller. This + * is guarenteed to be accurate, however, there's a fairly + * large performance penalty for doing so: the Madge chips + * must request the register from the Eagle, the Eagle must + * read them from its internal bus, and then take the route + * back out again, for a 16bit read. + * + * 2) Use the MC_CONTROL_REG0_SINTR bit from the Madge ASICs. + * The major disadvantage here is that the accuracy of the + * bit is in question. However, it cuts out the extra read + * cycles it takes to read the Eagle's SIF, as its only an + * 8bit read, and theoretically the Madge bit is directly + * connected to the interrupt latch coming out of the Eagle + * hardware (that statement is not verified). + * + * I can't determine which of these methods has the best win. For now, + * we make a compromise. Use the Madge way for the first interrupt, + * which should be the fast-path, and then once we hit the first + * interrupt, keep on trying using the SIF method until we've + * exhausted all contiguous interrupts. + * + */ +static void madgemc_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + int pending,reg1; + struct net_device *dev; + + if (!dev_id) { + printk("madgemc_interrupt: was not passed a dev_id!\n"); + return; + } + + dev = (struct net_device *)dev_id; + + /* Make sure its really us. -- the Madge way */ + pending = inb(dev->base_addr + MC_CONTROL_REG0); + if (!(pending & MC_CONTROL_REG0_SINTR)) + return; /* not our interrupt */ + + /* + * Since we're level-triggered, we may miss the rising edge + * of the next interrupt while we're off handling this one, + * so keep checking until the SIF verifies that it has nothing + * left for us to do. + */ + pending = STS_SYSTEM_IRQ; + do { + if (pending & STS_SYSTEM_IRQ) { + + /* Toggle the interrupt to reset the latch on card */ + reg1 = inb(dev->base_addr + MC_CONTROL_REG1); + outb(reg1 ^ MC_CONTROL_REG1_SINTEN, + dev->base_addr + MC_CONTROL_REG1); + outb(reg1, dev->base_addr + MC_CONTROL_REG1); + + /* Continue handling as normal */ + tms380tr_interrupt(irq, dev_id, regs); + + pending = SIFREADW(SIFSTS); /* restart - the SIF way */ + + } else + return; + } while (1); + + return; /* not reachable */ +} + +/* + * Set the card to the prefered ring speed. + * + * Unlike newer cards, the MC16/32 have their speed selection + * circuit connected to the Madge ASICs and not to the TMS380 + * NSELOUT pins. Set the ASIC bits correctly here, and return + * zero to leave the TMS NSELOUT bits unaffected. + * + */ +unsigned short madgemc_setnselout_pins(struct net_device *dev) +{ + unsigned char reg1; + struct net_local *tp = (struct net_local *)dev->priv; + + reg1 = inb(dev->base_addr + MC_CONTROL_REG1); + + if(tp->DataRate == SPEED_16) + reg1 |= MC_CONTROL_REG1_SPEED_SEL; /* add for 16mb */ + else if (reg1 & MC_CONTROL_REG1_SPEED_SEL) + reg1 ^= MC_CONTROL_REG1_SPEED_SEL; /* remove for 4mb */ + outb(reg1, dev->base_addr + MC_CONTROL_REG1); + + return 0; /* no change */ +} + +/* + * Set the register page. This equates to the SRSX line + * on the TMS380Cx6. + * + * Register selection is normally done via three contiguous + * bits. However, some boards (such as the MC16/32) use only + * two bits, plus a seperate bit in the glue chip. This + * sets the SRSX bit (the top bit). See page 4-17 in the + * Yellow Book for which registers are affected. + * + */ +static void madgemc_setregpage(struct net_device *dev, int page) +{ + static int reg1 = 0; + + reg1 = inb(dev->base_addr + MC_CONTROL_REG1); + if ((page == 0) && (reg1 & MC_CONTROL_REG1_SRSX)) { + outb(reg1 ^ MC_CONTROL_REG1_SRSX, + dev->base_addr + MC_CONTROL_REG1); + } + else if (page == 1) { + outb(reg1 | MC_CONTROL_REG1_SRSX, + dev->base_addr + MC_CONTROL_REG1); + } + reg1 = inb(dev->base_addr + MC_CONTROL_REG1); + + return; +} + +/* + * The SIF registers are not mapped into register space by default + * Set this to 1 to map them, 0 to map the BIA ROM. + * + */ +static void madgemc_setsifsel(struct net_device *dev, int val) +{ + unsigned int reg0; + + reg0 = inb(dev->base_addr + MC_CONTROL_REG0); + if ((val == 0) && (reg0 & MC_CONTROL_REG0_SIFSEL)) { + outb(reg0 ^ MC_CONTROL_REG0_SIFSEL, + dev->base_addr + MC_CONTROL_REG0); + } else if (val == 1) { + outb(reg0 | MC_CONTROL_REG0_SIFSEL, + dev->base_addr + MC_CONTROL_REG0); + } + reg0 = inb(dev->base_addr + MC_CONTROL_REG0); + + return; +} + +/* + * Enable SIF interrupts + * + * This does not enable interrupts in the SIF, but rather + * enables SIF interrupts to be passed onto the host. + * + */ +static void madgemc_setint(struct net_device *dev, int val) +{ + unsigned int reg1; + + reg1 = inb(dev->base_addr + MC_CONTROL_REG1); + if ((val == 0) && (reg1 & MC_CONTROL_REG1_SINTEN)) { + outb(reg1 ^ MC_CONTROL_REG1_SINTEN, + dev->base_addr + MC_CONTROL_REG1); + } else if (val == 1) { + outb(reg1 | MC_CONTROL_REG1_SINTEN, + dev->base_addr + MC_CONTROL_REG1); + } + + return; +} + +/* + * Cable type is set via control register 7. Bit zero high + * for UTP, low for STP. + */ +static void madgemc_setcabletype(struct net_device *dev, int type) +{ + outb((type==0)?MC_CONTROL_REG7_CABLEUTP:MC_CONTROL_REG7_CABLESTP, + dev->base_addr + MC_CONTROL_REG7); +} + +/* + * Enable the functions of the Madge chipset needed for + * full working order. + */ +static int madgemc_chipset_init(struct net_device *dev) +{ + outb(0, dev->base_addr + MC_CONTROL_REG1); /* pull SRESET low */ + tms380tr_wait(100); /* wait for card to reset */ + + /* bring back into normal operating mode */ + outb(MC_CONTROL_REG1_NSRESET, dev->base_addr + MC_CONTROL_REG1); + + /* map SIF registers */ + madgemc_setsifsel(dev, 1); + + /* enable SIF interrupts */ + madgemc_setint(dev, 1); + + return 0; +} + +/* + * Disable the board, and put back into power-up state. + */ +void madgemc_chipset_close(struct net_device *dev) +{ + /* disable interrupts */ + madgemc_setint(dev, 0); + /* unmap SIF registers */ + madgemc_setsifsel(dev, 0); + + return; +} + +/* + * Read the card type (MC16 or MC32) from the card. + * + * The configuration registers are stored in two seperate + * pages. Pages are flipped by clearing bit 3 of CONTROL_REG0 (PAGE) + * for page zero, or setting bit 3 for page one. + * + * Page zero contains the following data: + * Byte 0: Manufacturer ID (0x4D -- ASCII "M") + * Byte 1: Card type: + * 0x08 for MC16 + * 0x0D for MC32 + * Byte 2: Card revision + * Byte 3: Mirror of POS config register 0 + * Byte 4: Mirror of POS 1 + * Byte 5: Mirror of POS 2 + * + * Page one contains the following data: + * Byte 0: Unused + * Byte 1-6: BIA, MSB to LSB. + * + * Note that to read the BIA, we must unmap the SIF registers + * by clearing bit 2 of CONTROL_REG0 (SIFSEL), as the data + * will reside in the same logical location. For this reason, + * _never_ read the BIA while the Eagle processor is running! + * The SIF will be completely inaccessible until the BIA operation + * is complete. + * + */ +static void madgemc_read_rom(struct madgemc_card *card) +{ + unsigned long ioaddr; + unsigned char reg0, reg1, tmpreg0, i; + + ioaddr = card->dev->base_addr; + + reg0 = inb(ioaddr + MC_CONTROL_REG0); + reg1 = inb(ioaddr + MC_CONTROL_REG1); + + /* Switch to page zero and unmap SIF */ + tmpreg0 = reg0 & ~(MC_CONTROL_REG0_PAGE + MC_CONTROL_REG0_SIFSEL); + outb(tmpreg0, ioaddr + MC_CONTROL_REG0); + + card->manid = inb(ioaddr + MC_ROM_MANUFACTURERID); + card->cardtype = inb(ioaddr + MC_ROM_ADAPTERID); + card->cardrev = inb(ioaddr + MC_ROM_REVISION); + + /* Switch to rom page one */ + outb(tmpreg0 | MC_CONTROL_REG0_PAGE, ioaddr + MC_CONTROL_REG0); + + /* Read BIA */ + card->dev->addr_len = 6; + for (i = 0; i < 6; i++) + card->dev->dev_addr[i] = inb(ioaddr + MC_ROM_BIA_START + i); + + /* Restore original register values */ + outb(reg0, ioaddr + MC_CONTROL_REG0); + outb(reg1, ioaddr + MC_CONTROL_REG1); + + return; +} + +static int madgemc_open(struct net_device *dev) +{ + /* + * Go ahead and reinitialize the chipset again, just to + * make sure we didn't get left in a bad state. + */ + madgemc_chipset_init(dev); + tms380tr_open(dev); + MOD_INC_USE_COUNT; + return 0; +} + +static int madgemc_close(struct net_device *dev) +{ + tms380tr_close(dev); + madgemc_chipset_close(dev); + MOD_DEC_USE_COUNT; + return 0; +} + +/* + * Give some details available from /proc/mca/slotX + */ +static int madgemc_mcaproc(char *buf, int slot, void *d) +{ + struct net_device *dev = (struct net_device *)d; + struct madgemc_card *curcard = madgemc_card_list; + int len = 0; + + while (curcard) { /* search for card struct */ + if (curcard->dev == dev) + break; + curcard = curcard->next; + } + len += sprintf(buf+len, "-------\n"); + if (curcard) { + struct net_local *tp = (struct net_local *)dev->priv; + int i; + + len += sprintf(buf+len, "Card Revision: %d\n", curcard->cardrev); + len += sprintf(buf+len, "RAM Size: %dkb\n", curcard->ramsize); + len += sprintf(buf+len, "Cable type: %s\n", (curcard->cabletype)?"STP/DB9":"UTP/RJ-45"); + len += sprintf(buf+len, "Configured ring speed: %dMb/sec\n", (curcard->ringspeed)?16:4); + len += sprintf(buf+len, "Running ring speed: %dMb/sec\n", (tp->DataRate==SPEED_16)?16:4); + len += sprintf(buf+len, "Device: %s\n", dev->name); + len += sprintf(buf+len, "IO Port: 0x%04lx\n", dev->base_addr); + len += sprintf(buf+len, "IRQ: %d\n", dev->irq); + len += sprintf(buf+len, "Arbitration Level: %d\n", curcard->arblevel); + len += sprintf(buf+len, "Burst Mode: "); + switch(curcard->burstmode) { + case 0: len += sprintf(buf+len, "Cycle steal"); break; + case 1: len += sprintf(buf+len, "Limited burst"); break; + case 2: len += sprintf(buf+len, "Delayed release"); break; + case 3: len += sprintf(buf+len, "Immediate release"); break; + } + len += sprintf(buf+len, " (%s)\n", (curcard->fairness)?"Unfair":"Fair"); + + len += sprintf(buf+len, "Ring Station Address: "); + len += sprintf(buf+len, "%2.2x", dev->dev_addr[0]); + for (i = 1; i < 6; i++) + len += sprintf(buf+len, " %2.2x", dev->dev_addr[i]); + len += sprintf(buf+len, "\n"); + } else + len += sprintf(buf+len, "Card not configured\n"); + + return len; +} + +#ifdef MODULE + +int init_module(void) +{ + /* Probe for cards. */ + if (madgemc_probe()) { + printk(KERN_NOTICE "madgemc.c: No cards found.\n"); + } + /* lock_tms380_module(); */ + return (0); +} + +void cleanup_module(void) +{ + struct net_device *dev; + struct madgemc_card *this_card; + + while (madgemc_card_list) { + dev = madgemc_card_list->dev; + unregister_trdev(dev); + release_region(dev->base_addr-MADGEMC_SIF_OFFSET, MADGEMC_IO_EXTENT); + free_irq(dev->irq, dev); + kfree(dev->priv); + kfree(dev); + this_card = madgemc_card_list; + madgemc_card_list = this_card->next; + kfree(this_card); + } + /* unlock_tms380_module(); */ +} +#endif /* MODULE */ + + +/* + * Local variables: + * compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c madgemc.c" + * alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c madgemc.c" + * c-set-style "K&R" + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -ur --new-file old/linux/drivers/net/tokenring/madgemc.h new/linux/drivers/net/tokenring/madgemc.h --- old/linux/drivers/net/tokenring/madgemc.h Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/net/tokenring/madgemc.h Wed Jan 26 22:16:05 2000 @@ -0,0 +1,70 @@ +/* + * madgemc.h: Header for the madgemc tms380tr module + * + * Authors: + * - Adam Fritzler + */ + +#ifndef __LINUX_MADGEMC_H +#define __LINUX_MADGEMC_H + +#ifdef __KERNEL__ + +#define MADGEMC16_CARDNAME "Madge Smart 16/4 MC16 Ringnode" +#define MADGEMC32_CARDNAME "Madge Smart 16/4 MC32 Ringnode" + +/* + * Bit definitions for the POS config registers + */ +#define MC16_POS0_ADDR1 0x20 +#define MC16_POS2_ADDR2 0x04 +#define MC16_POS3_ADDR3 0x20 + +#define MC_CONTROL_REG0 ((long)-8) /* 0x00 */ +#define MC_CONTROL_REG1 ((long)-7) /* 0x01 */ +#define MC_ADAPTER_POS_REG0 ((long)-6) /* 0x02 */ +#define MC_ADAPTER_POS_REG1 ((long)-5) /* 0x03 */ +#define MC_ADAPTER_POS_REG2 ((long)-4) /* 0x04 */ +#define MC_ADAPTER_REG5_UNUSED ((long)-3) /* 0x05 */ +#define MC_ADAPTER_REG6_UNUSED ((long)-2) /* 0x06 */ +#define MC_CONTROL_REG7 ((long)-1) /* 0x07 */ + +#define MC_CONTROL_REG0_UNKNOWN1 0x01 +#define MC_CONTROL_REG0_UNKNOWN2 0x02 +#define MC_CONTROL_REG0_SIFSEL 0x04 +#define MC_CONTROL_REG0_PAGE 0x08 +#define MC_CONTROL_REG0_TESTINTERRUPT 0x10 +#define MC_CONTROL_REG0_UNKNOWN20 0x20 +#define MC_CONTROL_REG0_SINTR 0x40 +#define MC_CONTROL_REG0_UNKNOWN80 0x80 + +#define MC_CONTROL_REG1_SINTEN 0x01 +#define MC_CONTROL_REG1_BITOFDEATH 0x02 +#define MC_CONTROL_REG1_NSRESET 0x04 +#define MC_CONTROL_REG1_UNKNOWN8 0x08 +#define MC_CONTROL_REG1_UNKNOWN10 0x10 +#define MC_CONTROL_REG1_UNKNOWN20 0x20 +#define MC_CONTROL_REG1_SRSX 0x40 +#define MC_CONTROL_REG1_SPEED_SEL 0x80 + +#define MC_CONTROL_REG7_CABLESTP 0x00 +#define MC_CONTROL_REG7_CABLEUTP 0x01 + +/* + * ROM Page Zero + */ +#define MC_ROM_MANUFACTURERID 0x00 +#define MC_ROM_ADAPTERID 0x01 +#define MC_ROM_REVISION 0x02 +#define MC_ROM_CONFIG0 0x03 +#define MC_ROM_CONFIG1 0x04 +#define MC_ROM_CONFIG2 0x05 + +/* + * ROM Page One + */ +#define MC_ROM_UNUSED_BYTE 0x00 +#define MC_ROM_BIA_START 0x01 + +#endif /* __KERNEL__ */ +#endif /* __LINUX_MADGEMC_H */ diff -ur --new-file old/linux/drivers/net/tokenring/smctr.c new/linux/drivers/net/tokenring/smctr.c --- old/linux/drivers/net/tokenring/smctr.c Fri Jan 7 20:51:56 2000 +++ new/linux/drivers/net/tokenring/smctr.c Fri Jan 28 17:04:58 2000 @@ -17,11 +17,10 @@ * JS Jay Schulist * * To do: - * 1. MCA SMC TokenCard Support. (Some support is already done). - * 4. Multicast support. + * 1. Multicast support. */ -static const char *version = "smctr.c: v1.0 1/1/00 by jschlst@turbolinux.com\n"; +static const char *version = "smctr.c: v1.1 1/1/00 by jschlst@turbolinux.com\n"; static const char *cardname = "smctr"; #ifdef MODULE @@ -29,6 +28,7 @@ #include #endif +#include #include #include #include @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,10 @@ 0 }; +#ifdef CONFIG_MCA +static unsigned int smctr_posid = 0x6ec6; +#endif + static int ringspeed = 0; /* SMC Name of the Adapter. */ @@ -91,6 +96,7 @@ /* C */ static int smctr_checksum_firmware(struct net_device *dev); +static int __init smctr_chk_isa(struct net_device *dev); static int smctr_chg_rx_mask(struct net_device *dev); static int smctr_clear_int(struct net_device *dev); static int smctr_clear_trc_reset(int ioaddr); @@ -109,11 +115,8 @@ static int smctr_enable_adapter_ram(struct net_device *dev); static int smctr_enable_bic_int(struct net_device *dev); -/* F */ -static int __init smctr_find_adapter(struct net_device *dev); - /* G */ -static int __init smctr_get_boardid(struct net_device *dev); +static int __init smctr_get_boardid(struct net_device *dev, int mca); static int smctr_get_group_address(struct net_device *dev); static int smctr_get_functional_address(struct net_device *dev); static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev); @@ -478,13 +481,171 @@ return (0); } +static int smctr_chk_mca(struct net_device *dev) +{ +#ifdef CONFIG_MCA + struct net_local *tp = (struct net_local *)dev->priv; + int current_slot; + __u8 r1, r2, r3, r4, r5; + + current_slot = mca_find_unused_adapter(smctr_posid, 0); + if(current_slot == MCA_NOTFOUND) + return (-ENODEV); + + mca_set_adapter_name(current_slot, smctr_name); + mca_mark_as_used(current_slot); + tp->slot_num = current_slot; + + r1 = mca_read_stored_pos(tp->slot_num, 2); + r2 = mca_read_stored_pos(tp->slot_num, 3); + + if(tp->slot_num) + outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num - 1) | CNFG_SLOT_ENABLE_BIT)); + else + outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num) | CNFG_SLOT_ENABLE_BIT)); + + r1 = inb(CNFG_POS_REG1); + r2 = inb(CNFG_POS_REG0); + + tp->bic_type = BIC_594_CHIP; + + /* IO */ + r2 = mca_read_stored_pos(tp->slot_num, 2); + r2 &= 0xF0; + dev->base_addr = ((__u16)r2 << 8) + (__u16)0x800; + request_region(dev->base_addr, SMCTR_IO_EXTENT, smctr_name); + + /* IRQ */ + r5 = mca_read_stored_pos(tp->slot_num, 5); + r5 &= 0xC; + switch(r5) + { + case 0: + dev->irq = 3; + break; + + case 0x4: + dev->irq = 4; + break; + + case 0x8: + dev->irq = 10; + break; + + default: + dev->irq = 15; + break; + } + if(request_irq(dev->irq, smctr_interrupt, SA_SHIRQ, smctr_name, dev)) + return (-ENODEV); + + /* Get RAM base */ + r3 = mca_read_stored_pos(tp->slot_num, 3); + if(r3 & 0x8) + { + if(r3 & 0x80) + tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0xFD0000; + else + tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0x0D0000; + } + else + { + if(r3 & 0x80) + tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0xFC0000; + else + tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0x0C0000; + } + + /* Get Ram Size */ + r3 &= 0x30; + r3 >>= 4; + + tp->ram_usable = (__u16)CNFG_SIZE_8KB << r3; + tp->ram_size = (__u16)CNFG_SIZE_64KB; + tp->board_id |= TOKEN_MEDIA; + + r4 = mca_read_stored_pos(tp->slot_num, 4); + if(r4 & 0x8) + tp->rom_base = ((__u32)(r4 & 0x7) << 13) + 0xD0000; + else + tp->rom_base = ((__u32)(r4 & 0x7) << 13) + 0xC0000; + + /* Get ROM size. */ + r4 >>= 4; + if(r4 == 0) + tp->rom_size = CNFG_SIZE_8KB; + else + { + if(r4 == 1) + tp->rom_size = CNFG_SIZE_16KB; + else + { + if(r4 == 2) + tp->rom_size = CNFG_SIZE_32KB; + else + tp->rom_size = ROM_DISABLE; + } + } + + /* Get Media Type. */ + r5 = mca_read_stored_pos(tp->slot_num, 5); + r5 &= CNFG_MEDIA_TYPE_MASK; + switch(r5) + { + case (0): + tp->media_type = MEDIA_STP_4; + break; + + case (1): + tp->media_type = MEDIA_STP_16; + break; + + case (3): + tp->media_type = MEDIA_UTP_16; + break; + + default: + tp->media_type = MEDIA_UTP_4; + break; + } + tp->media_menu = 14; + + r2 = mca_read_stored_pos(tp->slot_num, 2); + if(!(r2 & 0x02)) + tp->mode_bits |= EARLY_TOKEN_REL; + + /* Disable slot */ + outb(CNFG_POS_CONTROL_REG, 0); + + tp->board_id = smctr_get_boardid(dev, 1); + switch(tp->board_id & 0xffff) + { + case WD8115TA: + smctr_model = "8115T/A"; + break; + + case WD8115T: + smctr_model = "8115T"; + break; + + default: + smctr_model = "Unknown"; + break; + } + + return (0); +#else + return (-1); +#endif /* CONFIG_MCA */ +} + static int smctr_chg_rx_mask(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; int err = 0; if(smctr_debug > 10) - printk("%s: smctr_chg_rx_mask\n", dev->name); + printk("%s: smctr_chg_rx_mask\n", dev->name); smctr_enable_16bit(dev); smctr_set_page(dev, (__u8 *)tp->ram_access); @@ -804,7 +965,7 @@ return (0); } -static int __init smctr_find_adapter(struct net_device *dev) +static int __init smctr_chk_isa(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -813,7 +974,10 @@ int i; if(smctr_debug > 10) - printk("%s: smctr_find_adapter %#4x\n", dev->name, ioaddr); + printk("%s: smctr_chk_isa %#4x\n", dev->name, ioaddr); + + if((ioaddr & 0x1F) != 0) + return (-ENODEV); /* Checksum SMC node address */ for(i = 0; i < 8; i++) @@ -823,7 +987,7 @@ } if(chksum != NODE_ADDR_CKSUM) - return (-1); /* Adapter Not Found */ + return (-ENODEV); /* Adapter Not Found */ /* Grab the region so that no one else tries to probe our ioports. */ request_region(ioaddr, SMCTR_IO_EXTENT, smctr_name); @@ -843,7 +1007,7 @@ return (-1); /* Get adapter ID */ - tp->board_id = smctr_get_boardid(dev); + tp->board_id = smctr_get_boardid(dev, 0); switch(tp->board_id & 0xffff) { case WD8115TA: @@ -1011,7 +1175,7 @@ return (0); } -static int __init smctr_get_boardid(struct net_device *dev) +static int __init smctr_get_boardid(struct net_device *dev, int mca) { struct net_local *tp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1020,22 +1184,35 @@ tp->board_id = BoardIdMask = 0; - BoardIdMask |= (INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT); - tp->extra_info |= (INTERFACE_584_CHIP + RAM_SIZE_64K - + NIC_825_BIT + ALTERNATE_IRQ_BIT); - - r = inb(ioaddr + BID_REG_1); - r &= 0x0c; - outb(r, ioaddr + BID_REG_1); - r = inb(ioaddr + BID_REG_1); + if(mca) + { + BoardIdMask |= (MICROCHANNEL+INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT); + tp->extra_info |= (INTERFACE_594_CHIP+RAM_SIZE_64K+NIC_825_BIT+ALTERNATE_IRQ_BIT+SLOT_16BIT); + } + else + { + BoardIdMask|=(INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT); + tp->extra_info |= (INTERFACE_584_CHIP + RAM_SIZE_64K + + NIC_825_BIT + ALTERNATE_IRQ_BIT); + } - if(r & BID_SIXTEEN_BIT_BIT) - { - tp->extra_info |= SLOT_16BIT; - tp->adapter_bus = BUS_ISA16_TYPE; - } - else - tp->adapter_bus = BUS_ISA8_TYPE; + if(!mca) + { + r = inb(ioaddr + BID_REG_1); + r &= 0x0c; + outb(r, ioaddr + BID_REG_1); + r = inb(ioaddr + BID_REG_1); + + if(r & BID_SIXTEEN_BIT_BIT) + { + tp->extra_info |= SLOT_16BIT; + tp->adapter_bus = BUS_ISA16_TYPE; + } + else + tp->adapter_bus = BUS_ISA8_TYPE; + } + else + tp->adapter_bus = BUS_MCA_TYPE; /* Get Board Id Byte */ IdByte = inb(ioaddr + BID_BOARD_ID_BYTE); @@ -3536,10 +3713,6 @@ return (-ENOMEM); #endif - /* See if we have a SMCTR card floating around. */ - if((ioaddr & 0x1F) != 0) - return (-ENODEV); /* No Adapter */ - /* Setup this devices private information structure */ tp = (struct net_local *)kmalloc(sizeof(struct net_local), GFP_KERNEL); @@ -3549,11 +3722,16 @@ dev->priv = tp; dev->base_addr = ioaddr; - err = smctr_find_adapter(dev); + /* Actually detect an adapter now. */ + err = smctr_chk_isa(dev); if(err < 0) { - kfree_s(tp, sizeof(struct net_local)); - return (-ENODEV); + err = smctr_chk_mca(dev); + if(err < 0) + { + kfree_s(tp, sizeof(struct net_local)); + return (-ENODEV); + } } tp = (struct net_local *)dev->priv; @@ -5696,6 +5874,12 @@ { if(dev_smctr[i]) { +#ifdef CONFIG_MCA + struct net_local *tp + = (struct net_local *)dev_smctr[i]->priv; + if(tp->slot_num) + mca_mark_as_unused(tp->slot_num); +#endif unregister_trdev(dev_smctr[i]); release_region(dev_smctr[i]->base_addr, SMCTR_IO_EXTENT); diff -ur --new-file old/linux/drivers/net/tokenring/smctr.h new/linux/drivers/net/tokenring/smctr.h --- old/linux/drivers/net/tokenring/smctr.h Fri Jan 7 00:01:56 2000 +++ new/linux/drivers/net/tokenring/smctr.h Wed Jan 26 22:16:05 2000 @@ -982,6 +982,9 @@ __u8 join_state; + __u8 slot_num; + __u16 pos_id; + __u32 *ptr_una; __u32 *ptr_bcn_type; __u32 *ptr_tx_fifo_underruns; @@ -1420,11 +1423,9 @@ * adapter_type The adapter_type field describes the adapter/bus * configuration. */ -#define BUS_UNK_TYPE 0x0000 /* */ #define BUS_ISA16_TYPE 0x0001 /* 16 bit adap in 16 bit (E)ISA slot */ #define BUS_ISA8_TYPE 0x0002 /* 8/16b adap in 8 bit XT/(E)ISA slot */ -#define BUS_MCA_TYPE 0x0003 /* Micro Channel adapter */#define BUS_EISA32M_TYPE 0x0004 /* EISA 32 bit bus master adapter */#define BUS_EISA32S_TYPE 0x0005 /* EISA 32 bit bus slave adapter */#define BUS_PCMCIA_TYPE 0x0006 /* PCMCIA adapter */ -#define BUS_PCI_TYPE 0x0007 /* PCI bus */ +#define BUS_MCA_TYPE 0x0003 /* Micro Channel adapter */ /* * Receive Mask definitions diff -ur --new-file old/linux/drivers/net/tokenring/tms380tr.c new/linux/drivers/net/tokenring/tms380tr.c --- old/linux/drivers/net/tokenring/tms380tr.c Fri Jan 14 20:25:21 2000 +++ new/linux/drivers/net/tokenring/tms380tr.c Wed Jan 26 22:16:05 2000 @@ -1,5 +1,5 @@ /* - * tms380tr.c: A network driver for Texas Instruments TMS380-based + * tms380tr.c: A network driver library for Texas Instruments TMS380-based * Token Ring Adapters. * * Originally sktr.c: Written 1997 by Christoph Goos @@ -10,14 +10,16 @@ * This software may be used and distributed according to the terms * of the GNU Public License, incorporated herein by reference. * - * This device driver works with the following TMS380 adapters: + * The following modules are currently available for card support: + * - tmspci (Generic PCI card support) + * - abyss (Madge PCI support) + * + * The following cards are currently lacking support, even + * though they were supported in previous versions, because + * their code did not get migrated into a seperate module: * - SysKonnect TR4/16(+) ISA (SK-4190) - * - SysKonnect TR4/16(+) PCI (SK-4590) - * - SysKonnect TR4/16 PCI (SK-4591) - * - Compaq TR 4/16 PCI - * - Thomas-Conrad TC4048 4/16 PCI - * - 3Com 3C339 Token Link Velocity - * - Any ISA or PCI adapter using only the TMS380 chipset + * They are no longer supported by this driver, at least until + * a module gets written for them. * * Sources: * - The hardware related parts of this driver are take from @@ -27,14 +29,16 @@ * - Also various other drivers in the linux source tree were taken * as samples for some tasks. * - TI TMS380 Second-Generation Token Ring User's Guide - * - TI datasheets for respective chips - * - David Hein at Texas Instruments + * - TI datasheets for respective chips + * - David Hein at Texas Instruments + * - Various Madge employees * * Maintainer(s): * JS Jay Schulist jschlst@turbolinux.com * CG Christoph Goos cgoos@syskonnect.de * AF Adam Fritzler mid@auk.cx - * + * MLP Mike Phillips phillim@amtrak.com + * * Modification History: * 29-Aug-97 CG Created * 04-Apr-98 CG Fixed problems caused by tok_timer_check @@ -42,22 +46,33 @@ * 27-May-98 JS Formated to Linux Kernel Format * 31-May-98 JS Hacked in PCI support * 16-Jun-98 JS Modulized for multiple cards with one driver - * Sep-99 AF Renamed to tms380tr (supports more than SK's) + * Sep-99 AF Renamed to tms380tr (supports more than SK's) * 23-Sep-99 AF Added Compaq and Thomas-Conrad PCI support * Fixed a bug causing double copies on PCI * Fixed for new multicast stuff (2.2/2.3) * 25-Sep-99 AF Uped TPL_NUM from 3 to 9 * Removed extraneous 'No free TPL' + * 22-Dec-99 AF Added Madge PCI Mk2 support and generalized + * parts of the initilization procedure. + * 30-Dec-99 AF Turned tms380tr into a library ala 8390. + * Madge support is provided in the abyss module + * Generic PCI support is in the tmspci module. * * To do: - * 1. Selectable 16 Mbps or 4Mbps - * 2. Multi/Broadcast packet handling (this may have fixed itself) - * + * 1. Multi/Broadcast packet handling (this may have fixed itself) + * 2. Write a sktrisa module that includes the old ISA support + * 3. Allow modules to load their own microcode + * 4. Speed up the BUD process -- freezing the kernel for 3+sec is + * quite unacceptable. + * 5. Still a few remaining stalls when the cable is unplugged. */ -static const char *version = "tms380tr.c: v1.03 29/09/1999 by Christoph Goos, Adam Fritzler\n"; +#ifdef MODULE +static const char *version = "tms380tr.c: v1.07 21/01/2000 by Christoph Goos, Adam Fritzler\n"; +#endif #ifdef MODULE +#define EXPORT_SYMTAB #include #include #endif @@ -78,6 +93,7 @@ #include #include #include +#include #include #include #include @@ -90,45 +106,6 @@ #include "tms380tr.h" /* Our Stuff */ #include "tms380tr_microcode.h" /* TI microcode for COMMprocessor */ -/* A zero-terminated list of I/O addresses to be probed. */ -static unsigned int tms380tr_portlist[] __initdata = { - 0x0A20, 0x1A20, 0x0B20, 0x1B20, 0x0980, 0x1980, 0x0900, 0x1900, - 0 -}; - -/* A zero-terminated list of IRQs to be probed. - * Used again after initial probe for tms380tr_chipset_init, called from tms380tr_open. - */ -static unsigned short tms380tr_irqlist[] = { - 3, 5, 9, 10, 11, 12, 15, - 0 -}; - -/* A zero-terminated list of DMAs to be probed. */ -static int tms380tr_dmalist[] __initdata = { - 5, 6, 7, - 0 -}; - -/* - * Table used for card detection and type determination. - */ -struct cardinfo_table cardinfo[] = { - { 0, 0, 0, - "Unknown TMS380 Token Ring Adapter"}, - { TMS_ISA, 0, 0, - "SK NET TR 4/16 ISA"}, - { TMS_PCI, PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TOKENRING, - "Compaq 4/16 TR PCI"}, - { TMS_PCI, PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_TR, - "SK NET TR 4/16 PCI"}, - { TMS_PCI, PCI_VENDOR_ID_TCONRAD, PCI_DEVICE_ID_TCONRAD_TOKENRING, - "Thomas-Conrad TC4048 PCI 4/16"}, - { TMS_PCI, PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C339, - "3Com Token Link Velocity"}, - { 0, 0, 0, NULL} -}; - /* Use 0 for production, 1 for verification, 2 for debug, and * 3 for very verbose debug. */ @@ -137,24 +114,24 @@ #endif static unsigned int tms380tr_debug = TMS380TR_DEBUG; -/* The number of low I/O ports used by the tokencard. */ -#define TMS380TR_IO_EXTENT 32 - /* Index to functions, as function prototypes. * Alphabetical by function name. */ +/* "A" */ /* "B" */ static int tms380tr_bringup_diags(struct net_device *dev); /* "C" */ static void tms380tr_cancel_tx_queue(struct net_local* tp); static int tms380tr_chipset_init(struct net_device *dev); static void tms380tr_chk_irq(struct net_device *dev); +#if 0 static unsigned char tms380tr_chk_frame(struct net_device *dev, unsigned char *Addr); +#endif static void tms380tr_chk_outstanding_cmds(struct net_device *dev); static void tms380tr_chk_src_addr(unsigned char *frame, unsigned char *hw_addr); static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqType); -static int tms380tr_close(struct net_device *dev); +int tms380tr_close(struct net_device *dev); static void tms380tr_cmd_status_irq(struct net_device *dev); /* "D" */ static void tms380tr_disable_interrupts(struct net_device *dev); @@ -176,20 +153,15 @@ static int tms380tr_init_card(struct net_device *dev); static void tms380tr_init_ipb(struct net_local *tp); static void tms380tr_init_net_local(struct net_device *dev); -static void tms380tr_init_opb(struct net_local *tp); -static void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int tms380tr_isa_chk_card(struct net_device *dev, int ioaddr, struct cardinfo_table **outcard); -static int tms380tr_isa_chk_ioaddr(int ioaddr); +static void tms380tr_init_opb(struct net_device *dev); +void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs); +/* "M" */ /* "O" */ -static int tms380tr_open(struct net_device *dev); +int tms380tr_open(struct net_device *dev); static void tms380tr_open_adapter(struct net_device *dev); /* "P" */ -static int tms380tr_pci_chk_card(struct net_device *dev, struct cardinfo_table **outcard); -int tms380tr_probe(struct net_device *dev); -static int tms380tr_probe1(struct net_device *dev, int ioaddr); /* "R" */ static void tms380tr_rcv_status_irq(struct net_device *dev); -static void tms380tr_read_addr(struct net_device *dev, unsigned char *Address); static int tms380tr_read_ptr(struct net_device *dev); static void tms380tr_read_ram(struct net_device *dev, unsigned char *Data, unsigned short Address, int Length); @@ -199,6 +171,7 @@ /* "S" */ static int tms380tr_send_packet(struct sk_buff *skb, struct net_device *dev); static void tms380tr_set_multicast_list(struct net_device *dev); +static int tms380tr_set_mac_address(struct net_device *dev, void *addr); /* "T" */ static void tms380tr_timer_chk(unsigned long data); static void tms380tr_timer_end_wait(unsigned long data); @@ -207,269 +180,61 @@ static void tms380tr_update_rcv_stats(struct net_local *tp, unsigned char DataPtr[], unsigned int Length); /* "W" */ -static void tms380tr_wait(unsigned long time); +void tms380tr_wait(unsigned long time); static void tms380tr_write_rpl_status(RPL *rpl, unsigned int Status); static void tms380tr_write_tpl_status(TPL *tpl, unsigned int Status); -/* - * Check for a network adapter of this type, and return '0' if one exists. - * If dev->base_addr == 0, probe all likely locations. - * If dev->base_addr == 1, always return failure. - */ -int __init tms380tr_probe(struct net_device *dev) -{ - int i; - int base_addr = dev ? dev->base_addr : 0; - - if(base_addr > 0x1ff) /* Check a single specified location. */ - return (tms380tr_probe1(dev, base_addr)); - else if(base_addr != 0) /* Don't probe at all. */ - return (-ENXIO); - - /* - * Let's check for pci adapters first - */ - if (tms380tr_probe1(dev,0) == 0) /* Success */ - return 0 ; - - /* - * No pci cards found, let's check for isa - */ +#define SIFREADB(reg) (((struct net_local *)dev->priv)->sifreadb(dev, reg)) +#define SIFWRITEB(val, reg) (((struct net_local *)dev->priv)->sifwriteb(dev, val, reg)) +#define SIFREADW(reg) (((struct net_local *)dev->priv)->sifreadw(dev, reg)) +#define SIFWRITEW(val, reg) (((struct net_local *)dev->priv)->sifwritew(dev, val, reg)) - for(i = 0; tms380tr_portlist[i]; i++) - { - int ioaddr = tms380tr_portlist[i]; - if(check_region(ioaddr, TMS380TR_IO_EXTENT)) /* Region already used */ - continue; - if(!tms380tr_probe1(dev, ioaddr)) - return (0); - } - return (-ENODEV); -} -struct cardinfo_table * __init tms380tr_pci_getcardinfo(unsigned short vendor, - unsigned short device) +#if TMS380TR_DEBUG > 0 +static int madgemc_sifprobe(struct net_device *dev) { - int cur; - for (cur = 1; cardinfo[cur].name != NULL; cur++) { - if (cardinfo[cur].type == 2) /* PCI */ - { - if ((cardinfo[cur].vendor_id == vendor) && (cardinfo[cur].device_id == device)) - return &cardinfo[cur]; - } - } + unsigned char old, chk1, chk2; - return NULL; -} + old = SIFREADB(SIFADR); /* Get the old SIFADR value */ -/* - * Detect and setup the PCI SysKonnect TR cards in slot order. - */ -static int __init tms380tr_pci_chk_card(struct net_device *dev, - struct cardinfo_table **outcard) -{ - struct pci_dev *pci_device = NULL ; - struct cardinfo_table *card; - int i; - - if(!pci_present()) - return (-1); /* No PCI present. */ - - while ( (pci_device=pci_find_class(PCI_CLASS_NETWORK_TOKEN_RING<<8, pci_device))) { - - unsigned int pci_irq_line; - unsigned int pci_ioaddr; - - /* Remove I/O space marker in bit 0. */ - pci_irq_line = pci_device->irq ; - pci_ioaddr = pci_device->resource[0].start ; -/* pci_ioaddr &= ~3; */ - - /* Don't return from here, just continue on the card discovery loop - MLP */ - if (!(card = tms380tr_pci_getcardinfo(pci_device->vendor, pci_device->device))) - continue ; - - if(check_region(pci_ioaddr, TMS380TR_IO_EXTENT)) - continue; - - request_region(pci_ioaddr, TMS380TR_IO_EXTENT, card->name); - if(request_irq(pci_device->irq, tms380tr_interrupt, SA_SHIRQ, - card->name, dev)) { - release_region(pci_ioaddr, TMS380TR_IO_EXTENT) ; - return (-ENODEV); /* continue; ?? */ - } - /* At this point we have found a valid tms380tr PCI TR card. */ - - pci_ioaddr &= ~3 ; - dev->base_addr = pci_ioaddr; - dev->irq = pci_irq_line; - dev->dma = 0; - - dev->addr_len = 6; - tms380tr_read_addr(dev, (unsigned char*)dev->dev_addr); + chk1 = 0; /* Begin with check value 0 */ + do { + madgemc_setregpage(dev, 0); + /* Write new SIFADR value */ + SIFWRITEB(chk1, SIFADR); + chk2 = SIFREADB(SIFADR); + if (chk2 != chk1) + return -1; - printk("%s: %s found at %#4x, IRQ %d, ring station ", - dev->name, card->name, pci_ioaddr, dev->irq); - printk("%2.2x", dev->dev_addr[0]); - for (i = 1; i < 6; i++) - printk(":%2.2x", dev->dev_addr[i]); - printk(".\n"); - - if (outcard) - *outcard = card; + madgemc_setregpage(dev, 1); + /* Read, invert and write */ + chk2 = SIFREADB(SIFADD); + if (chk2 != chk1) + return -1; + + madgemc_setregpage(dev, 0); + chk2 ^= 0x0FE; + SIFWRITEB(chk2, SIFADR); + + /* Read, invert and compare */ + madgemc_setregpage(dev, 1); + chk2 = SIFREADB(SIFADD); + madgemc_setregpage(dev, 0); + chk2 ^= 0x0FE; + + if(chk1 != chk2) + return (-1); /* No adapter */ + chk1 -= 2; + } while(chk1 != 0); /* Repeat 128 times (all byte values) */ + + madgemc_setregpage(dev, 0); /* sanity */ + /* Restore the SIFADR value */ + SIFWRITEB(old, SIFADR); - return 0 ; - } - - return (-1); + return (0); } - -/* - * Detect and setup the ISA SysKonnect TR cards. - */ -static int __init tms380tr_isa_chk_card(struct net_device *dev, int ioaddr, - struct cardinfo_table **outcard) -{ - int i, err; - unsigned long flags; - struct cardinfo_table *card = NULL; - - err = tms380tr_isa_chk_ioaddr(ioaddr); - if(err < 0) - return (-ENODEV); - - if(virt_to_bus((void*)((unsigned long)dev->priv+sizeof(struct net_local))) - > ISA_MAX_ADDRESS) - { - printk("%s: Memory not accessible for DMA\n", dev->name); - kfree(dev->priv); - return (-EAGAIN); - } - - /* FIXME */ - card = &cardinfo[1]; - - /* Grab the region so that no one else tries to probe our ioports. */ - request_region(ioaddr, TMS380TR_IO_EXTENT, card->name); - dev->base_addr = ioaddr; - - /* Autoselect IRQ and DMA if dev->irq == 0 */ - if(dev->irq == 0) - { - for(i = 0; tms380tr_irqlist[i] != 0; i++) - { - dev->irq = tms380tr_irqlist[i]; - err = request_irq(dev->irq, &tms380tr_interrupt, 0, card->name, dev); - if(!err) - break; - } - - if(tms380tr_irqlist[i] == 0) - { - printk("%s: AutoSelect no IRQ available\n", dev->name); - return (-EAGAIN); - } - } - else - { - err = request_irq(dev->irq, &tms380tr_interrupt, 0, card->name, dev); - if(err) - { - printk("%s: Selected IRQ not available\n", dev->name); - return (-EAGAIN); - } - } - - /* Always allocate the DMA channel after IRQ and clean up on failure */ - if(dev->dma == 0) - { - for(i = 0; tms380tr_dmalist[i] != 0; i++) - { - dev->dma = tms380tr_dmalist[i]; - err = request_dma(dev->dma, card->name); - if(!err) - break; - } - - if(dev->dma == 0) - { - printk("%s: AutoSelect no DMA available\n", dev->name); - free_irq(dev->irq, NULL); - return (-EAGAIN); - } - } - else - { - err = request_dma(dev->dma, card->name); - if(err) - { - printk("%s: Selected DMA not available\n", dev->name); - free_irq(dev->irq, NULL); - return (-EAGAIN); - } - } - - flags=claim_dma_lock(); - disable_dma(dev->dma); - set_dma_mode(dev->dma, DMA_MODE_CASCADE); - enable_dma(dev->dma); - release_dma_lock(flags); - - printk("%s: %s found at %#4x, using IRQ %d and DMA %d.\n", - dev->name, card->name, ioaddr, dev->irq, dev->dma); - - if (outcard) - *outcard = card; - - return (0); -} - -/* - * Passing an ioaddr of 0 tells us to do a pci card search - */ - -static int __init tms380tr_probe1(struct net_device *dev, int ioaddr) -{ - static unsigned version_printed = 0; - struct net_local *tp; - int err; - struct cardinfo_table *card = NULL; - - if(tms380tr_debug && version_printed++ == 0) - printk(KERN_INFO "%s", version); - -#ifndef MODULE - dev = init_trdev(dev, 0); - if(dev == NULL) - return (-ENOMEM); #endif - if (ioaddr == 0) { - err = tms380tr_pci_chk_card(dev, &card); - } else { - err = tms380tr_isa_chk_card(dev, ioaddr, &card); - } - if(err < 0) - return (-ENODEV); - - /* Setup this devices private information structure */ - tp = (struct net_local *)kmalloc(sizeof(struct net_local), GFP_KERNEL | GFP_DMA); - if(tp == NULL) - return (-ENOMEM); - memset(tp, 0, sizeof(struct net_local)); - init_waitqueue_head(&tp->wait_for_tok_int); - tp->CardType = card; - - dev->priv = tp; - dev->init = tms380tr_init_card; - dev->open = tms380tr_open; - dev->stop = tms380tr_close; - dev->do_ioctl = NULL ; - dev->hard_start_xmit = tms380tr_send_packet; - dev->get_stats = tms380tr_get_stats; - dev->set_multicast_list = &tms380tr_set_multicast_list; - return (0); -} /* Dummy function */ static int __init tms380tr_init_card(struct net_device *dev) @@ -481,42 +246,6 @@ } /* - * This function tests if an adapter is really installed at the - * given I/O address. Return negative if no adapter at IO addr. - */ -static int __init tms380tr_isa_chk_ioaddr(int ioaddr) -{ - unsigned char old, chk1, chk2; - - old = inb(ioaddr + SIFADR); /* Get the old SIFADR value */ - - chk1 = 0; /* Begin with check value 0 */ - do { - /* Write new SIFADR value */ - outb(chk1, ioaddr + SIFADR); - - /* Read, invert and write */ - chk2 = inb(ioaddr + SIFADD); - chk2 ^= 0x0FE; - outb(chk2, ioaddr + SIFADR); - - /* Read, invert and compare */ - chk2 = inb(ioaddr + SIFADD); - chk2 ^= 0x0FE; - - if(chk1 != chk2) - return (-1); /* No adapter */ - - chk1 -= 2; - } while(chk1 != 0); /* Repeat 128 times (all byte values) */ - - /* Restore the SIFADR value */ - outb(old, ioaddr + SIFADR); - - return (0); -} - -/* * Open/initialize the board. This is called sometime after * booting when the 'ifconfig' program is run. * @@ -524,14 +253,14 @@ * registers that "should" only need to be set once at boot, so that * there is non-reboot way to recover if something goes wrong. */ -static int tms380tr_open(struct net_device *dev) +int tms380tr_open(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; int err; /* Reset the hardware here. Don't forget to set the station address. */ err = tms380tr_chipset_init(dev); - if(err) + if(err) { printk(KERN_INFO "%s: Chipset initialization error\n", dev->name); @@ -548,7 +277,6 @@ printk(KERN_INFO "%s: Adapter RAM size: %dK\n", dev->name, tms380tr_read_ptr(dev)); - tms380tr_enable_interrupts(dev); tms380tr_open_adapter(dev); @@ -566,8 +294,8 @@ /* If AdapterVirtOpenFlag is 1, the adapter is now open for use */ if(tp->AdapterVirtOpenFlag == 0) { - tms380tr_disable_interrupts(dev); - return (-1); + tms380tr_disable_interrupts(dev); + return (-1); } dev->start = 1; @@ -579,10 +307,6 @@ tp->timer.function = tms380tr_timer_chk; tp->timer.data = (unsigned long)dev; add_timer(&tp->timer); - -#ifdef MODULE - MOD_INC_USE_COUNT; -#endif return (0); } @@ -610,47 +334,20 @@ static int tms380tr_chipset_init(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; - unsigned char PosReg, Tmp; - int i, err; + int err; tms380tr_init_ipb(tp); - tms380tr_init_opb(tp); + tms380tr_init_opb(dev); tms380tr_init_net_local(dev); - /* Set pos register: selects irq and dma channel. - * Only for ISA bus adapters. - */ - if(dev->dma > 0) - { - PosReg = 0; - for(i = 0; tms380tr_irqlist[i] != 0; i++) - { - if(tms380tr_irqlist[i] == dev->irq) - break; - } - - /* Choose default cycle time, 500 nsec */ - PosReg |= CYCLE_TIME << 2; - PosReg |= i << 4; - i = dev->dma - 5; - PosReg |= i; - - if(tp->DataRate == SPEED_4) - PosReg |= LINE_SPEED_BIT; - else - PosReg &= ~LINE_SPEED_BIT; - - outb(PosReg, dev->base_addr + POSREG); - Tmp = inb(dev->base_addr + POSREG); - if((Tmp & ~CYCLE_TIME) != (PosReg & ~CYCLE_TIME)) - printk(KERN_INFO "%s: POSREG error\n", dev->name); - } err = tms380tr_reset_adapter(dev); if(err < 0) return (-1); + err = tms380tr_bringup_diags(dev); if(err < 0) return (-1); + err = tms380tr_init_adapter(dev); if(err < 0) return (-1); @@ -690,7 +387,7 @@ skb_queue_head_init(&tp->SendSkbQueue); tp->QueueSkb = MAX_TX_QUEUE; - + /* Create circular chain of transmit lists */ for (i = 0; i < TPL_NUM; i++) { @@ -713,7 +410,7 @@ tp->Rpl[i].NextRPLAddr = htonl((unsigned long) virt_to_bus(&tp->Rpl[(i+1) % RPL_NUM])); tp->Rpl[i].Status = (RX_VALID | RX_START_FRAME | RX_END_FRAME | RX_FRAME_IRQ); tp->Rpl[i].FrameSize = 0; - tp->Rpl[i].FragList[0].DataCount = SWAPB(tp->MaxPacketSize); + tp->Rpl[i].FragList[0].DataCount = cpu_to_be16((unsigned short)tp->MaxPacketSize); /* Alloc skb and point adapter to data area */ tp->Rpl[i].Skb = dev_alloc_skb(tp->MaxPacketSize); @@ -731,7 +428,7 @@ skb_put(tp->Rpl[i].Skb, tp->MaxPacketSize); /* data unreachable for DMA ? then use local buffer */ - if(tp->CardType->type == TMS_ISA && virt_to_bus(tp->Rpl[i].Skb->data) + tp->MaxPacketSize > ISA_MAX_ADDRESS) + if(tp->dmalimit && virt_to_bus(tp->Rpl[i].Skb->data) + tp->MaxPacketSize > tp->dmalimit) { tp->Rpl[i].SkbStat = SKB_DATA_COPY; tp->Rpl[i].FragList[0].DataAddr = htonl(virt_to_bus(tp->LocalRxBuffers[i])); @@ -780,28 +477,37 @@ /* * Initializes the open parameter block. */ -static void tms380tr_init_opb(struct net_local *tp) +static void tms380tr_init_opb(struct net_device *dev) { + struct net_local *tp; unsigned long Addr; unsigned short RplSize = RPL_SIZE; unsigned short TplSize = TPL_SIZE; unsigned short BufferSize = BUFFER_SIZE; + int i; + + tp = (struct net_local *)dev->priv; tp->ocpl.OPENOptions = 0; tp->ocpl.OPENOptions |= ENABLE_FULL_DUPLEX_SELECTION; tp->ocpl.FullDuplex = 0; tp->ocpl.FullDuplex |= OPEN_FULL_DUPLEX_OFF; - /* Fixme: If mac address setable: - * for (i=0; iVam->ocpl.NodeAddr[i] = mac->CurrentAddress[i]; + /* + * Set node address + * + * We go ahead and put it in the OPB even though on + * most of the generic adapters this isn't required. + * Its simpler this way. -- ASF */ + for (i=0;i<6;i++) + tp->ocpl.NodeAddr[i] = ((unsigned char *)dev->dev_addr)[i]; tp->ocpl.GroupAddr = 0; tp->ocpl.FunctAddr = 0; - tp->ocpl.RxListSize = SWAPB(RplSize); - tp->ocpl.TxListSize = SWAPB(TplSize); - tp->ocpl.BufSize = SWAPB(BufferSize); + tp->ocpl.RxListSize = cpu_to_be16((unsigned short)RplSize); + tp->ocpl.TxListSize = cpu_to_be16((unsigned short)TplSize); + tp->ocpl.BufSize = cpu_to_be16((unsigned short)BufferSize); tp->ocpl.Reserved = 0; tp->ocpl.TXBufMin = TX_BUF_MIN; tp->ocpl.TXBufMax = TX_BUF_MAX; @@ -836,7 +542,7 @@ */ static void tms380tr_disable_interrupts(struct net_device *dev) { - outb(0, dev->base_addr + SIFACL); + SIFWRITEB(0, SIFACL); return; } @@ -847,7 +553,7 @@ */ static void tms380tr_enable_interrupts(struct net_device *dev) { - outb(ACL_SINTEN, dev->base_addr + SIFACL); + SIFWRITEB(ACL_SINTEN, SIFACL); return; } @@ -948,8 +654,7 @@ tp->QueueSkb++; /* Is buffer reachable for Busmaster-DMA? */ - if(tp->CardType->type == TMS_ISA && virt_to_bus((void*)(((long) skb->data) + skb->len)) - > ISA_MAX_ADDRESS) + if(tp->dmalimit && virt_to_bus((void*)(((long) skb->data) + skb->len)) > tp->dmalimit) { /* Copy frame to local buffer */ i = tp->TplFree->TPLIndex; @@ -975,11 +680,11 @@ /* Save the skb for delayed return of skb to system */ tpl->Skb = skb; - tpl->FragList[0].DataCount = (unsigned short) SWAPB(length); + tpl->FragList[0].DataCount = cpu_to_be16((unsigned short)length); tpl->FragList[0].DataAddr = htonl(virt_to_bus(newbuf)); /* Write the data length in the transmit list. */ - tpl->FrameSize = (unsigned short) SWAPB(length); + tpl->FrameSize = cpu_to_be16((unsigned short)length); tpl->MData = newbuf; /* Transmit the frame and set the status values. */ @@ -1057,48 +762,41 @@ /* * The typical workload of the driver: Handle the network interface interrupts. */ -static void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs) +void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct net_local *tp; - int ioaddr; unsigned short irq_type; - if(dev == NULL) - { + if(dev == NULL) { printk("%s: irq %d for unknown device.\n", dev->name, irq); return; } dev->interrupt = 1; - ioaddr = dev->base_addr; tp = (struct net_local *)dev->priv; - irq_type = inw(ioaddr + SIFSTS); + irq_type = SIFREADW(SIFSTS); - while(irq_type & STS_SYSTEM_IRQ) - { + while(irq_type & STS_SYSTEM_IRQ) { irq_type &= STS_IRQ_MASK; - if(!tms380tr_chk_ssb(tp, irq_type)) - { + if(!tms380tr_chk_ssb(tp, irq_type)) { printk(KERN_INFO "%s: DATA LATE occurred\n", dev->name); break; } - switch(irq_type) - { - case STS_IRQ_RECEIVE_STATUS: - tms380tr_reset_interrupt(dev); - tms380tr_rcv_status_irq(dev); - break; + switch(irq_type) { + case STS_IRQ_RECEIVE_STATUS: + tms380tr_reset_interrupt(dev); + tms380tr_rcv_status_irq(dev); + break; - case STS_IRQ_TRANSMIT_STATUS: - /* Check if TRANSMIT.HALT command is complete */ - if(tp->ssb.Parm[0] & COMMAND_COMPLETE) - { - tp->TransmitCommandActive = 0; + case STS_IRQ_TRANSMIT_STATUS: + /* Check if TRANSMIT.HALT command is complete */ + if(tp->ssb.Parm[0] & COMMAND_COMPLETE) { + tp->TransmitCommandActive = 0; tp->TransmitHaltScheduled = 0; /* Issue a new transmit command. */ @@ -1109,40 +807,51 @@ tms380tr_tx_status_irq(dev); break; - case STS_IRQ_COMMAND_STATUS: - /* The SSB contains status of last command - * other than receive/transmit. - */ - tms380tr_cmd_status_irq(dev); - break; - - case STS_IRQ_SCB_CLEAR: - /* The SCB is free for another command. */ - tp->ScbInUse = 0; - tms380tr_chk_outstanding_cmds(dev); - break; - - case STS_IRQ_RING_STATUS: - tms380tr_ring_status_irq(dev); - break; + case STS_IRQ_COMMAND_STATUS: + /* The SSB contains status of last command + * other than receive/transmit. + */ + tms380tr_cmd_status_irq(dev); + break; + + case STS_IRQ_SCB_CLEAR: + /* The SCB is free for another command. */ + tp->ScbInUse = 0; + tms380tr_chk_outstanding_cmds(dev); + break; + + case STS_IRQ_RING_STATUS: + tms380tr_ring_status_irq(dev); + break; - case STS_IRQ_ADAPTER_CHECK: - tms380tr_chk_irq(dev); - break; + case STS_IRQ_ADAPTER_CHECK: + tms380tr_chk_irq(dev); + break; - default: - printk(KERN_INFO "Unknown Token Ring IRQ\n"); - break; + case STS_IRQ_LLC_STATUS: + printk(KERN_DEBUG "tms380tr: unexpected LLC status IRQ\n"); + break; + + case STS_IRQ_TIMER: + printk(KERN_DEBUG "tms380tr: unexpected Timer IRQ\n"); + break; + + case STS_IRQ_RECEIVE_PENDING: + printk(KERN_DEBUG "tms380tr: unexpected Receive Pending IRQ\n"); + break; + + default: + printk(KERN_INFO "Unknown Token Ring IRQ (0x%04x)\n", irq_type); + break; } /* Reset system interrupt if not already done. */ if(irq_type != STS_IRQ_TRANSMIT_STATUS - && irq_type != STS_IRQ_RECEIVE_STATUS) - { + && irq_type != STS_IRQ_RECEIVE_STATUS) { tms380tr_reset_interrupt(dev); } - irq_type = inw(ioaddr + SIFSTS); + irq_type = SIFREADW(SIFSTS); } dev->interrupt = 0; @@ -1436,7 +1145,7 @@ /* * The inverse routine to tms380tr_open(). */ -static int tms380tr_close(struct net_device *dev) +int tms380tr_close(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; dev->tbusy = 1; @@ -1469,13 +1178,9 @@ release_dma_lock(flags); } - outw(0xFF00, dev->base_addr + SIFCMD); - if(dev->dma > 0) - outb(0xff, dev->base_addr + POSREG); - -#ifdef MODULE - MOD_DEC_USE_COUNT; -#endif + SIFWRITEW(0xFF00, SIFCMD); + if(dev->dma > 0) /* what the? */ + SIFWRITEB(0xff, POSREG); tms380tr_cancel_tx_queue(tp); @@ -1549,7 +1254,7 @@ /* * Wait for some time (microseconds) */ -static void tms380tr_wait(unsigned long time) +void tms380tr_wait(unsigned long time) { #if 0 long tmp; @@ -1570,7 +1275,6 @@ */ static void tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue) { - int ioaddr = dev->base_addr; unsigned short cmd; unsigned short SifStsValue; unsigned long loop_counter; @@ -1579,9 +1283,9 @@ cmd = (unsigned short)WriteValue; loop_counter = 0,5 * 800000; do { - SifStsValue = inw(ioaddr + SIFSTS); + SifStsValue = SIFREADW(SIFSTS); } while((SifStsValue & CMD_INTERRUPT_ADAPTER) && loop_counter--); - outw(cmd, ioaddr + SIFCMD); + SIFWRITEW(cmd, SIFCMD); return; } @@ -1595,22 +1299,19 @@ struct net_local *tp = (struct net_local *)dev->priv; unsigned short *fw_ptr = (unsigned short *)&tms380tr_code; unsigned short count, c; - int ioaddr = dev->base_addr; /* Hardware adapter reset */ - outw(ACL_ARESET, ioaddr + SIFACL); + SIFWRITEW(ACL_ARESET, SIFACL); tms380tr_wait(40); - c = inw(ioaddr + SIFACL); + c = SIFREADW(SIFACL); tms380tr_wait(20); if(dev->dma == 0) /* For PCI adapters */ { - c &= ~(ACL_SPEED4 | ACL_SPEED16); /* Clear bits */ - if(tp->DataRate == SPEED_4) - c |= ACL_SPEED4; /* Set 4Mbps */ - else - c |= ACL_SPEED16; /* Set 16Mbps */ + c &= ~(ACL_NSELOUT0 | ACL_NSELOUT1); /* Clear bits */ + if(tp->setnselout) + c |= (*tp->setnselout)(dev); } /* In case a command is pending - forget it */ @@ -1618,18 +1319,20 @@ c &= ~ACL_ARESET; /* Clear adapter reset bit */ c |= ACL_CPHALT; /* Halt adapter CPU, allow download */ + c |= ACL_BOOT; + c |= ACL_SINTEN; c &= ~ACL_PSDMAEN; /* Clear pseudo dma bit */ - outw(c, ioaddr + SIFACL); + SIFWRITEW(c, SIFACL); tms380tr_wait(40); /* Download firmware via DIO interface: */ do { /* Download first address part */ - outw(*fw_ptr, ioaddr + SIFADX); + SIFWRITEW(*fw_ptr, SIFADX); fw_ptr++; /* Download second address part */ - outw(*fw_ptr, ioaddr + SIFADD); + SIFWRITEW(*fw_ptr, SIFADD); fw_ptr++; if((count = *fw_ptr) != 0) /* Load loop counter */ @@ -1637,17 +1340,17 @@ fw_ptr++; /* Download block data */ for(; count > 0; count--) { - outw(*fw_ptr, ioaddr + SIFINC); + SIFWRITEW(*fw_ptr, SIFINC); fw_ptr++; } } else /* Stop, if last block downloaded */ { - c = inw(ioaddr + SIFACL); + c = SIFREADW(SIFACL); c &= (~ACL_CPHALT | ACL_SINTEN); /* Clear CPHALT and start BUD */ - outw(c, ioaddr + SIFACL); + SIFWRITEW(c, SIFACL); return (1); } } while(count == 0); @@ -1663,7 +1366,6 @@ { int loop_cnt, retry_cnt; unsigned short Status; - int ioaddr = dev->base_addr; tms380tr_wait(HALF_SECOND); tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET); @@ -1679,7 +1381,7 @@ do { /* Inspect BUD results */ loop_cnt--; tms380tr_wait(HALF_SECOND); - Status = inw(ioaddr + SIFSTS); + Status = SIFREADW(SIFSTS); Status &= STS_MASK; if(tms380tr_debug > 3) @@ -1701,11 +1403,16 @@ } } while(retry_cnt > 0); - Status = inw(ioaddr + SIFSTS); - Status &= STS_ERROR_MASK; /* Hardware error occurred! */ - - printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n", - dev->name, Status); + Status = SIFREADW(SIFSTS); + + /* Hardware error occurred! */ + Status &= 0x001f; + if (Status & 0x0010) + printk(KERN_INFO "%s: BUD Error: Timeout\n", dev->name); + else if ((Status & 0x000f) > 6) + printk(KERN_INFO "%s: BUD Error: Illegal Failure\n", dev->name); + else + printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n", dev->name, Status & 0x000f); return (-1); } @@ -1727,7 +1434,6 @@ unsigned char *sb_ptr = (unsigned char *) &tp->ssb; unsigned short Status; int i, loop_cnt, retry_cnt; - int ioaddr = dev->base_addr; /* Normalize: byte order low/high, word order high/low! (only IPB!) */ tp->ipb.SCB_Addr = SWAPW(virt_to_bus(&tp->scb)); @@ -1740,14 +1446,14 @@ retry_cnt--; /* Transfer initialization block */ - outw(0x0001, ioaddr + SIFADX); + SIFWRITEW(0x0001, SIFADX); /* To address 0001:0A00 of adapter RAM */ - outw(0x0A00, ioaddr + SIFADD); + SIFWRITEW(0x0A00, SIFADD); /* Write 11 words to adapter RAM */ for(i = 0; i < 11; i++) - outw(ipb_ptr[i], ioaddr + SIFINC); + SIFWRITEW(ipb_ptr[i], SIFINC); /* Execute SCB adapter command */ tms380tr_exec_sifcmd(dev, CMD_EXECUTE); @@ -1761,7 +1467,7 @@ tms380tr_wait(HALF_SECOND); /* Mask interesting status bits */ - Status = inw(ioaddr + SIFSTS); + Status = SIFREADW(SIFSTS); Status &= STS_MASK; } while(((Status &(STS_INITIALIZE | STS_ERROR | STS_TEST)) != 0) && ((Status & STS_ERROR) == 0) && (loop_cnt != 0)); @@ -1792,7 +1498,7 @@ if((Status & STS_ERROR) != 0) { /* Initialization error occurred */ - Status = inw(ioaddr + SIFSTS); + Status = SIFREADW(SIFSTS); Status &= STS_ERROR_MASK; /* ShowInitialisationErrorCode(Status); */ return (-1); /* Unrecoverable error */ @@ -1820,7 +1526,6 @@ { struct net_local *tp = (struct net_local *)dev->priv; unsigned long Addr = 0; - unsigned char i = 0; if(tp->CMDqueue == 0) return; /* No command execution */ @@ -1839,14 +1544,6 @@ /* Execute OPEN command */ tp->CMDqueue ^= OC_OPEN; - /* Copy the 18 bytes of the product ID */ - while((tp->CardType->name[i] != '\0') - && (i < PROD_ID_SIZE)) - { - tp->ProductID[i] = tp->CardType->name[i]; - i++; - } - Addr = htonl(virt_to_bus(&tp->ocpl)); tp->scb.Parm[0] = LOWORD(Addr); tp->scb.Parm[1] = HIWORD(Addr); @@ -2001,7 +1698,7 @@ { struct net_local *tp = (struct net_local *)dev->priv; - tp->CurrentRingStatus = SWAPB(tp->ssb.Parm[0]); + tp->CurrentRingStatus = be16_to_cpu((unsigned short)tp->ssb.Parm[0]); /* First: fill up statistics */ if(tp->ssb.Parm[0] & SIGNAL_LOSS) @@ -2071,19 +1768,18 @@ { int i; unsigned short AdapterCheckBlock[4]; - unsigned short ioaddr = dev->base_addr; struct net_local *tp = (struct net_local *)dev->priv; tp->AdapterOpenFlag = 0; /* Adapter closed now */ /* Page number of adapter memory */ - outw(0x0001, ioaddr + SIFADX); + SIFWRITEW(0x0001, SIFADX); /* Address offset */ - outw(CHECKADDR, ioaddr + SIFADR); + SIFWRITEW(CHECKADDR, SIFADR); /* Reading 8 byte adapter check block. */ for(i = 0; i < 4; i++) - AdapterCheckBlock[i] = inw(ioaddr + SIFINC); + AdapterCheckBlock[i] = SIFREADW(SIFINC); if(tms380tr_debug > 3) { @@ -2234,8 +1930,8 @@ tms380tr_read_ram(dev, (unsigned char *)&tp->intptrs.BurnedInAddrPtr, ADAPTER_INT_PTRS, 16); tms380tr_read_ram(dev, (unsigned char *)&adapterram, - (unsigned short)SWAPB(tp->intptrs.AdapterRAMPtr), 2); - return SWAPB(adapterram); + cpu_to_be16((unsigned short)tp->intptrs.AdapterRAMPtr), 2); + return be16_to_cpu(adapterram); } /* @@ -2246,22 +1942,21 @@ { int i; unsigned short old_sifadx, old_sifadr, InWord; - unsigned short ioaddr = dev->base_addr; /* Save the current values */ - old_sifadx = inw(ioaddr + SIFADX); - old_sifadr = inw(ioaddr + SIFADR); + old_sifadx = SIFREADW(SIFADX); + old_sifadr = SIFREADW(SIFADR); /* Page number of adapter memory */ - outw(0x0001, ioaddr + SIFADX); + SIFWRITEW(0x0001, SIFADX); /* Address offset in adapter RAM */ - outw(Address, ioaddr + SIFADR); + SIFWRITEW(Address, SIFADR); /* Copy len byte from adapter memory to system data area. */ i = 0; for(;;) { - InWord = inw(ioaddr + SIFINC); + InWord = SIFREADW(SIFINC); *(Data + i) = HIBYTE(InWord); /* Write first byte */ if(++i == Length) /* All is done break */ @@ -2273,30 +1968,8 @@ } /* Restore original values */ - outw(old_sifadx, ioaddr + SIFADX); - outw(old_sifadr, ioaddr + SIFADR); - - return; -} - -/* - * Reads MAC address from adapter ROM. - */ -static void tms380tr_read_addr(struct net_device *dev, unsigned char *Address) -{ - int i, In; - unsigned short ioaddr = dev->base_addr; - - /* Address: 0000:0000 */ - outw(0, ioaddr + SIFADX); - outw(0, ioaddr + SIFADR); - - /* Read six byte MAC address data */ - for(i = 0; i < 6; i++) - { - In = inw(ioaddr + SIFINC); - *(Address + i) = (unsigned char)(In >> 8); - } + SIFWRITEW(old_sifadx, SIFADX); + SIFWRITEW(old_sifadr, SIFADR); return; } @@ -2447,7 +2120,7 @@ /* Get the frame size (Byte swap for Intel). * Do this early (see workaround comment below) */ - Length = (unsigned short)SWAPB(rpl->FrameSize); + Length = be16_to_cpu((unsigned short)rpl->FrameSize); /* Check if the Frame_Start, Frame_End and * Frame_Complete bits are set. @@ -2463,15 +2136,16 @@ * Length2 is there because there have also been * cases where the FrameSize was partially written */ - Length2 = (unsigned short)SWAPB(rpl->FrameSize); + Length2 = be16_to_cpu((unsigned short)rpl->FrameSize); if(Length == 0 || Length != Length2) { tp->RplHead = SaveHead; break; /* Return to tms380tr_interrupt */ } -#if 0 /* This might happen for multicast or broadcast packets. - The upper layers are expected to handle this, not here */ +#if 0 /* This might happen for multicast or broadcast packets. + The upper layers are expected to handle this, not here */ + /* Drop frames sent by myself */ if(tms380tr_chk_frame(dev, rpl->MData)) { @@ -2552,8 +2226,7 @@ skb_put(rpl->Skb, tp->MaxPacketSize); /* Data unreachable for DMA ? then use local buffer */ - if(tp->CardType->type == TMS_ISA && virt_to_bus(rpl->Skb->data) + tp->MaxPacketSize - > ISA_MAX_ADDRESS) + if(tp->dmalimit && virt_to_bus(rpl->Skb->data) + tp->MaxPacketSize > tp->dmalimit) { rpl->SkbStat = SKB_DATA_COPY; rpl->FragList[0].DataAddr = htonl(virt_to_bus(tp->LocalRxBuffers[rpl->RPLIndex])); @@ -2568,7 +2241,7 @@ } } - rpl->FragList[0].DataCount = SWAPB(tp->MaxPacketSize); + rpl->FragList[0].DataCount = cpu_to_be16((unsigned short)tp->MaxPacketSize); rpl->FrameSize = 0; /* Pass the last RPL back to the adapter */ @@ -2619,6 +2292,7 @@ return; } +#if 0 /* * Check if it is a frame of myself. Compare source address with my current * address in reverse direction, and mask out the TR_RII. @@ -2639,6 +2313,20 @@ return (1); /* It is my frame. */ } +#endif + +static int tms380tr_set_mac_address(struct net_device *dev, void *addr) +{ + struct net_local *tp = (struct net_local *)dev->priv; + struct sockaddr *saddr = addr; + + if (tp->AdapterOpenFlag || tp->AdapterVirtOpenFlag) { + printk(KERN_WARNING "%s: Cannot set MAC/LAA address while card is open\n", dev->name); + return -EIO; + } + memcpy(dev->dev_addr, saddr->sa_data, dev->addr_len); + return 0; +} #if TMS380TR_DEBUG > 0 /* @@ -2651,80 +2339,73 @@ for (i = 0, j = 0; i < length / 8; i++, j += 8) { printk(KERN_DEBUG "%02x %02x %02x %02x %02x %02x %02x %02x\n", - Data[j+0],Data[j+1],Data[j+2],Data[j+3], - Data[j+4],Data[j+5],Data[j+6],Data[j+7]); + Data[j+0],Data[j+1],Data[j+2],Data[j+3], + Data[j+4],Data[j+5],Data[j+6],Data[j+7]); } return; } #endif -#ifdef MODULE +int tmsdev_init(struct net_device *dev) +{ + if (dev->priv == NULL) + { + struct net_local *tms_local; + + dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL | GFP_DMA); + if (dev->priv == NULL) + return -ENOMEM; + memset(dev->priv, 0, sizeof(struct net_local)); + tms_local = (struct net_local *)dev->priv; + init_waitqueue_head(&tms_local->wait_for_tok_int); + } + + /* These can be overridden by the card driver if needed */ + dev->init = tms380tr_init_card; + dev->open = tms380tr_open; + dev->stop = tms380tr_close; + dev->do_ioctl = NULL; + dev->hard_start_xmit = tms380tr_send_packet; + dev->get_stats = tms380tr_get_stats; + dev->set_multicast_list = &tms380tr_set_multicast_list; + dev->set_mac_address = tms380tr_set_mac_address; -static struct net_device* dev_tms380tr[TMS380TR_MAX_ADAPTERS]; -static int io[TMS380TR_MAX_ADAPTERS] = { 0, 0 }; -static int irq[TMS380TR_MAX_ADAPTERS] = { 0, 0 }; -static int mem[TMS380TR_MAX_ADAPTERS] = { 0, 0 }; - -MODULE_PARM(io, "1-" __MODULE_STRING(TMS380TR_MAX_ADAPTERS) "i"); -MODULE_PARM(irq, "1-" __MODULE_STRING(TMS380TR_MAX_ADAPTERS) "i"); -MODULE_PARM(mem, "1-" __MODULE_STRING(TMS380TR_MAX_ADAPTERS) "i"); + return 0; +} -int init_module(void) -{ - int i; +#ifdef MODULE - for(i = 0; i < TMS380TR_MAX_ADAPTERS; i++) - { - irq[i] = 0; - mem[i] = 0; - dev_tms380tr[i] = NULL; - dev_tms380tr[i] = init_trdev(dev_tms380tr[i], 0); - if(dev_tms380tr[i] == NULL) - return (-ENOMEM); - - dev_tms380tr[i]->base_addr = io[i]; - dev_tms380tr[i]->irq = irq[i]; - dev_tms380tr[i]->mem_start = mem[i]; - dev_tms380tr[i]->init = &tms380tr_probe; - - if(register_trdev(dev_tms380tr[i]) != 0) - { - kfree_s(dev_tms380tr[i], sizeof(struct net_device)); - dev_tms380tr[i] = NULL; - if(i == 0) - { - printk("tms380tr: register_trdev() returned non-zero.\n"); - return (-EIO); - } - else - return (0); - } +EXPORT_SYMBOL(tms380tr_open); +EXPORT_SYMBOL(tms380tr_close); +EXPORT_SYMBOL(tms380tr_interrupt); +EXPORT_SYMBOL(tmsdev_init); +EXPORT_SYMBOL(tms380tr_wait); - } +struct module *TMS380_module = NULL; - return (0); +int init_module(void) +{ + printk("%s", version); + + TMS380_module = &__this_module; + return 0; } void cleanup_module(void) { - int i; - - for(i = 0; i < TMS380TR_MAX_ADAPTERS; i++) - { - if(dev_tms380tr[i]) - { - unregister_trdev(dev_tms380tr[i]); - release_region(dev_tms380tr[i]->base_addr, TMS380TR_IO_EXTENT); - if(dev_tms380tr[i]->irq) - free_irq(dev_tms380tr[i]->irq, dev_tms380tr[i]); - if(dev_tms380tr[i]->dma > 0) - free_dma(dev_tms380tr[i]->dma); - if(dev_tms380tr[i]->priv) - kfree_s(dev_tms380tr[i]->priv, sizeof(struct net_local)); - kfree_s(dev_tms380tr[i], sizeof(struct net_device)); - dev_tms380tr[i] = NULL; - } - } + TMS380_module = NULL; } -#endif /* MODULE */ +#endif + + +/* + * Local variables: + * compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tms380tr.c" + * alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tms380tr.c" + * c-set-style "K&R" + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -ur --new-file old/linux/drivers/net/tokenring/tms380tr.h new/linux/drivers/net/tokenring/tms380tr.h --- old/linux/drivers/net/tokenring/tms380tr.h Thu Oct 14 23:22:09 1999 +++ new/linux/drivers/net/tokenring/tms380tr.h Wed Jan 26 22:16:05 2000 @@ -1,7 +1,9 @@ -/* tms380tr.h: TI TMS380 Token Ring driver for Linux +/* + * tms380tr.h: TI TMS380 Token Ring driver for Linux * * Authors: * - Christoph Goos + * - Adam Fritzler */ #ifndef __LINUX_TMS380TR_H @@ -9,6 +11,13 @@ #ifdef __KERNEL__ +/* module prototypes */ +int tms380tr_open(struct net_device *dev); +int tms380tr_close(struct net_device *dev); +void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs); +int tmsdev_init(struct net_device *dev); +void tms380tr_wait(unsigned long time); + #define TMS380TR_MAX_ADAPTERS 7 #define SEND_TIMEOUT 10*HZ @@ -30,9 +39,6 @@ /* -------------------------------------------------------------- */ /*------------------------------------------------------------------*/ -/* Swap bytes of a word. */ -#define SWAPB(x) (((unsigned short)((x) << 8)) | ((unsigned short)((x) >> 8))) - /* Swap words of a long. */ #define SWAPW(x) (((x) << 16) | ((x) >> 16)) @@ -51,24 +57,34 @@ /* Token ring adapter I/O addresses for normal mode. */ -#define SIFDAT 0L /* SIF/DMA data. */ -#define SIFINC 2L /* IO Word data with auto increment. */ -#define SIFINH 3L /* IO Byte data with auto increment. */ -#define SIFADR 4L /* SIF/DMA Address. */ -#define SIFCMD 6L /* SIF Command. */ -#define SIFSTS 6L /* SIF Status. */ -#define SIFACL 8L /* SIF Adapter Control Register. */ -#define SIFADD 10L /* SIF/DMA Address. */ -#define SIFADX 12L -#define DMALEN 14L /* SIF DMA length. */ -#define POSREG 16L /* Adapter Program Option Select (POS) + +/* + * The SIF registers. Common to all adapters. + */ +/* Basic SIF (SRSX = 0) */ +#define SIFDAT 0x00 /* SIF/DMA data. */ +#define SIFINC 0x02 /* IO Word data with auto increment. */ +#define SIFINH 0x03 /* IO Byte data with auto increment. */ +#define SIFADR 0x04 /* SIF/DMA Address. */ +#define SIFCMD 0x06 /* SIF Command. */ +#define SIFSTS 0x06 /* SIF Status. */ + +/* "Extended" SIF (SRSX = 1) */ +#define SIFACL 0x08 /* SIF Adapter Control Register. */ +#define SIFADD 0x0a /* SIF/DMA Address. -- 0x0a */ +#define SIFADX 0x0c /* 0x0c */ +#define DMALEN 0x0e /* SIF DMA length. -- 0x0e */ + +/* + * POS Registers. Only for ISA Adapters. + */ +#define POSREG 0x10 /* Adapter Program Option Select (POS) * Register: base IO address + 16 byte. */ #define POSREG_2 24L /* only for TR4/16+ adapter - * base IO address + 24 byte. + * base IO address + 24 byte. -- 0x18 */ - /* SIFCMD command codes (high-low) */ #define CMD_INTERRUPT_ADAPTER 0x8000 /* Cause internal adapter interrupt */ #define CMD_ADAPTER_RESET 0x4000 /* Hardware reset of adapter */ @@ -118,8 +134,13 @@ * (1/0): can be written if ACL_ARESET * is zero. */ -#define ACL_SPEED4 0x0003 -#define ACL_SPEED16 0x0001 +#define ACL_PEN 0x0004 + +#define ACL_NSELOUT0 0x0002 +#define ACL_NSELOUT1 0x0001 /* NSELOUTx have a card-specific + * meaning for setting ring speed. + */ + #define PS_DMA_MASK (ACL_SWHRQ | ACL_PSDMAEN) @@ -145,69 +166,72 @@ /* Interrupt Codes (only MAC IRQs) */ -#define STS_IRQ_ADAPTER_CHECK 0x0000 /* unrecoverable hardware or +#define STS_IRQ_ADAPTER_CHECK 0x0000 /* unrecoverable hardware or * software error. */ -#define STS_IRQ_RING_STATUS 0x0004 /* SSB is updated with ring status. */ -#define STS_IRQ_SCB_CLEAR 0x0006 /* SCB clear, following an +#define STS_IRQ_RING_STATUS 0x0004 /* SSB is updated with ring status. */ +#define STS_IRQ_LLC_STATUS 0x0005 /* Not used in MAC-only microcode */ +#define STS_IRQ_SCB_CLEAR 0x0006 /* SCB clear, following an * SCB_REQUEST IRQ. */ -#define STS_IRQ_COMMAND_STATUS 0x0008 /* SSB is updated with command +#define STS_IRQ_TIMER 0x0007 /* Not normally used in MAC ucode */ +#define STS_IRQ_COMMAND_STATUS 0x0008 /* SSB is updated with command * status. */ -#define STS_IRQ_RECEIVE_STATUS 0x000A /* SSB is updated with receive +#define STS_IRQ_RECEIVE_STATUS 0x000A /* SSB is updated with receive * status. */ -#define STS_IRQ_TRANSMIT_STATUS 0x000C /* SSB is updated with transmit +#define STS_IRQ_TRANSMIT_STATUS 0x000C /* SSB is updated with transmit * status */ -#define STS_IRQ_MASK 0x000F /* = STS_ERROR_MASK. */ +#define STS_IRQ_RECEIVE_PENDING 0x000E /* Not used in MAC-only microcode */ +#define STS_IRQ_MASK 0x000F /* = STS_ERROR_MASK. */ /* TRANSMIT_STATUS completion code: (SSB.Parm[0]) */ -#define COMMAND_COMPLETE 0x0080 /* TRANSMIT command completed +#define COMMAND_COMPLETE 0x0080 /* TRANSMIT command completed * (avoid this!) issue another transmit * to send additional frames. */ -#define FRAME_COMPLETE 0x0040 /* Frame has been transmitted; +#define FRAME_COMPLETE 0x0040 /* Frame has been transmitted; * INTERRUPT_FRAME bit was set in the * CSTAT request; indication of possibly * more than one frame transmissions! * SSB.Parm[0-1]: 32 bit pointer to * TPL of last frame. */ -#define LIST_ERROR 0x0020 /* Error in one of the TPLs that +#define LIST_ERROR 0x0020 /* Error in one of the TPLs that * compose the frame; TRANSMIT - * terminated; Parm[1-2]: 32 bit pointer + * terminated; Parm[1-2]: 32bit pointer * to TPL which starts the error * frame; error details in bits 8-13. * (14?) */ -#define FRAME_SIZE_ERROR 0x8000 /* FRAME_SIZE does not equal the sum of +#define FRAME_SIZE_ERROR 0x8000 /* FRAME_SIZE does not equal the sum of * the valid DATA_COUNT fields; * FRAME_SIZE less than header plus * information field. (15 bytes + * routing field) Or if FRAME_SIZE * was specified as zero in one list. */ -#define TX_THRESHOLD 0x4000 /* FRAME_SIZE greater than (BUFFER_SIZE +#define TX_THRESHOLD 0x4000 /* FRAME_SIZE greater than (BUFFER_SIZE * - 9) * TX_BUF_MAX. */ -#define ODD_ADDRESS 0x2000 /* Odd forward pointer value is +#define ODD_ADDRESS 0x2000 /* Odd forward pointer value is * read on a list without END_FRAME * indication. */ -#define FRAME_ERROR 0x1000 /* START_FRAME bit is (not) anticipated, +#define FRAME_ERROR 0x1000 /* START_FRAME bit (not) anticipated, * but (not) set. */ -#define ACCESS_PRIORITY_ERROR 0x0800 /* Access priority requested has not +#define ACCESS_PRIORITY_ERROR 0x0800 /* Access priority requested has not * been allowed. */ -#define UNENABLED_MAC_FRAME 0x0400 /* MAC frame has source class of zero +#define UNENABLED_MAC_FRAME 0x0400 /* MAC frame has source class of zero * or MAC frame PCF ATTN field is * greater than one. */ -#define ILLEGAL_FRAME_FORMAT 0x0200 /* Bit 0 or FC field was set to one. */ +#define ILLEGAL_FRAME_FORMAT 0x0200 /* Bit 0 or FC field was set to one. */ /* @@ -222,98 +246,98 @@ * * The following defines the command code bits and the command queue: */ -#define OC_OPEN 0x0001 /* OPEN command */ -#define OC_TRANSMIT 0x0002 /* TRANSMIT command */ -#define OC_TRANSMIT_HALT 0x0004 /* TRANSMIT_HALT command */ -#define OC_RECEIVE 0x0008 /* RECEIVE command */ -#define OC_CLOSE 0x0010 /* CLOSE command */ -#define OC_SET_GROUP_ADDR 0x0020 /* SET_GROUP_ADDR command */ -#define OC_SET_FUNCT_ADDR 0x0040 /* SET_FUNCT_ADDR command */ -#define OC_READ_ERROR_LOG 0x0080 /* READ_ERROR_LOG command */ -#define OC_READ_ADAPTER 0x0100 /* READ_ADAPTER command */ -#define OC_MODIFY_OPEN_PARMS 0x0400 /* MODIFY_OPEN_PARMS command */ -#define OC_RESTORE_OPEN_PARMS 0x0800 /* RESTORE_OPEN_PARMS command */ -#define OC_SET_FIRST_16_GROUP 0x1000 /* SET_FIRST_16_GROUP command */ -#define OC_SET_BRIDGE_PARMS 0x2000 /* SET_BRIDGE_PARMS command */ -#define OC_CONFIG_BRIDGE_PARMS 0x4000 /* CONFIG_BRIDGE_PARMS command */ +#define OC_OPEN 0x0001 /* OPEN command */ +#define OC_TRANSMIT 0x0002 /* TRANSMIT command */ +#define OC_TRANSMIT_HALT 0x0004 /* TRANSMIT_HALT command */ +#define OC_RECEIVE 0x0008 /* RECEIVE command */ +#define OC_CLOSE 0x0010 /* CLOSE command */ +#define OC_SET_GROUP_ADDR 0x0020 /* SET_GROUP_ADDR command */ +#define OC_SET_FUNCT_ADDR 0x0040 /* SET_FUNCT_ADDR command */ +#define OC_READ_ERROR_LOG 0x0080 /* READ_ERROR_LOG command */ +#define OC_READ_ADAPTER 0x0100 /* READ_ADAPTER command */ +#define OC_MODIFY_OPEN_PARMS 0x0400 /* MODIFY_OPEN_PARMS command */ +#define OC_RESTORE_OPEN_PARMS 0x0800 /* RESTORE_OPEN_PARMS command */ +#define OC_SET_FIRST_16_GROUP 0x1000 /* SET_FIRST_16_GROUP command */ +#define OC_SET_BRIDGE_PARMS 0x2000 /* SET_BRIDGE_PARMS command */ +#define OC_CONFIG_BRIDGE_PARMS 0x4000 /* CONFIG_BRIDGE_PARMS command */ -#define OPEN 0x0300 /* C: open command. S: completion. */ -#define TRANSMIT 0x0400 /* C: transmit command. S: completion +#define OPEN 0x0300 /* C: open command. S: completion. */ +#define TRANSMIT 0x0400 /* C: transmit command. S: completion * status. (reject: COMMAND_REJECT if * adapter not opened, TRANSMIT already * issued or address passed in the SCB * not word aligned) */ -#define TRANSMIT_HALT 0x0500 /* C: interrupt TX TPL chain; if no +#define TRANSMIT_HALT 0x0500 /* C: interrupt TX TPL chain; if no * TRANSMIT command issued, the command - * is ignored. (completion with TRANSMIT + * is ignored (completion with TRANSMIT * status (0x0400)!) */ -#define RECEIVE 0x0600 /* C: receive command. S: completion +#define RECEIVE 0x0600 /* C: receive command. S: completion * status. (reject: COMMAND_REJECT if * adapter not opened, RECEIVE already * issued or address passed in the SCB * not word aligned) */ -#define CLOSE 0x0700 /* C: close adapter. S: completion. +#define CLOSE 0x0700 /* C: close adapter. S: completion. * (COMMAND_REJECT if adapter not open) */ -#define SET_GROUP_ADDR 0x0800 /* C: alter adapter group address after - * OPEN. S: completion. (COMMAND_REJECT +#define SET_GROUP_ADDR 0x0800 /* C: alter adapter group address after + * OPEN. S: completion. (COMMAND_REJECT * if adapter not open) */ -#define SET_FUNCT_ADDR 0x0900 /* C: alter adapter functional address +#define SET_FUNCT_ADDR 0x0900 /* C: alter adapter functional address * after OPEN. S: completion. * (COMMAND_REJECT if adapter not open) */ -#define READ_ERROR_LOG 0x0A00 /* C: read adapter error counters. +#define READ_ERROR_LOG 0x0A00 /* C: read adapter error counters. * S: completion. (command ignored * if adapter not open!) */ -#define READ_ADAPTER 0x0B00 /* C: read data from adapter memory. +#define READ_ADAPTER 0x0B00 /* C: read data from adapter memory. * (important: after init and before * open!) S: completion. (ADAPTER_CHECK * interrupt if undefined storage area * read) */ -#define MODIFY_OPEN_PARMS 0x0D00 /* C: modify some adapter operational +#define MODIFY_OPEN_PARMS 0x0D00 /* C: modify some adapter operational * parameters. (bit correspondend to * WRAP_INTERFACE is ignored) * S: completion. (reject: * COMMAND_REJECT) */ -#define RESTORE_OPEN_PARMS 0x0E00 /* C: modify some adapter operational +#define RESTORE_OPEN_PARMS 0x0E00 /* C: modify some adapter operational * parameters. (bit correspondend * to WRAP_INTERFACE is ignored) * S: completion. (reject: * COMMAND_REJECT) */ -#define SET_FIRST_16_GROUP 0x0F00 /* C: alter the first two bytes in +#define SET_FIRST_16_GROUP 0x0F00 /* C: alter the first two bytes in * adapter group address. * S: completion. (reject: * COMMAND_REJECT) */ -#define SET_BRIDGE_PARMS 0x1000 /* C: values and conditions for the +#define SET_BRIDGE_PARMS 0x1000 /* C: values and conditions for the * adapter hardware to use when frames * are copied for forwarding. * S: completion. (reject: * COMMAND_REJECT) */ -#define CONFIG_BRIDGE_PARMS 0x1100 /* C: .. +#define CONFIG_BRIDGE_PARMS 0x1100 /* C: .. * S: completion. (reject: * COMMAND_REJECT) */ -#define SPEED_4 4 -#define SPEED_16 16 /* Default transmission speed */ +#define SPEED_4 4 +#define SPEED_16 16 /* Default transmission speed */ /* Initialization Parameter Block (IPB); word alignment necessary! */ -#define BURST_SIZE 0x0018 /* Default burst size */ -#define BURST_MODE 0x9F00 /* Burst mode enable */ -#define DMA_RETRIES 0x0505 /* Magic DMA retry number... */ +#define BURST_SIZE 0x0018 /* Default burst size */ +#define BURST_MODE 0x9F00 /* Burst mode enable */ +#define DMA_RETRIES 0x0505 /* Magic DMA retry number... */ -#define CYCLE_TIME 3 /* Default AT-bus cycle time: 500 ns +#define CYCLE_TIME 3 /* Default AT-bus cycle time: 500 ns * (later adapter version: fix cycle time!) */ #define LINE_SPEED_BIT 0x80 @@ -327,7 +351,7 @@ #define FOUR_SECONDS (ONE_SECOND_TICKS * 4) #define FIVE_SECONDS (ONE_SECOND_TICKS * 5) -#define BUFFER_SIZE 2048 /* Buffers on Adapter */ +#define BUFFER_SIZE 2048 /* Buffers on Adapter */ #pragma pack(1) typedef struct { @@ -337,18 +361,18 @@ /* Interrupt vectors the adapter places on attached system bus. */ unsigned char CMD_Status_IV; /* Interrupt vector: command status. */ - unsigned char TX_IV; /* Interrupt vector: transmit. */ - unsigned char RX_IV; /* Interrupt vector: receive. */ + unsigned char TX_IV; /* Interrupt vector: transmit. */ + unsigned char RX_IV; /* Interrupt vector: receive. */ unsigned char Ring_Status_IV; /* Interrupt vector: ring status. */ - unsigned char SCB_Clear_IV; /* Interrupt vector: SCB clear. */ + unsigned char SCB_Clear_IV; /* Interrupt vector: SCB clear. */ unsigned char Adapter_CHK_IV; /* Interrupt vector: adapter check. */ unsigned short RX_Burst_Size; /* Max. number of transfer cycles. */ unsigned short TX_Burst_Size; /* During DMA burst; even value! */ - unsigned short DMA_Abort_Thrhld; /* Number of DMA retries. */ + unsigned short DMA_Abort_Thrhld;/* Number of DMA retries. */ - unsigned long SCB_Addr; /* SCB address: even, word aligned, high-low. */ - unsigned long SSB_Addr; /* SSB address: even, word aligned, high-low. */ + unsigned long SCB_Addr; /* SCB address: even, word aligned, high-low */ + unsigned long SSB_Addr; /* SSB address: even, word aligned, high-low */ } IPB, *IPB_Ptr; #pragma pack() @@ -361,10 +385,10 @@ #define RPL_SIZE 14 /* (with TI firmware v2.26 handling * up to nine fragments possible) */ -#define TX_BUF_MIN 20 /* ??? (Stephan: calculation with */ -#define TX_BUF_MAX 40 /* BUFFER_SIZE and MAX_FRAME_SIZE) ??? +#define TX_BUF_MIN 20 /* ??? (Stephan: calculation with */ +#define TX_BUF_MAX 40 /* BUFFER_SIZE and MAX_FRAME_SIZE) ??? */ -#define DISABLE_EARLY_TOKEN_RELEASE 0x1000 +#define DISABLE_EARLY_TOKEN_RELEASE 0x1000 /* OPEN Options (high-low) */ #define WRAP_INTERFACE 0x0080 /* Inserting omitted for test @@ -372,51 +396,52 @@ * as receive data. (usefull for * testing; change: CLOSE necessary) */ -#define DISABLE_HARD_ERROR 0x0040 /* On HARD_ERROR & TRANSMIT_BEACON +#define DISABLE_HARD_ERROR 0x0040 /* On HARD_ERROR & TRANSMIT_BEACON * no RING.STATUS interrupt. */ -#define DISABLE_SOFT_ERROR 0x0020 /* On SOFT_ERROR, no RING.STATUS +#define DISABLE_SOFT_ERROR 0x0020 /* On SOFT_ERROR, no RING.STATUS * interrupt. */ -#define PASS_ADAPTER_MAC_FRAMES 0x0010 /* Passing unsupported MAC frames +#define PASS_ADAPTER_MAC_FRAMES 0x0010 /* Passing unsupported MAC frames * to system. */ -#define PASS_ATTENTION_FRAMES 0x0008 /* All changed attention MAC frames are +#define PASS_ATTENTION_FRAMES 0x0008 /* All changed attention MAC frames are * passed to the system. */ -#define PAD_ROUTING_FIELD 0x0004 /* Routing field is padded to 18 +#define PAD_ROUTING_FIELD 0x0004 /* Routing field is padded to 18 * bytes. */ -#define FRAME_HOLD 0x0002 /* Adapter waits for entire frame before +#define FRAME_HOLD 0x0002 /*Adapter waits for entire frame before * initiating DMA transfer; otherwise: * DMA transfer initiation if internal * buffer filled. */ -#define CONTENDER 0x0001 /* Adapter participates in the monitor +#define CONTENDER 0x0001 /* Adapter participates in the monitor * contention process. */ -#define PASS_BEACON_MAC_FRAMES 0x8000 /* Adapter passes beacon MAC frames +#define PASS_BEACON_MAC_FRAMES 0x8000 /* Adapter passes beacon MAC frames * to the system. */ -#define EARLY_TOKEN_RELEASE 0x1000 /* Only valid in 16 Mbps operation; +#define EARLY_TOKEN_RELEASE 0x1000 /* Only valid in 16 Mbps operation; * 0 = ETR. (no effect in 4 Mbps * operation) */ -#define COPY_ALL_MAC_FRAMES 0x0400 /* All MAC frames are copied to +#define COPY_ALL_MAC_FRAMES 0x0400 /* All MAC frames are copied to * the system. (after OPEN: duplicate * address test (DAT) MAC frame is * first received frame copied to the * system) */ -#define COPY_ALL_NON_MAC_FRAMES 0x0200 /* All non MAC frames are copied to +#define COPY_ALL_NON_MAC_FRAMES 0x0200 /* All non MAC frames are copied to * the system. */ -#define PASS_FIRST_BUF_ONLY 0x0100 /* Passes only first internal buffer +#define PASS_FIRST_BUF_ONLY 0x0100 /* Passes only first internal buffer * of each received frame; FrameSize * of RPLs must contain internal * BUFFER_SIZE bits for promiscous mode. */ -#define ENABLE_FULL_DUPLEX_SELECTION 0x2000 /* Enable the use of full-duplex +#define ENABLE_FULL_DUPLEX_SELECTION 0x2000 + /* Enable the use of full-duplex * settings with bits in byte 22 in * ocpl. (new feature in firmware * version 3.09) @@ -434,7 +459,7 @@ * fragments following. */ -#define ISA_MAX_ADDRESS 0x00ffffff +#define ISA_MAX_ADDRESS 0x00ffffff #pragma pack(1) typedef struct { @@ -1031,15 +1056,6 @@ int RPLIndex; }; -#define TMS_ISA 1 -#define TMS_PCI 2 -struct cardinfo_table { - int type; /* 1 = ISA, 2 = PCI */ - int vendor_id; - int device_id; - char *name; -}; - /* Information that need to be kept for each board. */ typedef struct net_local { #pragma pack(1) @@ -1094,7 +1110,7 @@ struct tr_statistics MacStat; /* MAC statistics structure */ - struct cardinfo_table *CardType; + unsigned long dmalimit; /* the max DMA address (ie, ISA) */ struct timer_list timer; @@ -1103,6 +1119,13 @@ INTPTRS intptrs; /* Internal adapter pointer. Must be read * before OPEN command. */ + unsigned short (*setnselout)(struct net_device *); + unsigned short (*sifreadb)(struct net_device *, unsigned short); + void (*sifwriteb)(struct net_device *, unsigned short, unsigned short); + unsigned short (*sifreadw)(struct net_device *, unsigned short); + void (*sifwritew)(struct net_device *, unsigned short, unsigned short); + + void *tmspriv; } NET_LOCAL; #endif /* __KERNEL__ */ diff -ur --new-file old/linux/drivers/net/tokenring/tmspci.c new/linux/drivers/net/tokenring/tmspci.c --- old/linux/drivers/net/tokenring/tmspci.c Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/net/tokenring/tmspci.c Wed Jan 26 22:16:05 2000 @@ -0,0 +1,336 @@ +/* + * tmspci.c: A generic network driver for TMS380-based PCI token ring cards. + * + * Written 1999 by Adam Fritzler + * + * This software may be used and distributed according to the terms + * of the GNU Public License, incorporated herein by reference. + * + * This driver module supports the following cards: + * - SysKonnect TR4/16(+) PCI (SK-4590) + * - SysKonnect TR4/16 PCI (SK-4591) + * - Compaq TR 4/16 PCI + * - Thomas-Conrad TC4048 4/16 PCI + * - 3Com 3C339 Token Link Velocity + * + * Maintainer(s): + * AF Adam Fritzler mid@auk.cx + * + * Modification History: + * 30-Dec-99 AF Split off from the tms380tr driver. + * 22-Jan-00 AF Updated to use indirect read/writes + * + * TODO: + * 1. See if we can use MMIO instead of port accesses + * + */ +static const char *version = "tmspci.c: v1.01 22/01/2000 by Adam Fritzler\n"; + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include "tms380tr.h" + +#define TMS_PCI_IO_EXTENT 32 + +struct cardinfo_table { + int vendor_id; /* PCI info */ + int device_id; + int registeroffset; /* SIF offset from dev->base_addr */ + unsigned char nselout[2]; /* NSELOUT vals for 4mb([0]) and 16mb([1]) */ + char *name; +}; + +struct cardinfo_table probelist[] = { + { 0, 0, + 0x0000, {0x00, 0x00}, "Unknown TMS380 Token Ring Adapter"}, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TOKENRING, + 0x0000, {0x03, 0x01}, "Compaq 4/16 TR PCI"}, + { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_TR, + 0x0000, {0x03, 0x01}, "SK NET TR 4/16 PCI"}, + { PCI_VENDOR_ID_TCONRAD, PCI_DEVICE_ID_TCONRAD_TOKENRING, + 0x0000, {0x03, 0x01}, "Thomas-Conrad TC4048 PCI 4/16"}, + { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C339, + 0x0000, {0x03, 0x01}, "3Com Token Link Velocity"}, + { 0, 0, 0, {0x00, 0x00}, NULL} +}; + +int tms_pci_probe(void); +static int tms_pci_open(struct net_device *dev); +static int tms_pci_close(struct net_device *dev); +static void tms_pci_read_eeprom(struct net_device *dev); +static unsigned short tms_pci_setnselout_pins(struct net_device *dev); + +static unsigned short tms_pci_sifreadb(struct net_device *dev, unsigned short reg) +{ + return inb(dev->base_addr + reg); +} + +static unsigned short tms_pci_sifreadw(struct net_device *dev, unsigned short reg) +{ + return inw(dev->base_addr + reg); +} + +static void tms_pci_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg) +{ + outb(val, dev->base_addr + reg); +} + +static void tms_pci_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg) +{ + outw(val, dev->base_addr + reg); +} + +struct tms_pci_card { + struct net_device *dev; + struct pci_dev *pci_dev; + struct cardinfo_table *cardinfo; + struct tms_pci_card *next; +}; +static struct tms_pci_card *tms_pci_card_list = NULL; + + +struct cardinfo_table * __init tms_pci_getcardinfo(unsigned short vendor, + unsigned short device) +{ + int cur; + for (cur = 1; probelist[cur].name != NULL; cur++) { + if ((probelist[cur].vendor_id == vendor) && + (probelist[cur].device_id == device)) + return &probelist[cur]; + } + + return NULL; +} + +int __init tms_pci_probe(void) +{ + static int versionprinted = 0; + struct pci_dev *pdev = NULL ; + struct net_device *dev; + struct net_local *tp; + int i; + + if (!pci_present()) + return (-1); /* No PCI present. */ + + while ( (pdev=pci_find_class(PCI_CLASS_NETWORK_TOKEN_RING<<8, pdev))) { + unsigned int pci_irq_line; + unsigned long pci_ioaddr; + struct tms_pci_card *card; + struct cardinfo_table *cardinfo; + + if ((cardinfo = + tms_pci_getcardinfo(pdev->vendor, pdev->device)) == NULL) + continue; + + if (versionprinted++ == 0) + printk("%s", version); + + pci_enable_device(pdev); + + /* Remove I/O space marker in bit 0. */ + pci_irq_line = pdev->irq; + pci_ioaddr = pdev->resource[0].start ; + + if(check_region(pci_ioaddr, TMS_PCI_IO_EXTENT)) + continue; + + /* At this point we have found a valid card. */ + + dev = init_trdev(NULL, 0); + + request_region(pci_ioaddr, TMS_PCI_IO_EXTENT, cardinfo->name); + if(request_irq(pdev->irq, tms380tr_interrupt, SA_SHIRQ, + cardinfo->name, dev)) { + release_region(pci_ioaddr, TMS_PCI_IO_EXTENT); + continue; /*return (-ENODEV);*/ /* continue; ?? */ + } + + /* + if (load_tms380_module("tmspci.c")) { + return 0; + } + */ + + pci_ioaddr &= ~3 ; + dev->base_addr = pci_ioaddr; + dev->irq = pci_irq_line; + dev->dma = 0; + + printk("%s: %s\n", dev->name, cardinfo->name); + printk("%s: IO: %#4lx IRQ: %d\n", + dev->name, dev->base_addr, dev->irq); + /* + * Some cards have their TMS SIF registers offset from + * their given base address. Account for that here. + */ + dev->base_addr += cardinfo->registeroffset; + + tms_pci_read_eeprom(dev); + + printk("%s: Ring Station Address: ", dev->name); + printk("%2.2x", dev->dev_addr[0]); + for (i = 1; i < 6; i++) + printk(":%2.2x", dev->dev_addr[i]); + printk("\n"); + + if (tmsdev_init(dev)) { + printk("%s: unable to get memory for dev->priv.\n", dev->name); + return 0; + } + + tp = (struct net_local *)dev->priv; + tp->dmalimit = 0; /* XXX: should be the max PCI32 DMA max */ + tp->setnselout = tms_pci_setnselout_pins; + + tp->sifreadb = tms_pci_sifreadb; + tp->sifreadw = tms_pci_sifreadw; + tp->sifwriteb = tms_pci_sifwriteb; + tp->sifwritew = tms_pci_sifwritew; + + memcpy(tp->ProductID, cardinfo->name, PROD_ID_SIZE + 1); + + tp->tmspriv = cardinfo; + + dev->open = tms_pci_open; + dev->stop = tms_pci_close; + + if (register_trdev(dev) == 0) { + /* Enlist in the card list */ + card = kmalloc(sizeof(struct tms_pci_card), GFP_KERNEL); + card->next = tms_pci_card_list; + tms_pci_card_list = card; + card->dev = dev; + card->pci_dev = pdev; + card->cardinfo = cardinfo; + } else { + printk("%s: register_trdev() returned non-zero.\n", dev->name); + kfree(dev->priv); + kfree(dev); + return -1; + } + } + + if (tms_pci_card_list) + return 0; + return (-1); +} + +/* + * Reads MAC address from adapter RAM, which should've read it from + * the onboard ROM. + * + * Calling this on a board that does not support it can be a very + * dangerous thing. The Madge board, for instance, will lock your + * machine hard when this is called. Luckily, its supported in a + * seperate driver. --ASF + */ +static void tms_pci_read_eeprom(struct net_device *dev) +{ + int i; + + /* Address: 0000:0000 */ + tms_pci_sifwritew(dev, 0, SIFADX); + tms_pci_sifwritew(dev, 0, SIFADR); + + /* Read six byte MAC address data */ + dev->addr_len = 6; + for(i = 0; i < 6; i++) + dev->dev_addr[i] = tms_pci_sifreadw(dev, SIFINC) >> 8; +} + +unsigned short tms_pci_setnselout_pins(struct net_device *dev) +{ + unsigned short val = 0; + struct net_local *tp = (struct net_local *)dev->priv; + struct cardinfo_table *cardinfo = (struct cardinfo_table *)tp->tmspriv; + + if(tp->DataRate == SPEED_4) + val |= cardinfo->nselout[0]; /* Set 4Mbps */ + else + val |= cardinfo->nselout[1]; /* Set 16Mbps */ + return val; +} + +static int tms_pci_open(struct net_device *dev) +{ + tms380tr_open(dev); + MOD_INC_USE_COUNT; + return 0; +} + +static int tms_pci_close(struct net_device *dev) +{ + tms380tr_close(dev); + MOD_DEC_USE_COUNT; + return 0; +} + +#ifdef MODULE + +int init_module(void) +{ + /* Probe for cards. */ + if (tms_pci_probe()) { + printk(KERN_NOTICE "tmspci.c: No cards found.\n"); + } + /* lock_tms380_module(); */ + return (0); +} + +void cleanup_module(void) +{ + struct net_device *dev; + struct tms_pci_card *this_card; + + while (tms_pci_card_list) { + dev = tms_pci_card_list->dev; + + /* + * If we used a register offset, revert here. + */ + if (dev->priv) + { + struct net_local *tp; + struct cardinfo_table *cardinfo; + + tp = (struct net_local *)dev->priv; + cardinfo = (struct cardinfo_table *)tp->tmspriv; + + dev->base_addr -= cardinfo->registeroffset; + } + unregister_netdev(dev); + release_region(dev->base_addr, TMS_PCI_IO_EXTENT); + free_irq(dev->irq, dev); + kfree(dev->priv); + kfree(dev); + this_card = tms_pci_card_list; + tms_pci_card_list = this_card->next; + kfree(this_card); + } + /* unlock_tms380_module(); */ +} +#endif /* MODULE */ + + +/* + * Local variables: + * compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tmspci.c" + * alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tmspci.c" + * c-set-style "K&R" + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -ur --new-file old/linux/drivers/net/wan/Config.in new/linux/drivers/net/wan/Config.in --- old/linux/drivers/net/wan/Config.in Mon Oct 11 19:13:25 1999 +++ new/linux/drivers/net/wan/Config.in Wed Jan 26 22:25:58 2000 @@ -34,10 +34,11 @@ if [ "$CONFIG_WAN_ROUTER_DRIVERS" = "y" ]; then dep_tristate ' Sangoma WANPIPE(tm) multiprotocol cards' CONFIG_VENDOR_SANGOMA $CONFIG_WAN_ROUTER_DRIVERS if [ "$CONFIG_VENDOR_SANGOMA" != "n" ]; then - int 'Maximum number of cards' CONFIG_WANPIPE_CARDS 1 - bool ' WANPIPE X.25 support' CONFIG_WANPIPE_X25 + int ' Maximum number of cards' CONFIG_WANPIPE_CARDS 1 + bool ' WANPIPE Cisco HDLC support' CONFIG_WANPIPE_CHDLC bool ' WANPIPE Frame Relay support' CONFIG_WANPIPE_FR bool ' WANPIPE PPP support' CONFIG_WANPIPE_PPP + bool ' WANPIPE X.25 support' CONFIG_WANPIPE_X25 fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then dep_tristate ' Cyclom 2X(tm) cards (EXPERIMENTAL)' CONFIG_CYCLADES_SYNC $CONFIG_WAN_ROUTER_DRIVERS diff -ur --new-file old/linux/drivers/net/wan/Makefile new/linux/drivers/net/wan/Makefile --- old/linux/drivers/net/wan/Makefile Mon Oct 11 19:13:25 1999 +++ new/linux/drivers/net/wan/Makefile Wed Jan 26 22:25:58 2000 @@ -102,6 +102,9 @@ ifeq ($(CONFIG_WANPIPE_X25),y) L_OBJS += sdla_x25.o endif + ifeq ($(CONFIG_WANPIPE_CHDLC),y) + L_OBJS += sdla_chdlc.o + endif ifeq ($(CONFIG_WANPIPE_FR),y) L_OBJS += sdla_fr.o endif @@ -121,6 +124,9 @@ endif ifeq ($(CONFIG_WANPIPE_FR),y) WANPIPE_OBJS += sdla_fr.o + endif + ifeq ($(CONFIG_WANPIPE_CHDLC),y) + WANPIPE_OBJS += sdla_chdlc.o endif ifeq ($(CONFIG_WANPIPE_PPP),y) WANPIPE_OBJS += sdla_ppp.o diff -ur --new-file old/linux/drivers/net/wan/cycx_main.c new/linux/drivers/net/wan/cycx_main.c --- old/linux/drivers/net/wan/cycx_main.c Sun Jan 9 06:36:20 2000 +++ new/linux/drivers/net/wan/cycx_main.c Wed Jan 26 22:25:58 2000 @@ -13,6 +13,8 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* 2000/01/21 acme rename cyclomx_open to cyclomx_mod_inc_use_count +* and cyclomx_close to cyclomx_mod_dec_use_count * 2000/01/08 acme cleanup * 1999/11/06 acme cycx_down back to life (it needs to be * called to iounmap the dpmbase) @@ -49,7 +51,7 @@ /* Defines & Macros */ #define DRV_VERSION 0 /* version number */ -#define DRV_RELEASE 5 /* release (minor version) number */ +#define DRV_RELEASE 6 /* release (minor version) number */ #define MAX_CARDS 1 /* max number of adapters */ #ifndef CONFIG_CYCLOMX_CARDS /* configurable option */ @@ -132,9 +134,9 @@ err = register_wan_device(wandev); if (err) { - printk(KERN_ERR - "%s: %s registration failed with error %d!\n", - drvname, card->devname, err); + printk(KERN_ERR "%s: %s registration failed with " + "error %d!\n", + drvname, card->devname, err); break; } } @@ -238,7 +240,7 @@ /* Initialize WAN device data space */ wandev->irq = irq; wandev->dma = wandev->ioport = 0; - wandev->maddr = (unsigned long*)card->hw.dpmbase; + wandev->maddr = card->hw.dpmbase; wandev->msize = card->hw.dpmsize; wandev->hw_opt[2] = 0; wandev->hw_opt[3] = card->hw.fwid; @@ -338,7 +340,7 @@ * have to call MOD_INC_USE_COUNT, but cannot include 'module.h' where it's * defined more than once into the same kernel module. */ -void cyclomx_open (cycx_t *card) +void cyclomx_mod_inc_use_count (cycx_t *card) { ++card->open_cnt; MOD_INC_USE_COUNT; @@ -350,7 +352,7 @@ * have to call MOD_DEC_USE_COUNT, but cannot include 'module.h' where it's * defined more than once into the same kernel module. */ -void cyclomx_close (cycx_t *card) +void cyclomx_mod_dec_use_count (cycx_t *card) { --card->open_cnt; MOD_DEC_USE_COUNT; diff -ur --new-file old/linux/drivers/net/wan/cycx_x25.c new/linux/drivers/net/wan/cycx_x25.c --- old/linux/drivers/net/wan/cycx_x25.c Sun Jan 9 06:36:20 2000 +++ new/linux/drivers/net/wan/cycx_x25.c Sat Jan 22 21:31:10 2000 @@ -70,6 +70,7 @@ * 1998/12/26 acme Minimal debug code cleanup * 1998/08/08 acme Initial version. */ + #define CYCLOMX_X25_DEBUG 1 #include @@ -188,7 +189,6 @@ * * This routine is called by the main Cyclom 2X module during setup. At this * point adapter is completely initialized and X.25 firmware is running. - * o read firmware version (to make sure it's alive) * o configure adapter * o initialize protocol-specific fields of the adapter data space. * @@ -336,7 +336,8 @@ * * Return: 0 o.k. * < 0 failure (channel will not be created) */ -static int new_if (wan_device_t *wandev, struct net_device *dev, wanif_conf_t *conf) +static int new_if (wan_device_t *wandev, struct net_device *dev, + wanif_conf_t *conf) { cycx_t *card = wandev->private; x25_channel_t *chan; @@ -507,7 +508,7 @@ dev->interrupt = 0; dev->tbusy = 0; dev->start = 1; - cyclomx_open(card); + cyclomx_mod_inc_use_count(card); return 0; } @@ -525,7 +526,7 @@ if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING) chan_disconnect(dev); - cyclomx_close(card); + cyclomx_mod_dec_use_count(card); return 0; } diff -ur --new-file old/linux/drivers/net/wan/sdla.c new/linux/drivers/net/wan/sdla.c --- old/linux/drivers/net/wan/sdla.c Tue Nov 9 17:20:12 1999 +++ new/linux/drivers/net/wan/sdla.c Sat Jan 22 21:31:10 2000 @@ -1666,7 +1666,7 @@ return(0); } -int __init sdla_setup(void) +int __init sdla_c_setup(void) { printk("%s.\n", version); register_frad(devname); @@ -1680,7 +1680,7 @@ { int result; - sdla_setup(); + sdla_c_setup(); if ((result = register_netdev(&sdla0)) != 0) return result; return 0; diff -ur --new-file old/linux/drivers/net/wan/sdla_chdlc.c new/linux/drivers/net/wan/sdla_chdlc.c --- old/linux/drivers/net/wan/sdla_chdlc.c Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/net/wan/sdla_chdlc.c Wed Jan 26 22:25:58 2000 @@ -0,0 +1,2785 @@ +/***************************************************************************** +* sdla_chdlc.c WANPIPE(tm) Multiprotocol WAN Link Driver. Cisco HDLC module. +* +* Authors: Nenad Corbic +* Gideon Hack +* +* Copyright: (c) 1995-1999 Sangoma Technologies 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. +* ============================================================================ +* Nov 20, 1999 Nenad Corbic Fixed zero length API bug. +* Sep 30, 1999 Nenad Corbic Fixed dynamic IP and route setup. +* Sep 23, 1999 Nenad Corbic Added SMP support, fixed tracing +* Sep 13, 1999 Nenad Corbic Split up Port 0 and 1 into separate devices. +* Jun 02, 1999 Gideon Hack Added support for the S514 adapter. +* Oct 30, 1998 Jaspreet Singh Added Support for CHDLC API (HDLC STREAMING). +* Oct 28, 1998 Jaspreet Singh Added Support for Dual Port CHDLC. +* Aug 07, 1998 David Fong Initial version. +*****************************************************************************/ + +#include +#include /* printk(), and other useful stuff */ +#include /* offsetof(), etc. */ +#include /* return codes */ +#include /* inline memset(), etc. */ +#include /* kmalloc(), kfree() */ +#include /* WAN router definitions */ +#include /* WANPIPE common user API definitions */ +#include /* ARPHRD_* defines */ +#include +#include +#include /* sockaddr_in */ +#include +#include +#include /* htons(), etc. */ +#include +#include + +#include /* CHDLC firmware API definitions */ + +/****** Defines & Macros ****************************************************/ + +#ifdef _DEBUG_ +#define STATIC +#else +#define STATIC static +#endif + +/* reasons for enabling the timer interrupt on the adapter */ +#define TMR_INT_ENABLED_UDP 0x0001 +#define TMR_INT_ENABLED_UPDATE 0x0002 + +#define CHDLC_DFLT_DATA_LEN 1500 /* default MTU */ +#define CHDLC_HDR_LEN 1 + +#define IFF_POINTTOPOINT 0x10 + +#define WANPIPE 0x00 +#define API 0x01 +#define CHDLC_API 0x01 + +#define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" ) + + +/******Data Structures*****************************************************/ + +/* This structure is placed in the private data area of the device structure. + * The card structure used to occupy the private area but now the following + * structure will incorporate the card structure along with CHDLC specific data + */ + +typedef struct chdlc_private_area +{ + sdla_t *card; + int TracingEnabled; /* For enabling Tracing */ + unsigned long curr_trace_addr; /* Used for Tracing */ + unsigned long start_trace_addr; + unsigned long end_trace_addr; + unsigned long base_addr_trace_buffer; + unsigned long end_addr_trace_buffer; + unsigned short number_trace_elements; + unsigned available_buffer_space; + unsigned long router_start_time; + unsigned char route_status; + unsigned char route_removed; + unsigned long tick_counter; /* For 5s timeout counter */ + unsigned long router_up_time; + u32 IP_address; /* IP addressing */ + u32 IP_netmask; + unsigned char mc; /* Mulitcast support on/off */ + unsigned short udp_pkt_lgth; /* udp packet processing */ + char udp_pkt_src; + char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT]; + unsigned short timer_int_enabled; + char update_comms_stats; /* updating comms stats */ + //FIXME: add driver stats as per frame relay! + +} chdlc_private_area_t; + +/* Route Status options */ +#define NO_ROUTE 0x00 +#define ADD_ROUTE 0x01 +#define ROUTE_ADDED 0x02 +#define REMOVE_ROUTE 0x03 + + +/* variable for keeping track of enabling/disabling FT1 monitor status */ +static int rCount = 0; + +/* variable for tracking how many interfaces to open for WANPIPE on the + two ports */ + +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + +/****** Function Prototypes *************************************************/ +/* WAN link driver entry points. These are called by the WAN router module. */ +static int update (wan_device_t* wandev); +static int new_if (wan_device_t* wandev, struct net_device* dev, + wanif_conf_t* conf); +static int del_if (wan_device_t* wandev, struct net_device* dev); + +/* Network device interface */ +static int if_init (struct net_device* dev); +static int if_open (struct net_device* dev); +static int if_close (struct net_device* dev); +static int if_header (struct sk_buff* skb, struct net_device* dev, + unsigned short type, void* daddr, void* saddr, unsigned len); +#ifdef LINUX_2_1 +static int if_rebuild_hdr (struct sk_buff *skb); +#else +static int if_rebuild_hdr (void* hdr, struct net_device* dev, unsigned long raddr, + struct sk_buff* skb); +#endif +static int if_send (struct sk_buff* skb, struct net_device* dev); +static struct enet_statistics* if_stats (struct net_device* dev); + +/* CHDLC Firmware interface functions */ +static int chdlc_configure (sdla_t* card, void* data); +static int chdlc_comm_enable (sdla_t* card); +static int chdlc_comm_disable (sdla_t* card); +static int chdlc_read_version (sdla_t* card, char* str); +static int chdlc_set_intr_mode (sdla_t* card, unsigned mode); +static int chdlc_send (sdla_t* card, void* data, unsigned len); +static int chdlc_read_comm_err_stats (sdla_t* card); +static int chdlc_read_op_stats (sdla_t* card); + + +/* Miscellaneous CHDLC Functions */ +static int set_chdlc_config (sdla_t* card); +static void init_chdlc_tx_rx_buff( sdla_t* card, struct net_device *dev ); +static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb); +static int process_chdlc_exception(sdla_t *card); +static int process_global_exception(sdla_t *card); +static int update_comms_stats(sdla_t* card, + chdlc_private_area_t* chdlc_priv_area); +static int configure_ip (sdla_t* card); +static int unconfigure_ip (sdla_t* card); +static void process_route(sdla_t *card); +static void port_set_state (sdla_t *card, int); + + +/* Interrupt handlers */ +static void wpc_isr (sdla_t* card); +static void rx_intr (sdla_t* card); +static void timer_intr(sdla_t *); + +/* Miscellaneous functions */ +static int chk_bcast_mcast_addr(sdla_t* card, struct net_device* dev, + struct sk_buff *skb); +static int reply_udp( unsigned char *data, unsigned int mbox_len ); +static int intr_test( sdla_t* card, struct net_device *dev ); +static int udp_pkt_type( struct sk_buff *skb , sdla_t* card); +static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card, + struct sk_buff *skb, struct net_device* dev, + chdlc_private_area_t* chdlc_priv_area); +static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev, + chdlc_private_area_t* chdlc_priv_area); +static unsigned short calc_checksum (char *, int); +static void s508_lock (sdla_t *card, unsigned long *smp_flags); +static void s508_unlock (sdla_t *card, unsigned long *smp_flags); + + +static int Intr_test_counter; +/****** Public Functions ****************************************************/ + +/*============================================================================ + * Cisco HDLC protocol initialization routine. + * + * This routine is called by the main WANPIPE module during setup. At this + * point adapter is completely initialized and firmware is running. + * o read firmware version (to make sure it's alive) + * o configure adapter + * o initialize protocol-specific fields of the adapter data space. + * + * Return: 0 o.k. + * < 0 failure. + */ +int wpc_init (sdla_t* card, wandev_conf_t* conf) +{ + unsigned char port_num; + int err; + unsigned long max_permitted_baud = 0; + + union + { + char str[80]; + } u; + volatile CHDLC_MAILBOX_STRUCT* mb; + CHDLC_MAILBOX_STRUCT* mb1; + unsigned long timeout; + + /* Verify configuration ID */ + if (conf->config_id != WANCONFIG_CHDLC) { + printk(KERN_INFO "%s: invalid configuration ID %u!\n", + card->devname, conf->config_id); + return -EINVAL; + } + + /* Find out which Port to use */ + if ((conf->comm_port == WANOPT_PRI) || (conf->comm_port == WANOPT_SEC)){ + if (card->next){ + + if (conf->comm_port != card->next->u.c.comm_port){ + card->u.c.comm_port = conf->comm_port; + }else{ + printk(KERN_ERR "%s: ERROR - %s port used!\n", + card->wandev.name, PORT(conf->comm_port)); + return -EINVAL; + } + }else{ + card->u.c.comm_port = conf->comm_port; + } + }else{ + printk(KERN_ERR "%s: ERROR - Invalid Port Selected!\n", + card->wandev.name); + return -EINVAL; + } + + + /* Initialize protocol-specific fields */ + if(card->hw.type != SDLA_S514){ + + if (card->u.c.comm_port == WANOPT_PRI){ + card->mbox = (void *) card->hw.dpmbase; + }else{ + card->mbox = (void *) card->hw.dpmbase + + SEC_BASE_ADDR_MB_STRUCT - PRI_BASE_ADDR_MB_STRUCT; + } + }else{ + /* for a S514 adapter, set a pointer to the actual mailbox in the */ + /* allocated virtual memory area */ + if (card->u.c.comm_port == WANOPT_PRI){ + card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT; + }else{ + card->mbox = (void *) card->hw.dpmbase + SEC_BASE_ADDR_MB_STRUCT; + } + } + + mb = mb1 = card->mbox; + + if (!card->configured){ + + /* The board will place an 'I' in the return code to indicate that it is + ready to accept commands. We expect this to be completed in less + than 1 second. */ + + timeout = jiffies; + while (mb->return_code != 'I') /* Wait 1s for board to initialize */ + if ((jiffies - timeout) > 1*HZ) break; + + if (mb->return_code != 'I') { + printk(KERN_INFO + "%s: Initialization not completed by adapter\n", + card->devname); + printk(KERN_INFO "Please contact Sangoma representative.\n"); + return -EIO; + } + } + + /* Read firmware version. Note that when adapter initializes, it + * clears the mailbox, so it may appear that the first command was + * executed successfully when in fact it was merely erased. To work + * around this, we execute the first command twice. + */ + + if (chdlc_read_version(card, u.str)) + return -EIO; + + printk(KERN_INFO "%s: Running Cisco HDLC firmware v%s\n", + card->devname, u.str); + + card->isr = &wpc_isr; + card->poll = NULL; + card->exec = NULL; + card->wandev.update = &update; + card->wandev.new_if = &new_if; + card->wandev.del_if = &del_if; + card->wandev.state = WAN_DUALPORT; + card->wandev.udp_port = conf->udp_port; + + card->wandev.new_if_cnt = 0; + + /* This is for the ports link state */ + card->u.c.state = WAN_DISCONNECTED; + + /* reset the number of times the 'update()' proc has been called */ + card->u.c.update_call_count = 0; + + card->wandev.ttl = conf->ttl; + card->wandev.interface = conf->interface; + + if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&& + card->hw.type != SDLA_S514){ + printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port \n", + card->devname, PORT(card->u.c.comm_port)); + return -EIO; + } + + card->wandev.clocking = conf->clocking; + + port_num = card->u.c.comm_port; + + /* Setup Port Bps */ + + if(card->wandev.clocking) { + + if(port_num == WANOPT_PRI) { + /* For Primary Port 0 */ + max_permitted_baud = + (card->hw.type == SDLA_S514) ? + PRI_MAX_BAUD_RATE_S514 : + PRI_MAX_BAUD_RATE_S508; + } + else if(port_num == WANOPT_SEC) { + /* For Secondary Port 1 */ + max_permitted_baud = + (card->hw.type == SDLA_S514) ? + SEC_MAX_BAUD_RATE_S514 : + SEC_MAX_BAUD_RATE_S508; + } + + if(conf->bps > max_permitted_baud) { + conf->bps = max_permitted_baud; + printk(KERN_INFO "%s: Baud too high!\n", + card->wandev.name); + printk(KERN_INFO "%s: Baud rate set to %lu bps\n", + card->wandev.name, max_permitted_baud); + } + + card->wandev.bps = conf->bps; + }else{ + card->wandev.bps = 0; + } + + /* Setup the Port MTU */ + if(port_num == WANOPT_PRI) { + /* For Primary Port 0 */ + card->wandev.mtu = + (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ? + min(conf->mtu, PRI_MAX_NO_DATA_BYTES_IN_FRAME) : + CHDLC_DFLT_DATA_LEN; + } else if(port_num == WANOPT_SEC) { + /* For Secondary Port 1 */ + card->wandev.mtu = + (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ? + min(conf->mtu, SEC_MAX_NO_DATA_BYTES_IN_FRAME) : + CHDLC_DFLT_DATA_LEN; + } + + /* Set up the interrupt status area */ + /* Read the CHDLC Configuration and obtain: + * Ptr to shared memory infor struct + * Use this pointer to calculate the value of card->u.c.flags ! + */ + mb1->buffer_length = 0; + mb1->command = READ_CHDLC_CONFIGURATION; + err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT; + if(err != COMMAND_OK) { + clear_bit(1, (void*)&card->wandev.critical); + + if(card->hw.type != SDLA_S514) + enable_irq(card->hw.irq); + + chdlc_error(card, err, mb1); + return -EIO; + } + + if(card->hw.type == SDLA_S514){ + card->u.c.flags = (void *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)-> + ptr_shared_mem_info_struct)); + }else{ + card->u.c.flags = (void *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)-> + ptr_shared_mem_info_struct % SDLA_WINDOWSIZE)); + } + + return 0; +} + +/******* WAN Device Driver Entry Points *************************************/ + +/*============================================================================ + * Update device status & statistics + * This procedure is called when updating the PROC file system and returns + * various communications statistics. These statistics are accumulated from 3 + * different locations: + * 1) The 'if_stats' recorded for the device. + * 2) Communication error statistics on the adapter. + * 3) CHDLC operational statistics on the adapter. + * The board level statistics are read during a timer interrupt. Note that we + * read the error and operational statistics during consecitive timer ticks so + * as to minimize the time that we are inside the interrupt handler. + * + */ +static int update (wan_device_t* wandev) +{ + sdla_t* card = wandev->private; + struct net_device* dev = card->wandev.dev; + volatile chdlc_private_area_t* chdlc_priv_area = dev->priv; + SHARED_MEMORY_INFO_STRUCT *flags; + unsigned long timeout; + + /* sanity checks */ + if((wandev == NULL) || (wandev->private == NULL)) + return -EFAULT; + + if(wandev->state == WAN_UNCONFIGURED) + return -ENODEV; + + /* more sanity checks */ + if(!card->u.c.flags) + return -ENODEV; + if(test_bit(1, (void*)&card->wandev.critical)) + return -EAGAIN; + + if(!dev->start) + return -ENODEV; + + flags = card->u.c.flags; + if(chdlc_priv_area->update_comms_stats){ + return -EAGAIN; + } + + /* we will need 2 timer interrupts to complete the */ + /* reading of the statistics */ + chdlc_priv_area->update_comms_stats = 2; + flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER; + chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UPDATE; + + /* wait a maximum of 1 second for the statistics to be updated */ + timeout = jiffies; + for(;;) { + if(chdlc_priv_area->update_comms_stats == 0) + break; + if ((jiffies - timeout) > (1 * HZ)){ + chdlc_priv_area->update_comms_stats = 0; + chdlc_priv_area->timer_int_enabled &= + ~TMR_INT_ENABLED_UPDATE; + return -EAGAIN; + } + } + + return 0; +} + + +/*============================================================================ + * Create new logical channel. + * This routine is called by the router when ROUTER_IFNEW IOCTL is being + * handled. + * o parse media- and hardware-specific configuration + * o make sure that a new channel can be created + * o allocate resources, if necessary + * o prepare network device structure for registaration. + * + * Return: 0 o.k. + * < 0 failure (channel will not be created) + */ +static int new_if (wan_device_t* wandev, struct net_device* dev, wanif_conf_t* conf) +{ + sdla_t* card = wandev->private; + chdlc_private_area_t* chdlc_priv_area; + + if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) { + printk(KERN_INFO "%s: invalid interface name!\n", + card->devname); + return -EINVAL; + } + + /* allocate and initialize private data */ + chdlc_priv_area = kmalloc(sizeof(chdlc_private_area_t), GFP_KERNEL); + + if(chdlc_priv_area == NULL) + return -ENOMEM; + + memset(chdlc_priv_area, 0, sizeof(chdlc_private_area_t)); + + chdlc_priv_area->card = card; + + /* initialize data */ + strcpy(card->u.c.if_name, conf->name); + + if(card->wandev.new_if_cnt > 0) { + kfree(chdlc_priv_area); + return -EEXIST; + } + + card->wandev.new_if_cnt++; + + chdlc_priv_area->TracingEnabled = 0; + chdlc_priv_area->route_status = NO_ROUTE; + chdlc_priv_area->route_removed = 0; + + /* Setup protocol options */ + + card->u.c.protocol_options = 0; + + if (conf->ignore_dcd == WANOPT_YES){ + card->u.c.protocol_options |= IGNORE_DCD_FOR_LINK_STAT; + } + + if (conf->ignore_cts == WANOPT_YES){ + card->u.c.protocol_options |= IGNORE_CTS_FOR_LINK_STAT; + } + + if (conf->ignore_keepalive == WANOPT_YES) { + card->u.c.protocol_options |= IGNORE_KPALV_FOR_LINK_STAT; + card->u.c.kpalv_tx = MIN_Tx_KPALV_TIMER; + card->u.c.kpalv_rx = MIN_Rx_KPALV_TIMER; + card->u.c.kpalv_err = MIN_KPALV_ERR_TOL; + + } else { /* Do not ignore keepalives */ + + card->u.c.kpalv_tx = + (conf->keepalive_tx_tmr - MIN_Tx_KPALV_TIMER) >= 0 ? + min (conf->keepalive_tx_tmr, MAX_Tx_KPALV_TIMER) : + DEFAULT_Tx_KPALV_TIMER; + + card->u.c.kpalv_rx = + (conf->keepalive_rx_tmr - MIN_Rx_KPALV_TIMER) >= 0 ? + min (conf->keepalive_rx_tmr, MAX_Rx_KPALV_TIMER) : + DEFAULT_Rx_KPALV_TIMER; + + card->u.c.kpalv_err = + (conf->keepalive_err_margin - MIN_KPALV_ERR_TOL) >= 0 ? + min (conf->keepalive_err_margin, MAX_KPALV_ERR_TOL) : + DEFAULT_KPALV_ERR_TOL; + } + + + /* Setup slarp timer to control delay between slarps + */ + card->u.c.slarp_timer = + (conf->slarp_timer - MIN_SLARP_REQ_TIMER) >=0 ? + min (conf->slarp_timer, MAX_SLARP_REQ_TIMER) : + DEFAULT_SLARP_REQ_TIMER; + + + /* If HDLC_STRAMING is enabled then IGNORE DCD, CTS and KEEPALIVES + * are automatically ignored + */ + if (conf->hdlc_streaming == WANOPT_YES) { + printk(KERN_INFO "%s: Enabling HDLC STREAMING Mode\n", + wandev->name); + card->u.c.protocol_options = HDLC_STREAMING_MODE; + } + + + /* Setup wanpipe as a router (WANPIPE) or as an API */ + if( strcmp(conf->usedby, "WANPIPE") == 0) { + printk(KERN_INFO "%s: Running in WANPIPE mode !\n",wandev->name); + card->u.c.usedby = WANPIPE; + + } else if( strcmp(conf->usedby, "API") == 0){ + +#ifdef CHDLC_API + card->u.c.usedby = API; + printk(KERN_INFO "%s: Running in API mode !\n",wandev->name); +#else + printk(KERN_INFO "%s: API Mode is not supported!\n", + wandev->name); + printk(KERN_INFO "%s: Chdlc API patch can be obtained from Sangoma Tech.\n", + wandev->name); + kfree(chdlc_priv_area); + return -EINVAL; +#endif + } + + + /* Get Multicast Information */ + chdlc_priv_area->mc = conf->mc; + + /* prepare network device data space for registration */ + dev->name = card->u.c.if_name; + dev->init = &if_init; + dev->priv = chdlc_priv_area; + + return 0; +} + +/*============================================================================ + * Delete logical channel. + */ +static int del_if (wan_device_t* wandev, struct net_device* dev) +{ + +/* FIXME: This code generates kernel panic during + router stop!. Investigate futher. + (Error is dereferencing a NULL pointer) + + if(dev->priv){ + + kfree(dev->priv); + dev->priv = NULL; + + } +*/ + return 0; +} + + +/****** Network Device Interface ********************************************/ + +/*============================================================================ + * Initialize Linux network interface. + * + * This routine is called only once for each interface, during Linux network + * interface registration. Returning anything but zero will fail interface + * registration. + */ +static int if_init (struct net_device* dev) + { + chdlc_private_area_t* chdlc_priv_area = dev->priv; + sdla_t* card = chdlc_priv_area->card; + wan_device_t* wandev = &card->wandev; +#ifndef LINUX_2_1 + int i; +#endif + + /* Initialize device driver entry points */ + dev->open = &if_open; + dev->stop = &if_close; + dev->hard_header = &if_header; + dev->rebuild_header = &if_rebuild_hdr; + dev->hard_start_xmit = &if_send; + dev->get_stats = &if_stats; + + /* Initialize media-specific parameters */ + dev->flags |= IFF_POINTTOPOINT; + + /* Enable Mulitcasting if user selected */ + if (chdlc_priv_area->mc == WANOPT_YES){ + dev->flags |= IFF_MULTICAST; + } + +#ifndef LINUX_2_1 + dev->family = AF_INET; +#endif + dev->type = ARPHRD_PPP; /* ARP hw type -- dummy value */ + dev->mtu = card->wandev.mtu; + dev->hard_header_len = CHDLC_HDR_LEN; + + /* Initialize hardware parameters */ + dev->irq = wandev->irq; + dev->dma = wandev->dma; + dev->base_addr = wandev->ioport; + dev->mem_start = wandev->maddr; + dev->mem_end = wandev->maddr + wandev->msize - 1; + + /* Set transmit buffer queue length + * If too low packets will not be retransmitted + * by stack. + */ + dev->tx_queue_len = 100; + + /* Initialize socket buffers */ +#ifdef LINUX_2_1 + dev_init_buffers(dev); +#else + for (i = 0; i < DEV_NUMBUFFS; ++i) + skb_queue_head_init(&dev->buffs[i]); +#endif + + return 0; +} + +/*============================================================================ + * Open network interface. + * o enable communications and interrupts. + * o prevent module from unloading by incrementing use count + * + * Return 0 if O.k. or errno. + */ +static int if_open (struct net_device* dev) +{ + chdlc_private_area_t* chdlc_priv_area = dev->priv; + sdla_t* card = chdlc_priv_area->card; + SHARED_MEMORY_INFO_STRUCT* flags = card->u.c.flags; + struct timeval tv; + int err = 0; + + /* Only one open per interface is allowed */ + + if(dev->start) + return -EBUSY; + + if(test_and_set_bit(1, (void*)&card->wandev.critical)) { + return -EAGAIN; + } + + /* Setup the Board for CHDLC */ + if (set_chdlc_config(card)) { + clear_bit(1, (void*)&card->wandev.critical); + return -EIO; + } + + if (!card->configured && !card->wandev.piggyback){ + /* Perform interrupt testing */ + err = intr_test(card, dev); + + if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) { + printk(KERN_ERR "%s: Interrupt test failed (%i)\n", + card->devname, Intr_test_counter); + printk(KERN_ERR "%s: Please choose another interrupt\n", + card->devname); + clear_bit(1, (void*)&card->wandev.critical); + return -EIO; + } + + printk(KERN_INFO "%s: Interrupt test passed (%i)\n", + card->devname, Intr_test_counter); + card->configured = 1; + }else{ + printk(KERN_INFO "%s: Card configured, skip interrupt test\n", + card->devname); + } + + /* Initialize Rx/Tx buffer control fields */ + init_chdlc_tx_rx_buff(card, dev); + + /* Set interrupt mode and mask */ + if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME | + APP_INT_ON_GLOBAL_EXCEP_COND | + APP_INT_ON_TX_FRAME | + APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){ + + clear_bit(1, (void*)&card->wandev.critical); + return -EIO; + } + + + /* Mask the Transmit and Timer interrupt */ + flags->interrupt_info_struct.interrupt_permission &= + ~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER); + + + /* Enable communications */ + if (chdlc_comm_enable(card)) { + clear_bit(1, (void*)&card->wandev.critical); + return -EIO; + } + + clear_bit(1, (void*)&card->wandev.critical); + + port_set_state(card, WAN_CONNECTING); + do_gettimeofday(&tv); + chdlc_priv_area->router_start_time = tv.tv_sec; + + dev->interrupt = 0; + dev->tbusy = 0; + dev->start = 1; + dev->flags |= IFF_POINTTOPOINT; + wanpipe_open(card); + + return err; +} + +/*============================================================================ + * Close network interface. + * o if this is the last close, then disable communications and interrupts. + * o reset flags. + */ +static int if_close (struct net_device* dev) +{ + chdlc_private_area_t* chdlc_priv_area = dev->priv; + sdla_t* card = chdlc_priv_area->card; + + if(test_and_set_bit(1, (void*)&card->wandev.critical)) + return -EAGAIN; + + dev->start = 0; + wanpipe_close(card); + port_set_state(card, WAN_DISCONNECTED); + chdlc_set_intr_mode(card, 0); + chdlc_comm_disable(card); + + clear_bit(1, (void*)&card->wandev.critical); + + return 0; +} + +/*============================================================================ + * Build media header. + * + * The trick here is to put packet type (Ethertype) into 'protocol' field of + * the socket buffer, so that we don't forget it. If packet type is not + * supported, set skb->protocol to 0 and discard packet later. + * + * Return: media header length. + */ +static int if_header (struct sk_buff* skb, struct net_device* dev, + unsigned short type, void* daddr, void* saddr, unsigned len) +{ + skb->protocol = htons(type); + + return CHDLC_HDR_LEN; +} + +/*============================================================================ + * Re-build media header. + * + * Return: 1 physical address resolved. + * 0 physical address not resolved + */ +#ifdef LINUX_2_1 +static int if_rebuild_hdr (struct sk_buff *skb) +{ + return 1; +} +#else +static int if_rebuild_hdr (void* hdr, struct net_device* dev, unsigned long raddr, + struct sk_buff* skb) +{ + return 1; +} +#endif + +/*============================================================================ + * Send a packet on a network interface. + * o set tbusy flag (marks start of the transmission) to block a timer-based + * transmit from overlapping. + * o check link state. If link is not up, then drop the packet. + * o execute adapter send command. + * o free socket buffer + * + * Return: 0 complete (socket buffer must be freed) + * non-0 packet may be re-transmitted (tbusy must be set) + * + * Notes: + * 1. This routine is called either by the protocol stack or by the "net + * bottom half" (with interrupts enabled). + * 2. Setting tbusy flag will inhibit further transmit requests from the + * protocol stack and can be used for flow control with protocol layer. + */ +static int if_send (struct sk_buff* skb, struct net_device* dev) +{ + chdlc_private_area_t *chdlc_priv_area = dev->priv; + sdla_t *card = chdlc_priv_area->card; + SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags; + INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct; + int udp_type = 0; + unsigned long smp_flags; + + if(skb == NULL) { + /* If we get here, some higher layer thinks we've missed an + * tx-done interrupt. + */ + printk(KERN_INFO "%s: interface %s got kicked!\n", + card->devname, dev->name); + mark_bh(NET_BH); + return 0; + } + + if(dev->tbusy) { + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + ++card->wandev.stats.collisions; + + if((jiffies - chdlc_priv_area->tick_counter) < (5 * HZ)) { + return 1; + } + + printk (KERN_INFO "%s: Transmit timeout !\n", + card->devname); + + /* unbusy the interface */ + dev->tbusy = 0; + } + + if(ntohs(skb->protocol) != 0x16) { + + /* check the udp packet type */ + udp_type = udp_pkt_type(skb, card); + if(udp_type == UDP_CPIPE_TYPE) { + if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev, + chdlc_priv_area)) + chdlc_int->interrupt_permission |= + APP_INT_ON_TIMER; + return 0; + } + + /* check to see if the source IP address is a broadcast or */ + /* multicast IP address */ + if(chk_bcast_mcast_addr(card, dev, skb)) + return 0; + } + + /* Lock the 508 Card: SMP is supported */ + if(card->hw.type != SDLA_S514){ + s508_lock(card,&smp_flags); + } + + if(test_and_set_bit(0, (void*)&card->wandev.critical)) { + + printk(KERN_INFO "%s: Critical in if_send: %x\n", + card->wandev.name,card->wandev.critical); + ++card->wandev.stats.tx_dropped; +#ifdef LINUX_2_1 + dev_kfree_skb(skb); +#else + dev_kfree_skb(skb, FREE_WRITE); +#endif + if(card->hw.type != SDLA_S514){ + s508_unlock(card,&smp_flags); + } + return 0; + } + + if(card->u.c.state != WAN_CONNECTED) + ++card->wandev.stats.tx_dropped; + + else if(!skb->protocol) + ++card->wandev.stats.tx_errors; + + else { + void* data = skb->data; + unsigned len = skb->len; + unsigned char attr; + + /* If it's an API packet pull off the API + * header. Also check that the packet size + * is larger than the API header + */ + if (card->u.c.usedby == API){ + api_tx_hdr_t* api_tx_hdr; + + if (len <= sizeof(api_tx_hdr_t)){ +#ifdef LINUX_2_1 + dev_kfree_skb(skb); +#else + dev_kfree_skb(skb, FREE_WRITE); +#endif + ++card->wandev.stats.tx_dropped; + clear_bit(0, (void*)&card->wandev.critical); + if(card->hw.type != SDLA_S514){ + s508_unlock(card,&smp_flags); + } + return 0; + } + + api_tx_hdr = (api_tx_hdr_t *)data; + attr = api_tx_hdr->attr; + data += sizeof(api_tx_hdr_t); + len -= sizeof(api_tx_hdr_t); + } + + if(chdlc_send(card, data, len)) { + dev->tbusy = 1; + chdlc_priv_area->tick_counter = jiffies; + chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME; + } + else { + ++card->wandev.stats.tx_packets; +#ifdef LINUX_2_1 + card->wandev.stats.tx_bytes += len; +#endif + } + } + + if (!dev->tbusy) { +#ifdef LINUX_2_1 + dev_kfree_skb(skb); +#else + dev_kfree_skb(skb, FREE_WRITE); +#endif + } + + clear_bit(0, (void*)&card->wandev.critical); + if(card->hw.type != SDLA_S514){ + s508_unlock(card,&smp_flags); + } + return dev->tbusy; +} + + +/*============================================================================ + * Check to see if the packet to be transmitted contains a broadcast or + * multicast source IP address. + */ + +static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev, + struct sk_buff *skb) +{ + u32 src_ip_addr; + u32 broadcast_ip_addr = 0; +#ifdef LINUX_2_1 + struct in_device *in_dev; +#endif + /* read the IP source address from the outgoing packet */ + src_ip_addr = *(u32 *)(skb->data + 12); + + /* read the IP broadcast address for the device */ +#ifdef LINUX_2_1 + in_dev = dev->ip_ptr; + if(in_dev != NULL) { + struct in_ifaddr *ifa= in_dev->ifa_list; + if(ifa != NULL) + broadcast_ip_addr = ifa->ifa_broadcast; + else + return 0; + } +#else + broadcast_ip_addr = dev->pa_brdaddr; +#endif + + /* check if the IP Source Address is a Broadcast address */ + if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) { + printk(KERN_INFO "%s: Broadcast Source Address silently discarded\n", + card->devname); +#ifdef LINUX_2_1 + dev_kfree_skb(skb); +#else + dev_kfree_skb(skb, FREE_WRITE); +#endif + ++card->wandev.stats.tx_dropped; + return 1; + } + + /* check if the IP Source Address is a Multicast address */ + if((ntohl(src_ip_addr) >= 0xE0000001) && + (ntohl(src_ip_addr) <= 0xFFFFFFFE)) { + printk(KERN_INFO "%s: Multicast Source Address silently discarded\n", + card->devname); +#ifdef LINUX_2_1 + dev_kfree_skb(skb); +#else + dev_kfree_skb(skb, FREE_WRITE); +#endif + ++card->wandev.stats.tx_dropped; + return 1; + } + + return 0; +} + + +/*============================================================================ + * Reply to UDP Management system. + * Return length of reply. + */ +static int reply_udp( unsigned char *data, unsigned int mbox_len ) +{ + + unsigned short len, udp_length, temp, ip_length; + unsigned long ip_temp; + int even_bound = 0; + chdlc_udp_pkt_t *c_udp_pkt = (chdlc_udp_pkt_t *)data; + + /* Set length of packet */ + len = sizeof(ip_pkt_t)+ + sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + sizeof(trace_info_t)+ + mbox_len; + + /* fill in UDP reply */ + c_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY; + + /* fill in UDP length */ + udp_length = sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + sizeof(trace_info_t)+ + mbox_len; + + /* put it on an even boundary */ + if ( udp_length & 0x0001 ) { + udp_length += 1; + len += 1; + even_bound = 1; + } + + temp = (udp_length<<8)|(udp_length>>8); + c_udp_pkt->udp_pkt.udp_length = temp; + + /* swap UDP ports */ + temp = c_udp_pkt->udp_pkt.udp_src_port; + c_udp_pkt->udp_pkt.udp_src_port = + c_udp_pkt->udp_pkt.udp_dst_port; + c_udp_pkt->udp_pkt.udp_dst_port = temp; + + /* add UDP pseudo header */ + temp = 0x1100; + *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound)) = temp; + temp = (udp_length<<8)|(udp_length>>8); + *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound+2)) = temp; + + + /* calculate UDP checksum */ + c_udp_pkt->udp_pkt.udp_checksum = 0; + c_udp_pkt->udp_pkt.udp_checksum = calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET); + + /* fill in IP length */ + ip_length = len; + temp = (ip_length<<8)|(ip_length>>8); + c_udp_pkt->ip_pkt.total_length = temp; + + /* swap IP addresses */ + ip_temp = c_udp_pkt->ip_pkt.ip_src_address; + c_udp_pkt->ip_pkt.ip_src_address = c_udp_pkt->ip_pkt.ip_dst_address; + c_udp_pkt->ip_pkt.ip_dst_address = ip_temp; + + /* fill in IP checksum */ + c_udp_pkt->ip_pkt.hdr_checksum = 0; + c_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data,sizeof(ip_pkt_t)); + + return len; + +} /* reply_udp */ + +unsigned short calc_checksum (char *data, int len) +{ + unsigned short temp; + unsigned long sum=0; + int i; + + for( i = 0; i > 16 ) { + sum = (sum & 0xffffUL) + (sum >> 16); + } + + temp = (unsigned short)sum; + temp = ~temp; + + if( temp == 0 ) + temp = 0xffff; + + return temp; +} + + +/*============================================================================ + * Get ethernet-style interface statistics. + * Return a pointer to struct enet_statistics. + */ +#ifdef LINUX_2_1 +static struct net_device_stats* if_stats (struct net_device* dev) +{ + sdla_t *my_card; + chdlc_private_area_t* chdlc_priv_area = dev->priv; + + my_card = chdlc_priv_area->card; + return &my_card->wandev.stats; +} +#else +static struct enet_statistics* if_stats (struct net_device* dev) +{ + sdla_t *my_card; + chdlc_private_area_t* chdlc_priv_area = dev->priv; + + my_card = chdlc_priv_area->card; + return &my_card->wandev.stats; +} +#endif + +/****** Cisco HDLC Firmware Interface Functions *******************************/ + +/*============================================================================ + * Read firmware code version. + * Put code version as ASCII string in str. + */ +static int chdlc_read_version (sdla_t* card, char* str) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + int len; + char err; + mb->buffer_length = 0; + mb->command = READ_CHDLC_CODE_VERSION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + + if(err != COMMAND_OK) { + chdlc_error(card,err,mb); + } + else if (str) { /* is not null */ + len = mb->buffer_length; + memcpy(str, mb->data, len); + str[len] = '\0'; + } + return (err); +} + +/*----------------------------------------------------------------------------- + * Configure CHDLC firmware. + */ +static int chdlc_configure (sdla_t* card, void* data) +{ + int err; + CHDLC_MAILBOX_STRUCT *mailbox = card->mbox; + int data_length = sizeof(CHDLC_CONFIGURATION_STRUCT); + + mailbox->buffer_length = data_length; + memcpy(mailbox->data, data, data_length); + mailbox->command = SET_CHDLC_CONFIGURATION; + err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT; + + if (err != COMMAND_OK) chdlc_error (card, err, mailbox); + + return err; +} + + +/*============================================================================ + * Set interrupt mode -- HDLC Version. + */ + +static int chdlc_set_intr_mode (sdla_t* card, unsigned mode) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + CHDLC_INT_TRIGGERS_STRUCT* int_data = + (CHDLC_INT_TRIGGERS_STRUCT *)mb->data; + int err; + + int_data->CHDLC_interrupt_triggers = mode; + int_data->IRQ = card->hw.irq; + int_data->interrupt_timer = 1; + + mb->buffer_length = sizeof(CHDLC_INT_TRIGGERS_STRUCT); + mb->command = SET_CHDLC_INTERRUPT_TRIGGERS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error (card, err, mb); + return err; +} + + +/*============================================================================ + * Enable communications. + */ + +static int chdlc_comm_enable (sdla_t* card) +{ + int err; + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + + mb->buffer_length = 0; + mb->command = ENABLE_CHDLC_COMMUNICATIONS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error(card, err, mb); + return err; +} + +/*============================================================================ + * Disable communications and Drop the Modem lines (DCD and RTS). + */ +static int chdlc_comm_disable (sdla_t* card) +{ + int err; + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + + mb->buffer_length = 0; + mb->command = DISABLE_CHDLC_COMMUNICATIONS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error(card,err,mb); + + mb->command = SET_MODEM_STATUS; + mb->buffer_length = 1; + mb->data[0] = 0; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error(card,err,mb); + + return err; +} + +/*============================================================================ + * Read communication error statistics. + */ +static int chdlc_read_comm_err_stats (sdla_t* card) +{ + int err; + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + + mb->buffer_length = 0; + mb->command = READ_COMMS_ERROR_STATS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error(card,err,mb); + return err; +} + + +/*============================================================================ + * Read CHDLC operational statistics. + */ +static int chdlc_read_op_stats (sdla_t* card) +{ + int err; + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + + mb->buffer_length = 0; + mb->command = READ_CHDLC_OPERATIONAL_STATS; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) + chdlc_error(card,err,mb); + return err; +} + + +/*============================================================================ + * Update communications error and general packet statistics. + */ +static int update_comms_stats(sdla_t* card, + chdlc_private_area_t* chdlc_priv_area) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + COMMS_ERROR_STATS_STRUCT* err_stats; + CHDLC_OPERATIONAL_STATS_STRUCT *op_stats; + + /* on the first timer interrupt, read the comms error statistics */ + if(chdlc_priv_area->update_comms_stats == 2) { + if(chdlc_read_comm_err_stats(card)) + return 1; + err_stats = (COMMS_ERROR_STATS_STRUCT *)mb->data; + card->wandev.stats.rx_over_errors = + err_stats->Rx_overrun_err_count; + card->wandev.stats.rx_crc_errors = + err_stats->CRC_err_count; + card->wandev.stats.rx_frame_errors = + err_stats->Rx_abort_count; + card->wandev.stats.rx_fifo_errors = + err_stats->Rx_dis_pri_bfrs_full_count; + card->wandev.stats.rx_missed_errors = + card->wandev.stats.rx_fifo_errors; + card->wandev.stats.tx_aborted_errors = + err_stats->sec_Tx_abort_count; + } + + /* on the second timer interrupt, read the operational statistics */ + else { + if(chdlc_read_op_stats(card)) + return 1; + op_stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)mb->data; + card->wandev.stats.rx_length_errors = + (op_stats->Rx_Data_discard_short_count + + op_stats->Rx_Data_discard_long_count); + } + + return 0; +} + +/*============================================================================ + * Send packet. + * Return: 0 - o.k. + * 1 - no transmit buffers available + */ +static int chdlc_send (sdla_t* card, void* data, unsigned len) +{ + CHDLC_DATA_TX_STATUS_EL_STRUCT *txbuf = card->u.c.txbuf; + + if (txbuf->opp_flag) + return 1; + + sdla_poke(&card->hw, txbuf->ptr_data_bfr, data, len); + + txbuf->frame_length = len; + txbuf->opp_flag = 1; /* start transmission */ + + /* Update transmit buffer control fields */ + card->u.c.txbuf = ++txbuf; + + if ((void*)txbuf > card->u.c.txbuf_last) + card->u.c.txbuf = card->u.c.txbuf_base; + + return 0; +} + +/****** Firmware Error Handler **********************************************/ + +/*============================================================================ + * Firmware error handler. + * This routine is called whenever firmware command returns non-zero + * return code. + * + * Return zero if previous command has to be cancelled. + */ +static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb) +{ + unsigned cmd = mb->command; + + switch (err) { + + case CMD_TIMEOUT: + printk(KERN_ERR "%s: command 0x%02X timed out!\n", + card->devname, cmd); + break; + + case S514_BOTH_PORTS_SAME_CLK_MODE: + if(cmd == SET_CHDLC_CONFIGURATION) { + printk(KERN_INFO + "%s: Configure both ports for the same clock source\n", + card->devname); + break; + } + + default: + printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n", + card->devname, cmd, err); + } + + return 0; +} + +/****** Interrupt Handlers **************************************************/ + +/*============================================================================ + * Cisco HDLC interrupt service routine. + */ +STATIC void wpc_isr (sdla_t* card) +{ + struct net_device* dev; + chdlc_private_area_t* chdlc_priv_area; + SHARED_MEMORY_INFO_STRUCT* flags = NULL; + int i, interrupt_serviced = 0; + sdla_t *my_card; + + + /* Check for which port the interrupt has been generated + * Since Secondary Port is piggybacking on the Primary + * the check must be done here. + */ + + flags = card->u.c.flags; + if (!flags->interrupt_info_struct.interrupt_type){ + /* Check for a second port (piggybacking) */ + if((my_card = card->next)){ + flags = my_card->u.c.flags; + if (flags->interrupt_info_struct.interrupt_type){ + card = my_card; + } + } + } + + dev = card->wandev.dev; + + card->in_isr = 1; + + /* if critical due to peripheral operations + * ie. update() or getstats() then reset the interrupt and + * wait for the board to retrigger. + */ + if(test_bit(1, (void*)&card->wandev.critical)) { + if(card->u.c.flags != NULL) { + flags = card->u.c.flags; + if(flags->interrupt_info_struct. + interrupt_type) { + flags->interrupt_info_struct. + interrupt_type = 0; + } + } + card->in_isr = 0; + return; + } + + + /* On a 508 Card, if critical due to if_send + * Major Error !!! + */ + if(card->hw.type != SDLA_S514) { + if(test_and_set_bit(0, (void*)&card->wandev.critical)) { + printk(KERN_INFO "%s: Critical while in ISR: %x\n", + card->devname, card->wandev.critical); + card->in_isr = 0; + return; + } + } + + /* FIXME: Take this check out later in the future */ + if(card->u.c.flags != NULL) { + + flags = card->u.c.flags; + + switch(flags->interrupt_info_struct.interrupt_type) { + + case RX_APP_INT_PEND: /* 0x01: receive interrupt */ + interrupt_serviced = 1; + rx_intr(card); + break; + + case TX_APP_INT_PEND: /* 0x02: transmit interrupt */ + interrupt_serviced = 1; + flags->interrupt_info_struct.interrupt_permission &= + ~APP_INT_ON_TX_FRAME; + + chdlc_priv_area = dev->priv; + dev->tbusy = 0; + mark_bh(NET_BH); + break; + + case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */ + interrupt_serviced = 1; + ++ Intr_test_counter; + break; + + case CHDLC_EXCEP_COND_APP_INT_PEND: /* 0x20 */ + interrupt_serviced = 1; + process_chdlc_exception(card); + break; + + case GLOBAL_EXCEP_COND_APP_INT_PEND: + interrupt_serviced = 1; + process_global_exception(card); + break; + + case TIMER_APP_INT_PEND: + interrupt_serviced = 1; + timer_intr(card); + break; + + default: + break; + } + } + + if(!interrupt_serviced) { + printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n", + card->devname, + flags->interrupt_info_struct.interrupt_type); + printk(KERN_INFO "Code name: "); + for(i = 0; i < 4; i ++) + printk(KERN_INFO "%c", + flags->global_info_struct.codename[i]); + printk(KERN_INFO "\nCode version: "); + for(i = 0; i < 4; i ++) + printk(KERN_INFO "%c", + flags->global_info_struct.codeversion[i]); + printk(KERN_INFO "\n"); + } + + card->in_isr = 0; + flags->interrupt_info_struct.interrupt_type = 0; + if(card->hw.type != SDLA_S514){ + clear_bit(0, (void*)&card->wandev.critical); + } + +} + +/*============================================================================ + * Receive interrupt handler. + */ +static void rx_intr (sdla_t* card) +{ + struct net_device *dev; + chdlc_private_area_t *chdlc_priv_area; + SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags; + CHDLC_DATA_RX_STATUS_EL_STRUCT *rxbuf = card->u.c.rxmb; + struct sk_buff *skb; + unsigned len; + void *buf; + int i,udp_type; + + if (rxbuf->opp_flag != 0x01) { + printk(KERN_INFO + "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n", + card->devname, (unsigned)rxbuf, rxbuf->opp_flag); + printk(KERN_INFO "Code name: "); + for(i = 0; i < 4; i ++) + printk(KERN_INFO "%c", + flags->global_info_struct.codename[i]); + printk(KERN_INFO "\nCode version: "); + for(i = 0; i < 4; i ++) + printk(KERN_INFO "%c", + flags->global_info_struct.codeversion[i]); + printk(KERN_INFO "\n"); + return; + } + + dev = card->wandev.dev; + chdlc_priv_area = dev->priv; + + if(dev && dev->start) { + + len = rxbuf->frame_length; + + /* Allocate socket buffer */ + skb = dev_alloc_skb(len); + + if (skb != NULL) { + /* Copy data to the socket buffer */ + unsigned addr = rxbuf->ptr_data_bfr; + + if((addr + len) > + card->u.c.rx_top + 1) { + unsigned tmp = + card->u.c.rx_top - addr + 1; + buf = skb_put(skb, tmp); + sdla_peek(&card->hw, addr, buf, tmp); + addr = card->u.c.rx_base; + len -= tmp; + } + + buf = skb_put(skb, len); + sdla_peek(&card->hw, addr, buf, len); + + /* Decapsulate packet */ + skb->protocol = htons(ETH_P_IP); + + card->wandev.stats.rx_packets ++; +#ifdef LINUX_2_1 + card->wandev.stats.rx_bytes += skb->len; +#endif + udp_type = udp_pkt_type( skb, card ); + + if(udp_type == UDP_CPIPE_TYPE) { + if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK, + card, skb, dev, chdlc_priv_area)) { + flags->interrupt_info_struct. + interrupt_permission |= + APP_INT_ON_TIMER; + } + + } else { + + if(card->u.c.usedby == API) { + api_rx_hdr_t* api_rx_hdr; + skb_push(skb, sizeof(api_rx_hdr_t)); + api_rx_hdr = + (api_rx_hdr_t*)&skb->data[0x00]; + api_rx_hdr->error_flag = + rxbuf->error_flag; + api_rx_hdr->time_stamp = + rxbuf->time_stamp; + skb->protocol = htons(0x16); + skb->pkt_type = PACKET_HOST; + } + +/* FIXME: we should check to see if the received packet is a multicast packet so that we can increment the multicast statistic + ++ chdlc_priv_area->if_stats.multicast; +*/ + /* Pass it up the protocol stack */ + skb->dev = dev; + skb->mac.raw = skb->data; + netif_rx(skb); + } + + } else { + printk(KERN_INFO + "%s: no socket buffers available!\n", + card->devname); + ++card->wandev.stats.rx_dropped; + } + } + + /* Release buffer element and calculate a pointer to the next one */ + rxbuf->opp_flag = 0x00; + card->u.c.rxmb = ++ rxbuf; + if((void*)rxbuf > card->u.c.rxbuf_last) + card->u.c.rxmb = card->u.c.rxbuf_base; +} + +/*============================================================================ + * Timer interrupt handler. + * The timer interrupt is used for two purposes: + * 1) Processing udp calls from 'cpipemon'. + * 2) Reading board-level statistics for updating the proc file system. + */ +void timer_intr(sdla_t *card) +{ + struct net_device* dev; + chdlc_private_area_t* chdlc_priv_area = NULL; + SHARED_MEMORY_INFO_STRUCT* flags = NULL; + + dev = card->wandev.dev; + chdlc_priv_area = dev->priv; + + /* process a udp call if pending */ + if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP) { + process_udp_mgmt_pkt(card, dev, + chdlc_priv_area); + chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP; + } + + /* read the communications statistics if required */ + if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE) { + update_comms_stats(card, chdlc_priv_area); + if(!(-- chdlc_priv_area->update_comms_stats)) { + chdlc_priv_area->timer_int_enabled &= + ~TMR_INT_ENABLED_UPDATE; + } + } + + /* only disable the timer interrupt if there are no udp or statistic */ + /* updates pending */ + if(!chdlc_priv_area->timer_int_enabled) { + flags = card->u.c.flags; + flags->interrupt_info_struct.interrupt_permission &= + ~APP_INT_ON_TIMER; + } +} + +/*------------------------------------------------------------------------------ + Miscellaneous Functions + - set_chdlc_config() used to set configuration options on the board +------------------------------------------------------------------------------*/ + +static int set_chdlc_config(sdla_t* card) +{ + + struct net_device * dev = card->wandev.dev; + chdlc_private_area_t *chdlc_priv_area = dev->priv; + CHDLC_CONFIGURATION_STRUCT cfg; + + memset(&cfg, 0, sizeof(CHDLC_CONFIGURATION_STRUCT)); + + if(card->wandev.clocking) + cfg.baud_rate = card->wandev.bps; + + cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ? + INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35; + + cfg.modem_config_options = 0; + cfg.modem_status_timer = 100; + + cfg.CHDLC_protocol_options = card->u.c.protocol_options; + cfg.percent_data_buffer_for_Tx = 50; + cfg.CHDLC_statistics_options = (CHDLC_TX_DATA_BYTE_COUNT_STAT | + CHDLC_RX_DATA_BYTE_COUNT_STAT); + cfg.max_CHDLC_data_field_length = card->wandev.mtu; + cfg.transmit_keepalive_timer = card->u.c.kpalv_tx; + cfg.receive_keepalive_timer = card->u.c.kpalv_rx; + cfg.keepalive_error_tolerance = card->u.c.kpalv_err; + cfg.SLARP_request_timer = card->u.c.slarp_timer; + + if (cfg.SLARP_request_timer) { + cfg.IP_address = 0; + cfg.IP_netmask = 0; + } + else { +#ifdef LINUX_2_1 + struct in_device *in_dev = dev->ip_ptr; + + if(in_dev != NULL) { + struct in_ifaddr *ifa = in_dev->ifa_list; + + if (ifa != NULL ) { + cfg.IP_address = ntohl(ifa->ifa_local); + cfg.IP_netmask = ntohl(ifa->ifa_mask); + chdlc_priv_area->IP_address = + ntohl(ifa->ifa_local); + chdlc_priv_area->IP_netmask = + ntohl(ifa->ifa_mask); + } + } +#else + cfg.IP_address = ntohl(dev->pa_addr); + cfg.IP_netmask = ntohl(dev->pa_mask); + chdlc_priv_area->IP_address = ntohl(dev->pa_addr); + chdlc_priv_area->IP_netmask = ntohl(dev->pa_mask); +#endif + + /* FIXME: We must re-think this message in next release + if((cfg.IP_address & 0x000000FF) > 2) { + printk(KERN_WARNING "\n"); + printk(KERN_WARNING " WARNING:%s configured with an\n", + card->devname); + printk(KERN_WARNING " invalid local IP address.\n"); + printk(KERN_WARNING " Slarp pragmatics will fail.\n"); + printk(KERN_WARNING " IP address should be of the\n"); + printk(KERN_WARNING " format A.B.C.1 or A.B.C.2.\n"); + } + */ + } + + return chdlc_configure(card, &cfg); +} + + + +/*============================================================================ + * Process global exception condition + */ +static int process_global_exception(sdla_t *card) +{ + CHDLC_MAILBOX_STRUCT* mbox = card->mbox; + int err; + + mbox->buffer_length = 0; + mbox->command = READ_GLOBAL_EXCEPTION_CONDITION; + err = sdla_exec(mbox) ? mbox->return_code : CMD_TIMEOUT; + + if(err != CMD_TIMEOUT ){ + + switch(mbox->return_code) { + + case EXCEP_MODEM_STATUS_CHANGE: + + printk(KERN_INFO "%s: Modem status change\n", + card->devname); + + switch(mbox->data[0] & (DCD_HIGH | CTS_HIGH)) { + case (DCD_HIGH): + printk(KERN_INFO "%s: DCD high, CTS low\n",card->devname); + break; + case (CTS_HIGH): + printk(KERN_INFO "%s: DCD low, CTS high\n",card->devname); break; + case ((DCD_HIGH | CTS_HIGH)): + printk(KERN_INFO "%s: DCD high, CTS high\n",card->devname); + break; + default: + printk(KERN_INFO "%s: DCD low, CTS low\n",card->devname); + break; + } + break; + + case EXCEP_TRC_DISABLED: + printk(KERN_INFO "%s: Line trace disabled\n", + card->devname); + break; + + case EXCEP_IRQ_TIMEOUT: + printk(KERN_INFO "%s: IRQ timeout occurred\n", + card->devname); + break; + + default: + printk(KERN_INFO "%s: Global exception %x\n", + card->devname, mbox->return_code); + break; + } + } + return 0; +} + + +/*============================================================================ + * Process chdlc exception condition + */ +static int process_chdlc_exception(sdla_t *card) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + int err; + + mb->buffer_length = 0; + mb->command = READ_CHDLC_EXCEPTION_CONDITION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if(err != CMD_TIMEOUT) { + + switch (err) { + + case EXCEP_LINK_ACTIVE: + port_set_state(card, WAN_CONNECTED); + break; + + case EXCEP_LINK_INACTIVE_MODEM: + port_set_state(card, WAN_DISCONNECTED); + unconfigure_ip(card); + break; + + case EXCEP_LINK_INACTIVE_KPALV: + port_set_state(card, WAN_DISCONNECTED); + printk(KERN_INFO "%s: Keepalive timer expired.\n", + card->devname); + unconfigure_ip(card); + break; + + case EXCEP_IP_ADDRESS_DISCOVERED: + if (configure_ip(card)) + return -1; + break; + + case EXCEP_LOOPBACK_CONDITION: + printk(KERN_INFO "%s: Loopback Condition Detected.\n", + card->devname); + break; + + case NO_CHDLC_EXCEP_COND_TO_REPORT: + printk(KERN_INFO "%s: No exceptions reported.\n", + card->devname); + break; + } + + } + return 0; +} + + +/*============================================================================ + * Configure IP from SLARP negotiation + * This adds dynamic routes when SLARP has provided valid addresses + */ + +static int configure_ip (sdla_t* card) +{ + struct net_device *dev = card->wandev.dev; + chdlc_private_area_t *chdlc_priv_area = dev->priv; + char err; + + /* set to discover */ + if(card->u.c.slarp_timer != 0x00) { + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + CHDLC_CONFIGURATION_STRUCT *cfg; + + mb->buffer_length = 0; + mb->command = READ_CHDLC_CONFIGURATION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + + if(err != COMMAND_OK) { + chdlc_error(card,err,mb); + return -1; + } + + cfg = (CHDLC_CONFIGURATION_STRUCT *)mb->data; + chdlc_priv_area->IP_address = cfg->IP_address; + chdlc_priv_area->IP_netmask = cfg->IP_netmask; + } + + /* Set flag to add route */ + chdlc_priv_area->route_status = ADD_ROUTE; + + /* The idea here is to add the route in the poll routine. + This way, we aren't in interrupt context when adding routes */ + card->poll = process_route; + + return 0; +} + + +/*============================================================================ + * Un-Configure IP negotiated by SLARP + * This removes dynamic routes when the link becomes inactive. + */ + +static int unconfigure_ip (sdla_t* card) +{ + struct net_device *dev = card->wandev.dev; + chdlc_private_area_t *chdlc_priv_area= dev->priv; + + if (chdlc_priv_area->route_status == ROUTE_ADDED) { + chdlc_priv_area->route_status = REMOVE_ROUTE; + /* The idea here is to delete the route in + * the poll routine. + * This way, we aren't in interrupt context + * when adding routes + */ + card->poll = process_route; + } + return 0; +} + +/*============================================================================ + * Routine to add/remove routes + * Called like a polling routine when Routes are flagged to be added/removed. + */ + +static void process_route (sdla_t *card) +{ + struct net_device *dev = card->wandev.dev; + unsigned char port_num; + chdlc_private_area_t *chdlc_priv_area = NULL; + u32 local_IP_addr = 0; + u32 remote_IP_addr = 0; + u32 IP_netmask, IP_addr; + int err = 0; +#ifdef LINUX_2_1 + struct in_device *in_dev; + mm_segment_t fs; + struct ifreq if_info; + struct sockaddr_in *if_data1, *if_data2; +#else + unsigned long fs = 0; + struct rtentry route; +#endif + + chdlc_priv_area = dev->priv; + port_num = card->u.c.comm_port; + + if((chdlc_priv_area->route_status == ADD_ROUTE) && + ((chdlc_priv_area->IP_address & 0x000000FF) > 2)) { + printk(KERN_INFO "%s: Dynamic route failure.\n",card->devname); + if(card->u.c.slarp_timer) { + printk(KERN_INFO "%s: Bad IP address %s received\n", + card->devname, + in_ntoa(ntohl(chdlc_priv_area->IP_address))); + printk(KERN_INFO "%s: from remote station.\n", + card->devname); + }else{ + printk(KERN_INFO "%s: Bad IP address %s issued\n", + card->devname, + in_ntoa(ntohl(chdlc_priv_area->IP_address))); + printk(KERN_INFO "%s: to remote station. Local\n", + card->devname); + printk(KERN_INFO "%s: IP address must be A.B.C.1\n", + card->devname); + printk(KERN_INFO "%s: or A.B.C.2.\n",card->devname); + } + + /* remove the route due to the IP address error condition */ + chdlc_priv_area->route_status = REMOVE_ROUTE; + err = 1; + } + + /* If we are removing a route with bad IP addressing, then use the */ + /* locally configured IP addresses */ + if((chdlc_priv_area->route_status == REMOVE_ROUTE) && err) { + + /* do not remove a bad route that has already been removed */ + if(chdlc_priv_area->route_removed) { + card->poll = NULL; + return; + } + +#ifdef LINUX_2_1 + in_dev = dev->ip_ptr; + + if(in_dev != NULL) { + struct in_ifaddr *ifa = in_dev->ifa_list; + if (ifa != NULL ) { + local_IP_addr = ifa->ifa_local; + IP_netmask = ifa->ifa_mask; + } + } +#else + local_IP_addr = dev->pa_addr; + remote_IP_addr = dev->pa_dstaddr; + IP_netmask = dev->pa_mask; +#endif + }else{ + /* According to Cisco HDLC, if the point-to-point address is + A.B.C.1, then we are the opposite (A.B.C.2), and vice-versa. + */ + IP_netmask = ntohl(chdlc_priv_area->IP_netmask); + remote_IP_addr = ntohl(chdlc_priv_area->IP_address); + local_IP_addr = (remote_IP_addr & ntohl(0xFFFFFF00)) + + (~remote_IP_addr & ntohl(0x0003)); + + if(!card->u.c.slarp_timer) { + IP_addr = local_IP_addr; + local_IP_addr = remote_IP_addr; + remote_IP_addr = IP_addr; + } + } + + fs = get_fs(); /* Save file system */ + set_fs(get_ds()); /* Get user space block */ + +#ifdef LINUX_2_1 + /* Setup a structure for adding/removing routes */ + memset(&if_info, 0, sizeof(if_info)); + strcpy(if_info.ifr_name, dev->name); + +#else + /* Setup a structure for adding/removing routes */ + dev->pa_mask = IP_netmask; + dev->pa_dstaddr = remote_IP_addr; + dev->pa_addr = local_IP_addr; + + memset(&route, 0, sizeof(route)); + route.rt_dev = dev->name; + route.rt_flags = 0; + ((struct sockaddr_in *)&(route.rt_dst))->sin_addr.s_addr = + dev->pa_dstaddr; + ((struct sockaddr_in *)&(route.rt_dst))->sin_family = AF_INET; + ((struct sockaddr_in *)&(route.rt_genmask))->sin_addr.s_addr = + 0xFFFFFFFF; + ((struct sockaddr_in *)&(route.rt_genmask))->sin_family = + AF_INET; +#endif + + switch (chdlc_priv_area->route_status) { + + case ADD_ROUTE: + + if(!card->u.c.slarp_timer) { +#ifdef LINUX_2_1 + if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr; + if_data2->sin_addr.s_addr = remote_IP_addr; + if_data2->sin_family = AF_INET; + err = devinet_ioctl(SIOCSIFDSTADDR, &if_info); +#else + err = ip_rt_new(&route); +#endif + } else { +#ifdef LINUX_2_1 + if_data1 = (struct sockaddr_in *)&if_info.ifr_addr; + if_data1->sin_addr.s_addr = local_IP_addr; + if_data1->sin_family = AF_INET; + if(!(err = devinet_ioctl(SIOCSIFADDR, &if_info))){ + if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr; + if_data2->sin_addr.s_addr = remote_IP_addr; + if_data2->sin_family = AF_INET; + err = devinet_ioctl(SIOCSIFDSTADDR, &if_info); + } +#else + err = ip_rt_new(&route); +#endif + } + + if(err) { + printk(KERN_INFO "%s: Add route %s failed (%d)\n", + card->devname, in_ntoa(remote_IP_addr), err); + } else { + ((chdlc_private_area_t *)dev->priv)->route_status = ROUTE_ADDED; + printk(KERN_INFO "%s: Dynamic route added.\n", + card->devname); + printk(KERN_INFO "%s: Local IP addr : %s\n", + card->devname, in_ntoa(local_IP_addr)); + printk(KERN_INFO "%s: Remote IP addr: %s\n", + card->devname, in_ntoa(remote_IP_addr)); + chdlc_priv_area->route_removed = 0; + } + break; + + + case REMOVE_ROUTE: + +#ifdef LINUX_2_1 + /* Change the local ip address of the interface to 0. + * This will also delete the destination route. + */ + if(!card->u.c.slarp_timer) { + if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr; + if_data2->sin_addr.s_addr = 0; + if_data2->sin_family = AF_INET; + err = devinet_ioctl(SIOCSIFDSTADDR, &if_info); + } else { + if_data1 = (struct sockaddr_in *)&if_info.ifr_addr; + if_data1->sin_addr.s_addr = 0; + if_data1->sin_family = AF_INET; + err = devinet_ioctl(SIOCSIFADDR,&if_info); + + } +#else + /* set the point-to-point IP address to 0.0.0.0 */ + dev->pa_dstaddr = 0; + err = ip_rt_kill(&route); +#endif + if(err) { + printk(KERN_INFO + "%s: Remove route %s failed, (err %d)\n", + card->devname, in_ntoa(remote_IP_addr), + err); + } else { + ((chdlc_private_area_t *)dev->priv)->route_status = + NO_ROUTE; + printk(KERN_INFO "%s: Dynamic route removed: %s\n", + card->devname, in_ntoa(local_IP_addr)); + chdlc_priv_area->route_removed = 1; + } + break; + } + + set_fs(fs); /* Restore file system */ + + /* Once we've processed the route, stop polling */ + card->poll = NULL; + +} + + +/*============================================================================= + * Store a UDP management packet for later processing. + */ + +static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card, + struct sk_buff *skb, struct net_device* dev, + chdlc_private_area_t* chdlc_priv_area ) +{ + int udp_pkt_stored = 0; + + if(!chdlc_priv_area->udp_pkt_lgth && + (skb->len <= MAX_LGTH_UDP_MGNT_PKT)) { + chdlc_priv_area->udp_pkt_lgth = skb->len; + chdlc_priv_area->udp_pkt_src = udp_pkt_src; + memcpy(chdlc_priv_area->udp_pkt_data, skb->data, skb->len); + chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UDP; + udp_pkt_stored = 1; + } + +#ifdef LINUX_2_1 + dev_kfree_skb(skb); +#else + if(udp_pkt_src == UDP_PKT_FRM_STACK) + dev_kfree_skb(skb, FREE_WRITE); + else + dev_kfree_skb(skb, FREE_READ); +#endif + + return(udp_pkt_stored); +} + + +/*============================================================================= + * Process UDP management packet. + */ + +static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev, + chdlc_private_area_t* chdlc_priv_area ) +{ + unsigned char *buf; + unsigned int frames, len; + struct sk_buff *new_skb; + unsigned short buffer_length, real_len; + unsigned long data_ptr; + unsigned data_length; + int udp_mgmt_req_valid = 1; + CHDLC_MAILBOX_STRUCT *mb = card->mbox; + SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags; + chdlc_udp_pkt_t *chdlc_udp_pkt; + struct timeval tv; + int err; + char ut_char; + + chdlc_udp_pkt = (chdlc_udp_pkt_t *) chdlc_priv_area->udp_pkt_data; + + switch(chdlc_udp_pkt->cblock.command) { + + case FT1_MONITOR_STATUS_CTRL: + case CPIPE_ENABLE_TRACING: + case CPIPE_DISABLE_TRACING: + case CPIPE_GET_TRACE_INFO: + case SET_FT1_MODE: + if(chdlc_priv_area->udp_pkt_src == + UDP_PKT_FRM_NETWORK) { + udp_mgmt_req_valid = 0; + } + break; + + default: + break; + } + + if(!udp_mgmt_req_valid) { + + /* set length to 0 */ + chdlc_udp_pkt->cblock.buffer_length = 0; + + /* set return code */ + chdlc_udp_pkt->cblock.return_code = 0xCD; + + } else { + unsigned long trace_status_cfg_addr = 0; + TRACE_STATUS_EL_CFG_STRUCT trace_cfg_struct; + TRACE_STATUS_ELEMENT_STRUCT trace_element_struct; + + switch(chdlc_udp_pkt->cblock.command) { + + case CPIPE_ENABLE_TRACING: + if (!chdlc_priv_area->TracingEnabled) { + + /* OPERATE_DATALINE_MONITOR */ + + mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT); + mb->command = SET_TRACE_CONFIGURATION; + + ((LINE_TRACE_CONFIG_STRUCT *)mb->data)-> + trace_config = TRACE_ACTIVE; + /* Trace delay mode is not used because it slows + down transfer and results in a standoff situation + when there is a lot of data */ + + /* Configure the Trace based on user inputs */ + ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->trace_config |= + chdlc_udp_pkt->data[0]; + + ((LINE_TRACE_CONFIG_STRUCT *)mb->data)-> + trace_deactivation_timer = 4000; + + + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) { + chdlc_error(card,err,mb); + card->TracingEnabled = 0; + chdlc_udp_pkt->cblock.return_code = err; + mb->buffer_length = 0; + break; + } + + /* Get the base address of the trace element list */ + mb->buffer_length = 0; + mb->command = READ_TRACE_CONFIGURATION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + + if (err != COMMAND_OK) { + chdlc_error(card,err,mb); + chdlc_priv_area->TracingEnabled = 0; + chdlc_udp_pkt->cblock.return_code = err; + mb->buffer_length = 0; + break; + } + + trace_status_cfg_addr =((LINE_TRACE_CONFIG_STRUCT *) + mb->data) -> ptr_trace_stat_el_cfg_struct; + + sdla_peek(&card->hw, trace_status_cfg_addr, + &trace_cfg_struct, sizeof(trace_cfg_struct)); + + chdlc_priv_area->start_trace_addr = trace_cfg_struct. + base_addr_trace_status_elements; + + chdlc_priv_area->number_trace_elements = + trace_cfg_struct.number_trace_status_elements; + + chdlc_priv_area->end_trace_addr = (unsigned long) + ((TRACE_STATUS_ELEMENT_STRUCT *) + chdlc_priv_area->start_trace_addr + + (chdlc_priv_area->number_trace_elements - 1)); + + chdlc_priv_area->base_addr_trace_buffer = + trace_cfg_struct.base_addr_trace_buffer; + + chdlc_priv_area->end_addr_trace_buffer = + trace_cfg_struct.end_addr_trace_buffer; + + chdlc_priv_area->curr_trace_addr = + trace_cfg_struct.next_trace_element_to_use; + + chdlc_priv_area->available_buffer_space = 2000 - + sizeof(ip_pkt_t) - + sizeof(udp_pkt_t) - + sizeof(wp_mgmt_t) - + sizeof(cblock_t) - + sizeof(trace_info_t); + } + chdlc_udp_pkt->cblock.return_code = COMMAND_OK; + mb->buffer_length = 0; + chdlc_priv_area->TracingEnabled = 1; + break; + + + case CPIPE_DISABLE_TRACING: + if (chdlc_priv_area->TracingEnabled) { + + /* OPERATE_DATALINE_MONITOR */ + mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT); + mb->command = SET_TRACE_CONFIGURATION; + ((LINE_TRACE_CONFIG_STRUCT *)mb->data)-> + trace_config = TRACE_INACTIVE; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + } + + chdlc_priv_area->TracingEnabled = 0; + chdlc_udp_pkt->cblock.return_code = COMMAND_OK; + mb->buffer_length = 0; + break; + + + case CPIPE_GET_TRACE_INFO: + + if (!chdlc_priv_area->TracingEnabled) { + chdlc_udp_pkt->cblock.return_code = 1; + mb->buffer_length = 0; + break; + } + + chdlc_udp_pkt->trace_info.ismoredata = 0x00; + buffer_length = 0; /* offset of packet already occupied */ + + for (frames=0; frames < chdlc_priv_area->number_trace_elements; frames++){ + + trace_pkt_t *trace_pkt = (trace_pkt_t *) + &chdlc_udp_pkt->data[buffer_length]; + + sdla_peek(&card->hw, chdlc_priv_area->curr_trace_addr, + (unsigned char *)&trace_element_struct, + sizeof(TRACE_STATUS_ELEMENT_STRUCT)); + + if (trace_element_struct.opp_flag == 0x00) { + break; + } + + /* get pointer to real data */ + data_ptr = trace_element_struct.ptr_data_bfr; + + /* See if there is actual data on the trace buffer */ + if (data_ptr){ + data_length = trace_element_struct.trace_length; + }else{ + data_length = 0; + chdlc_udp_pkt->trace_info.ismoredata = 0x01; + } + + if( (chdlc_priv_area->available_buffer_space - buffer_length) + < ( sizeof(trace_pkt_t) + data_length) ) { + + /* indicate there are more frames on board & exit */ + chdlc_udp_pkt->trace_info.ismoredata = 0x01; + break; + } + + trace_pkt->status = trace_element_struct.trace_type; + + trace_pkt->time_stamp = + trace_element_struct.trace_time_stamp; + + trace_pkt->real_length = + trace_element_struct.trace_length; + + /* see if we can fit the frame into the user buffer */ + real_len = trace_pkt->real_length; + + if (data_ptr == 0) { + trace_pkt->data_avail = 0x00; + } else { + unsigned tmp = 0; + + /* get the data from circular buffer + must check for end of buffer */ + trace_pkt->data_avail = 0x01; + + if ((data_ptr + real_len) > + chdlc_priv_area->end_addr_trace_buffer + 1){ + + tmp = chdlc_priv_area->end_addr_trace_buffer - data_ptr + 1; + sdla_peek(&card->hw, data_ptr, + trace_pkt->data,tmp); + data_ptr = chdlc_priv_area->base_addr_trace_buffer; + } + + sdla_peek(&card->hw, data_ptr, + &trace_pkt->data[tmp], real_len - tmp); + } + + /* zero the opp flag to show we got the frame */ + ut_char = 0x00; + sdla_poke(&card->hw, chdlc_priv_area->curr_trace_addr, &ut_char, 1); + + /* now move onto the next frame */ + chdlc_priv_area->curr_trace_addr += sizeof(TRACE_STATUS_ELEMENT_STRUCT); + + /* check if we went over the last address */ + if ( chdlc_priv_area->curr_trace_addr > chdlc_priv_area->end_trace_addr ) { + chdlc_priv_area->curr_trace_addr = chdlc_priv_area->start_trace_addr; + } + + if(trace_pkt->data_avail == 0x01) { + buffer_length += real_len - 1; + } + + /* for the header */ + buffer_length += sizeof(trace_pkt_t); + + } /* For Loop */ + + if (frames == chdlc_priv_area->number_trace_elements){ + chdlc_udp_pkt->trace_info.ismoredata = 0x01; + } + chdlc_udp_pkt->trace_info.num_frames = frames; + + mb->buffer_length = buffer_length; + chdlc_udp_pkt->cblock.buffer_length = buffer_length; + + chdlc_udp_pkt->cblock.return_code = COMMAND_OK; + + break; + + + case CPIPE_FT1_READ_STATUS: + ((unsigned char *)chdlc_udp_pkt->data )[0] = + flags->FT1_info_struct.parallel_port_A_input; + + ((unsigned char *)chdlc_udp_pkt->data )[1] = + flags->FT1_info_struct.parallel_port_B_input; + + chdlc_udp_pkt->cblock.return_code = COMMAND_OK; + mb->buffer_length = 2; + break; + + case CPIPE_ROUTER_UP_TIME: + do_gettimeofday( &tv ); + chdlc_priv_area->router_up_time = tv.tv_sec - + chdlc_priv_area->router_start_time; + *(unsigned long *)&chdlc_udp_pkt->data = + chdlc_priv_area->router_up_time; + mb->buffer_length = sizeof(unsigned long); + break; + + case FT1_MONITOR_STATUS_CTRL: + /* Enable FT1 MONITOR STATUS */ + if ((chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_STATUS) || + (chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_OP_STATS)) { + + if( rCount++ != 0 ) { + chdlc_udp_pkt->cblock. + return_code = COMMAND_OK; + mb->buffer_length = 1; + break; + } + } + + /* Disable FT1 MONITOR STATUS */ + if( chdlc_udp_pkt->data[0] == 0) { + + if( --rCount != 0) { + chdlc_udp_pkt->cblock. + return_code = COMMAND_OK; + mb->buffer_length = 1; + break; + } + } + + default: + /* it's a board command */ + mb->command = chdlc_udp_pkt->cblock.command; + mb->buffer_length = chdlc_udp_pkt->cblock.buffer_length; + if (mb->buffer_length) { + memcpy(&mb->data, (unsigned char *) chdlc_udp_pkt-> + data, mb->buffer_length); + } + /* run the command on the board */ + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != COMMAND_OK) { + break; + } + + /* copy the result back to our buffer */ + memcpy(&chdlc_udp_pkt->cblock, mb, sizeof(cblock_t)); + + if (mb->buffer_length) { + memcpy(&chdlc_udp_pkt->data, &mb->data, + mb->buffer_length); + } + + } /* end of switch */ + } /* end of else */ + + /* Fill UDP TTL */ + chdlc_udp_pkt->ip_pkt.ttl = card->wandev.ttl; + + len = reply_udp(chdlc_priv_area->udp_pkt_data, mb->buffer_length); + + if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) { + if(!chdlc_send(card, chdlc_priv_area->udp_pkt_data, len)) { + ++ card->wandev.stats.tx_packets; +#ifdef LINUX_2_1 + card->wandev.stats.tx_bytes += len; +#endif + } + } else { + + /* Pass it up the stack + Allocate socket buffer */ + if ((new_skb = dev_alloc_skb(len)) != NULL) { + /* copy data into new_skb */ + + buf = skb_put(new_skb, len); + memcpy(buf, chdlc_priv_area->udp_pkt_data, len); + + /* Decapsulate pkt and pass it up the protocol stack */ + new_skb->protocol = htons(ETH_P_IP); + new_skb->dev = dev; + new_skb->mac.raw = new_skb->data; + + netif_rx(new_skb); + } else { + + printk(KERN_INFO "%s: no socket buffers available!\n", + card->devname); + } + } + + chdlc_priv_area->udp_pkt_lgth = 0; + + return 0; +} + +/*============================================================================ + * Initialize Receive and Transmit Buffers. + */ + +static void init_chdlc_tx_rx_buff( sdla_t* card, struct net_device *dev ) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + CHDLC_TX_STATUS_EL_CFG_STRUCT *tx_config; + CHDLC_RX_STATUS_EL_CFG_STRUCT *rx_config; + char err; + + mb->buffer_length = 0; + mb->command = READ_CHDLC_CONFIGURATION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + + if(err != COMMAND_OK) { + chdlc_error(card,err,mb); + return; + } + + if(card->hw.type == SDLA_S514) { + tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> + ptr_CHDLC_Tx_stat_el_cfg_struct)); + rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> + ptr_CHDLC_Rx_stat_el_cfg_struct)); + + /* Setup Head and Tails for buffers */ + card->u.c.txbuf_base = (void *)(card->hw.dpmbase + + tx_config->base_addr_Tx_status_elements); + card->u.c.txbuf_last = + (CHDLC_DATA_TX_STATUS_EL_STRUCT *) + card->u.c.txbuf_base + + (tx_config->number_Tx_status_elements - 1); + + card->u.c.rxbuf_base = (void *)(card->hw.dpmbase + + rx_config->base_addr_Rx_status_elements); + card->u.c.rxbuf_last = + (CHDLC_DATA_RX_STATUS_EL_STRUCT *) + card->u.c.rxbuf_base + + (rx_config->number_Rx_status_elements - 1); + + /* Set up next pointer to be used */ + card->u.c.txbuf = (void *)(card->hw.dpmbase + + tx_config->next_Tx_status_element_to_use); + card->u.c.rxmb = (void *)(card->hw.dpmbase + + rx_config->next_Rx_status_element_to_use); + } + else { + tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> + ptr_CHDLC_Tx_stat_el_cfg_struct % SDLA_WINDOWSIZE)); + + rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> + ptr_CHDLC_Rx_stat_el_cfg_struct % SDLA_WINDOWSIZE)); + + /* Setup Head and Tails for buffers */ + card->u.c.txbuf_base = (void *)(card->hw.dpmbase + + (tx_config->base_addr_Tx_status_elements % SDLA_WINDOWSIZE)); + card->u.c.txbuf_last = + (CHDLC_DATA_TX_STATUS_EL_STRUCT *)card->u.c.txbuf_base + + (tx_config->number_Tx_status_elements - 1); + card->u.c.rxbuf_base = (void *)(card->hw.dpmbase + + (rx_config->base_addr_Rx_status_elements % SDLA_WINDOWSIZE)); + card->u.c.rxbuf_last = + (CHDLC_DATA_RX_STATUS_EL_STRUCT *)card->u.c.rxbuf_base + + (rx_config->number_Rx_status_elements - 1); + + /* Set up next pointer to be used */ + card->u.c.txbuf = (void *)(card->hw.dpmbase + + (tx_config->next_Tx_status_element_to_use % SDLA_WINDOWSIZE)); + card->u.c.rxmb = (void *)(card->hw.dpmbase + + (rx_config->next_Rx_status_element_to_use % SDLA_WINDOWSIZE)); + } + + /* Setup Actual Buffer Start and end addresses */ + card->u.c.rx_base = rx_config->base_addr_Rx_buffer; + card->u.c.rx_top = rx_config->end_addr_Rx_buffer; + +} + +/*============================================================================= + * Perform Interrupt Test by running READ_CHDLC_CODE_VERSION command MAX_INTR + * _TEST_COUNTER times. + */ +static int intr_test( sdla_t* card, struct net_device *dev ) +{ + CHDLC_MAILBOX_STRUCT* mb = card->mbox; + int err,i; + + Intr_test_counter = 0; + + /* The critical flag is unset because during intialization (if_open) + * we want the interrupts to be enabled so that when the wpc_isr is + * called it does not exit due to critical flag set. + */ + + clear_bit(1, (void*)&card->wandev.critical); + err = chdlc_set_intr_mode(card, APP_INT_ON_COMMAND_COMPLETE); + + if (err == CMD_OK) { + for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) { + mb->buffer_length = 0; + mb->command = READ_CHDLC_CODE_VERSION; + err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; + if (err != CMD_OK) + chdlc_error(card, err, mb); + } + } + else { + return err; + } + + err = chdlc_set_intr_mode(card, 0); + set_bit(1, (void*)&card->wandev.critical); + + + if (err != CMD_OK) + return err; + + return 0; +} + +/*============================================================================== + * Determine what type of UDP call it is. CPIPEAB ? + */ +static int udp_pkt_type(struct sk_buff *skb, sdla_t* card) +{ + chdlc_udp_pkt_t *chdlc_udp_pkt = (chdlc_udp_pkt_t *)skb->data; + + if (!strncmp(chdlc_udp_pkt->wp_mgmt.signature,UDPMGMT_SIGNATURE,8) && + (chdlc_udp_pkt->udp_pkt.udp_dst_port == ntohs(card->wandev.udp_port)) && + (chdlc_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) && + (chdlc_udp_pkt->wp_mgmt.request_reply == UDPMGMT_REQUEST)) { + return UDP_CPIPE_TYPE; + } + else return UDP_INVALID_TYPE; +} + +/*============================================================================ + * Set PORT state. + */ +static void port_set_state (sdla_t *card, int state) +{ + if (card->u.c.state != state) + { + switch (state) + { + case WAN_CONNECTED: + printk (KERN_INFO "%s: Link connected!\n", + card->devname); + break; + + case WAN_CONNECTING: + printk (KERN_INFO "%s: Link connecting...\n", + card->devname); + break; + + case WAN_DISCONNECTED: + printk (KERN_INFO "%s: Link disconnected!\n", + card->devname); + break; + } + + card->wandev.state = card->u.c.state = state; + } +} + +void s508_lock (sdla_t *card, unsigned long *smp_flags) +{ +#ifdef __SMP__ + spin_lock_irqsave(&card->lock, *smp_flags); + if (card->next){ + spin_lock(&card->next->lock); + } +#else + disable_irq(card->hw.irq); +#endif +} + +void s508_unlock (sdla_t *card, unsigned long *smp_flags) +{ +#ifdef __SMP__ + if (card->next){ + spin_unlock(&card->next->lock); + } + spin_unlock_irqrestore(&card->lock, *smp_flags); +#else + enable_irq(card->hw.irq); +#endif +} + +/****** End ****************************************************************/ diff -ur --new-file old/linux/drivers/net/wan/sdla_fr.c new/linux/drivers/net/wan/sdla_fr.c --- old/linux/drivers/net/wan/sdla_fr.c Mon Oct 11 19:13:25 1999 +++ new/linux/drivers/net/wan/sdla_fr.c Wed Jan 26 22:25:58 2000 @@ -1,16 +1,38 @@ /***************************************************************************** * sdla_fr.c WANPIPE(tm) Multiprotocol WAN Link Driver. Frame relay module. * -* Author(s): Gene Kozin -* Jaspreet Singh +* Author(s): Nenad Corbic +* Gideon Hack * -* Copyright: (c) 1995-1997 Sangoma Technologies Inc. +* Copyright: (c) 1995-1999 Sangoma Technologies 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. * ============================================================================ +* Nov 08, 1999 Nenad Corbic o Combined all debug UDP calls into one function +* o Removed the ARP support. This has to be done +* in the next version. +* o Only a Node can implement NO signalling. +* Initialize DLCI during if_open() if NO +* signalling. +* o Took out IPX support, implement in next +* version +* Sep 29, 1999 Nenad Corbic o Added SMP support and changed the update +* function to use timer interrupt. +* o Fixed the CIR bug: Set the value of BC +* to CIR when the CIR is enabled. +* o Updated comments, statistics and tracing. +* Jun 02, 1999 Gideon Hack o Updated for S514 support. +* Sep 18, 1998 Jaspreet Singh o Updated for 2.2.X kernels. +* Jul 31, 1998 Jaspreet Singh o Removed wpf_poll routine. The channel/DLCI +* status is received through an event interrupt. +* Jul 08, 1998 David Fong o Added inverse ARP support. +* Mar 26, 1997 Jaspreet Singh o Returning return codes for failed UDP cmds. +* Jan 28, 1997 Jaspreet Singh o Improved handling of inactive DLCIs. +* Dec 30, 1997 Jaspreet Singh o Replaced dev_tint() with mark_bh(NET_BH) +* Dec 16, 1997 Jaspreet Singh o Implemented Multiple IPX support. * Nov 26, 1997 Jaspreet Singh o Improved load sharing with multiple boards * o Added Cli() to protect enabling of interrupts * while polling is called. @@ -42,7 +64,8 @@ * o Added ability to discard multicast and * broadcast source addressed packets * Jun 27, 1997 Jaspreet Singh o Added FT1 monitor capabilities -* New case (0x44) statement in if_send routine * Added a global variable rCount to keep track +* New case (0x44) statement in if_send routine +* Added a global variable rCount to keep track * of FT1 status enabled on the board. * May 29, 1997 Jaspreet Singh o Fixed major Flow Control Problem * With multiple boards a problem was seen where @@ -50,13 +73,15 @@ * packet after running for a while. The code * got into a stage where the interrupts were * disabled and dev->tbusy was set to 1. -* This caused the If_send() routine to get into* the if clause for it(0,dev->tbusy) +* This caused the If_send() routine to get into +* the if clause for it(0,dev->tbusy) * forever. * The code got into this stage due to an -* interrupt occurring within the if clause for +* interrupt occuring within the if clause for * set_bit(0,dev->tbusy). Since an interrupt * disables furhter transmit interrupt and -* makes dev->tbusy = 0, this effect was undone * by making dev->tbusy = 1 in the if clause. +* makes dev->tbusy = 0, this effect was undone +* by making dev->tbusy = 1 in the if clause. * The Fix checks to see if Transmit interrupts * are disabled then do not make dev->tbusy = 1 * Introduced a global variable: int_occur and @@ -83,6 +108,7 @@ * Jan 02, 1997 Gene Kozin Initial version. *****************************************************************************/ +#include #include /* printk(), and other useful stuff */ #include /* offsetof(), etc. */ #include /* return codes */ @@ -93,140 +119,133 @@ #include /* ARPHRD_* defines */ #include /* htons(), etc. */ #include /* for inb(), outb(), etc. */ -#include /* for do_gettimeofday */ -#define _GNUC_ -#include /* frame relay firmware API definitions */ +#include /* for do_gettimeofday */ +#include /* sockaddr_in */ +#include /* in_ntoa(), etc... */ #include +#include +#include +#include /* Dynamic Route Creation */ +#include +#include /* frame relay firmware API definitions */ +#if LINUX_VERSION_CODE < 0x020125 +#define test_and_set_bit set_bit +#endif + /****** Defines & Macros ****************************************************/ -#define MAX_CMD_RETRY 10 /* max number of firmware retries */ -#define FR_HEADER_LEN 8 /* max encapsulation header size */ -#define FR_CHANNEL_MTU 1500 /* unfragmented logical channel MTU */ +#define MAX_CMD_RETRY 10 /* max number of firmware retries */ -/* Q.922 frame types */ +#define FR_HEADER_LEN 8 /* max encapsulation header size */ +#define FR_CHANNEL_MTU 1500 /* unfragmented logical channel MTU */ -#define Q922_UI 0x03 /* Unnumbered Info frame */ -#define Q922_XID 0xAF /* ??? */ +/* Q.922 frame types */ +#define Q922_UI 0x03 /* Unnumbered Info frame */ +#define Q922_XID 0xAF /* DLCI configured or not */ - #define DLCI_NOT_CONFIGURED 0x00 #define DLCI_CONFIG_PENDING 0x01 #define DLCI_CONFIGURED 0x02 /* CIR enabled or not */ - #define CIR_ENABLED 0x00 #define CIR_DISABLED 0x01 -/* Interrupt mode for DLCI = 0 */ - -#define BUFFER_INTR_MODE 0x00 -#define DLCI_LIST_INTR_MODE 0x01 - -/* Transmit Interrupt Status */ - -#define DISABLED 0x00 -#define WAITING_TO_BE_ENABLED 0x01 +#define WANPIPE 0x00 +#define API 0x01 +#define FRAME_RELAY_API 1 /* For handle_IPXWAN() */ - #define CVHexToAscii(b) (((unsigned char)(b) > (unsigned char)9) ? ((unsigned char)'A' + ((unsigned char)(b) - (unsigned char)10)) : ((unsigned char)'0' + (unsigned char)(b))) - + /****** Data Structures *****************************************************/ /* This is an extention of the 'struct net_device' we create for each network * interface to keep the rest of channel-specific data. */ -typedef struct fr_channel { - char name[WAN_IFNAME_SZ + 1]; /* interface name, ASCIIZ */ - unsigned dlci_configured; /* check whether configured or not */ - unsigned cir_status; /* check whether CIR enabled or not */ - unsigned dlci; /* logical channel number */ - unsigned cir; /* committed information rate */ - unsigned bc; /* committed burst size */ - unsigned be; /* excess burst size */ - unsigned mc; /* multicast support on or off */ - unsigned tx_int_status; /* Transmit Interrupt Status */ +typedef struct fr_channel +{ + char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */ + unsigned dlci_configured ; /* check whether configured or not */ + unsigned cir_status; /* check whether CIR enabled or not */ + unsigned dlci; /* logical channel number */ + unsigned cir; /* committed information rate */ + unsigned bc; /* committed burst size */ + unsigned be; /* excess burst size */ + unsigned mc; /* multicast support on or off */ + unsigned tx_int_status; /* Transmit Interrupt Status */ unsigned short pkt_length; /* Packet Length */ - unsigned long router_start_time; /* Router start time in seconds */ + unsigned long router_start_time;/* Router start time in seconds */ unsigned long tick_counter; /* counter for transmit time out */ char dev_pending_devtint; /* interface pending dev_tint() */ - char state; /* channel state */ - void *dlci_int_interface; /* pointer to the DLCI Interface */ - unsigned long IB_addr; /* physical address of Interface Byte */ + char state; /* channel state */ + void *dlci_int_interface; /* pointer to the DLCI Interface */ + unsigned long IB_addr; /* physical address of Interface Byte */ unsigned long state_tick; /* time of the last state change */ - sdla_t *card; /* -> owner */ - struct net_device_stats ifstats; /* interface statistics */ - unsigned long if_send_entry; - unsigned long if_send_skb_null; - unsigned long if_send_broadcast; - unsigned long if_send_multicast; - unsigned long if_send_critical_ISR; - unsigned long if_send_critical_non_ISR; - unsigned long if_send_busy; - unsigned long if_send_busy_timeout; - unsigned long if_send_FPIPE_request; - unsigned long if_send_DRVSTATS_request; - unsigned long if_send_wan_disconnected; - unsigned long if_send_dlci_disconnected; - unsigned long if_send_no_bfrs; - unsigned long if_send_adptr_bfrs_full; - unsigned long if_send_bfrs_passed_to_adptr; - unsigned long rx_intr_no_socket; - unsigned long rx_intr_dev_not_started; - unsigned long rx_intr_FPIPE_request; - unsigned long rx_intr_DRVSTATS_request; - unsigned long rx_intr_bfr_not_passed_to_stack; - unsigned long rx_intr_bfr_passed_to_stack; - unsigned long UDP_FPIPE_mgmt_kmalloc_err; - unsigned long UDP_FPIPE_mgmt_direction_err; - unsigned long UDP_FPIPE_mgmt_adptr_type_err; - unsigned long UDP_FPIPE_mgmt_adptr_cmnd_OK; - unsigned long UDP_FPIPE_mgmt_adptr_cmnd_timeout; - unsigned long UDP_FPIPE_mgmt_adptr_send_passed; - unsigned long UDP_FPIPE_mgmt_adptr_send_failed; - unsigned long UDP_FPIPE_mgmt_not_passed_to_stack; - unsigned long UDP_FPIPE_mgmt_passed_to_stack; - unsigned long UDP_FPIPE_mgmt_no_socket; - unsigned long UDP_DRVSTATS_mgmt_kmalloc_err; - unsigned long UDP_DRVSTATS_mgmt_adptr_cmnd_OK; - unsigned long UDP_DRVSTATS_mgmt_adptr_cmnd_timeout; - unsigned long UDP_DRVSTATS_mgmt_adptr_send_passed; - unsigned long UDP_DRVSTATS_mgmt_adptr_send_failed; - unsigned long UDP_DRVSTATS_mgmt_not_passed_to_stack; - unsigned long UDP_DRVSTATS_mgmt_passed_to_stack; - unsigned long UDP_DRVSTATS_mgmt_no_socket; + unsigned char enable_IPX; /* Enable/Disable the use of IPX */ + unsigned long network_number; /* Internal Network Number for IPX*/ + sdla_t *card; /* -> owner */ + unsigned route_flag; /* Add/Rem dest addr in route tables */ + unsigned inarp; /* Inverse Arp Request status */ + int inarp_interval; /* Time between InArp Requests */ + unsigned long inarp_tick; /* InArp jiffies tick counter */ + struct net_device_stats ifstats; /* interface statistics */ + if_send_stat_t drvstats_if_send; + rx_intr_stat_t drvstats_rx_intr; + pipe_mgmt_stat_t drvstats_gen; + + unsigned char usedby; /* Used by WANPIPE or API */ + unsigned long router_up_time; + + unsigned short transmit_length; + char transmit_buffer[FR_MAX_NO_DATA_BYTES_IN_FRAME]; } fr_channel_t; -typedef struct dlci_status { - unsigned short dlci PACKED; - unsigned char state PACKED; +/* Route Flag options */ +#define NO_ROUTE 0x00 +#define ADD_ROUTE 0x01 +#define ROUTE_ADDED 0x02 +#define REMOVE_ROUTE 0x03 + +/* inarp options */ +#define INARP_NONE 0x00 +#define INARP_REQUEST 0x01 +#define INARP_CONFIGURED 0x02 + +/* reasons for enabling the timer interrupt on the adapter */ +#define TMR_INT_ENABLED_UDP 0x01 +#define TMR_INT_ENABLED_UPDATE 0x02 + + +typedef struct dlci_status +{ + unsigned short dlci PACKED; + unsigned char state PACKED; } dlci_status_t; -typedef struct dlci_IB_mapping { - unsigned short dlci PACKED; - unsigned long addr_value PACKED; +typedef struct dlci_IB_mapping +{ + unsigned short dlci PACKED; + unsigned long addr_value PACKED; } dlci_IB_mapping_t; /* This structure is used for DLCI list Tx interrupt mode. It is used to enable interrupt bit and set the packet length for transmission */ +typedef struct fr_dlci_interface +{ + unsigned char gen_interrupt PACKED; + unsigned short packet_length PACKED; + unsigned char reserved PACKED; +} fr_dlci_interface_t; -typedef struct fr_dlci_interface { - unsigned char gen_interrupt PACKED; - unsigned short packet_length PACKED; - unsigned char reserved PACKED; -} fr_dlci_interface_t; - -static unsigned short num_frames; -static unsigned long curr_trace_addr; -static unsigned long start_trace_addr; -static unsigned short available_buffer_space; -static char TracingEnabled; /* variable for keeping track of enabling/disabling FT1 monitor status */ +/* variable for keeping track of enabling/disabling FT1 monitor status */ static int rCount = 0; + +extern int ip_rt_ioctl(unsigned int, void *); extern void disable_irq(unsigned int); extern void enable_irq(unsigned int); @@ -234,70 +253,96 @@ * interrupt test routine */ static int Intr_test_counter; - /****** Function Prototypes *************************************************/ /* WAN link driver entry points. These are called by the WAN router module. */ -static int update(wan_device_t * wandev); -static int new_if(wan_device_t * wandev, struct net_device *dev, - wanif_conf_t * conf); -static int del_if(wan_device_t * wandev, struct net_device *dev); +static int update(wan_device_t *wandev); +static int new_if(wan_device_t *wandev, struct net_device *dev, wanif_conf_t *conf); +static int del_if(wan_device_t *wandev, struct net_device *dev); + /* WANPIPE-specific entry points */ static int wpf_exec(struct sdla *card, void *u_cmd, void *u_data); + /* Network device interface */ static int if_init(struct net_device *dev); static int if_open(struct net_device *dev); static int if_close(struct net_device *dev); -static int if_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, unsigned len); +static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); static int if_rebuild_hdr(struct sk_buff *skb); static int if_send(struct sk_buff *skb, struct net_device *dev); +static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev, + struct sk_buff *skb); static struct net_device_stats *if_stats(struct net_device *dev); + /* Interrupt handlers */ -static void fr502_isr(sdla_t * card); -static void fr508_isr(sdla_t * card); -static void fr502_rx_intr(sdla_t * card); -static void fr508_rx_intr(sdla_t * card); -static void tx_intr(sdla_t * card); -static void spur_intr(sdla_t * card); -/* Background polling routines */ -static void wpf_poll(sdla_t * card); +static void fr_isr(sdla_t *card); +static void rx_intr(sdla_t *card); +static void tx_intr(sdla_t *card); +static void timer_intr(sdla_t *card); +static void spur_intr(sdla_t *card); + /* Frame relay firmware interface functions */ -static int fr_read_version(sdla_t * card, char *str); -static int fr_configure(sdla_t * card, fr_conf_t * conf); -static int fr_dlci_configure(sdla_t * card, fr_dlc_conf_t * conf, unsigned dlci); -static int fr_set_intr_mode(sdla_t * card, unsigned mode, unsigned mtu); -static int fr_comm_enable(sdla_t * card); -static int fr_comm_disable(sdla_t * card); -static int fr_get_err_stats(sdla_t * card); -static int fr_get_stats(sdla_t * card); -static int fr_add_dlci(sdla_t * card, int dlci, int num); -static int fr_activate_dlci(sdla_t * card, int dlci, int num); -static int fr_issue_isf(sdla_t * card, int isf); -static int fr502_send(sdla_t * card, int dlci, int attr, int len, void *buf); -static int fr508_send(sdla_t * card, int dlci, int attr, int len, void *buf); +static int fr_read_version(sdla_t *card, char *str); +static int fr_configure(sdla_t *card, fr_conf_t *conf); +static int fr_dlci_configure(sdla_t *card, fr_dlc_conf_t *conf, unsigned dlci); +static int fr_init_dlci (sdla_t *card, fr_channel_t *chan); +static int fr_set_intr_mode (sdla_t *card, unsigned mode, unsigned mtu, unsigned short timeout); +static int fr_comm_enable(sdla_t *card); +static int fr_comm_disable(sdla_t *card); +static int fr_get_err_stats(sdla_t *card); +static int fr_get_stats(sdla_t *card); +static int fr_add_dlci(sdla_t *card, int dlci); +static int fr_activate_dlci(sdla_t *card, int dlci); +static int fr_delete_dlci (sdla_t* card, int dlci); +static int fr_issue_isf(sdla_t *card, int isf); +static int fr_send(sdla_t *card, int dlci, unsigned char attr, int len, + void *buf); + /* Firmware asynchronous event handlers */ -static int fr_event(sdla_t * card, int event, fr_mbox_t * mbox); -static int fr_modem_failure(sdla_t * card, fr_mbox_t * mbox); -static int fr_dlci_change(sdla_t * card, fr_mbox_t * mbox); +static int fr_event(sdla_t *card, int event, fr_mbox_t *mbox); +static int fr_modem_failure(sdla_t *card, fr_mbox_t *mbox); +static int fr_dlci_change(sdla_t *card, fr_mbox_t *mbox); + /* Miscellaneous functions */ static int update_chan_state(struct net_device *dev); static void set_chan_state(struct net_device *dev, int state); -static struct net_device *find_channel(sdla_t * card, unsigned dlci); -static int is_tx_ready(sdla_t * card, fr_channel_t * chan); +static struct net_device *find_channel(sdla_t *card, unsigned dlci); +static int is_tx_ready(sdla_t *card, fr_channel_t *chan); static unsigned int dec_to_uint(unsigned char *str, int len); -static int reply_udp(unsigned char *data, unsigned int mbox_len); -static int intr_test(sdla_t * card); -static void init_chan_statistics(fr_channel_t * chan); -static void init_global_statistics(sdla_t * card); -static void read_DLCI_IB_mapping(sdla_t * card, fr_channel_t * chan); +static int reply_udp( unsigned char *data, unsigned int mbox_len ); + +static int intr_test( sdla_t* card ); +static void init_chan_statistics( fr_channel_t* chan ); +static void init_global_statistics( sdla_t* card ); +static void read_DLCI_IB_mapping( sdla_t* card, fr_channel_t* chan ); +static void setup_for_delayed_transmit(struct net_device* dev, void* buf, + unsigned len); + + +/* Inverse ARP and Dynamic routing functions */ +int process_ARP(arphdr_1490_t *ArpPacket, sdla_t *card, struct net_device *dev); +int is_arp(void *buf); +int send_inarp_request(sdla_t *card, struct net_device *dev); + /* Udp management functions */ -static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan); -static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan); -static int udp_pkt_type(struct sk_buff *skb, sdla_t * card); +static int process_udp_mgmt_pkt(sdla_t *card); +static int udp_pkt_type( struct sk_buff *skb, sdla_t *card ); +static int store_udp_mgmt_pkt(int udp_type, char udp_pkt_src, sdla_t* card, + struct sk_buff *skb, int dlci); + /* IPX functions */ -static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming); -static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number); +static void switch_net_numbers(unsigned char *sendpacket, + unsigned long network_number, unsigned char incoming); + +static int handle_IPXWAN(unsigned char *sendpacket, char *devname, + unsigned char enable_IPX, unsigned long network_number); + +/* Lock Functions: SMP supported */ +void s508_s514_unlock(sdla_t *card, unsigned long *smp_flags); +void s508_s514_lock(sdla_t *card, unsigned long *smp_flags); + +unsigned short calc_checksum (char *, int); + /****** Public Functions ****************************************************/ @@ -313,154 +358,251 @@ * Return: 0 o.k. * < 0 failure. */ -int wpf_init(sdla_t * card, wandev_conf_t * conf) +int wpf_init(sdla_t *card, wandev_conf_t *conf) { - union { + + int err; + + union + { char str[80]; fr_conf_t cfg; } u; + fr_buf_info_t* buf_info; int i; + /* Verify configuration ID */ - if (conf->config_id != WANCONFIG_FR) - { + if (conf->config_id != WANCONFIG_FR) { + printk(KERN_INFO "%s: invalid configuration ID %u!\n", - card->devname, conf->config_id); + card->devname, conf->config_id); return -EINVAL; + } + /* Initialize protocol-specific fields of adapter data space */ - switch (card->hw.fwid) - { - case SFID_FR502: - card->mbox = (void *) (card->hw.dpmbase + FR502_MBOX_OFFS); - card->rxmb = (void *) (card->hw.dpmbase + FR502_RXMB_OFFS); - card->flags = (void *) (card->hw.dpmbase + FR502_FLAG_OFFS); - card->isr = &fr502_isr; - break; + switch (card->hw.fwid) { + case SFID_FR508: - card->mbox = (void *) (card->hw.dpmbase + FR508_MBOX_OFFS); - card->flags = (void *) (card->hw.dpmbase + FR508_FLAG_OFFS); - card->isr = &fr508_isr; + card->mbox = (void*)(card->hw.dpmbase + + FR508_MBOX_OFFS); + card->flags = (void*)(card->hw.dpmbase + + FR508_FLAG_OFFS); + if(card->hw.type == SDLA_S514) { + card->mbox += FR_MB_VECTOR; + card->flags += FR_MB_VECTOR; + } + card->isr = &fr_isr; break; + default: return -EINVAL; } + /* Read firmware version. Note that when adapter initializes, it * clears the mailbox, so it may appear that the first command was * executed successfully when in fact it was merely erased. To work * around this, we execute the first command twice. */ + if (fr_read_version(card, NULL) || fr_read_version(card, u.str)) return -EIO; + printk(KERN_INFO "%s: running frame relay firmware v%s\n", - card->devname, u.str); + card->devname, u.str); + /* Adjust configuration */ - conf->mtu = max(min(conf->mtu, 4080), FR_CHANNEL_MTU + FR_HEADER_LEN); + conf->mtu += FR_HEADER_LEN; + conf->mtu = (conf->mtu >= MIN_LGTH_FR_DATA_CFG) ? + min(conf->mtu, FR_MAX_NO_DATA_BYTES_IN_FRAME) : + FR_CHANNEL_MTU + FR_HEADER_LEN; + conf->bps = min(conf->bps, 2048000); - /* Configure adapter firmware */ + + /* Initialze the configuration structure sent to the board to zero */ memset(&u.cfg, 0, sizeof(u.cfg)); - u.cfg.mtu = conf->mtu; - u.cfg.kbps = conf->bps / 1000; - u.cfg.cir_fwd = u.cfg.cir_bwd = 16; - u.cfg.bc_fwd = u.cfg.bc_bwd = 16; - if (conf->station == WANOPT_CPE) - { - u.cfg.options = 0x0080; - printk(KERN_INFO "%s: Global CIR enabled by Default\n", card->devname); - } - else - { - u.cfg.options = 0x0081; - } - switch (conf->u.fr.signalling) - { - case WANOPT_FR_Q933: - u.cfg.options |= 0x0200; + + memset(card->u.f.dlci_to_dev_map, 0, sizeof(card->u.f.dlci_to_dev_map)); + + /* Configure adapter firmware */ + + u.cfg.mtu = conf->mtu; + u.cfg.kbps = conf->bps / 1000; + + u.cfg.cir_fwd = u.cfg.cir_bwd = 16; + u.cfg.bc_fwd = u.cfg.bc_bwd = 16; + + u.cfg.options = 0x0000; + printk(KERN_INFO "%s: Global CIR enabled by Default\n", card->devname); + + switch (conf->u.fr.signalling) { + + case WANOPT_FR_ANSI: + u.cfg.options = 0x0000; + break; + + case WANOPT_FR_Q933: + u.cfg.options |= 0x0200; + break; + + case WANOPT_FR_LMI: + u.cfg.options |= 0x0400; break; - case WANOPT_FR_LMI: - u.cfg.options |= 0x0400; + + case WANOPT_NO: + u.cfg.options |= 0x0800; break; + default: + printk(KERN_INFO "%s: Illegal Signalling option\n", + card->wandev.name); + return -EINVAL; } - if (conf->station == WANOPT_CPE) - { + + + card->wandev.signalling = conf->u.fr.signalling; + + if (conf->station == WANOPT_CPE) { + + + if (conf->u.fr.signalling == WANOPT_NO){ + printk(KERN_INFO + "%s: ERROR - For NO signalling, station must be set to Node!", + card->devname); + return -EINVAL; + } + + u.cfg.station = 0; u.cfg.options |= 0x8000; /* auto config DLCI */ - card->u.f.dlci_num = 0; - } - else - { + card->u.f.dlci_num = 0; + + } else { + u.cfg.station = 1; /* switch emulation mode */ + /* For switch emulation we have to create a list of dlci(s) * that will be sent to be global SET_DLCI_CONFIGURATION * command in fr_configure() routine. */ - card->u.f.dlci_num = min(max(conf->u.fr.dlci_num, 1), 100); - for (i = 0; i < card->u.f.dlci_num; i++) - { - card->u.f.node_dlci[i] = (unsigned short) - conf->u.fr.dlci[i] ? conf->u.fr.dlci[i] : 16; + + card->u.f.dlci_num = min(max(conf->u.fr.dlci_num, 1), 100); + + for ( i = 0; i < card->u.f.dlci_num; i++) { + + card->u.f.node_dlci[i] = (unsigned short) + conf->u.fr.dlci[i] ? conf->u.fr.dlci[i] : 16; + } } + if (conf->clocking == WANOPT_INTERNAL) u.cfg.port |= 0x0001; + if (conf->interface == WANOPT_RS232) u.cfg.port |= 0x0002; + if (conf->u.fr.t391) u.cfg.t391 = min(conf->u.fr.t391, 30); else u.cfg.t391 = 5; + if (conf->u.fr.t392) u.cfg.t392 = min(conf->u.fr.t392, 30); else u.cfg.t392 = 15; + if (conf->u.fr.n391) u.cfg.n391 = min(conf->u.fr.n391, 255); else u.cfg.n391 = 2; + if (conf->u.fr.n392) u.cfg.n392 = min(conf->u.fr.n392, 10); else - u.cfg.n392 = 3; + u.cfg.n392 = 3; + if (conf->u.fr.n393) u.cfg.n393 = min(conf->u.fr.n393, 10); else u.cfg.n393 = 4; + if (fr_configure(card, &u.cfg)) return -EIO; - if (card->hw.fwid == SFID_FR508) - { - fr_buf_info_t *buf_info = - (void *) (card->hw.dpmbase + FR508_RXBC_OFFS); - card->rxmb = (void *) (buf_info->rse_next - FR_MB_VECTOR + card->hw.dpmbase); - card->u.f.rxmb_base = (void *) (buf_info->rse_base - FR_MB_VECTOR + card->hw.dpmbase); - card->u.f.rxmb_last = (void *) (buf_info->rse_base + (buf_info->rse_num - 1) * - sizeof(fr_buf_ctl_t) - FR_MB_VECTOR + card->hw.dpmbase); - card->u.f.rx_base = buf_info->buf_base; - card->u.f.rx_top = buf_info->buf_top; - } - card->wandev.mtu = conf->mtu; - card->wandev.bps = conf->bps; - card->wandev.interface = conf->interface; - card->wandev.clocking = conf->clocking; - card->wandev.station = conf->station; - card->poll = &wpf_poll; - card->exec = &wpf_exec; - card->wandev.update = &update; - card->wandev.new_if = &new_if; - card->wandev.del_if = &del_if; - card->wandev.state = WAN_DISCONNECTED; - card->wandev.ttl = conf->ttl; - card->wandev.udp_port = conf->udp_port; - card->wandev.enable_tx_int = 0; - card->irq_dis_if_send_count = 0; - card->irq_dis_poll_count = 0; - card->wandev.enable_IPX = conf->enable_IPX; - if (conf->network_number) - card->wandev.network_number = conf->network_number; - else - card->wandev.network_number = 0xDEADBEEF; + + if (card->hw.type == SDLA_S514) { + + buf_info = (void*)(card->hw.dpmbase + FR_MB_VECTOR + + FR508_RXBC_OFFS); + + card->rxmb = (void*)(buf_info->rse_next + card->hw.dpmbase); + + card->u.f.rxmb_base = + (void*)(buf_info->rse_base + card->hw.dpmbase); + + card->u.f.rxmb_last = + (void*)(buf_info->rse_base + + (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) + + card->hw.dpmbase); + } + + else { + buf_info = (void*)(card->hw.dpmbase + FR508_RXBC_OFFS); + + card->rxmb = (void*)(buf_info->rse_next - + FR_MB_VECTOR + card->hw.dpmbase); + + card->u.f.rxmb_base = + (void*)(buf_info->rse_base - + FR_MB_VECTOR + card->hw.dpmbase); + + card->u.f.rxmb_last = + (void*)(buf_info->rse_base + + (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) - + FR_MB_VECTOR + card->hw.dpmbase); + } + + card->u.f.rx_base = buf_info->buf_base; + card->u.f.rx_top = buf_info->buf_top; + + card->u.f.tx_interrupts_pending = 0; + + card->wandev.mtu = conf->mtu; + card->wandev.bps = conf->bps; + card->wandev.interface = conf->interface; + card->wandev.clocking = conf->clocking; + card->wandev.station = conf->station; + card->poll = NULL; + card->exec = &wpf_exec; + card->wandev.update = &update; + card->wandev.new_if = &new_if; + card->wandev.del_if = &del_if; + card->wandev.state = WAN_DISCONNECTED; + card->wandev.ttl = conf->ttl; + card->wandev.udp_port = conf->udp_port; + /* Intialize global statistics for a card */ - init_global_statistics(card); - TracingEnabled = 0; - return 0; + init_global_statistics( card ); + + card->TracingEnabled = 0; + + /* Interrupt Test */ + Intr_test_counter = 0; + card->intr_mode = INTR_TEST_MODE; + err = intr_test( card ); + + if (err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) { + printk( + "%s: Interrupt Test Failed, Counter: %i\n", + card->devname, Intr_test_counter); + printk( "Please choose another interrupt\n"); + err = -EIO; + return err; + } + + printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n", + card->devname, Intr_test_counter); + + + return 0; } /******* WAN Device Driver Entry Points *************************************/ @@ -468,21 +610,38 @@ /*============================================================================ * Update device status & statistics. */ - -static int update(wan_device_t * wandev) +static int update (wan_device_t* wandev) { - sdla_t *card; + volatile sdla_t* card; + unsigned long timeout; + fr508_flags_t* flags; + /* sanity checks */ if ((wandev == NULL) || (wandev->private == NULL)) return -EFAULT; + if (wandev->state == WAN_UNCONFIGURED) return -ENODEV; - if (test_and_set_bit(0, (void *) &wandev->critical)) + + if (test_bit(1, (void*)&wandev->critical)) return -EAGAIN; + card = wandev->private; - fr_get_err_stats(card); - fr_get_stats(card); - wandev->critical = 0; + flags = card->flags; + + + card->u.f.update_comms_stats = 1; + card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UPDATE; + flags->imask |= FR_INTR_TIMER; + timeout = jiffies; + for(;;) { + if(card->u.f.update_comms_stats == 0) + break; + if ((jiffies - timeout) > (1 * HZ)){ + card->u.f.update_comms_stats = 0; + return -EAGAIN; + } + } return 0; } @@ -498,85 +657,216 @@ * Return: 0 o.k. * < 0 failure (channel will not be created) */ - -static int new_if(wan_device_t * wandev, struct net_device *dev, wanif_conf_t * conf) +static int new_if (wan_device_t* wandev, struct net_device* dev, wanif_conf_t* conf) { - sdla_t *card = wandev->private; - fr_channel_t *chan; + sdla_t* card = wandev->private; + fr_channel_t* chan; + int dlci = 0; int err = 0; - if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) - { + + if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) { + printk(KERN_INFO "%s: invalid interface name!\n", - card->devname); + card->devname); return -EINVAL; } + /* allocate and initialize private data */ chan = kmalloc(sizeof(fr_channel_t), GFP_KERNEL); + if (chan == NULL) return -ENOMEM; + memset(chan, 0, sizeof(fr_channel_t)); strcpy(chan->name, conf->name); chan->card = card; + /* verify media address */ - if (is_digit(conf->addr[0])) - { - int dlci = dec_to_uint(conf->addr, 0); - if (dlci && (dlci <= 4095)) - { + if (is_digit(conf->addr[0])) { + + dlci = dec_to_uint(conf->addr, 0); + + if (dlci && (dlci <= HIGHEST_VALID_DLCI)) { + chan->dlci = dlci; - } - else - { - printk(KERN_ERR "%s: invalid DLCI %u on interface %s!\n", - wandev->name, dlci, chan->name); + + } else { + + printk(KERN_ERR + "%s: invalid DLCI %u on interface %s!\n", + wandev->name, dlci, chan->name); err = -EINVAL; } - } - else - { - printk(KERN_ERR "%s: invalid media address on interface %s!\n", - wandev->name, chan->name); + + } else { + printk(KERN_ERR + "%s: invalid media address on interface %s!\n", + wandev->name, chan->name); err = -EINVAL; } - if (err) - { + + /* Setup wanpipe as a router (WANPIPE) or as an API */ + if(strcmp(conf->usedby, "WANPIPE") == 0){ + printk(KERN_INFO "%s: Running in WANPIPE mode %s\n", + wandev->name, chan->name); + chan->usedby = WANPIPE; + + } else if(strcmp(conf->usedby, "API") == 0){ + +#ifdef FRAME_RELAY_API + chan->usedby = API; + printk(KERN_INFO "%s: Running in API mode %s\n", + wandev->name, chan->name); +#else + printk(KERN_INFO "%s: API Mode is not supported !\n", + wandev->name); + printk(KERN_INFO + "%s: API patch can be obtained from Sangoma Tech.\n", + wandev->name); + err = -EINVAL; +#endif + } + + if (err) { + kfree(chan); return err; } + + card->u.f.dlci_to_dev_map[dlci] = dev; + /* place cir,be,bc and other channel specific information into the * chan structure - */ - if (conf->cir) - { - chan->cir = max(1, min(conf->cir, 512)); - chan->cir_status = CIR_ENABLED; - if (conf->bc) - chan->bc = max(1, min(conf->bc, 512)); - if (conf->be) - chan->be = max(0, min(conf->be, 511)); - } - else + */ + if (conf->cir) { + + chan->cir = max( 1, min( conf->cir, 512 ) ); + chan->cir_status = CIR_ENABLED; + + + /* If CIR is enabled, force BC to equal CIR + * this solves number of potential problems if CIR is + * set and BC is not + */ + chan->bc = chan->cir; + + if (conf->be){ + chan->be = max( 0, min( conf->be, 511) ); + }else{ + conf->be = 0; + } + + printk (KERN_INFO "%s: CIR enabled for DLCI %i \n", + wandev->name,chan->dlci); + printk (KERN_INFO "%s: CIR = %i ; BC = %i ; BE = %i\n", + wandev->name,chan->cir,chan->bc,chan->be); + + + }else{ chan->cir_status = CIR_DISABLED; + printk (KERN_INFO "%s: CIR disabled for DLCI %i\n", + wandev->name,chan->dlci); + } + chan->mc = conf->mc; - chan->dlci_configured = DLCI_NOT_CONFIGURED; - chan->tx_int_status = DISABLED; + + /* FIXME: ARP is not supported by this frame relay verson */ + if (conf->inarp == WANOPT_YES){ + printk(KERN_INFO "%s: ERROR - This version of WANPIPE doesn't support ARPs\n", + card->devname); + + //chan->inarp = conf->inarp ? INARP_REQUEST : INARP_NONE; + //chan->inarp_interval = conf->inarp_interval ? conf->inarp_interval : 10; + kfree(chan); + return -EINVAL; + }else{ + chan->inarp = INARP_NONE; + chan->inarp_interval = 10; + } + + chan->dlci_configured = DLCI_NOT_CONFIGURED; + + + /*FIXME: IPX disabled in this WANPIPE version */ + if (conf->enable_IPX == WANOPT_YES){ + printk(KERN_INFO "%s: ERROR - This version of WANPIPE doesn't support IPX\n", + card->devname); + kfree(chan); + return -EINVAL; + }else{ + chan->enable_IPX = WANOPT_NO; + } + + if (conf->network_number){ + chan->network_number = conf->network_number; + }else{ + chan->network_number = 0xDEADBEEF; + } + + chan->route_flag = NO_ROUTE; + init_chan_statistics(chan); + + chan->transmit_length = 0; + /* prepare network device data space for registration */ dev->name = chan->name; dev->init = &if_init; dev->priv = chan; + + + /* Enable Interrupts and Communications */ + if (!wandev->new_if_cnt){ + fr508_flags_t* flags = card->flags; + + wandev->new_if_cnt++; + + /* + If you enable comms and then set ints, you get a Tx int as you + perform the SET_INT_TRIGGERS command. So, we only set int + triggers and then adjust the interrupt mask (to disable Tx ints) + before enabling comms. + */ + if (fr_set_intr_mode(card, (FR_INTR_RXRDY | FR_INTR_TXRDY | + FR_INTR_DLC | FR_INTR_TIMER | FR_INTR_TX_MULT_DLCIs) , + card->wandev.mtu, 0)) { + kfree(chan); + return -EIO; + } + + flags->imask &= ~(FR_INTR_TXRDY | FR_INTR_TIMER); + + if (fr_comm_enable(card)) { + kfree(chan); + return -EIO; + } + wanpipe_set_state(card, WAN_CONNECTED); + } + return 0; } + /*============================================================================ * Delete logical channel. */ -static int del_if(wan_device_t * wandev, struct net_device *dev) +static int del_if (wan_device_t* wandev, struct net_device* dev) { - if (dev->priv) - { + sdla_t *card = wandev->private; + + /* Execute shutdown very first time we enter del_if */ + + if (!wandev->del_if_cnt) { + wandev->del_if_cnt++; + wanpipe_set_state(card, WAN_DISCONNECTED); + fr_set_intr_mode(card, 0, 0, 0); + fr_comm_disable(card); + } + + if (dev->priv) { kfree(dev->priv); dev->priv = NULL; } + return 0; } @@ -585,41 +875,47 @@ /*============================================================================ * Execute adapter interface command. */ -static int wpf_exec(struct sdla *card, void *u_cmd, void *u_data) +static int wpf_exec (struct sdla* card, void* u_cmd, void* u_data) { - fr_mbox_t *mbox = card->mbox; + fr_mbox_t* mbox = card->mbox; int retry = MAX_CMD_RETRY; int err, len; fr_cmd_t cmd; - if(copy_from_user((void *) &cmd, u_cmd, sizeof(cmd))) - return -EFAULT; + + if(copy_from_user((void*)&cmd, u_cmd, sizeof(cmd))) + return -EFAULT; + /* execute command */ - do + do { memcpy(&mbox->cmd, &cmd, sizeof(cmd)); - if (cmd.length) - { - if(copy_from_user((void *) &mbox->data, u_data, cmd.length)) + + if (cmd.length){ + if( copy_from_user((void*)&mbox->data, u_data, cmd.length)) return -EFAULT; } + if (sdla_exec(mbox)) err = mbox->cmd.result; - else - return -EIO; - } - while (err && retry-- && fr_event(card, err, mbox)); - /* return result */ + else return -EIO; + + } while (err && retry-- && fr_event(card, err, mbox)); - if(copy_to_user(u_cmd, (void *) &mbox->cmd, sizeof(fr_cmd_t))) + /* return result */ + if (copy_to_user(u_cmd, (void*)&mbox->cmd, sizeof(fr_cmd_t))) return -EFAULT; + len = mbox->cmd.length; - if (len && u_data && copy_to_user(u_data, (void *) &mbox->data, len)) + + if (len && u_data && !copy_to_user(u_data, (void*)&mbox->data, len)) return -EFAULT; return 0; + } /****** Network Device Interface ********************************************/ + /*============================================================================ * Initialize Linux network interface. * @@ -627,35 +923,55 @@ * interface registration. Returning anything but zero will fail interface * registration. */ -static int if_init(struct net_device *dev) +static int if_init (struct net_device* dev) { - fr_channel_t *chan = dev->priv; - sdla_t *card = chan->card; - wan_device_t *wandev = &card->wandev; + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + wan_device_t* wandev = &card->wandev; /* Initialize device driver entry points */ - dev->open = &if_open; - dev->stop = &if_close; - dev->hard_header = &if_header; - dev->rebuild_header = &if_rebuild_hdr; - dev->hard_start_xmit = &if_send; - dev->get_stats = &if_stats; + dev->open = &if_open; + dev->stop = &if_close; + dev->hard_header = &if_header; + dev->rebuild_header = &if_rebuild_hdr; + dev->hard_start_xmit = &if_send; + dev->get_stats = &if_stats; + /* Initialize media-specific parameters */ - dev->type = ARPHRD_DLCI; /* ARP h/w type */ - dev->mtu = FR_CHANNEL_MTU; - dev->hard_header_len = FR_HEADER_LEN; /* media header length */ - dev->addr_len = 2; /* hardware address length */ - *(unsigned short *) dev->dev_addr = htons(chan->dlci); + dev->type = ARPHRD_DLCI; /* ARP h/w type */ + dev->flags |= IFF_POINTOPOINT; + + /* Enable Multicast addressing */ + if (chan->mc == WANOPT_YES){ + dev->flags |= IFF_MULTICAST; + } + + dev->mtu = wandev->mtu - FR_HEADER_LEN; + /* For an API, the maximum number of bytes that the stack will pass + to the driver is (dev->mtu + dev->hard_header_len). So, adjust the + mtu so that a frame of maximum size can be transmitted by the API. + */ + if(chan->usedby == API) { + dev->mtu += (sizeof(api_tx_hdr_t) - FR_HEADER_LEN); + } + + dev->hard_header_len = FR_HEADER_LEN;/* media header length */ + dev->addr_len = 2; /* hardware address length */ + *(unsigned short*)dev->dev_addr = htons(chan->dlci); + /* Initialize hardware parameters (just for reference) */ - dev->irq = wandev->irq; - dev->dma = wandev->dma; - dev->base_addr = wandev->ioport; - dev->mem_start = (unsigned long)wandev->maddr; - dev->mem_end = dev->mem_start + wandev->msize - 1; - /* Set transmit buffer queue length */ - dev->tx_queue_len = 10; + dev->irq = wandev->irq; + dev->dma = wandev->dma; + dev->base_addr = wandev->ioport; + dev->mem_start = wandev->maddr; + dev->mem_end = wandev->maddr + wandev->msize - 1; + + /* Set transmit buffer queue length */ + dev->tx_queue_len = 100; + /* Initialize socket buffers */ dev_init_buffers(dev); + set_chan_state(dev, WAN_DISCONNECTED); return 0; } @@ -667,127 +983,62 @@ * * Return 0 if O.k. or errno. */ - -static int if_open(struct net_device *dev) +static int if_open (struct net_device* dev) { - fr_channel_t *chan = dev->priv; - sdla_t *card = chan->card; - struct net_device *dev2; + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; int err = 0; - fr508_flags_t *flags = card->flags; struct timeval tv; + if (dev->start) - return -EBUSY; /* only one open is allowed */ - if (test_and_set_bit(0, (void *) &card->wandev.critical)) + return -EBUSY; /* only one open is allowed */ + + if (test_and_set_bit(1, (void*)&card->wandev.critical)) return -EAGAIN; - if (!card->open_cnt) - { - Intr_test_counter = 0; - card->intr_mode = INTR_TEST_MODE; - err = intr_test(card); - if ((err) || (Intr_test_counter != (MAX_INTR_TEST_COUNTER + 1))) { - printk(KERN_INFO - "%s: Interrupt Test Failed, Counter: %i\n", - card->devname, Intr_test_counter); - err = -EIO; - card->wandev.critical = 0; - return err; - } - printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n" - ,card->devname, Intr_test_counter); - /* The following allocates and intializes a circular - * link list of interfaces per card. - */ - card->devs_struct = kmalloc(sizeof(load_sharing_t), GFP_KERNEL); - if (card->devs_struct == NULL) - return -ENOMEM; - card->dev_to_devtint_next = card->devs_struct; - for (dev2 = card->wandev.dev; dev2; dev2 = dev2->slave) { - (card->devs_struct)->dev_ptr = dev2; - if (dev2->slave == NULL) - (card->devs_struct)->next = card->dev_to_devtint_next; - else { - (card->devs_struct)->next = kmalloc( - sizeof(load_sharing_t), GFP_KERNEL); - if ((card->devs_struct)->next == NULL) - return -ENOMEM; - card->devs_struct = (card->devs_struct)->next; - } - } - card->devs_struct = card->dev_to_devtint_next; - card->intr_mode = BUFFER_INTR_MODE; - /* - check all the interfaces for the device to see if CIR has - been enabled for any DLCI(s). If so then use the DLCI list - Interrupt mode for fr_set_intr_mode(), otherwise use the default global interrupt mode - */ - for (dev2 = card->wandev.dev; dev2; dev2 = dev2->slave) { - if (((fr_channel_t *) dev2->priv)->cir_status - == CIR_ENABLED) { - card->intr_mode = DLCI_LIST_INTR_MODE; - break; - } - } - /* - If you enable comms and then set ints, you get a Tx int as you - perform the SET_INT_TRIGGERS command. So, we only set int - triggers and then adjust the interrupt mask (to disable Tx ints) before enabling comms. - */ - if (card->intr_mode == BUFFER_INTR_MODE) { - if (fr_set_intr_mode(card, 0x03, card->wandev.mtu)) { - err = -EIO; - card->wandev.critical = 0; - return err; - } - printk(KERN_INFO - "%s: Global Buffering Tx Interrupt Mode\n" - ,card->devname); - } else if (card->intr_mode == DLCI_LIST_INTR_MODE) { - if (fr_set_intr_mode(card, 0x83, card->wandev.mtu)) { - err = -EIO; - card->wandev.critical = 0; - return err; - } - printk(KERN_INFO - "%s: DLCI list Tx Interrupt Mode\n", - card->devname); - } - flags->imask &= ~0x02; - if (fr_comm_enable(card)) { - err = -EIO; - card->wandev.critical = 0; - return err; - } - wanpipe_set_state(card, WAN_CONNECTED); - if (card->wandev.station == WANOPT_CPE) { - /* CPE: issue full status enquiry */ - fr_issue_isf(card, FR_ISF_FSE); - } else { /* FR switch: activate DLCI(s) */ - /* For Switch emulation we have to ADD and ACTIVATE - * the DLCI(s) that were configured with the SET_DLCI_ - * CONFIGURATION command. Add and Activate will fail if - * DLCI specified is not included in the list. - * - * Also If_open is called once for each interface. But - * it does not get in here for all the interface. So - * we have to pass the entire list of DLCI(s) to add - * activate routines. - */ - fr_add_dlci(card, - card->u.f.node_dlci[0], card->u.f.dlci_num); - fr_activate_dlci(card, - card->u.f.node_dlci[0], card->u.f.dlci_num); + + + /* If signalling is set to NO, then setup + * DLCI addresses right away. Don't have to wait for + * link to connect. + */ + if (card->wandev.signalling == WANOPT_NO){ + printk(KERN_INFO "%s: Signalling set to NO: Mapping DLCI's\n", + card->wandev.name); + if (fr_init_dlci(card,chan)){ + return -EAGAIN; } } - dev->mtu = min(dev->mtu, card->wandev.mtu - FR_HEADER_LEN); + + if (card->wandev.station == WANOPT_CPE) { + + /* CPE: issue full status enquiry */ + fr_issue_isf(card, FR_ISF_FSE); + + } else { /* FR switch: activate DLCI(s) */ + + /* For Switch emulation we have to ADD and ACTIVATE + * the DLCI(s) that were configured with the SET_DLCI_ + * CONFIGURATION command. Add and Activate will fail if + * DLCI specified is not included in the list. + * + * Also If_open is called once for each interface. But + * it does not get in here for all the interface. So + * we have to pass the entire list of DLCI(s) to add + * activate routines. + */ + + fr_add_dlci(card, chan->dlci); + fr_activate_dlci(card, chan->dlci); + } + dev->interrupt = 0; dev->tbusy = 0; dev->start = 1; wanpipe_open(card); update_chan_state(dev); - do_gettimeofday(&tv); + do_gettimeofday( &tv ); chan->router_start_time = tv.tv_sec; - card->wandev.critical = 0; + clear_bit(1, (void*)&card->wandev.critical); return err; } @@ -796,22 +1047,21 @@ * o if this is the last open, then disable communications and interrupts. * o reset flags. */ - -static int if_close(struct net_device *dev) +static int if_close (struct net_device* dev) { - fr_channel_t *chan = dev->priv; - sdla_t *card = chan->card; - if (test_and_set_bit(0, (void *) &card->wandev.critical)) + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + + if (test_and_set_bit(1, (void*)&card->wandev.critical)) return -EAGAIN; + dev->start = 0; wanpipe_close(card); - if (!card->open_cnt) - { - wanpipe_set_state(card, WAN_DISCONNECTED); - fr_set_intr_mode(card, 0, 0); - fr_comm_disable(card); + if (card->wandev.station == WANOPT_NODE) { + fr_delete_dlci (card,chan->dlci); } - card->wandev.critical = 0; + + clear_bit(1, (void*)&card->wandev.critical); return 0; } @@ -825,15 +1075,15 @@ * * Return: media header length. */ - -static int if_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, unsigned len) +static int if_header (struct sk_buff* skb, struct net_device* dev, + unsigned short type, void* daddr, void* saddr, unsigned len) { int hdr_len = 0; + skb->protocol = type; hdr_len = wanrouter_encapsulate(skb, dev); - if (hdr_len < 0) - { + + if (hdr_len < 0) { hdr_len = 0; skb->protocol = 0; } @@ -849,14 +1099,14 @@ * Return: 1 physical address resolved. * 0 physical address not resolved */ - -static int if_rebuild_hdr(struct sk_buff *skb) +static int if_rebuild_hdr (struct sk_buff* skb) { - struct net_device *dev=skb->dev; - fr_channel_t *chan = dev->priv; - sdla_t *card = chan->card; + struct net_device *dev = skb->dev; + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + printk(KERN_INFO "%s: rebuild_header() called for interface %s!\n", - card->devname, dev->name); + card->devname, dev->name); return 1; } @@ -864,6 +1114,7 @@ * Send a packet on a network interface. * o set tbusy flag (marks start of the transmission) to block a timer-based * transmit from overlapping. + * o set critical flag when accessing board. * o check link state. If link is not up, then drop the packet. * o check channel status. If it's down then initiate a call. * o pass a packet to corresponding WAN device. @@ -878,876 +1129,951 @@ * 2. Setting tbusy flag will inhibit further transmit requests from the * protocol stack and can be used for flow control with protocol layer. */ - -static int if_send(struct sk_buff *skb, struct net_device *dev) +static int if_send (struct sk_buff* skb, struct net_device* dev) { - fr_channel_t *chan = dev->priv; - sdla_t *card = chan->card; - int retry = 0, err; - unsigned char *sendpacket; - struct net_device *dev2; - unsigned long check_braddr, check_mcaddr; - fr508_flags_t *adptr_flags = card->flags; + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + int err; + unsigned char *sendpacket; + fr508_flags_t* adptr_flags = card->flags; int udp_type, send_data; - fr_dlci_interface_t *dlci_interface = chan->dlci_int_interface; - unsigned long host_cpu_flags; - ++chan->if_send_entry; + unsigned long smp_flags=0; + void* data; + unsigned len; + + chan->drvstats_if_send.if_send_entry++; + + if (skb == NULL) { + /* if we get here, some higher layer thinks we've missed an + * tx-done interrupt. + */ + printk(KERN_INFO "%s: interface %s got kicked!\n", + card->devname, dev->name); + chan->drvstats_if_send.if_send_skb_null ++; + mark_bh(NET_BH); + return 0; + } + + /* We must set the 'tbusy' flag if we already have a packet queued for + transmission in the transmit interrupt handler. However, we must + ensure that the transmit interrupt does not reset the 'tbusy' flag + just before we set it, as this will result in a "transmit timeout". + */ + set_bit(2, (void*)&card->wandev.critical); + if(chan->transmit_length) { + dev->tbusy = 1; + chan->tick_counter = jiffies; + clear_bit(2, (void*)&card->wandev.critical); + return 1; + } + clear_bit(2, (void*)&card->wandev.critical); + + if (dev->tbusy) { - if (dev->tbusy) - { /* If our device stays busy for at least 5 seconds then we will - * kick start the device by making dev->tbusy = 0. We expect - * that our device never stays busy more than 5 seconds. So this * is only used as a last resort. - */ - ++chan->if_send_busy; + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + + chan->drvstats_if_send.if_send_tbusy++; ++chan->ifstats.collisions; - if ((jiffies - chan->tick_counter) < (5 * HZ)) + + if ((jiffies - chan->tick_counter) < (5 * HZ)) { return 1; + } printk(KERN_INFO "%s: Transmit timed out\n", chan->name); - ++chan->if_send_busy_timeout; - /* unbusy all the interfaces on the card */ - for (dev2 = card->wandev.dev; dev2; dev2 = dev2->slave) - dev2->tbusy = 0; - } + chan->drvstats_if_send.if_send_tbusy_timeout ++; + dev->tbusy = 0; + } + + data = skb->data; sendpacket = skb->data; + len = skb->len; + udp_type = udp_pkt_type(skb, card); - if (udp_type == UDP_DRVSTATS_TYPE) - { - ++chan->if_send_DRVSTATS_request; - process_udp_driver_call(UDP_PKT_FRM_STACK, card, skb, dev, 0, - chan); - dev_kfree_skb(skb); - return 0; - } - else if (udp_type == UDP_FPIPE_TYPE) - ++chan->if_send_FPIPE_request; - /* retreive source address in two forms: broadcast & multicast */ - check_braddr = sendpacket[17]; - check_mcaddr = sendpacket[14]; - check_braddr = check_braddr << 8; - check_mcaddr = check_mcaddr << 8; - check_braddr |= sendpacket[16]; - check_mcaddr |= sendpacket[15]; - check_braddr = check_braddr << 8; - check_mcaddr = check_mcaddr << 8; - check_braddr |= sendpacket[15]; - check_mcaddr |= sendpacket[16]; - check_braddr = check_braddr << 8; - check_mcaddr = check_mcaddr << 8; - check_braddr |= sendpacket[14]; - check_mcaddr |= sendpacket[17]; - /* if the Source Address is a Multicast address */ - if ((chan->mc == WANOPT_NO) && (check_mcaddr >= 0xE0000001) && - (check_mcaddr <= 0xFFFFFFFE)) - { - printk(KERN_INFO "%s: Multicast Src. Addr. silently discarded\n" - ,card->devname); - dev_kfree_skb(skb); - ++chan->ifstats.tx_dropped; - ++chan->if_send_multicast; + + if(udp_type != UDP_INVALID_TYPE) { + if(store_udp_mgmt_pkt(udp_type, UDP_PKT_FRM_STACK, card, skb, + chan->dlci)) { + adptr_flags->imask |= FR_INTR_TIMER; + if (udp_type == UDP_FPIPE_TYPE){ + chan->drvstats_if_send. + if_send_PIPE_request ++; + } + } return 0; } - disable_irq(card->hw.irq); - ++card->irq_dis_if_send_count; - if (test_and_set_bit(0, (void *) &card->wandev.critical)) - { - if (card->wandev.critical == CRITICAL_IN_ISR) - { - ++chan->if_send_critical_ISR; - if (card->intr_mode == DLCI_LIST_INTR_MODE) - { - /* The enable_tx_int flag is set here so that if - * the critical flag is set due to an interrupt - * then we want to enable transmit interrupts - * again. - */ - card->wandev.enable_tx_int = 1; - /* Setting this flag to WAITING_TO_BE_ENABLED - * specifies that interrupt bit has to be - * enabled for that particular interface. - * (delayed interrupt) - */ - chan->tx_int_status = WAITING_TO_BE_ENABLED; - /* This is used for enabling dynamic calculation - * of CIRs relative to the packet length. - */ - chan->pkt_length = skb->len; - dev->tbusy = 1; - chan->tick_counter = jiffies; - } - else - { - card->wandev.enable_tx_int = 1; - dev->tbusy = 1; - chan->tick_counter = jiffies; - } - save_flags(host_cpu_flags); - cli(); - if ((!(--card->irq_dis_if_send_count)) && - (!card->irq_dis_poll_count)) - enable_irq(card->hw.irq); - restore_flags(host_cpu_flags); - return 1; - } - ++chan->if_send_critical_non_ISR; - ++chan->ifstats.tx_dropped; + + if((chan->usedby == API) && (len <= sizeof(api_tx_hdr_t))) { + //FIXME: increment some error statistic + dev_kfree_skb(skb); + return 0; + } + + //FIXME: can we do better than sendpacket[2]? + if ((chan->usedby == WANPIPE) && (sendpacket[2] == 0x45)) { + /* check to see if the source IP address is a broadcast or */ + /* multicast IP address */ + if(chk_bcast_mcast_addr(card, dev, skb)) + return 0; + } + + /* Lock the 508 card: SMP Supported */ + s508_s514_lock(card,&smp_flags); + + if (test_and_set_bit(0, (void*)&card->wandev.critical)) { + chan->drvstats_if_send.if_send_critical_non_ISR ++; + chan->ifstats.tx_dropped ++; + printk(KERN_INFO "%s Critical in IF_SEND %02X\n", + card->devname, card->wandev.critical); dev_kfree_skb(skb); - save_flags(host_cpu_flags); - cli(); - if ((!(--card->irq_dis_if_send_count)) && - (!card->irq_dis_poll_count)) - enable_irq(card->hw.irq); - restore_flags(host_cpu_flags); + /* Unlock the 508 card */ + s508_s514_unlock(card,&smp_flags); return 0; } - card->wandev.critical = 0x21; - if (udp_type == UDP_FPIPE_TYPE) - { - err = process_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, - dev, 0, chan); - } - else if (card->wandev.state != WAN_CONNECTED) - { - ++chan->if_send_wan_disconnected; + + if (card->wandev.state != WAN_CONNECTED) { + chan->drvstats_if_send.if_send_wan_disconnected ++; ++chan->ifstats.tx_dropped; - ++card->wandev.stats.tx_dropped; - } - else if (chan->state != WAN_CONNECTED) - { - ++chan->if_send_dlci_disconnected; + ++card->wandev.stats.tx_dropped; + + } else if (chan->state != WAN_CONNECTED) { + chan->drvstats_if_send.if_send_dlci_disconnected ++; + /* Critical area on 514, since disabl_irq is not used + * thus, interrupt would execute a command at + * the same time as if_send. + */ + set_bit(1, (void*)&card->wandev.critical); update_chan_state(dev); - ++chan->ifstats.tx_dropped; - ++card->wandev.stats.tx_dropped; - } - else if (!is_tx_ready(card, chan)) - { - if (card->intr_mode == DLCI_LIST_INTR_MODE) - { - dlci_interface->gen_interrupt |= 0x40; - dlci_interface->packet_length = skb->len; - } - dev->tbusy = 1; - chan->tick_counter = jiffies; - adptr_flags->imask |= 0x02; - ++chan->if_send_no_bfrs; - retry = 1; - } - else - { + clear_bit(1, (void*)&card->wandev.critical); + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + + } else if (!is_tx_ready(card, chan)) { + setup_for_delayed_transmit(dev, data, len); + chan->drvstats_if_send.if_send_no_bfrs++; + } else { send_data = 1; - /* If it's an IPX packet */ - if (sendpacket[1] == 0x00 && - sendpacket[2] == 0x80 && - sendpacket[6] == 0x81 && - sendpacket[7] == 0x37) - { - if (card->wandev.enable_IPX) - { - switch_net_numbers(sendpacket, - card->wandev.network_number, 0); - } - else - { - /* increment some statistic here! */ + //FIXME: IPX is not implemented in this version of Frame Relay ? + if((chan->usedby == WANPIPE) && + sendpacket[1] == 0x00 && + sendpacket[2] == 0x80 && + sendpacket[6] == 0x81 && + sendpacket[7] == 0x37) { + + if( chan->enable_IPX ) { + switch_net_numbers(sendpacket, + chan->network_number, 0); + } else { + //FIXME: Take this out when IPX is fixed + printk(KERN_INFO + "%s: WARNING: Unsupported IPX data in send, packet dropped\n", + card->devname); send_data = 0; } } - if (send_data) - { - err = (card->hw.fwid == SFID_FR508) ? - fr508_send(card, chan->dlci, 0, skb->len, skb->data) : - fr502_send(card, chan->dlci, 0, skb->len, skb->data); - if (err) - { - if (card->intr_mode == DLCI_LIST_INTR_MODE) - { - dlci_interface->gen_interrupt |= 0x40; - dlci_interface->packet_length = skb->len; + + if (send_data) { + unsigned char attr = 0; + + /* For an API transmission, get rid of the API header */ + if (chan->usedby == API) { + api_tx_hdr_t* api_tx_hdr; + api_tx_hdr = (api_tx_hdr_t*)&skb->data[0x00]; + attr = api_tx_hdr->attr; + data += sizeof(api_tx_hdr_t); + len -= sizeof(api_tx_hdr_t); + } + + err = fr_send(card, chan->dlci, attr, len, data); + if (err) { + switch(err) { + case FRRES_CIR_OVERFLOW: + case FRRES_BUFFER_OVERFLOW: + setup_for_delayed_transmit(dev, data, + len); + chan->drvstats_if_send. + if_send_adptr_bfrs_full ++; + break; + default: + chan->drvstats_if_send. + if_send_dlci_disconnected ++; + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + break; } - dev->tbusy = 1; - chan->tick_counter = jiffies; - adptr_flags->imask |= 0x02; - retry = 1; - ++chan->if_send_adptr_bfrs_full; - ++chan->ifstats.tx_errors; - ++card->wandev.stats.tx_errors; - } - else - { - ++chan->if_send_bfrs_passed_to_adptr; + } else { + chan->drvstats_if_send. + if_send_bfr_passed_to_adptr++; ++chan->ifstats.tx_packets; ++card->wandev.stats.tx_packets; - chan->ifstats.tx_bytes += skb->len; - card->wandev.stats.tx_bytes += skb->len; + chan->ifstats.tx_bytes += len; + card->wandev.stats.tx_bytes += len; } } } - if (!retry) + + if (!dev->tbusy) { dev_kfree_skb(skb); + } - card->wandev.critical = 0; - save_flags(host_cpu_flags); - cli(); - if ((!(--card->irq_dis_if_send_count)) && (!card->irq_dis_poll_count)) - enable_irq(card->hw.irq); - restore_flags(host_cpu_flags); - return retry; + clear_bit(0, (void*)&card->wandev.critical); + + s508_s514_unlock(card,&smp_flags); + + return (dev->tbusy); +} + + + +/*============================================================================ + * Setup so that a frame can be transmitted on the occurence of a transmit + * interrupt. + */ +static void setup_for_delayed_transmit (struct net_device* dev, void* buf, + unsigned len) +{ + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + fr508_flags_t* adptr_flags = card->flags; + fr_dlci_interface_t* dlci_interface = chan->dlci_int_interface; + + if(chan->transmit_length) { + printk(KERN_INFO "%s: Big mess in setup_for_del...\n", + card->devname); + return; + } + + if(len > FR_MAX_NO_DATA_BYTES_IN_FRAME) { + //FIXME: increment some statistic */ + return; + } + + chan->transmit_length = len; + memcpy(chan->transmit_buffer, buf, len); + + dlci_interface->gen_interrupt |= FR_INTR_TXRDY; + dlci_interface->packet_length = len; + adptr_flags->imask |= FR_INTR_TXRDY; + + card->u.f.tx_interrupts_pending ++; +} + + +/*============================================================================ + * Check to see if the packet to be transmitted contains a broadcast or + * multicast source IP address. + * Return 0 if not broadcast/multicast address, otherwise return 1. + */ + +static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev, + struct sk_buff *skb) +{ + u32 src_ip_addr; + u32 broadcast_ip_addr = 0; + struct in_device *in_dev; + fr_channel_t* chan = dev->priv; + + /* read the IP source address from the outgoing packet */ + src_ip_addr = *(u32 *)(skb->data + 14); + + /* read the IP broadcast address for the device */ + in_dev = dev->ip_ptr; + if(in_dev != NULL) { + struct in_ifaddr *ifa= in_dev->ifa_list; + if(ifa != NULL) + broadcast_ip_addr = ifa->ifa_broadcast; + else + return 0; + } + + /* check if the IP Source Address is a Broadcast address */ + if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) { printk(KERN_INFO + "%s: Broadcast Source Address silently discarded\n", + card->devname); + dev_kfree_skb(skb); + ++ chan->ifstats.tx_dropped; + return 1; + } + + /* check if the IP Source Address is a Multicast address */ + if((chan->mc == WANOPT_NO) && (ntohl(src_ip_addr) >= 0xE0000001) && + (ntohl(src_ip_addr) <= 0xFFFFFFFE)) { + printk(KERN_INFO + "%s: Multicast Source Address silently discarded\n", + card->devname); + dev_kfree_skb(skb); + ++ chan->ifstats.tx_dropped; + return 1; + } + + return 0; } /*============================================================================ * Reply to UDP Management system. * Return nothing. */ - -static int reply_udp(unsigned char *data, unsigned int mbox_len) +static int reply_udp( unsigned char *data, unsigned int mbox_len ) { - unsigned short len, udp_length, temp, i, ip_length; - unsigned long sum; + unsigned short len, udp_length, temp, ip_length; + unsigned long ip_temp; + int even_bound = 0; + + + fr_udp_pkt_t *fr_udp_pkt = (fr_udp_pkt_t *)data; + /* Set length of packet */ - len = mbox_len + 62; + len = sizeof(fr_encap_hdr_t)+ + sizeof(ip_pkt_t)+ + sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + mbox_len; + + /* fill in UDP reply */ - data[38] = 0x02; + fr_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY; + /* fill in UDP length */ - udp_length = mbox_len + 40; + udp_length = sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + mbox_len; + + /* put it on an even boundary */ - if (udp_length & 0x0001) - { + if ( udp_length & 0x0001 ) { udp_length += 1; len += 1; + even_bound = 1; } - temp = (udp_length << 8) | (udp_length >> 8); - memcpy(&data[26], &temp, 2); + + temp = (udp_length<<8)|(udp_length>>8); + fr_udp_pkt->udp_pkt.udp_length = temp; + /* swap UDP ports */ - memcpy(&temp, &data[22], 2); - memcpy(&data[22], &data[24], 2); - memcpy(&data[24], &temp, 2); + temp = fr_udp_pkt->udp_pkt.udp_src_port; + fr_udp_pkt->udp_pkt.udp_src_port = + fr_udp_pkt->udp_pkt.udp_dst_port; + fr_udp_pkt->udp_pkt.udp_dst_port = temp; + + + /* add UDP pseudo header */ temp = 0x1100; - memcpy(&data[udp_length + 22], &temp, 2); - temp = (udp_length << 8) | (udp_length >> 8); - memcpy(&data[udp_length + 24], &temp, 2); + *((unsigned short *) + (fr_udp_pkt->data+mbox_len+even_bound)) = temp; + temp = (udp_length<<8)|(udp_length>>8); + *((unsigned short *) + (fr_udp_pkt->data+mbox_len+even_bound+2)) = temp; + /* calculate UDP checksum */ - data[28] = data[29] = 0; - sum = 0; - for (i = 0; i < udp_length + 12; i += 2) - { - memcpy(&temp, &data[14 + i], 2); - sum += (unsigned long) temp; - } - while (sum >> 16) - sum = (sum & 0xffffUL) + (sum >> 16); + fr_udp_pkt->udp_pkt.udp_checksum = 0; + + fr_udp_pkt->udp_pkt.udp_checksum = + calc_checksum(&data[UDP_OFFSET+sizeof(fr_encap_hdr_t)], + udp_length+UDP_OFFSET); - temp = (unsigned short) sum; - temp = ~temp; - if (temp == 0) - temp = 0xffff; - memcpy(&data[28], &temp, 2); /* fill in IP length */ - ip_length = udp_length + 20; - temp = (ip_length << 8) | (ip_length >> 8); - memcpy(&data[4], &temp, 2); + ip_length = udp_length + sizeof(ip_pkt_t); + temp = (ip_length<<8)|(ip_length>>8); + fr_udp_pkt->ip_pkt.total_length = temp; + /* swap IP addresses */ - memcpy(&temp, &data[14], 2); - memcpy(&data[14], &data[18], 2); - memcpy(&data[18], &temp, 2); - memcpy(&temp, &data[16], 2); - memcpy(&data[16], &data[20], 2); - memcpy(&data[20], &temp, 2); + ip_temp = fr_udp_pkt->ip_pkt.ip_src_address; + fr_udp_pkt->ip_pkt.ip_src_address = + fr_udp_pkt->ip_pkt.ip_dst_address; + fr_udp_pkt->ip_pkt.ip_dst_address = ip_temp; + + /* fill in IP checksum */ - data[12] = data[13] = 0; - sum = 0; - for (i = 0; i < 20; i += 2) - { - memcpy(&temp, &data[2 + i], 2); - sum += (unsigned long) temp; + fr_udp_pkt->ip_pkt.hdr_checksum = 0; + fr_udp_pkt->ip_pkt.hdr_checksum = + calc_checksum(&data[sizeof(fr_encap_hdr_t)], + sizeof(ip_pkt_t)); + + return len; +} /* reply_udp */ + +unsigned short calc_checksum (char *data, int len) +{ + unsigned short temp; + unsigned long sum=0; + int i; + + for( i = 0; i > 16) + + while (sum >> 16 ) { sum = (sum & 0xffffUL) + (sum >> 16); - temp = (unsigned short) sum; + } + + temp = (unsigned short)sum; temp = ~temp; - if (temp == 0) + + if( temp == 0 ) temp = 0xffff; - memcpy(&data[12], &temp, 2); - return len; -} /* reply_udp */ + + return temp; +} + /* If incoming is 0 (outgoing)- if the net numbers is ours make it 0 if incoming is 1 - if the net number is 0 make it ours - */ +*/ static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming) { unsigned long pnetwork_number; - pnetwork_number = (unsigned long) ((sendpacket[14] << 24) + - (sendpacket[15] << 16) + (sendpacket[16] << 8) + - sendpacket[17]); + + pnetwork_number = (unsigned long)((sendpacket[14] << 24) + + (sendpacket[15] << 16) + (sendpacket[16] << 8) + + sendpacket[17]); + if (!incoming) { /* If the destination network number is ours, make it 0 */ - if (pnetwork_number == network_number) { - sendpacket[14] = sendpacket[15] = sendpacket[16] = - sendpacket[17] = 0x00; + if( pnetwork_number == network_number) { + sendpacket[14] = sendpacket[15] = sendpacket[16] = + sendpacket[17] = 0x00; } } else { /* If the incoming network is 0, make it ours */ - if (pnetwork_number == 0) - { - sendpacket[14] = (unsigned char) (network_number >> 24); - sendpacket[15] = (unsigned char) ((network_number & - 0x00FF0000) >> 16); - sendpacket[16] = (unsigned char) ((network_number & - 0x0000FF00) >> 8); - sendpacket[17] = (unsigned char) (network_number & - 0x000000FF); + if( pnetwork_number == 0) { + sendpacket[14] = (unsigned char)(network_number >> 24); + sendpacket[15] = (unsigned char)((network_number & + 0x00FF0000) >> 16); + sendpacket[16] = (unsigned char)((network_number & + 0x0000FF00) >> 8); + sendpacket[17] = (unsigned char)(network_number & + 0x000000FF); } } - pnetwork_number = (unsigned long) ((sendpacket[26] << 24) + - (sendpacket[27] << 16) + (sendpacket[28] << 8) + - sendpacket[29]); - if (!incoming) { + + + pnetwork_number = (unsigned long)((sendpacket[26] << 24) + + (sendpacket[27] << 16) + (sendpacket[28] << 8) + + sendpacket[29]); + + if( !incoming ) { /* If the source network is ours, make it 0 */ - if (pnetwork_number == network_number) - { - sendpacket[26] = sendpacket[27] = sendpacket[28] = - sendpacket[29] = 0x00; + if( pnetwork_number == network_number) { + sendpacket[26] = sendpacket[27] = sendpacket[28] = + sendpacket[29] = 0x00; } } else { /* If the source network is 0, make it ours */ - if (pnetwork_number == 0) { - sendpacket[26] = (unsigned char) (network_number >> 24); - sendpacket[27] = (unsigned char) ((network_number & - 0x00FF0000) >> 16); - sendpacket[28] = (unsigned char) ((network_number & - 0x0000FF00) >> 8); - sendpacket[29] = (unsigned char) (network_number & - 0x000000FF); + if( pnetwork_number == 0 ) { + sendpacket[26] = (unsigned char)(network_number >> 24); + sendpacket[27] = (unsigned char)((network_number & + 0x00FF0000) >> 16); + sendpacket[28] = (unsigned char)((network_number & + 0x0000FF00) >> 8); + sendpacket[29] = (unsigned char)(network_number & + 0x000000FF); } } -} /* switch_net_numbers */ +} /* switch_net_numbers */ /*============================================================================ - * Get Ethernet-style interface statistics. - * Return a pointer to struct net_device_stats. + * Get ethernet-style interface statistics. + * Return a pointer to struct enet_statistics. */ - -static struct net_device_stats *if_stats(struct net_device *dev) +static struct enet_statistics* if_stats (struct net_device* dev) { - fr_channel_t *chan = dev->priv; - if(chan==NULL) + fr_channel_t* chan = dev->priv; + + if(chan == NULL) return NULL; - + return &chan->ifstats; } /****** Interrupt Handlers **************************************************/ -/*============================================================================ - * S502 frame relay interrupt service routine. - */ -static void fr502_isr(sdla_t * card) -{ - fr502_flags_t *flags = card->flags; - switch (flags->iflag) - { - case 0x01: /* receive interrupt */ - fr502_rx_intr(card); - break; - case 0x02: /* transmit interrupt */ - flags->imask &= ~0x02; - tx_intr(card); - break; - default: - spur_intr(card); - } - flags->iflag = 0; -} /*============================================================================ * S508 frame relay interrupt service routine. */ - -static void fr508_isr(sdla_t * card) +static void fr_isr (sdla_t* card) { - fr508_flags_t *flags = card->flags; - fr_buf_ctl_t *bctl; + fr508_flags_t* flags = card->flags; char *ptr = &flags->iflag; - struct net_device *dev = card->wandev.dev; - struct net_device *dev2; - int i; - unsigned long host_cpu_flags; - unsigned disable_tx_intr = 1; - fr_channel_t *chan; - fr_dlci_interface_t *dlci_interface; + int i,err; + fr_mbox_t* mbox = card->mbox; + /* This flag prevents nesting of interrupts. See sdla_isr() routine - * in sdlamain.c. + * in sdlamain.c. */ card->in_isr = 1; + ++card->statistics.isr_entry; - if (test_and_set_bit(0, (void *) &card->wandev.critical)) - { - printk(KERN_INFO "fr508_isr: %s, wandev.critical set to 0x%02X, int type = 0x%02X\n", card->devname, card->wandev.critical, flags->iflag); - ++card->statistics.isr_already_critical; + + if(test_bit(1, (void*)&card->wandev.critical)) { + card->wandev.critical = 0; + flags->iflag = 0; card->in_isr = 0; return; } - /* For all interrupts set the critical flag to CRITICAL_RX_INTR. - * If the if_send routine is called with this flag set it will set - * the enable transmit flag to 1. (for a delayed interrupt) - */ - card->wandev.critical = CRITICAL_IN_ISR; - card->dlci_int_mode_unbusy = 0; - card->buff_int_mode_unbusy = 0; - switch (flags->iflag) - { - case 0x01: /* receive interrupt */ - ++card->statistics.isr_rx; - fr508_rx_intr(card); - break; - case 0x02: /* transmit interrupt */ - ++card->statistics.isr_tx; - bctl = (void *) (flags->tse_offs - FR_MB_VECTOR + - card->hw.dpmbase); - bctl->flag = 0xA0; - if (card->intr_mode == DLCI_LIST_INTR_MODE) - { - /* Find the structure and make it unbusy */ - dev = find_channel(card, flags->dlci); - dev->tbusy = 0; - /* This is used to perform devtint at the - * end of the isr - */ - card->dlci_int_mode_unbusy = 1; - /* check to see if any other interfaces are - * busy. If so then do not disable the tx - * interrupts - */ - for (dev2 = card->wandev.dev; dev2; - dev2 = dev2->slave) - { - if (dev2->tbusy == 1) - { - disable_tx_intr = 0; - break; - } - } - if (disable_tx_intr) - flags->imask &= ~0x02; - } - else if (card->intr_mode == BUFFER_INTR_MODE) - { - for (dev2 = card->wandev.dev; dev2; - dev2 = dev2->slave) - { - if (!dev2 || !dev2->start) - { - ++card->statistics.tx_intr_dev_not_started; - continue; - } - if (dev2->tbusy) - { - card->buff_int_mode_unbusy = 1; - ((fr_channel_t *) dev2->priv)->dev_pending_devtint = 1; - dev2->tbusy = 0; - } - else - ((fr_channel_t *) dev2->priv)->dev_pending_devtint = 0; - } - flags->imask &= ~0x02; - } - break; - case 0x08: - Intr_test_counter++; + + if(card->hw.type != SDLA_S514) { + if (test_and_set_bit(0, (void*)&card->wandev.critical)) { + printk(KERN_INFO "%s: Critical while in ISR (0x%02X)\n", + card->devname, card->wandev.critical); + ++card->statistics.isr_already_critical; + card->in_isr = 0; + return; + } + } + + switch (flags->iflag) { + + case FR_INTR_RXRDY: /* receive interrupt */ + ++card->statistics.isr_rx; + rx_intr(card); + break; + + + case FR_INTR_TXRDY: /* transmit interrupt */ + ++ card->statistics.isr_tx; + tx_intr(card); + break; + + case FR_INTR_READY: + Intr_test_counter++; ++card->statistics.isr_intr_test; + break; + + case FR_INTR_DLC: /* Event interrupt occured */ + mbox->cmd.command = FR_READ_STATUS; + mbox->cmd.length = 0; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + if (err) + fr_event(card, err, mbox); + break; + + case FR_INTR_TIMER: /* Timer interrupt */ + timer_intr(card); break; + default: - ++card->statistics.isr_spurious; - spur_intr(card); - printk(KERN_INFO "%s: Interrupt Type 0x%02X!\n", - card->devname, flags->iflag); - printk(KERN_INFO "%s: ID Bytes = ", card->devname); - for (i = 0; i < 8; i++) + ++card->statistics.isr_spurious; + spur_intr(card); + printk(KERN_INFO "%s: Interrupt Type 0x%02X!\n", + card->devname, flags->iflag); + + printk(KERN_INFO "%s: ID Bytes = ",card->devname); + for(i = 0; i < 8; i ++) printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i)); - printk(KERN_INFO "\n"); + printk(KERN_INFO "\n"); + break; - } - card->wandev.critical = CRITICAL_INTR_HANDLED; - if (card->wandev.enable_tx_int) - { - if (card->intr_mode == DLCI_LIST_INTR_MODE) - { - for (dev2 = card->wandev.dev; dev2; dev2 = dev2->slave) - { - chan = dev2->priv; - if (chan->tx_int_status == WAITING_TO_BE_ENABLED) - { - dlci_interface = chan->dlci_int_interface; - dlci_interface->gen_interrupt |= 0x40; - dlci_interface->packet_length = chan->pkt_length; - chan->tx_int_status = DISABLED; - } - } - } - card->wandev.enable_tx_int = 0; - flags->imask |= 0x02; - ++card->statistics.isr_enable_tx_int; - } - save_flags(host_cpu_flags); - cli(); + } + card->in_isr = 0; - card->wandev.critical = 0xD1; flags->iflag = 0; - card->wandev.critical = 0; - restore_flags(host_cpu_flags); - /* Device is now ready to send. The instant this is executed the If_Send - routine is called. That is why this is put at the bottom of the ISR - to prevent a endless loop condition caused by repeated Interrupts and - enable_tx_int flag. - */ - if (card->dlci_int_mode_unbusy) - mark_bh(NET_BH); - if (card->buff_int_mode_unbusy) - { - for (;;) - { - if (((fr_channel_t *) ((card->devs_struct)->dev_ptr)->priv)->dev_pending_devtint == 1) - { - ((fr_channel_t *) ((card->devs_struct)->dev_ptr)->priv)->dev_pending_devtint = 0; - mark_bh(NET_BH); - } - if ((card->devs_struct)->next == card->dev_to_devtint_next) - break; - card->devs_struct = (card->devs_struct)->next; - } - card->devs_struct = (card->dev_to_devtint_next)->next; - card->dev_to_devtint_next = card->devs_struct; - } + if(card->hw.type != SDLA_S514) + clear_bit(0, (void*)&card->wandev.critical); } + + + /*============================================================================ * Receive interrupt handler. - */ + * When a receive interrupt occurs do the following: + * 1- Find the structure for the dlci that the interrupt occured on + * 2- If it doesn't exist then print appropriate msg and goto step 8. + * 3- If it exist then copy data to a skb. + * 4- If skb contains Sangoma UDP data then process them + * 5- If skb contains IPXWAN data then send IPXWAN reply packets + * 6- If skb contains Inverse Arp data then send Inv Arp replies + * 7- If skb contains any other data then decapsulate the packet and + * send it to the stack. + * 8- Release the receive element and update receive pointers on the board + */ +static void rx_intr (sdla_t* card) +{ + fr_rx_buf_ctl_t* frbuf = card->rxmb; + fr508_flags_t* flags = card->flags; + fr_channel_t* chan; + char *ptr = &flags->iflag; + struct sk_buff* skb; + struct net_device* dev; + void* buf; + unsigned dlci, len, offs, len_incl_hdr; + int i, udp_type; + + if (frbuf->flag != 0x01) { + + printk(KERN_INFO + "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n", + card->devname, (unsigned)frbuf, frbuf->flag); + + printk(KERN_INFO "%s: ID Bytes = ",card->devname); + for(i = 0; i < 8; i ++) + printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i)); + printk(KERN_INFO "\n"); + + ++card->statistics.rx_intr_corrupt_rx_bfr; + return; + } + + len = frbuf->length; + dlci = frbuf->dlci; + offs = frbuf->offset; -static void fr502_rx_intr(sdla_t * card) -{ - fr_mbox_t *mbox = card->rxmb; - struct sk_buff *skb; - struct net_device *dev; - fr_channel_t *chan; - unsigned dlci, len; - void *buf; - unsigned char *sendpacket; - unsigned char buf2[3]; - int udp_type; - sdla_mapmem(&card->hw, FR502_RX_VECTOR); - dlci = mbox->cmd.dlci; - len = mbox->cmd.length; /* Find network interface for this packet */ dev = find_channel(card, dlci); - if (dev == NULL) - { - /* Invalid channel, discard packet */ - printk(KERN_INFO "%s: receiving on orphaned DLCI %d!\n", - card->devname, dlci); - sdla_mapmem(&card->hw, FR_MB_VECTOR); - } - chan = dev->priv; - if (!dev->start) - { - ++chan->ifstats.rx_dropped; - sdla_mapmem(&card->hw, FR_MB_VECTOR); - } - /* Allocate socket buffer */ - skb = dev_alloc_skb(len); - if (skb == NULL) - { - printk(KERN_INFO "%s: no socket buffers available!\n", - card->devname); - ++chan->ifstats.rx_dropped; - sdla_mapmem(&card->hw, FR_MB_VECTOR); - } - /* Copy data to the socket buffer */ - buf = skb_put(skb, len); - memcpy(buf, mbox->data, len); - sdla_mapmem(&card->hw, FR_MB_VECTOR); - /* Check if it's a UDP management packet */ - sendpacket = skb->data; - memcpy(&buf2, &card->wandev.udp_port, 2); - udp_type = udp_pkt_type(skb, card); - if ((udp_type == UDP_FPIPE_TYPE) || (udp_type == UDP_DRVSTATS_TYPE)) - { - if (udp_type == UDP_DRVSTATS_TYPE) - { - ++chan->rx_intr_DRVSTATS_request; - process_udp_driver_call(UDP_PKT_FRM_NETWORK, card, skb, - dev, dlci, chan); - } - else - { - ++chan->rx_intr_FPIPE_request; - process_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK, card, skb, - dev, dlci, chan); - } - } - else - { - /* Decapsulate packet and pass it up the protocol stack */ - skb->dev = dev; - buf = skb_pull(skb, 1); /* remove hardware header */ - if (!wanrouter_type_trans(skb, dev)) - { - /* can't decapsulate packet */ - dev_kfree_skb(skb); - ++chan->ifstats.rx_errors; - ++card->wandev.stats.rx_errors; - } - else - { - netif_rx(skb); - ++chan->ifstats.rx_packets; - ++card->wandev.stats.rx_packets; - chan->ifstats.rx_bytes += skb->len; - card->wandev.stats.rx_bytes += skb->len; - } - } - sdla_mapmem(&card->hw, FR_MB_VECTOR); -} -/*============================================================================ - * Receive interrupt handler. - */ + + if (dev == NULL) { -static void fr508_rx_intr(sdla_t * card) -{ - fr_buf_ctl_t *frbuf = card->rxmb; - struct sk_buff *skb; - struct net_device *dev; - fr_channel_t *chan; - unsigned dlci, len, offs; - void *buf; - unsigned rx_count = 0; - fr508_flags_t *flags = card->flags; - char *ptr = &flags->iflag; - int i, err, udp_type; - if (frbuf->flag != 0x01) - { - printk(KERN_INFO - "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n", - card->devname, (unsigned) frbuf, frbuf->flag); - printk(KERN_INFO "%s: ID Bytes = ", card->devname); - for (i = 0; i < 8; i++) - printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i)); - printk(KERN_INFO "\n"); - ++card->statistics.rx_intr_corrupt_rx_bfr; - return; - } - - do - { - len = frbuf->length; - dlci = frbuf->dlci; - offs = frbuf->offset; - /* Find network interface for this packet */ - dev = find_channel(card, dlci); + /* unconfigured DLCI, so discard packet */ + printk(KERN_INFO "%s: received data on unconfigured DLCI %d!\n", + card->devname, dlci); + ++card->statistics.rx_intr_on_orphaned_DLCI; + + } else { chan = dev->priv; - if (dev == NULL) - { - /* Invalid channel, discard packet */ - printk(KERN_INFO "%s: receiving on orphaned DLCI %d!\n" - ,card->devname, dlci); - ++card->statistics.rx_intr_on_orphaned_DLCI; - } - else - { - skb = dev_alloc_skb(len); - if (!dev->start || (skb == NULL)) - { - ++chan->ifstats.rx_dropped; - if (dev->start) - { - printk(KERN_INFO - "%s: no socket buffers available!\n", - card->devname); - ++chan->rx_intr_no_socket; - } else - ++chan->rx_intr_dev_not_started; + + skb = dev_alloc_skb(len); + + if (!dev->start || (skb == NULL)) { + ++chan->ifstats.rx_dropped; + + if(dev->start) { + + printk(KERN_INFO + "%s: no socket buffers available!\n", + card->devname); + chan->drvstats_rx_intr.rx_intr_no_socket ++; + + } else + chan->drvstats_rx_intr. + rx_intr_dev_not_started ++; + } else { + /* Copy data to the socket buffer */ + if ((offs + len) > card->u.f.rx_top + 1) { + unsigned tmp = card->u.f.rx_top - offs + 1; + + buf = skb_put(skb, tmp); + sdla_peek(&card->hw, offs, buf, tmp); + offs = card->u.f.rx_base; + len -= tmp; + } + + buf = skb_put(skb, len); + sdla_peek(&card->hw, offs, buf, len); + + udp_type = udp_pkt_type( skb, card ); + + if(udp_type != UDP_INVALID_TYPE) { + if(store_udp_mgmt_pkt(udp_type, + UDP_PKT_FRM_NETWORK, card, skb, dlci)) { + flags->imask |= FR_INTR_TIMER; + if (udp_type == UDP_FPIPE_TYPE){ + chan->drvstats_rx_intr. + rx_intr_PIPE_request ++; + } + } } - else - { - /* Copy data to the socket buffer */ - if ((offs + len) > card->u.f.rx_top + 1) - { - unsigned tmp = card->u.f.rx_top - offs + 1; - buf = skb_put(skb, tmp); - sdla_peek(&card->hw, offs, buf, tmp); - offs = card->u.f.rx_base; - len -= tmp; - } - buf = skb_put(skb, len); - sdla_peek(&card->hw, offs, buf, len); - udp_type = udp_pkt_type(skb, card); - if (udp_type == UDP_DRVSTATS_TYPE) - { - ++chan->rx_intr_DRVSTATS_request; - process_udp_driver_call( - UDP_PKT_FRM_NETWORK, card, skb, - dev, dlci, chan); + + else if (chan->usedby == API) { + api_rx_hdr_t* api_rx_hdr; + chan->drvstats_rx_intr. + rx_intr_bfr_passed_to_stack ++; + chan->ifstats.rx_packets ++; + card->wandev.stats.rx_packets ++; + chan->ifstats.rx_bytes += skb->len; + card->wandev.stats.rx_bytes += skb->len; + + skb_push(skb, sizeof(api_rx_hdr_t)); + api_rx_hdr = (api_rx_hdr_t*)&skb->data[0x00]; + api_rx_hdr->attr = frbuf->attr; + api_rx_hdr->time_stamp = frbuf->tmstamp; + skb->protocol = htons(0x16); + skb->pkt_type = PACKET_HOST; + /* Pass it up the protocol stack */ + skb->dev = dev; + skb->mac.raw = skb->data; + netif_rx(skb); + + } else if (handle_IPXWAN(skb->data,chan->name, + chan->enable_IPX, chan->network_number)) { + if (chan->enable_IPX) { + fr_send(card, dlci, 0, skb->len, + skb->data); } - else if (udp_type == UDP_FPIPE_TYPE) - { - ++chan->rx_intr_FPIPE_request; - err = process_udp_mgmt_pkt( - UDP_PKT_FRM_NETWORK, card, - skb, dev, dlci, chan); + dev_kfree_skb(skb); + +/*FIXME: Fix the ARPS in next release + + } else if (is_arp(skb->data)) { + if (process_ARP((arphdr_1490_t *)skb->data, card, dev)) { + printk (KERN_INFO "%s: Error processing ARP Packet.\n", card->devname); } - else if (handle_IPXWAN(skb->data, card->devname, card->wandev.enable_IPX, card->wandev.network_number)) - { - if (card->wandev.enable_IPX) - fr508_send(card, dlci, 0, skb->len, skb->data); - } - else - { - /* Decapsulate packet and pass it up the - protocol stack */ - skb->dev = dev; - /* remove hardware header */ - buf = skb_pull(skb, 1); - if (!wanrouter_type_trans(skb, dev)) - { - /* can't decapsulate packet */ - dev_kfree_skb(skb); - ++chan-> - rx_intr_bfr_not_passed_to_stack; - ++chan-> - ifstats.rx_errors; - ++card-> - wandev.stats.rx_errors; - } - else - { - netif_rx(skb); - ++chan->rx_intr_bfr_passed_to_stack; - ++chan->ifstats.rx_packets; - ++card->wandev.stats.rx_packets; - chan->ifstats.rx_bytes += skb->len; - card->wandev.stats.rx_bytes += skb->len; - } + dev_kfree_skb(skb); +*/ + + } else if ( skb->data[0] != 0x03) { + printk(KERN_INFO "%s: Non IETF packet discarded.\n", card->devname); + dev_kfree_skb(skb); + + } else { + + len_incl_hdr = skb->len; + /* Decapsulate packet and pass it up the + protocol stack */ + skb->dev = dev; + + /* remove hardware header */ + buf = skb_pull(skb, 1); + + if (!wanrouter_type_trans(skb, dev)) { + + /* can't decapsulate packet */ + dev_kfree_skb(skb); + chan->drvstats_rx_intr. + rx_intr_bfr_not_passed_to_stack ++; + ++ chan->ifstats.rx_errors; + ++ card->wandev.stats.rx_errors; + + } else { + netif_rx(skb); + chan->drvstats_rx_intr. + rx_intr_bfr_passed_to_stack ++; + ++ chan->ifstats.rx_packets; + ++ card->wandev.stats.rx_packets; + chan->ifstats.rx_bytes += len_incl_hdr; + card->wandev.stats.rx_bytes += + len_incl_hdr; } - } - } - /* Release buffer element and calculate a pointer to the next - one */ - frbuf->flag = 0; - card->rxmb = ++frbuf; - if ((void *) frbuf > card->u.f.rxmb_last) - card->rxmb = card->u.f.rxmb_base; - /* The loop put in is temporary, that is why the break is - * placed here. (?????) - */ - break; - frbuf = card->rxmb; - } - while (frbuf->flag && ((++rx_count) < 4)); + } + } + } + + /* Release buffer element and calculate a pointer to the next one */ + frbuf->flag = 0; + card->rxmb = ++frbuf; + if ((void*)frbuf > card->u.f.rxmb_last) + card->rxmb = card->u.f.rxmb_base; + } + /*============================================================================ * Transmit interrupt handler. - * o print a warning - * o - * If number of spurious interrupts exceeded some limit, then ??? */ -static void tx_intr(sdla_t * card) +static void tx_intr(sdla_t *card) { - struct net_device *dev = card->wandev.dev; - if (card->intr_mode == BUFFER_INTR_MODE) - { - for (; dev; dev = dev->slave) - { - if (!dev || !dev->start) - { - ++card->statistics.tx_intr_dev_not_started; - continue; + fr508_flags_t* flags = card->flags; + fr_tx_buf_ctl_t* bctl; + struct net_device* dev = card->wandev.dev; + fr_channel_t* chan; + + if(card->hw.type == SDLA_S514){ + bctl = (void*)(flags->tse_offs + card->hw.dpmbase); + }else{ + bctl = (void*)(flags->tse_offs - FR_MB_VECTOR + + card->hw.dpmbase); + } + + /* Find the structure and make it unbusy */ + dev = find_channel(card, flags->dlci); + chan = dev->priv; + + if(!chan->transmit_length) { + printk(KERN_INFO "%s: tx int error - transmit length zero\n", + card->wandev.name); + return; + } + + /* If the 'if_send()' procedure is currently checking the 'tbusy' + status, then we cannot transmit. Instead, we configure the microcode + so as to re-issue this transmit interrupt at a later stage. + */ + if (test_bit(2, (void*)&card->wandev.critical)) { + fr_dlci_interface_t* dlci_interface = chan->dlci_int_interface; + bctl->flag = 0xA0; + dlci_interface->gen_interrupt |= FR_INTR_TXRDY; + printk(KERN_INFO "%s: TX Interrupt Detected busy if_send\n",card->devname); + + } else { + bctl->dlci = flags->dlci; + bctl->length = chan->transmit_length; + sdla_poke(&card->hw, bctl->offset, chan->transmit_buffer, + chan->transmit_length); + bctl->flag = 0xC0; + + ++chan->ifstats.tx_packets; + ++card->wandev.stats.tx_packets; + chan->ifstats.tx_bytes += chan->transmit_length; + card->wandev.stats.tx_bytes += chan->transmit_length; + chan->transmit_length = 0; + + /* if any other interfaces have transmit interrupts pending, */ + /* do not disable the global transmit interrupt */ + if(!(-- card->u.f.tx_interrupts_pending)) + flags->imask &= ~FR_INTR_TXRDY; + + dev->tbusy = 0; + mark_bh(NET_BH); + } +} + + +/*============================================================================ + * Timer interrupt handler. + FIXME: update comments as we modify the code + * The timer interrupt is used for three purposes: + * 1) Processing udp calls from 'fpipemon'. + * 2) Processing update calls from /proc file system + * 2) Reading board-level statistics for updating the proc file system. + * 3) Sending inverse ARP request packets. + */ +static void timer_intr(sdla_t *card) +{ + fr508_flags_t* flags = card->flags; + + if(card->u.f.timer_int_enabled & TMR_INT_ENABLED_UDP) { + if(card->u.f.udp_type == UDP_FPIPE_TYPE) { + if(process_udp_mgmt_pkt(card)) { + card->u.f.timer_int_enabled &= + ~TMR_INT_ENABLED_UDP; } - dev->tbusy = 0; - mark_bh(NET_BH); } + } + + if(card->u.f.timer_int_enabled & TMR_INT_ENABLED_UPDATE) { + fr_get_err_stats(card); + fr_get_stats(card); + card->u.f.update_comms_stats = 0; + card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_UPDATE; } - else - { - dev->tbusy = 0; - mark_bh(NET_BH); + + +//FIXME: Fix the dynamic IP addressing +/* +goto L4; + + // Used to send inarp request at given interval + if (card->wandev.state == WAN_CONNECTED) { + int num_remaining = 0; + for (dev=card->wandev.dev;dev;dev=dev->slave) { + fr_channel_t *chan = dev->priv; + + if (chan->inarp == INARP_REQUEST && + chan->state == WAN_CONNECTED) { + num_remaining++; + + if ((jiffies - chan->inarp_tick) > (chan->inarp_interval * HZ)) { + send_inarp_request(card,dev); + chan->inarp_tick = jiffies; + } + } + } + if (!num_remaining) { // no more to process + flags->imask &= ~FR_INTR_TIMER; + } } +L4: + ; +*/ + if(!card->u.f.timer_int_enabled) + flags->imask &= ~FR_INTR_TIMER; } + /*============================================================================ * Spurious interrupt handler. * o print a warning * o - * If number of spurious interrupts exceeded some limit, then ??? */ - -static void spur_intr(sdla_t * card) +static void spur_intr (sdla_t* card) { printk(KERN_INFO "%s: spurious interrupt!\n", card->devname); } -/* - Return 0 for non-IPXWAN packet - 1 for IPXWAN packet or IPX is not enabled! +//FIXME: Fix the IPX in next version +/*=========================================================================== + * Return 0 for non-IPXWAN packet + * 1 for IPXWAN packet or IPX is not enabled! + * FIXME: Use a IPX structure here not offsets */ - static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number) { int i; - if (sendpacket[1] == 0x00 && + + if( sendpacket[1] == 0x00 && sendpacket[2] == 0x80 && sendpacket[6] == 0x81 && - sendpacket[7] == 0x37) - { + sendpacket[7] == 0x37) { + /* It's an IPX packet */ - if (!enable_IPX) { + if(!enable_IPX) { /* Return 1 so we don't pass it up the stack. */ + //FIXME: Take this out when IPX is fixed + printk (KERN_INFO + "%s: WARNING: Unsupported IPX packet received and dropped\n", + devname); return 1; } - } - else - { + } else { /* It's not IPX so return and pass it up the stack. */ return 0; } - if (sendpacket[24] == 0x90 && - sendpacket[25] == 0x04) + + if( sendpacket[24] == 0x90 && + sendpacket[25] == 0x04) { /* It's IPXWAN */ - if (sendpacket[10] == 0x02 && - sendpacket[42] == 0x00) + + if( sendpacket[10] == 0x02 && + sendpacket[42] == 0x00) { /* It's a timer request packet */ - printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n", devname); - /* Go through the routing options and answer no to every */ - /* option except Unnumbered RIP/SAP */ - for (i = 49; sendpacket[i] == 0x00; i += 5) + printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n",devname); + + /* Go through the routing options and answer no to every + * option except Unnumbered RIP/SAP + */ + for(i = 49; sendpacket[i] == 0x00; i += 5) { /* 0x02 is the option for Unnumbered RIP/SAP */ - if (sendpacket[i + 4] != 0x02) + if( sendpacket[i + 4] != 0x02) { sendpacket[i + 1] = 0; } } + /* Skip over the extended Node ID option */ - if (sendpacket[i] == 0x04) + if( sendpacket[i] == 0x04 ) + { i += 8; - /* We also want to turn off all header compression opt. */ - for (; sendpacket[i] == 0x80;) + } + + /* We also want to turn off all header compression opt. + */ + for(; sendpacket[i] == 0x80 ;) { sendpacket[i + 1] = 0; i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4; } + /* Set the packet type to timer response */ sendpacket[42] = 0x01; - printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n", devname); + + printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n",devname); } - else if (sendpacket[42] == 0x02) + else if( sendpacket[42] == 0x02 ) { /* This is an information request packet */ - printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n", devname); + printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n",devname); + /* Set the packet type to information response */ sendpacket[42] = 0x03; + /* Set the router name */ sendpacket[59] = 'F'; sendpacket[60] = 'P'; @@ -1756,465 +2082,558 @@ sendpacket[63] = 'E'; sendpacket[64] = '-'; sendpacket[65] = CVHexToAscii(network_number >> 28); - sendpacket[66] = CVHexToAscii((network_number & 0x0F000000) >> 24); - sendpacket[67] = CVHexToAscii((network_number & 0x00F00000) >> 20); - sendpacket[68] = CVHexToAscii((network_number & 0x000F0000) >> 16); - sendpacket[69] = CVHexToAscii((network_number & 0x0000F000) >> 12); - sendpacket[70] = CVHexToAscii((network_number & 0x00000F00) >> 8); - sendpacket[71] = CVHexToAscii((network_number & 0x000000F0) >> 4); + sendpacket[66] = CVHexToAscii((network_number & 0x0F000000)>> 24); + sendpacket[67] = CVHexToAscii((network_number & 0x00F00000)>> 20); + sendpacket[68] = CVHexToAscii((network_number & 0x000F0000)>> 16); + sendpacket[69] = CVHexToAscii((network_number & 0x0000F000)>> 12); + sendpacket[70] = CVHexToAscii((network_number & 0x00000F00)>> 8); + sendpacket[71] = CVHexToAscii((network_number & 0x000000F0)>> 4); sendpacket[72] = CVHexToAscii(network_number & 0x0000000F); - for (i = 73; i < 107; i += 1) + for(i = 73; i < 107; i+= 1) + { sendpacket[i] = 0; - printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n", devname); + } + + printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n",devname); } else { - printk(KERN_INFO "%s: Unknown IPXWAN packet!\n", devname); + printk(KERN_INFO "%s: Unknown IPXWAN packet!\n",devname); return 0; } + /* Set the WNodeID to our network address */ - sendpacket[43] = (unsigned char) (network_number >> 24); - sendpacket[44] = (unsigned char) ((network_number & 0x00FF0000) >> 16); - sendpacket[45] = (unsigned char) ((network_number & 0x0000FF00) >> 8); - sendpacket[46] = (unsigned char) (network_number & 0x000000FF); + sendpacket[43] = (unsigned char)(network_number >> 24); + sendpacket[44] = (unsigned char)((network_number & 0x00FF0000) >> 16); + sendpacket[45] = (unsigned char)((network_number & 0x0000FF00) >> 8); + sendpacket[46] = (unsigned char)(network_number & 0x000000FF); + return 1; } - /* If we get here, its an IPX-data packet so it'll get passed up the stack. */ - /* switch the network numbers */ - switch_net_numbers(sendpacket, network_number, 1); + + /* If we get here, its an IPX-data packet so it'll get passed up the + * stack. + * switch the network numbers + */ + switch_net_numbers(sendpacket, network_number ,1); return 0; } +/*============================================================================ + * Process Route. + * This routine is called as a polling routine to dynamically add/delete routes + * negotiated by inverse ARP. It is in this "task" because we don't want routes + * to be added while in interrupt context. +*/ + +static void process_route (sdla_t* card) +{ + struct net_device* dev; + struct in_device *in_dev; + struct rtentry route; + int err = 0; + mm_segment_t fs; + + + /* Dynamic Route adding/removing */ + for (dev = card->wandev.dev; dev ; dev = dev->slave) { + if ( ((fr_channel_t*)dev->priv)->route_flag == ADD_ROUTE || + ((fr_channel_t*)dev->priv)->route_flag == REMOVE_ROUTE ) { + fs = get_fs(); + + in_dev = dev->ip_ptr; -/****** Background Polling Routines ****************************************/ + if( in_dev != NULL && in_dev->ifa_list != NULL) { + memset(&route, 0, sizeof(route)); + route.rt_dev = dev->name; + route.rt_flags = 0; + + ((struct sockaddr_in *) &(route.rt_dst)) -> + sin_addr.s_addr=in_dev->ifa_list->ifa_address; + ((struct sockaddr_in *) &(route.rt_dst)) -> + sin_family = AF_INET; + ((struct sockaddr_in *) &(route.rt_genmask)) -> + sin_addr.s_addr = 0xFFFFFFFF; + ((struct sockaddr_in *) &(route.rt_genmask)) -> + sin_family = AF_INET; + + switch(((fr_channel_t*)dev->priv)->route_flag) { + + case ADD_ROUTE: + set_fs(get_ds()); /* get user space block */ + err = ip_rt_ioctl( SIOCADDRT, &route); + set_fs(fs); /* restore old block */ + + if (err) { + printk(KERN_INFO "%s: Adding of route failed. Error: %d\n", card->devname,err); + printk(KERN_INFO "%s: Address: %s\n", + ((fr_channel_t*)dev->priv)->name, + in_ntoa(in_dev->ifa_list->ifa_address) ); + } + else { + ((fr_channel_t*)dev->priv)-> + route_flag = ROUTE_ADDED; + } + break; -/*============================================================================ - * Main polling routine. - * This routine is repeatedly called by the WANPIPE 'thead' to allow for - * time-dependent housekeeping work. - * - * o fetch asynchronous network events. - * - * Notes: - * 1. This routine may be called on interrupt context with all interrupts - * enabled. Beware! - */ + case REMOVE_ROUTE: + set_fs(get_ds()); /* get user space block */ + err = ip_rt_ioctl( SIOCDELRT, &route); + set_fs(fs); /* restore old block */ + + if (err) { + printk(KERN_INFO "%s: Deleting of route failed. Error: %d\n", card->devname,err); + printk(KERN_INFO "%s: Address: %s\n", + dev->name,in_ntoa(in_dev->ifa_list->ifa_address) ); + } else { + printk(KERN_INFO "%s: Removed route.\n", + ((fr_channel_t*)dev->priv)->name); + ((fr_channel_t*)dev->priv)->route_flag = NO_ROUTE; + } + break; + } /* Case Statement */ + } + } /* If ADD/DELETE ROUTE */ + } /* Device 'For' Loop */ -static void wpf_poll(sdla_t * card) -{ -/* struct net_device* dev = card->wandev.dev; */ - fr508_flags_t *flags = card->flags; - unsigned long host_cpu_flags; - ++card->statistics.poll_entry; - if (((jiffies - card->state_tick) < HZ) || - (card->intr_mode == INTR_TEST_MODE)) - return; - disable_irq(card->hw.irq); - ++card->irq_dis_poll_count; - if (test_and_set_bit(0, (void *) &card->wandev.critical)) - { - ++card->statistics.poll_already_critical; - save_flags(host_cpu_flags); - cli(); - if ((!card->irq_dis_if_send_count) && - (!(--card->irq_dis_poll_count))) - enable_irq(card->hw.irq); - restore_flags(host_cpu_flags); - return; - } - card->wandev.critical = 0x11; - ++card->statistics.poll_processed; - /* This is to be changed later ??? */ - /* - if( dev && dev->tbusy && !(flags->imask & 0x02) ) { - printk(KERN_INFO "%s: Wpf_Poll: tbusy = 0x01, imask = 0x%02X\n", card->devname, flags->imask); - } - */ - if (flags->event) - { - fr_mbox_t *mbox = card->mbox; - int err; - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); - mbox->cmd.command = FR_READ_STATUS; - err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - if (err) - fr_event(card, err, mbox); - } - card->wandev.critical = 0; - save_flags(host_cpu_flags); - cli(); - if ((!card->irq_dis_if_send_count) && (!(--card->irq_dis_poll_count))) - enable_irq(card->hw.irq); - restore_flags(host_cpu_flags); - card->state_tick = jiffies; + card->poll = NULL; } + + /****** Frame Relay Firmware-Specific Functions *****************************/ /*============================================================================ * Read firmware code version. * o fill string str with firmware version info. */ - -static int fr_read_version(sdla_t * card, char *str) +static int fr_read_version (sdla_t* card, char* str) { - fr_mbox_t *mbox = card->mbox; + fr_mbox_t* mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; - do + + do { - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); mbox->cmd.command = FR_READ_CODE_VERSION; + mbox->cmd.length = 0; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; } while (err && retry-- && fr_event(card, err, mbox)); - if (!err && str) - { + if (!err && str) { int len = mbox->cmd.length; memcpy(str, mbox->data, len); - str[len] = '\0'; + str[len] = '\0'; } return err; } + /*============================================================================ * Set global configuration. */ - -static int fr_configure(sdla_t * card, fr_conf_t * conf) +static int fr_configure (sdla_t* card, fr_conf_t *conf) { - fr_mbox_t *mbox = card->mbox; + fr_mbox_t* mbox = card->mbox; int retry = MAX_CMD_RETRY; int dlci_num = card->u.f.dlci_num; int err, i; - do + + do { - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); memcpy(mbox->data, conf, sizeof(fr_conf_t)); - if (dlci_num) - for (i = 0; i < dlci_num; ++i) - ((fr_conf_t *) mbox->data)->dlci[i] = - card->u.f.node_dlci[i]; + + if (dlci_num) for (i = 0; i < dlci_num; ++i) + ((fr_conf_t*)mbox->data)->dlci[i] = + card->u.f.node_dlci[i]; + mbox->cmd.command = FR_SET_CONFIG; mbox->cmd.length = - sizeof(fr_conf_t) + dlci_num * sizeof(short); + sizeof(fr_conf_t) + dlci_num * sizeof(short); + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && retry-- && fr_event(card, err, mbox)); + + } while (err && retry-- && fr_event(card, err, mbox)); return err; } + /*============================================================================ * Set DLCI configuration. */ -static int fr_dlci_configure(sdla_t * card, fr_dlc_conf_t * conf, unsigned dlci) +static int fr_dlci_configure (sdla_t* card, fr_dlc_conf_t *conf, unsigned dlci) { - fr_mbox_t *mbox = card->mbox; + fr_mbox_t* mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; + do { - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); memcpy(mbox->data, conf, sizeof(fr_dlc_conf_t)); - mbox->cmd.dlci = (unsigned short) dlci; + mbox->cmd.dlci = (unsigned short) dlci; mbox->cmd.command = FR_SET_CONFIG; - mbox->cmd.length = 0x0E; + mbox->cmd.length = sizeof(fr_dlc_conf_t); err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && retry--); + } while (err && retry--); + return err; } /*============================================================================ * Set interrupt mode. */ -static int fr_set_intr_mode(sdla_t * card, unsigned mode, unsigned mtu) +static int fr_set_intr_mode (sdla_t* card, unsigned mode, unsigned mtu, + unsigned short timeout) { - fr_mbox_t *mbox = card->mbox; + fr_mbox_t* mbox = card->mbox; + fr508_intr_ctl_t* ictl = (void*)mbox->data; int retry = MAX_CMD_RETRY; int err; + do { - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); - if (card->hw.fwid == SFID_FR502) - { - fr502_intr_ctl_t *ictl = (void *) mbox->data; - memset(ictl, 0, sizeof(fr502_intr_ctl_t)); - ictl->mode = mode; - ictl->tx_len = mtu; - mbox->cmd.length = sizeof(fr502_intr_ctl_t); - } - else - { - fr508_intr_ctl_t *ictl = (void *) mbox->data; - memset(ictl, 0, sizeof(fr508_intr_ctl_t)); - ictl->mode = mode; - ictl->tx_len = mtu; - ictl->irq = card->hw.irq; - mbox->cmd.length = sizeof(fr508_intr_ctl_t); - } + memset(ictl, 0, sizeof(fr508_intr_ctl_t)); + ictl->mode = mode; + ictl->tx_len = mtu; + ictl->irq = card->hw.irq; + + /* indicate timeout on timer */ + if (mode & 0x20) ictl->timeout = timeout; + + mbox->cmd.length = sizeof(fr508_intr_ctl_t); mbox->cmd.command = FR_SET_INTR_MODE; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && retry-- && fr_event(card, err, mbox)); + + } while (err && retry-- && fr_event(card, err, mbox)); return err; } + /*============================================================================ * Enable communications. */ -static int fr_comm_enable(sdla_t * card) +static int fr_comm_enable (sdla_t* card) { - fr_mbox_t *mbox = card->mbox; + fr_mbox_t* mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; - do + + do { - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); mbox->cmd.command = FR_COMM_ENABLE; + mbox->cmd.length = 0; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && retry-- && fr_event(card, err, mbox)); + } while (err && retry-- && fr_event(card, err, mbox)); return err; } + /*============================================================================ * Disable communications. */ -static int fr_comm_disable(sdla_t * card) +static int fr_comm_disable (sdla_t* card) { - fr_mbox_t *mbox = card->mbox; + fr_mbox_t* mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; + do { - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); mbox->cmd.command = FR_COMM_DISABLE; + mbox->cmd.length = 0; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && retry-- && fr_event(card, err, mbox)); + } while (err && retry-- && fr_event(card, err, mbox)); + + retry = MAX_CMD_RETRY; + + do { + mbox->cmd.command = FR_SET_MODEM_STATUS; + mbox->cmd.length = 1; + mbox->data[0] = 0; + err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && fr_event(card, err, mbox)); return err; } + /*============================================================================ * Get communications error statistics. */ -static int fr_get_err_stats(sdla_t * card) +static int fr_get_err_stats (sdla_t* card) { - fr_mbox_t *mbox = card->mbox; + fr_mbox_t* mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; - + + do { - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); mbox->cmd.command = FR_READ_ERROR_STATS; + mbox->cmd.length = 0; + mbox->cmd.dlci = 0; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && retry-- && fr_event(card, err, mbox)); - - if (!err) - { - fr_comm_stat_t *stats = (void *) mbox->data; - card->wandev.stats.rx_over_errors = stats->rx_overruns; - card->wandev.stats.rx_crc_errors = stats->rx_bad_crc; - card->wandev.stats.rx_missed_errors = stats->rx_aborts; - card->wandev.stats.rx_length_errors = stats->rx_too_long; + } while (err && retry-- && fr_event(card, err, mbox)); + + if (!err) { + fr_comm_stat_t* stats = (void*)mbox->data; + card->wandev.stats.rx_over_errors = stats->rx_overruns; + card->wandev.stats.rx_crc_errors = stats->rx_bad_crc; + card->wandev.stats.rx_missed_errors = stats->rx_aborts; + card->wandev.stats.rx_length_errors = stats->rx_too_long; card->wandev.stats.tx_aborted_errors = stats->tx_aborts; + } + return err; } + /*============================================================================ * Get statistics. */ -static int fr_get_stats(sdla_t * card) +static int fr_get_stats (sdla_t* card) { - fr_mbox_t *mbox = card->mbox; + fr_mbox_t* mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; - do + + + do { - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); mbox->cmd.command = FR_READ_STATISTICS; + mbox->cmd.length = 0; + mbox->cmd.dlci = 0; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && retry-- && fr_event(card, err, mbox)); - - if (!err) - { - fr_link_stat_t *stats = (void *) mbox->data; + } while (err && retry-- && fr_event(card, err, mbox)); + + if (!err) { + fr_link_stat_t* stats = (void*)mbox->data; card->wandev.stats.rx_frame_errors = stats->rx_bad_format; - card->wandev.stats.rx_dropped = stats->rx_dropped + stats->rx_dropped2; + card->wandev.stats.rx_dropped = + stats->rx_dropped + stats->rx_dropped2; } + return err; } + /*============================================================================ * Add DLCI(s) (Access Node only!). * This routine will perform the ADD_DLCIs command for the specified DLCI. */ -static int fr_add_dlci(sdla_t * card, int dlci, int num) +static int fr_add_dlci (sdla_t* card, int dlci) { - fr_mbox_t *mbox = card->mbox; + fr_mbox_t* mbox = card->mbox; int retry = MAX_CMD_RETRY; - int err, i; - do + int err; + + do { - unsigned short *dlci_list = (void *) mbox->data; - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); - for (i = 0; i < num; ++i) - dlci_list[i] = card->u.f.node_dlci[i]; - mbox->cmd.length = num * sizeof(short); + unsigned short* dlci_list = (void*)mbox->data; + + mbox->cmd.length = sizeof(short); + dlci_list[0] = dlci; mbox->cmd.command = FR_ADD_DLCI; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && retry-- && fr_event(card, err, mbox)); + + } while (err && retry-- && fr_event(card, err, mbox)); return err; } + /*============================================================================ * Activate DLCI(s) (Access Node only!). - * This routine will perform the ACTIVATE_DLCIs command with a list of DLCIs. + * This routine will perform the ACTIVATE_DLCIs command with a DLCI number. */ -static int fr_activate_dlci(sdla_t * card, int dlci, int num) +static int fr_activate_dlci (sdla_t* card, int dlci) { - fr_mbox_t *mbox = card->mbox; + fr_mbox_t* mbox = card->mbox; int retry = MAX_CMD_RETRY; - int err, i; + int err; + do { - unsigned short *dlci_list = (void *) mbox->data; - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); - for (i = 0; i < num; ++i) - dlci_list[i] = card->u.f.node_dlci[i]; - mbox->cmd.length = num * sizeof(short); + unsigned short* dlci_list = (void*)mbox->data; + + mbox->cmd.length = sizeof(short); + dlci_list[0] = dlci; mbox->cmd.command = FR_ACTIVATE_DLCI; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && retry-- && fr_event(card, err, mbox)); + + } while (err && retry-- && fr_event(card, err, mbox)); return err; } + /*============================================================================ - * Issue in-channel signalling frame. + * Delete DLCI(s) (Access Node only!). + * This routine will perform the DELETE_DLCIs command with a DLCI number. */ -static int fr_issue_isf(sdla_t * card, int isf) +static int fr_delete_dlci (sdla_t* card, int dlci) { - fr_mbox_t *mbox = card->mbox; + fr_mbox_t* mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; + do { - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); - mbox->data[0] = isf; - mbox->cmd.length = 1; - mbox->cmd.command = FR_ISSUE_IS_FRAME; + unsigned short* dlci_list = (void*)mbox->data; + + mbox->cmd.length = sizeof(short); + dlci_list[0] = dlci; + mbox->cmd.command = FR_DELETE_DLCI; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && retry-- && fr_event(card, err, mbox)); + + } while (err && retry-- && fr_event(card, err, mbox)); return err; } + + + /*============================================================================ - * Send a frame (S502 version). + * Issue in-channel signalling frame. */ -static int fr502_send(sdla_t * card, int dlci, int attr, int len, void *buf) +static int fr_issue_isf (sdla_t* card, int isf) { - fr_mbox_t *mbox = card->mbox; + fr_mbox_t* mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; - - do + + do { - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); - memcpy(mbox->data, buf, len); - mbox->cmd.dlci = dlci; - mbox->cmd.attr = attr; - mbox->cmd.length = len; - mbox->cmd.command = FR_WRITE; + mbox->data[0] = isf; + mbox->cmd.length = 1; + mbox->cmd.command = FR_ISSUE_IS_FRAME; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && retry-- && fr_event(card, err, mbox)); + } while (err && retry-- && fr_event(card, err, mbox)); return err; } + /*============================================================================ - * Send a frame (S508 version). + * Send a frame on a selected DLCI. */ -static int fr508_send(sdla_t * card, int dlci, int attr, int len, void *buf) +static int fr_send (sdla_t* card, int dlci, unsigned char attr, int len, + void *buf) { - fr_mbox_t *mbox = card->mbox; + fr_mbox_t* mbox = card->mbox + 0x800; int retry = MAX_CMD_RETRY; int err; - + do { - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); - mbox->cmd.dlci = dlci; - mbox->cmd.attr = attr; - mbox->cmd.length = len; + mbox->cmd.dlci = dlci; + mbox->cmd.attr = attr; + mbox->cmd.length = len; mbox->cmd.command = FR_WRITE; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && retry-- && fr_event(card, err, mbox)); - - if (!err) - { - fr_buf_ctl_t *frbuf = (void *) (*(unsigned long *) mbox->data - - FR_MB_VECTOR + card->hw.dpmbase); - sdla_poke(&card->hw, frbuf->offset, buf, len); - frbuf->flag = 0x01; - } + } while (err && retry-- && fr_event(card, err, mbox)); + + if (!err) { + + fr_tx_buf_ctl_t* frbuf; + + if(card->hw.type == SDLA_S514) + frbuf = (void*)(*(unsigned long*)mbox->data + + card->hw.dpmbase); + else + frbuf = (void*)(*(unsigned long*)mbox->data - + FR_MB_VECTOR + card->hw.dpmbase); + + sdla_poke(&card->hw, frbuf->offset, buf, len); + frbuf->flag = 0x01; + } + return err; } /****** Firmware Asynchronous Event Handlers ********************************/ /*============================================================================ - * Main asynchronous event/error handler. + * Main asyncronous event/error handler. * This routine is called whenever firmware command returns non-zero * return code. * * Return zero if previous command has to be cancelled. */ - -static int fr_event(sdla_t * card, int event, fr_mbox_t * mbox) +static int fr_event (sdla_t *card, int event, fr_mbox_t* mbox) { - fr508_flags_t *flags = card->flags; + fr508_flags_t* flags = card->flags; char *ptr = &flags->iflag; int i; - switch (event) - { + + switch (event) { + case FRRES_MODEM_FAILURE: return fr_modem_failure(card, mbox); + case FRRES_CHANNEL_DOWN: + { + struct net_device *dev; + + /* Remove all routes from associated DLCI's */ + for (dev = card->wandev.dev; dev; dev = dev->slave) { + fr_channel_t *chan = dev->priv; + if (chan->route_flag == ROUTE_ADDED) { + chan->route_flag = REMOVE_ROUTE; + card->poll = &process_route; + } + + if (chan->inarp == INARP_CONFIGURED) { + chan->inarp = INARP_REQUEST; + } + } + wanpipe_set_state(card, WAN_DISCONNECTED); return 1; + } + case FRRES_CHANNEL_UP: + { + struct net_device *dev; + int num_requests = 0; + + /* Remove all routes from associated DLCI's */ + for (dev = card->wandev.dev; dev; dev = dev->slave) { + fr_channel_t *chan = dev->priv; + if( chan->inarp == INARP_REQUEST ){ + num_requests++; + chan->inarp_tick = jiffies; + } + } + + /* Allow timer interrupts */ + if (num_requests) flags->imask |= 0x20; wanpipe_set_state(card, WAN_CONNECTED); return 1; + } + case FRRES_DLCI_CHANGE: return fr_dlci_change(card, mbox); + case FRRES_DLCI_MISMATCH: - printk(KERN_INFO "%s: DLCI list mismatch!\n", - card->devname); + printk(KERN_INFO "%s: DLCI list mismatch!\n", + card->devname); return 1; + case CMD_TIMEOUT: printk(KERN_ERR "%s: command 0x%02X timed out!\n", - card->devname, mbox->cmd.command); - printk(KERN_INFO "%s: ID Bytes = ", card->devname); - for (i = 0; i < 8; i++) - printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i)); - printk(KERN_INFO "\n"); + card->devname, mbox->cmd.command); + printk(KERN_INFO "%s: ID Bytes = ",card->devname); + for(i = 0; i < 8; i ++) + printk(KERN_INFO "0x%02X ", *(ptr + 0x18 + i)); + printk(KERN_INFO "\n"); + break; + case FRRES_DLCI_INACTIVE: - printk(KERN_ERR "%s: DLCI %u is inactive!\n", - card->devname, mbox->cmd.dlci); break; + case FRRES_CIR_OVERFLOW: break; case FRRES_BUFFER_OVERFLOW: - break; + break; default: printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n" - ,card->devname, mbox->cmd.command, event); + , card->devname, mbox->cmd.command, event); } + return 0; } @@ -2223,178 +2642,228 @@ * * Return zero if previous command has to be cancelled. */ -static int fr_modem_failure(sdla_t * card, fr_mbox_t * mbox) +static int fr_modem_failure (sdla_t *card, fr_mbox_t* mbox) { printk(KERN_INFO "%s: physical link down! (modem error 0x%02X)\n", - card->devname, mbox->data[0]); - switch (mbox->cmd.command) - { + card->devname, mbox->data[0]); + + switch (mbox->cmd.command){ case FR_WRITE: + case FR_READ: return 0; } + return 1; } + /*============================================================================ * Handle DLCI status change. * * Return zero if previous command has to be cancelled. */ -static int fr_dlci_change(sdla_t * card, fr_mbox_t * mbox) +static int fr_dlci_change (sdla_t *card, fr_mbox_t* mbox) { - dlci_status_t *status = (void *) mbox->data; + dlci_status_t* status = (void*)mbox->data; int cnt = mbox->cmd.length / sizeof(dlci_status_t); - fr_dlc_conf_t cfg; fr_channel_t *chan; - struct net_device *dev2; - for (; cnt; --cnt, ++status) - { - unsigned short dlci = status->dlci; - struct net_device *dev = find_channel(card, dlci); - if (dev == NULL) - { - printk(KERN_INFO - "%s: CPE contains unconfigured DLCI= %d\n", - card->devname, dlci); - } - else - { - if (status->state & 0x01) - { + struct net_device* dev2; + + + for (; cnt; --cnt, ++status) { + + unsigned short dlci= status->dlci; + struct net_device* dev = find_channel(card, dlci); + + if (dev == NULL){ + printk(KERN_INFO + "%s: CPE contains unconfigured DLCI= %d\n", + card->devname, dlci); + + printk(KERN_INFO + "%s: unconfigured DLCI %d reported by network\n" + , card->devname, dlci); + + }else{ + if (status->state == FR_LINK_INOPER) { printk(KERN_INFO - "%s: DLCI %u has been deleted!\n", - card->devname, dlci); + "%s: DLCI %u is inactive!\n", + card->devname, dlci); + if (dev && dev->start) set_chan_state(dev, WAN_DISCONNECTED); } - else if (status->state & 0x02) - { + + if (status->state & FR_DLCI_DELETED) { + printk(KERN_INFO - "%s: DLCI %u becomes active!\n", - card->devname, dlci); + "%s: DLCI %u has been deleted!\n", + card->devname, dlci); + + if (dev && dev->start) { + fr_channel_t *chan = dev->priv; + + if (chan->route_flag == ROUTE_ADDED) { + chan->route_flag = REMOVE_ROUTE; + card->poll = &process_route; + } + + if (chan->inarp == INARP_CONFIGURED) { + chan->inarp = INARP_REQUEST; + } + + set_chan_state(dev, WAN_DISCONNECTED); + } + + } else if (status->state & FR_DLCI_ACTIVE) { + chan = dev->priv; + /* This flag is used for configuring specific DLCI(s) when they become active. - */ + */ chan->dlci_configured = DLCI_CONFIG_PENDING; + if (dev && dev->start) set_chan_state(dev, WAN_CONNECTED); + } } } - for (dev2 = card->wandev.dev; dev2; dev2 = dev2->slave) - { + + for (dev2 =card->wandev.dev; dev2; dev2 = dev2->slave){ + chan = dev2->priv; - if (chan->dlci_configured == DLCI_CONFIG_PENDING) - { - memset(&cfg, 0, sizeof(cfg)); - if (chan->cir_status == CIR_DISABLED) - { - cfg.cir_fwd = cfg.cir_bwd = 16; - cfg.bc_fwd = cfg.bc_bwd = 16; - cfg.conf_flags = 0x0001; - printk(KERN_INFO "%s: CIR Disabled for %s\n", - card->devname, chan->name); - } else if (chan->cir_status == CIR_ENABLED) { - cfg.cir_fwd = cfg.cir_bwd = chan->cir; - cfg.bc_fwd = cfg.bc_bwd = chan->bc; - cfg.be_fwd = cfg.be_bwd = chan->be; - cfg.conf_flags = 0x0000; - printk(KERN_INFO "%s: CIR Enabled for %s\n", - card->devname, chan->name); - } - if (fr_dlci_configure(card, &cfg, chan->dlci)) - { - printk(KERN_INFO - "%s: DLCI Configure failed for %d\n", - card->devname, chan->dlci); + + if (chan->dlci_configured == DLCI_CONFIG_PENDING) { + if (fr_init_dlci(card, chan)){ return 1; } - chan->dlci_configured = DLCI_CONFIGURED; - /* Read the interface byte mapping into the channel - structure. - */ - if (card->intr_mode == DLCI_LIST_INTR_MODE) - read_DLCI_IB_mapping(card, chan); } + } return 1; } + + +static int fr_init_dlci (sdla_t *card, fr_channel_t *chan) +{ + fr_dlc_conf_t cfg; + fr508_flags_t* flags = card->flags; + + memset(&cfg, 0, sizeof(cfg)); + + if ( chan->cir_status == CIR_DISABLED) { + + cfg.cir_fwd = cfg.cir_bwd = 16; + cfg.bc_fwd = cfg.bc_bwd = 16; + cfg.conf_flags = 0x0001; + + }else if (chan->cir_status == CIR_ENABLED) { + + cfg.cir_fwd = cfg.cir_bwd = chan->cir; + cfg.bc_fwd = cfg.bc_bwd = chan->bc; + cfg.be_fwd = cfg.be_bwd = chan->be; + cfg.conf_flags = 0x0000; + } + + if (fr_dlci_configure( card, &cfg , chan->dlci)){ + printk(KERN_INFO + "%s: DLCI Configure failed for %d\n", + card->devname, chan->dlci); + return 1; + } + + chan->dlci_configured = DLCI_CONFIGURED; + + /* Allow timer interrupts */ + if( chan->inarp == INARP_REQUEST && card->wandev.state == WAN_CONNECTED) { + chan->inarp_tick = jiffies; + flags->imask |= 0x20; + } + + /* Read the interface byte mapping into the channel + structure. + */ + read_DLCI_IB_mapping( card, chan ); + + return 0; +} /******* Miscellaneous ******************************************************/ /*============================================================================ * Update channel state. */ -static int update_chan_state(struct net_device *dev) +static int update_chan_state (struct net_device* dev) { - fr_channel_t *chan = dev->priv; - sdla_t *card = chan->card; - fr_mbox_t *mbox = card->mbox; + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; + fr_mbox_t* mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; - int dlci_found = 0; - do + do { - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); mbox->cmd.command = FR_LIST_ACTIVE_DLCI; + mbox->cmd.length = 0; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && retry-- && fr_event(card, err, mbox)); + } while (err && retry-- && fr_event(card, err, mbox)); - if (!err) - { - unsigned short *list = (void *) mbox->data; + if (!err) { + + unsigned short* list = (void*)mbox->data; int cnt = mbox->cmd.length / sizeof(short); - for (; cnt; --cnt, ++list) - { - if (*list == chan->dlci) - { - dlci_found = 1; - set_chan_state(dev, WAN_CONNECTED); + + for (; cnt; --cnt, ++list) { + + if (*list == chan->dlci) { + set_chan_state(dev, WAN_CONNECTED); break; } } - if (!dlci_found) - printk(KERN_INFO "%s: DLCI %u is inactive\n", - card->devname, chan->dlci); } - + return err; } + /*============================================================================ * Set channel state. */ -static void set_chan_state(struct net_device *dev, int state) +static void set_chan_state (struct net_device* dev, int state) { - fr_channel_t *chan = dev->priv; - sdla_t *card = chan->card; + fr_channel_t* chan = dev->priv; + sdla_t* card = chan->card; unsigned long flags; - + save_flags(flags); cli(); - - if (chan->state != state) - { - switch (state) - { + + if (chan->state != state) { + + switch (state) { + case WAN_CONNECTED: - printk(KERN_INFO "%s: interface %s connected!\n" - ,card->devname, dev->name); + printk(KERN_INFO + "%s: Interface %s: DLCI %d connected\n", + card->devname, dev->name, chan->dlci); break; + case WAN_CONNECTING: - printk(KERN_INFO - "%s: interface %s connecting...\n", - card->devname, dev->name); + printk(KERN_INFO + "%s: Interface %s: DLCI %d connecting\n", + card->devname, dev->name, chan->dlci); break; + case WAN_DISCONNECTED: - printk(KERN_INFO - "%s: interface %s disconnected!\n", - card->devname, dev->name); + printk (KERN_INFO + "%s: Interface %s: DLCI %d disconnected!\n", + card->devname, dev->name, chan->dlci); break; } + chan->state = state; } + chan->state_tick = jiffies; restore_flags(flags); } @@ -2402,14 +2871,14 @@ /*============================================================================ * Find network device by its channel number. */ -static struct net_device *find_channel(sdla_t * card, unsigned dlci) +static struct net_device* find_channel (sdla_t* card, unsigned dlci) { - struct net_device *dev; - for (dev = card->wandev.dev; dev; dev = dev->slave) - if (((fr_channel_t *) dev->priv)->dlci == dlci) - break; - return dev; + if(dlci > HIGHEST_VALID_DLCI) + return NULL; + + return(card->u.f.dlci_to_dev_map[dlci]); } + /*============================================================================ * Check to see if a frame can be sent. If no transmit buffers available, * enable transmit interrupts. @@ -2417,22 +2886,17 @@ * Return: 1 - Tx buffer(s) available * 0 - no buffers available */ - -static int is_tx_ready(sdla_t * card, fr_channel_t * chan) +static int is_tx_ready (sdla_t* card, fr_channel_t* chan) { - if (card->hw.fwid == SFID_FR508) - { - unsigned char sb = inb(card->hw.port); - if (sb & 0x02) - return 1; - } - else - { - fr502_flags_t *flags = card->flags; - if (flags->tx_ready) - return 1; - flags->imask |= 0x02; - } + unsigned char sb; + + if(card->hw.type == SDLA_S514) + return 1; + + sb = inb(card->hw.port); + if (sb & 0x02) + return 1; + return 0; } @@ -2440,688 +2904,790 @@ * Convert decimal string to unsigned integer. * If len != 0 then only 'len' characters of the string are converted. */ -static unsigned int dec_to_uint(unsigned char *str, int len) +static unsigned int dec_to_uint (unsigned char* str, int len) { unsigned val; - if (!len) + + if (!len) len = strlen(str); + for (val = 0; len && is_digit(*str); ++str, --len) - val = (val * 10) + (*str - (unsigned) '0'); + val = (val * 10) + (*str - (unsigned)'0'); + return val; } + + +/*============================================================================= + * Store a UDP management packet for later processing. + */ + +static int store_udp_mgmt_pkt(int udp_type, char udp_pkt_src, sdla_t* card, + struct sk_buff *skb, int dlci) +{ + int udp_pkt_stored = 0; + + if(!card->u.f.udp_pkt_lgth &&(skb->len <= MAX_LGTH_UDP_MGNT_PKT)){ + card->u.f.udp_pkt_lgth = skb->len; + card->u.f.udp_type = udp_type; + card->u.f.udp_pkt_src = udp_pkt_src; + card->u.f.udp_dlci = dlci; + memcpy(card->u.f.udp_pkt_data, skb->data, skb->len); + card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UDP; + udp_pkt_stored = 1; + + }else{ + printk(KERN_INFO "ERROR: UDP packet not stored for DLCI %d\n", + dlci); + } + + dev_kfree_skb(skb); + + return(udp_pkt_stored); +} + + /*============================================================================== * Process UDP call of type FPIPE8ND */ - -static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan) +static int process_udp_mgmt_pkt(sdla_t* card) { + int c_retry = MAX_CMD_RETRY; - unsigned char *data; unsigned char *buf; - unsigned char buf2[5]; - unsigned int loops, frames, len; - unsigned long data_ptr; - unsigned short real_len, buffer_length; + unsigned char frames; + unsigned int len; + unsigned short buffer_length; struct sk_buff *new_skb; - unsigned char *sendpacket; - fr_mbox_t *mbox = card->mbox; + fr_mbox_t* mbox = card->mbox; int err; struct timeval tv; int udp_mgmt_req_valid = 1; - sendpacket = skb->data; - memcpy(&buf2, &card->wandev.udp_port, 2); - if ((data = kmalloc(2000, GFP_ATOMIC)) == NULL) - { - printk(KERN_INFO - "%s: Error allocating memory for UDP management cmnd 0x%02X", - card->devname, data[47]); - ++chan->UDP_FPIPE_mgmt_kmalloc_err; - return 1; - } - memcpy(data, sendpacket, skb->len); - switch (data[47]) - { - /* FPIPE_ENABLE_TRACE */ - case 0x41: - /* FPIPE_DISABLE_TRACE */ - case 0x42: - /* FPIPE_GET_TRACE_INFO */ - case 0x43: - /* SET FT1 MODE */ - case 0x81: - if (udp_pkt_src == UDP_PKT_FRM_NETWORK) - { - ++chan->UDP_FPIPE_mgmt_direction_err; + struct net_device* dev; + fr_channel_t* chan; + fr_udp_pkt_t *fr_udp_pkt; + unsigned short num_trc_els; + fr_trc_el_t* ptr_trc_el; + fr_trc_el_t trc_el; + fpipemon_trc_t* fpipemon_trc; + + char udp_pkt_src = card->u.f.udp_pkt_src; + int dlci = card->u.f.udp_dlci; + + /* Find network interface for this packet */ + dev = find_channel(card, dlci); + chan = dev->priv; + + /* If the UDP packet is from the network, we are going to have to + transmit a response. Before doing so, we must check to see that + we are not currently transmitting a frame (in 'if_send()') and + that we are not already in a 'delayed transmit' state. + */ + if(udp_pkt_src == UDP_PKT_FRM_NETWORK) { + if (test_bit(0, (void*)&card->wandev.critical) || + test_bit(2, (void*)&card->wandev.critical)) { + return 0; + } + if((dev->tbusy) || (card->u.f.tx_interrupts_pending)) { + return 0; + } + } + + fr_udp_pkt = (fr_udp_pkt_t *)card->u.f.udp_pkt_data; + + switch(fr_udp_pkt->cblock.command) { + + case FPIPE_ENABLE_TRACING: + case FPIPE_DISABLE_TRACING: + case FPIPE_GET_TRACE_INFO: + case FR_SET_FT1_MODE: + if(udp_pkt_src == UDP_PKT_FRM_NETWORK) { + chan->drvstats_gen. + UDP_PIPE_mgmt_direction_err ++; udp_mgmt_req_valid = 0; break; } - /* FPIPE_FT1_READ_STATUS */ - case 0x44: - /* FT1 MONITOR STATUS */ - case 0x80: - if (card->hw.fwid != SFID_FR508) - { - ++chan->UDP_FPIPE_mgmt_adptr_type_err; - udp_mgmt_req_valid = 0; - } - break; + default: break; - } - if (!udp_mgmt_req_valid) - { + } + + if(!udp_mgmt_req_valid) { /* set length to 0 */ - data[48] = data[49] = 0; + fr_udp_pkt->cblock.length = 0; /* set return code */ - data[50] = (card->hw.fwid != SFID_FR508) ? 0x1F : 0xCD; - } - else - { - switch (data[47]) - { - /* FPIPE_ENABLE_TRACE */ - case 0x41: - if (!TracingEnabled) - { - do - { - /* SET_TRACE_CONFIGURATION */ - mbox->cmd.command = 0x60; - mbox->cmd.length = 1; - mbox->cmd.dlci = 0x00; - mbox->data[0] = 0x37; - err = sdla_exec(mbox) ? - mbox->cmd.result : CMD_TIMEOUT; - } - while (err && c_retry-- && fr_event(card, err, mbox)); - - if (err) - { - TracingEnabled = 0; - /* set the return code */ - data[50] = mbox->cmd.result; - mbox->cmd.length = 0; - break; - } - /* get num_frames */ - sdla_peek(&card->hw, 0x9000, &num_frames, 2); - sdla_peek(&card->hw, 0x9002, &curr_trace_addr,4); - start_trace_addr = curr_trace_addr; - /* MAX_SEND_BUFFER_SIZE - - * sizeof(UDP_MGMT_PACKET) - 41 */ - available_buffer_space = 1926; - /* set return code */ - data[50] = 0; - } - else - { - /* set return code to line trace already - enabled */ - data[50] = 1; - } - mbox->cmd.length = 0; - TracingEnabled = 1; - break; - /* FPIPE_DISABLE_TRACE */ - case 0x42: - if (TracingEnabled) - { - do - { - /* SET_TRACE_CONFIGURATION */ - mbox->cmd.command = 0x60; - mbox->cmd.length = 1; - mbox->cmd.dlci = 0x00; - mbox->data[0] = 0x36; - err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && c_retry-- && fr_event(card, err, mbox)); - } - /* set return code */ - data[50] = 0; - mbox->cmd.length = 0; - TracingEnabled = 0; - break; - /* FPIPE_GET_TRACE_INFO */ - case 0x43: - /* Line trace cannot be performed on the 502 */ - if (!TracingEnabled) - { - /* set return code */ - data[50] = 1; + fr_udp_pkt->cblock.result = 0xCD; + } else { + + switch(fr_udp_pkt->cblock.command) { + + case FPIPE_ENABLE_TRACING: + if(!card->TracingEnabled) { + do { + mbox->cmd.command = FR_SET_TRACE_CONFIG; + mbox->cmd.length = 1; + mbox->cmd.dlci = 0x00; + mbox->data[0] = fr_udp_pkt->data[0] | + RESET_TRC; + err = sdla_exec(mbox) ? + mbox->cmd.result : CMD_TIMEOUT; + } while (err && c_retry-- && fr_event(card, err, + mbox)); + + if(err) { + card->TracingEnabled = 0; + /* set the return code */ + fr_udp_pkt->cblock.result = + mbox->cmd.result; mbox->cmd.length = 0; break; } - buffer_length = 0; - loops = (num_frames < 20) ? num_frames : 20; - for (frames = 0; frames < loops; frames += 1) - { - sdla_peek(&card->hw, curr_trace_addr, &buf2, 1); - /* no data on board so exit */ - if (buf2[0] == 0x00) - break; - /* 1+sizeof(FRAME_DATA) = 9 */ - if ((available_buffer_space - buffer_length) < 9) - { - /* indicate we have more frames on board - and exit */ - data[62] |= 0x02; - break; - } - /* get frame status */ - sdla_peek(&card->hw, curr_trace_addr + 0x05, &data[62 + buffer_length], 1); - /* get time stamp */ - sdla_peek(&card->hw, curr_trace_addr + 0x06, &data[66 + buffer_length], 2); - /* get frame length */ - sdla_peek(&card->hw, curr_trace_addr + 0x01, &data[64 + buffer_length], 2); - /* get pointer to real data */ - sdla_peek(&card->hw, curr_trace_addr + 0x0C,&data_ptr, 4); - /* see if we can fit the frame into the user buffer */ - memcpy(&real_len, &data[64 + buffer_length], 2); - if (data_ptr == 0 || real_len + 8 > available_buffer_space) - { - data[63 + buffer_length] = 0x00; - } - else - { - /* we can take it next time */ - if (available_buffer_space - buffer_length < real_len + 8) - { - data[62] |= 0x02; - break; - } - /* ok, get the frame */ - data[63 + buffer_length] = 0x01; - /* get the data */ - sdla_peek(&card->hw, data_ptr, &data[68 + buffer_length], real_len); - /* zero the opp flag to show we got the frame */ - buf2[0] = 0x00; - sdla_poke(&card->hw, curr_trace_addr, &buf2, 1); - /* now move onto the next frame */ - curr_trace_addr += 16; - /* check if we passed the last address */ - if (curr_trace_addr >= (start_trace_addr + num_frames * 16)) - curr_trace_addr = start_trace_addr; - /* update buffer length and make sure - its even */ - if (data[63 + buffer_length] == 0x01) - buffer_length += real_len - 1; - /* for the header */ - buffer_length += 8; - if (buffer_length & 0x0001) - buffer_length += 1; - } - } - /* ok now set the total number of frames passed in the - high 5 bits */ - data[62] = (frames << 3) | data[62]; - /* set the data length */ - mbox->cmd.length = buffer_length; - memcpy(&data[48], &buffer_length, 2); - data[50] = 0; - break; - /* FPIPE_FT1_READ_STATUS */ - case 0x44: - sdla_peek(&card->hw, 0xF020, &data[62], 2); - data[48] = 2; - data[49] = 0; - data[50] = 0; - mbox->cmd.length = 2; - break; - /* FPIPE_FLUSH_DRIVER_STATS */ - case 0x48: - init_chan_statistics(chan); - init_global_statistics(card); - mbox->cmd.length = 0; - break; - case 0x49: - do_gettimeofday(&tv); - chan->router_up_time = tv.tv_sec - chan->router_start_time; - *(unsigned long *) &data[62] = chan->router_up_time; - mbox->cmd.length = 4; - break; - /* FPIPE_KILL_BOARD */ - case 0x50: - break; - /* FT1 MONITOR STATUS */ - case 0x80: - if (data[62] == 1) - { - if (rCount++ != 0) - { - data[50] = 0; - mbox->cmd.length = 1; - break; - } - } - /* Disable FT1 MONITOR STATUS */ - if (data[62] == 0) - { - if (--rCount != 0) - { - data[50] = 0; - mbox->cmd.length = 1; - break; - } - } - default: - do - { - memcpy(&mbox->cmd, &sendpacket[47], sizeof(fr_cmd_t)); - if (mbox->cmd.length) - memcpy(&mbox->data, &sendpacket[62],mbox->cmd.length); - err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && c_retry-- && fr_event(card, err, mbox)); + + sdla_peek(&card->hw, NO_TRC_ELEMENTS_OFF, + &num_trc_els, 2); + sdla_peek(&card->hw, BASE_TRC_ELEMENTS_OFF, + &card->u.f.trc_el_base, 4); + card->u.f.curr_trc_el = card->u.f.trc_el_base; + card->u.f.trc_el_last = card->u.f.curr_trc_el + + ((num_trc_els - 1) * + sizeof(fr_trc_el_t)); + + /* Calculate the maximum trace data area in */ + /* the UDP packet */ + card->u.f.trc_bfr_space=(MAX_LGTH_UDP_MGNT_PKT - + sizeof(fr_encap_hdr_t) - + sizeof(ip_pkt_t) - + sizeof(udp_pkt_t) - + sizeof(wp_mgmt_t) - + sizeof(cblock_t)); + + /* set return code */ + fr_udp_pkt->cblock.result = 0; - if (!err) - { - ++chan->UDP_FPIPE_mgmt_adptr_cmnd_OK; - memcpy(data, sendpacket, skb->len); - memcpy(&data[47], &mbox->cmd, sizeof(fr_cmd_t)); - if (mbox->cmd.length) - { - memcpy(&data[62], &mbox->data,mbox->cmd.length); - } + } else { + /* set return code to line trace already + enabled */ + fr_udp_pkt->cblock.result = 1; + } + + mbox->cmd.length = 0; + card->TracingEnabled = 1; + break; + + + case FPIPE_DISABLE_TRACING: + if(card->TracingEnabled) { + + do { + mbox->cmd.command = FR_SET_TRACE_CONFIG; + mbox->cmd.length = 1; + mbox->cmd.dlci = 0x00; + mbox->data[0] = ~ACTIVATE_TRC; + err = sdla_exec(mbox) ? + mbox->cmd.result : CMD_TIMEOUT; + } while (err && c_retry-- && fr_event(card, err, mbox)); + } + + /* set return code */ + fr_udp_pkt->cblock.result = 0; + mbox->cmd.length = 0; + card->TracingEnabled = 0; + break; + + case FPIPE_GET_TRACE_INFO: + + /* Line trace cannot be performed on the 502 */ + if(!card->TracingEnabled) { + /* set return code */ + fr_udp_pkt->cblock.result = 1; + mbox->cmd.length = 0; + break; + } + + (void *)ptr_trc_el = card->u.f.curr_trc_el; + + buffer_length = 0; + fr_udp_pkt->data[0x00] = 0x00; + + for(frames = 0; frames < MAX_FRMS_TRACED; frames ++) { + + sdla_peek(&card->hw, (unsigned long)ptr_trc_el, + (void *)&trc_el.flag, + sizeof(fr_trc_el_t)); + if(trc_el.flag == 0x00) { + break; } - else - { - ++chan->UDP_FPIPE_mgmt_adptr_cmnd_timeout; + if((card->u.f.trc_bfr_space - buffer_length) + < sizeof(fpipemon_trc_hdr_t)) { + fr_udp_pkt->data[0x00] |= MORE_TRC_DATA; + break; + } + + fpipemon_trc = + (fpipemon_trc_t *)&fr_udp_pkt->data[buffer_length]; + fpipemon_trc->fpipemon_trc_hdr.status = + trc_el.attr; + fpipemon_trc->fpipemon_trc_hdr.tmstamp = + trc_el.tmstamp; + fpipemon_trc->fpipemon_trc_hdr.length = + trc_el.length; + + if(!trc_el.offset || !trc_el.length) { + + fpipemon_trc->fpipemon_trc_hdr.data_passed = 0x00; + + }else if((trc_el.length + sizeof(fpipemon_trc_hdr_t) + 1) > + (card->u.f.trc_bfr_space - buffer_length)){ + + fpipemon_trc->fpipemon_trc_hdr.data_passed = 0x00; + fr_udp_pkt->data[0x00] |= MORE_TRC_DATA; + + }else { + fpipemon_trc->fpipemon_trc_hdr.data_passed = 0x01; + sdla_peek(&card->hw, trc_el.offset, + fpipemon_trc->data, + trc_el.length); + } + + trc_el.flag = 0x00; + sdla_poke(&card->hw, (unsigned long)ptr_trc_el, + &trc_el.flag, 1); + + ptr_trc_el ++; + if((void *)ptr_trc_el > card->u.f.trc_el_last) + (void*)ptr_trc_el = card->u.f.trc_el_base; + + buffer_length += sizeof(fpipemon_trc_hdr_t); + if(fpipemon_trc->fpipemon_trc_hdr.data_passed) { + buffer_length += trc_el.length; + } + + if(fr_udp_pkt->data[0x00] & MORE_TRC_DATA) { + break; } + } + + if(frames == MAX_FRMS_TRACED) { + fr_udp_pkt->data[0x00] |= MORE_TRC_DATA; + } + + card->u.f.curr_trc_el = (void *)ptr_trc_el; + + /* set the total number of frames passed */ + fr_udp_pkt->data[0x00] |= + ((frames << 1) & (MAX_FRMS_TRACED << 1)); + + /* set the data length and return code */ + fr_udp_pkt->cblock.length = mbox->cmd.length = buffer_length; + fr_udp_pkt->cblock.result = 0; + break; + + case FPIPE_FT1_READ_STATUS: + sdla_peek(&card->hw, 0xF020, + &fr_udp_pkt->data[0x00] , 2); + fr_udp_pkt->cblock.length = 2; + fr_udp_pkt->cblock.result = 0; + break; + + case FPIPE_FLUSH_DRIVER_STATS: + init_chan_statistics(chan); + init_global_statistics(card); + mbox->cmd.length = 0; + break; + + case FPIPE_ROUTER_UP_TIME: + do_gettimeofday(&tv); + chan->router_up_time = tv.tv_sec - + chan->router_start_time; + *(unsigned long *)&fr_udp_pkt->data = + chan->router_up_time; + mbox->cmd.length = 4; + break; + + + case FR_FT1_STATUS_CTRL: + if(fr_udp_pkt->data[0] == 1) { + if(rCount++ != 0 ){ + fr_udp_pkt->cblock.result = 0; + mbox->cmd.length = 1; + break; + } } - } - /* Fill UDP TTL */ - data[10] = card->wandev.ttl; - len = reply_udp(data, mbox->cmd.length); - if (udp_pkt_src == UDP_PKT_FRM_NETWORK) - { - err = fr508_send(card, dlci, 0, len, data); - if (err) - ++chan->UDP_FPIPE_mgmt_adptr_send_passed; + + /* Disable FT1 MONITOR STATUS */ + if(fr_udp_pkt->data[0] == 0) { + if( --rCount != 0) { + fr_udp_pkt->cblock.result = 0; + mbox->cmd.length = 1; + break; + } + } + + case FPIPE_DRIVER_STAT_IFSEND: + memcpy(fr_udp_pkt->data, + &chan->drvstats_if_send.if_send_entry, + sizeof(if_send_stat_t)); + mbox->cmd.length = sizeof(if_send_stat_t); + break; + + case FPIPE_DRIVER_STAT_INTR: + memcpy(fr_udp_pkt->data, + &card->statistics.isr_entry, + sizeof(global_stats_t)); + memcpy(&fr_udp_pkt->data[sizeof(global_stats_t)], + &chan->drvstats_rx_intr.rx_intr_no_socket, + sizeof(rx_intr_stat_t)); + mbox->cmd.length = sizeof(global_stats_t) + + sizeof(rx_intr_stat_t); + break; + + case FPIPE_DRIVER_STAT_GEN: + memcpy(fr_udp_pkt->data, + &chan->drvstats_gen.UDP_PIPE_mgmt_kmalloc_err, + sizeof(pipe_mgmt_stat_t)); + + memcpy(&fr_udp_pkt->data[sizeof(pipe_mgmt_stat_t)], + &card->statistics, sizeof(global_stats_t)); + + fr_udp_pkt->cblock.result = 0; + fr_udp_pkt->cblock.length = sizeof(global_stats_t)+ + sizeof(rx_intr_stat_t); + mbox->cmd.length = fr_udp_pkt->cblock.length; + break; + + default: + do { + memcpy(&mbox->cmd, + &fr_udp_pkt->cblock.command, + sizeof(fr_cmd_t)); + if(mbox->cmd.length) { + memcpy(&mbox->data, + (char *)fr_udp_pkt->data, + mbox->cmd.length); + } + + err = sdla_exec(mbox) ? mbox->cmd.result : + CMD_TIMEOUT; + } while (err && c_retry-- && fr_event(card, err, mbox)); + + if(!err) + chan->drvstats_gen. + UDP_PIPE_mgmt_adptr_cmnd_OK ++; + else + chan->drvstats_gen. + UDP_PIPE_mgmt_adptr_cmnd_timeout ++; + + /* copy the result back to our buffer */ + memcpy(&fr_udp_pkt->cblock.command, + &mbox->cmd, sizeof(fr_cmd_t)); + + if(mbox->cmd.length) { + memcpy(&fr_udp_pkt->data, + &mbox->data, mbox->cmd.length); + } + } + } + + /* Fill UDP TTL */ + fr_udp_pkt->ip_pkt.ttl = card->wandev.ttl; + len = reply_udp(card->u.f.udp_pkt_data, mbox->cmd.length); + + if(udp_pkt_src == UDP_PKT_FRM_NETWORK) { + + err = fr_send(card, dlci, 0, len, card->u.f.udp_pkt_data); + if (err) + chan->drvstats_gen.UDP_PIPE_mgmt_adptr_send_passed ++; else - ++chan->UDP_FPIPE_mgmt_adptr_send_failed; - dev_kfree_skb(skb); - } - else - { + chan->drvstats_gen.UDP_PIPE_mgmt_adptr_send_failed ++; + } else { /* Allocate socket buffer */ - if ((new_skb = dev_alloc_skb(len)) != NULL) - { + if((new_skb = dev_alloc_skb(len)) != NULL) { + /* copy data into new_skb */ buf = skb_put(new_skb, len); - memcpy(buf, data, len); + memcpy(buf, card->u.f.udp_pkt_data, len); + /* Decapsulate packet and pass it up the protocol stack */ new_skb->dev = dev; - buf = skb_pull(new_skb, 1); /* remove hardware header */ - if (!wanrouter_type_trans(new_skb, dev)) - { - ++chan->UDP_FPIPE_mgmt_not_passed_to_stack; + buf = skb_pull(new_skb, 1); /* remove hardware header*/ + + if(!wanrouter_type_trans(new_skb, dev)) { + + chan->drvstats_gen. + UDP_PIPE_mgmt_not_passed_to_stack ++; /* can't decapsulate packet */ dev_kfree_skb(new_skb); - } - else - { - ++chan->UDP_FPIPE_mgmt_passed_to_stack; + } else { + chan->drvstats_gen. + UDP_PIPE_mgmt_passed_to_stack ++; netif_rx(new_skb); - } - } - else - { - ++chan->UDP_FPIPE_mgmt_no_socket; - printk(KERN_INFO - "%s: UDP mgmt cmnd, no socket buffers available!\n", - card->devname); - } - } - kfree(data); - return 0; + } + + } else { + chan->drvstats_gen.UDP_PIPE_mgmt_no_socket ++; + printk(KERN_INFO + "%s: UDP mgmt cmnd, no socket buffers available!\n", + card->devname); + } + } + + card->u.f.udp_pkt_lgth = 0; + + return 1; } + /*============================================================================== - * Perform the Interrupt Test by running the READ_CODE_VERSION command MAX_INTR_ - * TEST_COUNTER times. + * Send Inverse ARP Request */ - -static int intr_test(sdla_t * card) + +int send_inarp_request(sdla_t *card, struct net_device *dev) { - fr_mbox_t *mb = card->mbox; - int err, i; - /* The critical flag is unset here because we want to get into the - ISR without the flag already set. The If_open sets the flag. - */ - card->wandev.critical = 0; - err = fr_set_intr_mode(card, 0x08, card->wandev.mtu); - if (err == CMD_OK) - { - for (i = 0; i < MAX_INTR_TEST_COUNTER; i++) - { - /* Run command READ_CODE_VERSION */ - memset(&mb->cmd, 0, sizeof(fr_cmd_t)); - mb->cmd.length = 0; - mb->cmd.command = 0x40; - err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; - if (err != CMD_OK) - fr_event(card, err, mb); - } - } - else - { - return err; + arphdr_1490_t *ArpPacket; + arphdr_fr_t *arphdr; + fr_channel_t *chan = dev->priv; + struct in_device *in_dev; + + in_dev = dev->ip_ptr; + + if(in_dev != NULL ) { + + ArpPacket = kmalloc(sizeof(arphdr_1490_t) + sizeof(arphdr_fr_t), GFP_ATOMIC); + /* SNAP Header indicating ARP */ + ArpPacket->control = 0x03; + ArpPacket->pad = 0x00; + ArpPacket->NLPID = 0x80; + ArpPacket->OUI[0] = 0; + ArpPacket->OUI[1] = 0; + ArpPacket->OUI[2] = 0; + ArpPacket->PID = 0x0608; + + arphdr = (arphdr_fr_t *)(ArpPacket + 1); // Go to ARP Packet + + /* InARP request */ + arphdr->ar_hrd = 0x0F00; /* Frame Relay HW type */ + arphdr->ar_pro = 0x0008; /* IP Protocol */ + arphdr->ar_hln = 2; /* HW addr length */ + arphdr->ar_pln = 4; /* IP addr length */ + arphdr->ar_op = htons(0x08); /* InARP Request */ + arphdr->ar_sha = 0; /* src HW DLCI - Doesn't matter */ + if(in_dev->ifa_list != NULL) + arphdr->ar_sip = in_dev->ifa_list->ifa_local; /* Local Address */else + arphdr->ar_sip = 0; + arphdr->ar_tha = 0; /* dst HW DLCI - Doesn't matter */ + arphdr->ar_tip = 0; /* Remote Address -- what we want */ + + printk(KERN_INFO "%s: Sending InARP request on DLCI %d.\n", card->devname, chan->dlci); + fr_send(card, chan->dlci, 0, + sizeof(arphdr_1490_t) + sizeof(arphdr_fr_t), + (void *)ArpPacket); + kfree(ArpPacket); } - err = fr_set_intr_mode(card, 0, card->wandev.mtu); - if (err != CMD_OK) - return err; - card->wandev.critical = 1; - return 0; + + return 1; } -/*============================================================================ - * Process UDP call of type DRVSTATS. + + +/*============================================================================== + * Check packet for ARP Type */ -static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan) + +int is_arp(void *buf) { - int c_retry = MAX_CMD_RETRY; - unsigned char *sendpacket; - unsigned char buf2[5]; - unsigned char *data; - unsigned char *buf; - unsigned int len; - fr_mbox_t *mbox = card->mbox; - struct sk_buff *new_skb; - int err; - sendpacket = skb->data; - memcpy(&buf2, &card->wandev.udp_port, 2); - if ((data = kmalloc(2000, GFP_ATOMIC)) == NULL) - { - printk(KERN_INFO - "%s: Error allocating memory for UDP DRIVER STATS cmnd0x%02X" - ,card->devname, data[45]); - ++chan->UDP_DRVSTATS_mgmt_kmalloc_err; + arphdr_1490_t *arphdr = (arphdr_1490_t *)buf; + + if (arphdr->pad == 0x00 && + arphdr->NLPID == 0x80 && + arphdr->PID == 0x0608) return 1; - } - memcpy(data, sendpacket, skb->len); - switch (data[47]) - { - case 0x45: - *(unsigned long *) &data[62] = chan->if_send_entry; - *(unsigned long *) &data[66] = chan->if_send_skb_null; - *(unsigned long *) &data[70] = chan->if_send_broadcast; - *(unsigned long *) &data[74] = chan->if_send_multicast; - *(unsigned long *) &data[78] = chan->if_send_critical_ISR; - *(unsigned long *) &data[82] = chan->if_send_critical_non_ISR; - *(unsigned long *) &data[86] = chan->if_send_busy; - *(unsigned long *) &data[90] = chan->if_send_busy_timeout; - *(unsigned long *) &data[94] = chan->if_send_DRVSTATS_request; - *(unsigned long *) &data[98] = chan->if_send_FPIPE_request; - *(unsigned long *) &data[102] = chan->if_send_wan_disconnected; - *(unsigned long *) &data[106] = chan->if_send_dlci_disconnected; - *(unsigned long *) &data[110] = chan->if_send_no_bfrs; - *(unsigned long *) &data[114] = chan->if_send_adptr_bfrs_full; - *(unsigned long *) &data[118] = chan->if_send_bfrs_passed_to_adptr; - *(unsigned long *) &data[120] = card->irq_dis_if_send_count; - mbox->cmd.length = 62; - break; - case 0x46: - *(unsigned long *) &data[62] = card->statistics.isr_entry; - *(unsigned long *) &data[66] = card->statistics.isr_already_critical; - *(unsigned long *) &data[70] = card->statistics.isr_rx; - *(unsigned long *) &data[74] = card->statistics.isr_tx; - *(unsigned long *) &data[78] = card->statistics.isr_intr_test; - *(unsigned long *) &data[82] = card->statistics.isr_spurious; - *(unsigned long *) &data[86] = card->statistics.isr_enable_tx_int; - *(unsigned long *) &data[90] = card->statistics.tx_intr_dev_not_started; - *(unsigned long *) &data[94] = card->statistics.rx_intr_corrupt_rx_bfr; - *(unsigned long *) &data[98] = card->statistics.rx_intr_on_orphaned_DLCI; - *(unsigned long *) &data[102] = chan->rx_intr_no_socket; - *(unsigned long *) &data[106] = chan->rx_intr_dev_not_started; - *(unsigned long *) &data[110] = chan->rx_intr_DRVSTATS_request; - *(unsigned long *) &data[114] = chan->rx_intr_FPIPE_request; - *(unsigned long *) &data[118] = chan->rx_intr_bfr_not_passed_to_stack; - *(unsigned long *) &data[122] = chan->rx_intr_bfr_passed_to_stack; - mbox->cmd.length = 64; - break; - case 0x47: - *(unsigned long *) &data[62] = chan->UDP_FPIPE_mgmt_kmalloc_err; - *(unsigned long *) &data[66] = chan->UDP_FPIPE_mgmt_adptr_type_err; - *(unsigned long *) &data[70] = chan->UDP_FPIPE_mgmt_direction_err; - *(unsigned long *) &data[74] = chan->UDP_FPIPE_mgmt_adptr_cmnd_timeout; - *(unsigned long *) &data[78] = chan->UDP_FPIPE_mgmt_adptr_cmnd_OK; - *(unsigned long *) &data[82] = chan->UDP_FPIPE_mgmt_adptr_send_passed; - *(unsigned long *) &data[86] = chan->UDP_FPIPE_mgmt_adptr_send_failed; - *(unsigned long *) &data[90] = chan->UDP_FPIPE_mgmt_no_socket; - *(unsigned long *) &data[94] = chan->UDP_FPIPE_mgmt_not_passed_to_stack; - *(unsigned long *) &data[98] = chan->UDP_FPIPE_mgmt_passed_to_stack; - *(unsigned long *) &data[102] = chan->UDP_DRVSTATS_mgmt_kmalloc_err; - *(unsigned long *) &data[106] = chan->UDP_DRVSTATS_mgmt_adptr_cmnd_timeout; - *(unsigned long *) &data[110] = chan->UDP_DRVSTATS_mgmt_adptr_cmnd_OK; - *(unsigned long *) &data[114] = chan->UDP_DRVSTATS_mgmt_adptr_send_passed; - *(unsigned long *) &data[118] = chan->UDP_DRVSTATS_mgmt_adptr_send_failed; - *(unsigned long *) &data[122] = chan->UDP_DRVSTATS_mgmt_no_socket; - *(unsigned long *) &data[126] = chan->UDP_DRVSTATS_mgmt_not_passed_to_stack; - *(unsigned long *) &data[130] = chan->UDP_DRVSTATS_mgmt_passed_to_stack; - *(unsigned long *) &data[134] = card->statistics.poll_entry; - *(unsigned long *) &data[138] = card->statistics.poll_already_critical; - *(unsigned long *) &data[142] = card->statistics.poll_processed; - *(unsigned long *) &data[144] = card->irq_dis_poll_count; - mbox->cmd.length = 86; - break; - default: - do - { - memcpy(&mbox->cmd, &sendpacket[47], sizeof(fr_cmd_t)); - if (mbox->cmd.length) - memcpy(&mbox->data, &sendpacket[62], mbox->cmd.length); - err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - } - while (err && c_retry-- && fr_event(card, err, mbox)); + else return 0; +} + +/*============================================================================== + * Process ARP Packet Type + */ + +int process_ARP(arphdr_1490_t *ArpPacket, sdla_t *card, struct net_device* dev) +{ + + arphdr_fr_t *arphdr = (arphdr_fr_t *)(ArpPacket + 1); /* Skip header */ + fr_rx_buf_ctl_t* frbuf = card->rxmb; + struct in_device *in_dev; + + + in_dev = dev->ip_ptr; + if( in_dev != NULL && in_dev->ifa_list != NULL) { + switch (ntohs(arphdr->ar_op)) { + + case 0x08: // Inverse ARP request -- Send Reply, add route. - if (!err) - { - ++chan->UDP_DRVSTATS_mgmt_adptr_cmnd_OK; - memcpy(data, sendpacket, skb->len); - memcpy(&data[47], &mbox->cmd, sizeof(fr_cmd_t)); - if (mbox->cmd.length) - memcpy(&data[62], &mbox->data, mbox->cmd.length); - } - else - { - ++chan->UDP_DRVSTATS_mgmt_adptr_cmnd_timeout; + /* Check for valid Address */ + printk(KERN_INFO "%s: Recvd PtP addr %s -InArp Req\n", ((fr_channel_t *)dev->priv)->name, in_ntoa(arphdr->ar_sip)); + + if ((in_dev->ifa_list->ifa_mask & arphdr->ar_sip) != (in_dev->ifa_list->ifa_mask & in_dev->ifa_list->ifa_local)) { + printk(KERN_INFO "%s: Invalid PtP address. InARP ignored.\n", card->devname); + printk(KERN_INFO "mask %X\n", in_dev->ifa_list->ifa_mask); + printk(KERN_INFO "local %X\n", in_dev->ifa_list->ifa_local); + return -1; } - } - /* Fill UDP TTL */ - data[10] = card->wandev.ttl; - len = reply_udp(data, mbox->cmd.length); - if (udp_pkt_src == UDP_PKT_FRM_NETWORK) - { - err = fr508_send(card, dlci, 0, len, data); - if (err) - ++chan->UDP_DRVSTATS_mgmt_adptr_send_failed; - else - ++chan->UDP_DRVSTATS_mgmt_adptr_send_passed; - dev_kfree_skb(skb); - } - else - { - /* Allocate socket buffer */ - if ((new_skb = dev_alloc_skb(len)) != NULL) - { - /* copy data into new_skb */ - buf = skb_put(new_skb, len); - memcpy(buf, data, len); - /* Decapsulate packet and pass it up the - protocol stack */ - new_skb->dev = dev; - /* remove hardware header */ - buf = skb_pull(new_skb, 1); - if (!wanrouter_type_trans(new_skb, dev)) + + if (in_dev->ifa_list->ifa_local == arphdr->ar_sip) { + printk(KERN_INFO "%s: Local addr = PtP addr. InARP ignored.\n", card->devname); + return -1; + } + + arphdr->ar_op = htons(0x09); /* InARP Reply */ + + /* Set addresses */ + arphdr->ar_tip = arphdr->ar_sip; + arphdr->ar_sip = in_dev->ifa_list->ifa_local; + + fr_send(card, frbuf->dlci, 0, frbuf->length, (void *)ArpPacket); + + /* Modify Point-to-Point Address */ { - /* can't decapsulate packet */ - ++chan->UDP_DRVSTATS_mgmt_not_passed_to_stack; - dev_kfree_skb(new_skb); + struct ifreq if_info; + struct sockaddr_in *if_data; + mm_segment_t fs = get_fs(); + int err; + + /* Set remote addresses */ + memset(&if_info, 0, sizeof(if_info)); + strcpy(if_info.ifr_name, dev->name); + + set_fs(get_ds()); /* get user space block */ + + if_data = (struct sockaddr_in *)&if_info.ifr_dstaddr; + if_data->sin_addr.s_addr = arphdr->ar_tip; + if_data->sin_family = AF_INET; + err = devinet_ioctl( SIOCSIFDSTADDR, &if_info ); + + set_fs(fs); /* restore old block */ } - else + + /* Add Route Flag */ + /* The route will be added in the polling routine so + that it is not interrupt context. */ + + ((fr_channel_t *) dev->priv)->route_flag = ADD_ROUTE; + card->poll = &process_route; + + break; + + case 0x09: // Inverse ARP reply + + /* Check for valid Address */ + printk(KERN_INFO "%s: Recvd PtP addr %s -InArp Reply\n", ((fr_channel_t *)dev->priv)->name, in_ntoa(arphdr->ar_sip)); + + if ((in_dev->ifa_list->ifa_mask & arphdr->ar_sip) != (in_dev->ifa_list->ifa_mask & in_dev->ifa_list->ifa_local)) { + printk(KERN_INFO "%s: Invalid PtP address. InARP ignored.\n", card->devname); + return -1; + } + + if (in_dev->ifa_list->ifa_local == arphdr->ar_sip) { + printk(KERN_INFO "%s: Local addr = PtP addr. InARP ignored.\n", card->devname); + return -1; + } + + /* Modify Point-to-Point Address */ { - ++chan->UDP_DRVSTATS_mgmt_passed_to_stack; - netif_rx(new_skb); + struct ifreq if_info; + struct sockaddr_in *if_data; + mm_segment_t fs = get_fs(); + int err; + + /* Set remote addresses */ + memset(&if_info, 0, sizeof(if_info)); + strcpy(if_info.ifr_name, dev->name); + + set_fs(get_ds()); /* get user space block */ + + if_data = (struct sockaddr_in *)&if_info.ifr_dstaddr; + if_data->sin_addr.s_addr = arphdr->ar_sip; + if_data->sin_family = AF_INET; + err = devinet_ioctl( SIOCSIFDSTADDR, &if_info ); + + set_fs(fs); /* restore old block */ } + + /* Add Route Flag */ + /* The route will be added in the polling routine so + that it is not interrupt context. */ + + ((fr_channel_t *) dev->priv)->route_flag = ADD_ROUTE; + ((fr_channel_t *) dev->priv)->inarp = INARP_CONFIGURED; + card->poll = &process_route; + + break; + default: // ARP's and RARP's -- Shouldn't happen. } - else - { - ++chan->UDP_DRVSTATS_mgmt_no_socket; - printk(KERN_INFO "%s: UDP mgmt cmnd, no socket buffers available!\n", card->devname); + } + + return 0; +} + + +/*============================================================================== + * Perform the Interrupt Test by running the READ_CODE_VERSION command MAX_INTR_ + * TEST_COUNTER times. + */ +static int intr_test( sdla_t* card ) +{ + fr_mbox_t* mb = card->mbox; + int err,i; + + /* The critical flag is unset here because we want to get into the + ISR without the flag already set. The If_open sets the flag. + */ + clear_bit(1, (void*)&card->wandev.critical); + + err = fr_set_intr_mode(card, FR_INTR_READY, card->wandev.mtu, 0 ); + + if (err == CMD_OK) { + + for ( i = 0; i < MAX_INTR_TEST_COUNTER; i++ ) { + /* Run command READ_CODE_VERSION */ + mb->cmd.length = 0; + mb->cmd.command = FR_READ_CODE_VERSION; + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + if (err != CMD_OK) + fr_event(card, err, mb); } + + } else { + return err; } - kfree(data); + + err = fr_set_intr_mode( card, 0, card->wandev.mtu, 0 ); + + if( err != CMD_OK ) + return err; + + set_bit(1, (void*)&card->wandev.critical); return 0; } /*============================================================================== - * Determine what type of UDP call it is. DRVSTATS or FPIPE8ND ? + * Determine what type of UDP call it is. FPIPE8ND ? */ - -static int udp_pkt_type(struct sk_buff *skb, sdla_t * card) +static int udp_pkt_type( struct sk_buff *skb, sdla_t* card ) { - unsigned char *sendpacket; - unsigned char buf2[5]; - sendpacket = skb->data; - memcpy(&buf2, &card->wandev.udp_port, 2); - if (sendpacket[2] == 0x45 && /* IP packet */ - sendpacket[11] == 0x11 && /* UDP packet */ - sendpacket[24] == buf2[1] && /* UDP Port */ - sendpacket[25] == buf2[0] && - sendpacket[38] == 0x01) - { - if (sendpacket[30] == 0x46 && /* FPIPE8ND: Signature */ - sendpacket[31] == 0x50 && - sendpacket[32] == 0x49 && - sendpacket[33] == 0x50 && - sendpacket[34] == 0x45 && - sendpacket[35] == 0x38 && - sendpacket[36] == 0x4E && - sendpacket[37] == 0x44) - { - return UDP_FPIPE_TYPE; - } else if (sendpacket[30] == 0x44 && /* DRVSTATS: Signature */ - sendpacket[31] == 0x52 && - sendpacket[32] == 0x56 && - sendpacket[33] == 0x53 && - sendpacket[34] == 0x54 && - sendpacket[35] == 0x41 && - sendpacket[36] == 0x54 && - sendpacket[37] == 0x53) - { - return UDP_DRVSTATS_TYPE; - } - else - return UDP_INVALID_TYPE; + fr_udp_pkt_t *fr_udp_pkt = (fr_udp_pkt_t *)skb->data; + + if((fr_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) && + (fr_udp_pkt->ip_pkt.ver_inet_hdr_length == 0x45) && + (fr_udp_pkt->udp_pkt.udp_dst_port == + ntohs(card->wandev.udp_port)) && + (fr_udp_pkt->wp_mgmt.request_reply == + UDPMGMT_REQUEST)) { + if(!strncmp(fr_udp_pkt->wp_mgmt.signature, + UDPMGMT_FPIPE_SIGNATURE, 8)) + return UDP_FPIPE_TYPE; } - else - return UDP_INVALID_TYPE; + + return UDP_INVALID_TYPE; } + + /*============================================================================== * Initializes the Statistics values in the fr_channel structure. */ - -void init_chan_statistics(fr_channel_t * chan) +void init_chan_statistics( fr_channel_t* chan) { - chan->if_send_entry = 0; - chan->if_send_skb_null = 0; - chan->if_send_broadcast = 0; - chan->if_send_multicast = 0; - chan->if_send_critical_ISR = 0; - chan->if_send_critical_non_ISR = 0; - chan->if_send_busy = 0; - chan->if_send_busy_timeout = 0; - chan->if_send_FPIPE_request = 0; - chan->if_send_DRVSTATS_request = 0; - chan->if_send_wan_disconnected = 0; - chan->if_send_dlci_disconnected = 0; - chan->if_send_no_bfrs = 0; - chan->if_send_adptr_bfrs_full = 0; - chan->if_send_bfrs_passed_to_adptr = 0; - chan->rx_intr_no_socket = 0; - chan->rx_intr_dev_not_started = 0; - chan->rx_intr_FPIPE_request = 0; - chan->rx_intr_DRVSTATS_request = 0; - chan->rx_intr_bfr_not_passed_to_stack = 0; - chan->rx_intr_bfr_passed_to_stack = 0; - chan->UDP_FPIPE_mgmt_kmalloc_err = 0; - chan->UDP_FPIPE_mgmt_direction_err = 0; - chan->UDP_FPIPE_mgmt_adptr_type_err = 0; - chan->UDP_FPIPE_mgmt_adptr_cmnd_OK = 0; - chan->UDP_FPIPE_mgmt_adptr_cmnd_timeout = 0; - chan->UDP_FPIPE_mgmt_adptr_send_passed = 0; - chan->UDP_FPIPE_mgmt_adptr_send_failed = 0; - chan->UDP_FPIPE_mgmt_not_passed_to_stack = 0; - chan->UDP_FPIPE_mgmt_passed_to_stack = 0; - chan->UDP_FPIPE_mgmt_no_socket = 0; - chan->UDP_DRVSTATS_mgmt_kmalloc_err = 0; - chan->UDP_DRVSTATS_mgmt_adptr_cmnd_OK = 0; - chan->UDP_DRVSTATS_mgmt_adptr_cmnd_timeout = 0; - chan->UDP_DRVSTATS_mgmt_adptr_send_passed = 0; - chan->UDP_DRVSTATS_mgmt_adptr_send_failed = 0; - chan->UDP_DRVSTATS_mgmt_not_passed_to_stack = 0; - chan->UDP_DRVSTATS_mgmt_passed_to_stack = 0; - chan->UDP_DRVSTATS_mgmt_no_socket = 0; + memset(&chan->drvstats_if_send.if_send_entry, 0, + sizeof(if_send_stat_t)); + memset(&chan->drvstats_rx_intr.rx_intr_no_socket, 0, + sizeof(rx_intr_stat_t)); + memset(&chan->drvstats_gen.UDP_PIPE_mgmt_kmalloc_err, 0, + sizeof(pipe_mgmt_stat_t)); } + /*============================================================================== * Initializes the Statistics values in the Sdla_t structure. */ - -void init_global_statistics(sdla_t * card) +void init_global_statistics( sdla_t* card ) { /* Intialize global statistics for a card */ - card->statistics.isr_entry = 0; - card->statistics.isr_already_critical = 0; - card->statistics.isr_rx = 0; - card->statistics.isr_tx = 0; - card->statistics.isr_intr_test = 0; - card->statistics.isr_spurious = 0; - card->statistics.isr_enable_tx_int = 0; - card->statistics.rx_intr_corrupt_rx_bfr = 0; - card->statistics.rx_intr_on_orphaned_DLCI = 0; - card->statistics.tx_intr_dev_not_started = 0; - card->statistics.poll_entry = 0; - card->statistics.poll_already_critical = 0; - card->statistics.poll_processed = 0; + memset(&card->statistics.isr_entry, 0, sizeof(global_stats_t)); } -static void read_DLCI_IB_mapping(sdla_t * card, fr_channel_t * chan) +static void read_DLCI_IB_mapping( sdla_t* card, fr_channel_t* chan ) { - fr_mbox_t *mbox = card->mbox; - int retry = MAX_CMD_RETRY; - dlci_IB_mapping_t *result; - int err, counter, found; - do - { - memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); + fr_mbox_t* mbox = card->mbox; + int retry = MAX_CMD_RETRY; + dlci_IB_mapping_t* result; + int err, counter, found; + + do { mbox->cmd.command = FR_READ_DLCI_IB_MAPPING; + mbox->cmd.length = 0; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + } while (err && retry-- && fr_event(card, err, mbox)); + + if( mbox->cmd.result != 0){ + printk(KERN_INFO "%s: Read DLCI IB Mapping failed\n", + chan->name); } - while (err && retry-- && fr_event(card, err, mbox)); - - if (mbox->cmd.result != 0) - printk(KERN_INFO "%s: Read DLCI IB Mapping failed\n", chan->name); counter = mbox->cmd.length / sizeof(dlci_IB_mapping_t); - result = (void *) mbox->data; + result = (void *)mbox->data; + found = 0; - for (; counter; --counter, ++result) - { - if (result->dlci == chan->dlci) - { - printk(KERN_INFO "%s: DLCI= %d, IB addr = %lx for %s\n" - ,card->devname, result->dlci, result->addr_value ,chan->name); + for (; counter; --counter, ++result) { + if ( result->dlci == chan->dlci ) { chan->IB_addr = result->addr_value; - chan->dlci_int_interface = (void *) (card->hw.dpmbase + - (chan->IB_addr & 0x00001FFF)); + if(card->hw.type == SDLA_S514){ + chan->dlci_int_interface = + (void*)(card->hw.dpmbase + + chan->IB_addr); + }else{ + chan->dlci_int_interface = + (void*)(card->hw.dpmbase + + (chan->IB_addr & 0x00001FFF)); + + } found = 1; - break; - } + break; + } } if (!found) - printk(KERN_INFO "%s: DLCI %d not found by IB MAPPING cmd\n", - card->devname, chan->dlci); + printk( KERN_INFO "%s: DLCI %d not found by IB MAPPING cmd\n", + card->devname, chan->dlci); +} + +void s508_s514_lock(sdla_t *card, unsigned long *smp_flags) +{ + + if (card->hw.type != SDLA_S514){ +#ifdef __SMP__ + spin_lock_irqsave(&card->lock, *smp_flags); +#else + disable_irq(card->hw.irq); +#endif + } +#ifdef __SMP__ + else{ + spin_lock(&card->lock); + } +#endif +} + +void s508_s514_unlock(sdla_t *card, unsigned long *smp_flags) +{ + if (card->hw.type != SDLA_S514){ +#ifdef __SMP__ + spin_unlock_irqrestore(&card->lock, *smp_flags); +#else + enable_irq(card->hw.irq); +#endif + } +#ifdef __SMP__ + else{ + spin_unlock(&card->lock); + } +#endif + } /****** End *****************************************************************/ diff -ur --new-file old/linux/drivers/net/wan/sdla_ppp.c new/linux/drivers/net/wan/sdla_ppp.c --- old/linux/drivers/net/wan/sdla_ppp.c Mon Oct 11 19:13:25 1999 +++ new/linux/drivers/net/wan/sdla_ppp.c Fri Jan 28 17:04:58 2000 @@ -1,21 +1,39 @@ /***************************************************************************** * sdla_ppp.c WANPIPE(tm) Multiprotocol WAN Link Driver. PPP module. * -* Author: Jaspreet Singh +* Author: Nenad Corbic * -* Copyright: (c) 1995-1997 Sangoma Technologies Inc. +* Copyright: (c) 1995-1999 Sangoma Technologies 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. * ============================================================================ -* Mar 15, 1998 Alan Cox o 2.1.8x basic port. +* +* Oct 25, 1999 Nenad Corbic o Support for 2.0.X kernels +* Moved dynamic route processing into +* a polling routine. +* Oct 07, 1999 Nenad Corbic o Support for S514 PCI card. +* Gideon Hack o UPD and Updates executed using timer interrupt +* Sep 10, 1999 Nenad Corbic o Fixed up the /proc statistics +* Jul 20, 1999 Nenad Corbic o Remove the polling routines and use +* interrupts instead. +* Sep 17, 1998 Jaspreet Singh o Updates for 2.2.X Kernels. +* Aug 13, 1998 Jaspreet Singh o Improved Line Tracing. +* Jun 22, 1998 David Fong o Added remote IP address assignment +* Mar 15, 1998 Alan Cox o 2.1.8x basic port. +* Apr 16, 1998 Jaspreet Singh o using htons() for the IPX protocol. +* Dec 09, 1997 Jaspreet Singh o Added PAP and CHAP. +* o Implemented new routines like +* ppp_set_inbnd_auth(), ppp_set_outbnd_auth(), +* tokenize() and strstrip(). * Nov 27, 1997 Jaspreet Singh o Added protection against enabling of irqs * while they have been disabled. * Nov 24, 1997 Jaspreet Singh o Fixed another RACE condition caused by * disabling and enabling of irqs. -* o Added new counters for stats on disable/enable* IRQs. +* o Added new counters for stats on disable/enable +* IRQs. * Nov 10, 1997 Jaspreet Singh o Initialized 'skb->mac.raw' to 'skb->data' * before every netif_rx(). * o Free up the device structure in del_if(). @@ -56,6 +74,7 @@ * Jan 06, 1997 Gene Kozin Initial version. *****************************************************************************/ +#include #include /* printk(), and other useful stuff */ #include /* offsetof(), etc. */ #include /* return codes */ @@ -65,10 +84,15 @@ #include /* WANPIPE common user API definitions */ #include /* ARPHRD_* defines */ #include /* htons(), etc. */ -#include /* copyto/from user */ -#define _GNUC_ -#include /* PPP firmware API definitions */ +#include /* sockaddr_in */ +#include /* in_aton(), in_ntoa() prototypes */ + +#include +#include +#include +#include /* PPP firmware API definitions */ +#include /* S514 Type Definition */ /****** Defines & Macros ****************************************************/ #ifdef _DEBUG_ @@ -76,130 +100,183 @@ #else #define STATIC static #endif -#define PPP_DFLT_MTU 1500 /* default MTU */ -#define PPP_MAX_MTU 4000 /* maximum MTU */ + +#define PPP_DFLT_MTU 1500 /* default MTU */ +#define PPP_MAX_MTU 4000 /* maximum MTU */ #define PPP_HDR_LEN 1 -#define CONNECT_TIMEOUT (90*HZ) /* link connection timeout */ -#define HOLD_DOWN_TIME (30*HZ) /* link hold down time */ + +#define CONNECT_TIMEOUT (90*HZ) /* link connection timeout */ +#define HOLD_DOWN_TIME (5*HZ) /* link hold down time : Changed from 30 to 5 */ /* For handle_IPXWAN() */ #define CVHexToAscii(b) (((unsigned char)(b) > (unsigned char)9) ? ((unsigned char)'A' + ((unsigned char)(b) - (unsigned char)10)) : ((unsigned char)'0' + (unsigned char)(b))) +/* Macro for enabling/disabling debugging comments */ +//#define NEX_DEBUG +#ifdef NEX_DEBUG +#define NEX_PRINTK(format, a...) printk(format, ## a) +#else +#define NEX_PRINTK(format, a...) +#endif /* NEX_DEBUG */ + +#define DCD(a) ( a & 0x08 ? "HIGH" : "LOW" ) +#define CTS(a) ( a & 0x20 ? "HIGH" : "LOW" ) +#define LCP(a) ( a == 0x09 ? "OPEN" : "CLOSED" ) +#define IP(a) ( a == 0x09 ? "ENABLED" : "DISABLED" ) + +#define TMR_INT_ENABLED_UPDATE 1 +#define TMR_INT_ENABLED_PPP_EVENT 2 +#define TMR_INT_ENABLED_UDP 4 + +/* Set Configuraton Command Definitions */ +#define PERCENT_TX_BUFF 60 +#define TIME_BETWEEN_CONF_REQ 30 +#define TIME_BETWEEN_PAP_CHAP_REQ 30 +#define WAIT_PAP_CHAP_WITHOUT_REPLY 300 +#define WAIT_AFTER_DCD_CTS_LOW 5 +#define TIME_DCD_CTS_LOW_AFTER_LNK_DOWN 10 +#define WAIT_DCD_HIGH_AFTER_ENABLE_COMM 900 +#define MAX_CONF_REQ_WITHOUT_REPLY 10 +#define MAX_TERM_REQ_WITHOUT_REPLY 2 +#define NUM_CONF_NAK_WITHOUT_REPLY 5 +#define NUM_AUTH_REQ_WITHOUT_REPLY 10 + +#define END_OFFSET 0x1F0 +#if LINUX_VERSION_CODE < 0x020125 +#define test_and_set_bit set_bit +#endif + /******Data Structures*****************************************************/ + /* This structure is placed in the private data area of the device structure. * The card structure used to occupy the private area but now the following * structure will incorporate the card structure along with PPP specific data */ - -typedef struct ppp_private_area + +typedef struct ppp_private_area { - sdla_t *card; + sdla_t* card; unsigned long router_start_time; /*router start time in sec */ - unsigned long tick_counter; /*used for 5 second counter */ - unsigned mc; /*multicast support on or off */ + unsigned long tick_counter; /*used for 5 second counter*/ + unsigned mc; /*multicast support on or off*/ + unsigned char enable_IPX; + unsigned long network_number; + unsigned char pap; + unsigned char chap; + unsigned char sysname[31]; /* system name for in-bnd auth*/ + unsigned char userid[511]; /* list of user ids */ + unsigned char passwd[511]; /* list of passwords */ + unsigned protocol; /* SKB Protocol */ + u32 ip_local; /* Local IP Address */ + u32 ip_remote; /* remote IP Address */ + + unsigned char timer_int_enabled; /* Who enabled the timer inter*/ + unsigned char update_comms_stats; /* Used by update function */ + unsigned long curr_trace_addr; /* Trace information */ + unsigned long start_trace_addr; + unsigned long end_trace_addr; + + unsigned short udp_pkt_lgth; + char udp_pkt_src; + char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT]; + /* PPP specific statistics */ - unsigned long if_send_entry; - unsigned long if_send_skb_null; - unsigned long if_send_broadcast; - unsigned long if_send_multicast; - unsigned long if_send_critical_ISR; - unsigned long if_send_critical_non_ISR; - unsigned long if_send_busy; - unsigned long if_send_busy_timeout; - unsigned long if_send_DRVSTATS_request; - unsigned long if_send_PTPIPE_request; - unsigned long if_send_wan_disconnected; - unsigned long if_send_adptr_bfrs_full; - unsigned long if_send_protocol_error; - unsigned long if_send_tx_int_enabled; - unsigned long if_send_bfr_passed_to_adptr; - unsigned long rx_intr_no_socket; - unsigned long rx_intr_DRVSTATS_request; - unsigned long rx_intr_PTPIPE_request; - unsigned long rx_intr_bfr_not_passed_to_stack; - unsigned long rx_intr_bfr_passed_to_stack; - unsigned long UDP_PTPIPE_mgmt_kmalloc_err; - unsigned long UDP_PTPIPE_mgmt_adptr_type_err; - unsigned long UDP_PTPIPE_mgmt_direction_err; - unsigned long UDP_PTPIPE_mgmt_adptr_cmnd_timeout; - unsigned long UDP_PTPIPE_mgmt_adptr_cmnd_OK; - unsigned long UDP_PTPIPE_mgmt_passed_to_adptr; - unsigned long UDP_PTPIPE_mgmt_passed_to_stack; - unsigned long UDP_PTPIPE_mgmt_no_socket; - unsigned long UDP_DRVSTATS_mgmt_kmalloc_err; - unsigned long UDP_DRVSTATS_mgmt_adptr_type_err; - unsigned long UDP_DRVSTATS_mgmt_direction_err; - unsigned long UDP_DRVSTATS_mgmt_adptr_cmnd_timeout; - unsigned long UDP_DRVSTATS_mgmt_adptr_cmnd_OK; - unsigned long UDP_DRVSTATS_mgmt_passed_to_adptr; - unsigned long UDP_DRVSTATS_mgmt_passed_to_stack; - unsigned long UDP_DRVSTATS_mgmt_no_socket; - unsigned long router_up_time; -} ppp_private_area_t; -/* variable for keeping track of enabling/disabling FT1 monitor status */ + if_send_stat_t if_send_stat; + rx_intr_stat_t rx_intr_stat; + pipe_mgmt_stat_t pipe_mgmt_stat; + unsigned long router_up_time; + +}ppp_private_area_t; + +/* variable for keeping track of enabling/disabling FT1 monitor status */ static int rCount = 0; + extern void disable_irq(unsigned int); extern void enable_irq(unsigned int); /****** Function Prototypes *************************************************/ /* WAN link driver entry points. These are called by the WAN router module. */ -static int update(wan_device_t * wandev); -static int new_if(wan_device_t * wandev, struct net_device *dev, - wanif_conf_t * conf); -static int del_if(wan_device_t * wandev, struct net_device *dev); +static int update(wan_device_t *wandev); +static int new_if(wan_device_t *wandev, struct net_device *dev, wanif_conf_t *conf); +static int del_if(wan_device_t *wandev, struct net_device *dev); + /* WANPIPE-specific entry points */ -static int wpp_exec(struct sdla *card, void *u_cmd, void *u_data); +static int wpp_exec (struct sdla *card, void *u_cmd, void *u_data); + /* Network device interface */ static int if_init(struct net_device *dev); static int if_open(struct net_device *dev); static int if_close(struct net_device *dev); -static int if_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, unsigned len); +static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, + void *daddr, void *saddr, unsigned len); static int if_rebuild_hdr(struct sk_buff *skb); +static struct net_device_stats *if_stats(struct net_device *dev); static int if_send(struct sk_buff *skb, struct net_device *dev); -static struct enet_statistics *if_stats(struct net_device *dev); + + /* PPP firmware interface functions */ -static int ppp_read_version(sdla_t * card, char *str); -static int ppp_configure(sdla_t * card, void *data); -static int ppp_set_intr_mode(sdla_t * card, unsigned mode); -static int ppp_comm_enable(sdla_t * card); -static int ppp_comm_disable(sdla_t * card); -static int ppp_get_err_stats(sdla_t * card); -static int ppp_send(sdla_t * card, void *data, unsigned len, unsigned proto); -static int ppp_error(sdla_t * card, int err, ppp_mbox_t * mb); -/* Interrupt handlers */ -STATIC void wpp_isr(sdla_t * card); -static void rx_intr(sdla_t * card); -static void tx_intr(sdla_t * card); +static int ppp_read_version(sdla_t *card, char *str); +static int ppp_set_outbnd_auth(sdla_t *card, ppp_private_area_t *ppp_priv_area); +static int ppp_set_inbnd_auth(sdla_t *card, ppp_private_area_t *ppp_priv_area); +static int ppp_configure(sdla_t *card, void *data); +static int ppp_set_intr_mode(sdla_t *card, unsigned char mode); +static int ppp_comm_enable(sdla_t *card); +static int ppp_comm_disable(sdla_t *card); +static int ppp_get_err_stats(sdla_t *card); +static int ppp_send(sdla_t *card, void *data, unsigned len, unsigned proto); +static int ppp_error(sdla_t *card, int err, ppp_mbox_t *mb); + +STATIC void wpp_isr(sdla_t *card); +static void rx_intr(sdla_t *card); +static void event_intr(sdla_t *card); +static void timer_intr(sdla_t *card); + /* Background polling routines */ -static void wpp_poll(sdla_t * card); -static void poll_active(sdla_t * card); -static void poll_connecting(sdla_t * card); -static void poll_disconnected(sdla_t * card); +static void process_route(sdla_t *card); +static void poll_disconnected(sdla_t *card); + /* Miscellaneous functions */ -static int config502(sdla_t * card); -static int config508(sdla_t * card); +static int read_info( sdla_t *card ); +static int read_connection_info (sdla_t *card); +static int remove_route( sdla_t *card ); +static int config508(ppp_private_area_t *ppp_priv_area, sdla_t *card); static void show_disc_cause(sdla_t * card, unsigned cause); -static unsigned char bps_to_speed_code(unsigned long bps); -static int reply_udp(unsigned char *data, unsigned int mbox_len); -static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, ppp_private_area_t * ppp_priv_area); -static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, ppp_private_area_t * ppp_priv_area); -static void init_ppp_tx_rx_buff(sdla_t * card); -static int intr_test(sdla_t * card); -static int udp_pkt_type(struct sk_buff *skb, sdla_t * card); -static void init_ppp_priv_struct(ppp_private_area_t * ppp_priv_area); -static void init_global_statistics(sdla_t * card); +static int reply_udp( unsigned char *data, unsigned int mbox_len ); +static void process_udp_mgmt_pkt(sdla_t *card, struct net_device *dev, + ppp_private_area_t *ppp_priv_area); +static void init_ppp_tx_rx_buff( sdla_t *card ); +static int intr_test( sdla_t *card ); +static int udp_pkt_type( struct sk_buff *skb , sdla_t *card); +static void init_ppp_priv_struct( ppp_private_area_t *ppp_priv_area); +static void init_global_statistics( sdla_t *card ); +static int tokenize(char *str, char **tokens); +static char* strstrip(char *str, char *s); +static int chk_bcast_mcast_addr(sdla_t* card, struct net_device* dev, + struct sk_buff *skb); +static int Read_connection_info; static int Intr_test_counter; -static char TracingEnabled; -static unsigned long curr_trace_addr; -static unsigned long start_trace_addr; static unsigned short available_buffer_space; + /* IPX functions */ -static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming); -static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number, unsigned short proto); +static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, + unsigned char incoming); +static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_PX, + unsigned long network_number, unsigned short proto); + +/* Lock Functions */ +static void s508_lock (sdla_t *card, unsigned long *smp_flags); +static void s508_unlock (sdla_t *card, unsigned long *smp_flags); + +static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card, + struct sk_buff *skb, struct net_device* dev, + ppp_private_area_t* ppp_priv_area ); +static unsigned short calc_checksum (char *data, int len); + + + /****** Public Functions ****************************************************/ @@ -215,30 +292,40 @@ * Return: 0 o.k. * < 0 failure. */ -int wpp_init(sdla_t * card, wandev_conf_t * conf) +int wpp_init(sdla_t *card, wandev_conf_t *conf) { - union { + union + { char str[80]; } u; + /* Verify configuration ID */ if (conf->config_id != WANCONFIG_PPP) { + printk(KERN_INFO "%s: invalid configuration ID %u!\n", - card->devname, conf->config_id); + card->devname, conf->config_id); return -EINVAL; + } - /* Initialize protocol-specific fields */ - switch (card->hw.fwid) { - case SFID_PPP502: - card->mbox = (void *) (card->hw.dpmbase + PPP502_MB_OFFS); - card->flags = (void *) (card->hw.dpmbase + PPP502_FLG_OFFS); - break; - case SFID_PPP508: - card->mbox = (void *) (card->hw.dpmbase + PPP508_MB_OFFS); - card->flags = (void *) (card->hw.dpmbase + PPP508_FLG_OFFS); - break; - default: - return -EINVAL; + + /* Initialize miscellaneous pointers to structures on the adapter */ + switch (card->hw.type) { + + case SDLA_S508: + card->mbox =(void*)(card->hw.dpmbase + PPP508_MB_OFFS); + card->flags=(void*)(card->hw.dpmbase + PPP508_FLG_OFFS); + break; + + case SDLA_S514: + card->mbox =(void*)(card->hw.dpmbase + PPP514_MB_OFFS); + card->flags=(void*)(card->hw.dpmbase + PPP514_FLG_OFFS); + break; + + default: + return -EINVAL; + } + /* Read firmware version. Note that when adapter initializes, it * clears the mailbox, so it may appear that the first command was * executed successfully when in fact it was merely erased. To work @@ -246,33 +333,36 @@ */ if (ppp_read_version(card, NULL) || ppp_read_version(card, u.str)) return -EIO; - printk(KERN_INFO "%s: running PPP firmware v%s\n", card->devname, u.str); + + printk(KERN_INFO "%s: running PPP firmware v%s\n",card->devname, u.str); /* Adjust configuration and set defaults */ card->wandev.mtu = (conf->mtu) ? - min(conf->mtu, PPP_MAX_MTU) : PPP_DFLT_MTU; - card->wandev.bps = conf->bps; - card->wandev.interface = conf->interface; - card->wandev.clocking = conf->clocking; - card->wandev.station = conf->station; - card->isr = &wpp_isr; - card->poll = &wpp_poll; - card->exec = &wpp_exec; - card->wandev.update = &update; - card->wandev.new_if = &new_if; - card->wandev.del_if = &del_if; - card->wandev.state = WAN_DISCONNECTED; - card->wandev.udp_port = conf->udp_port; - card->wandev.ttl = conf->ttl; + min(conf->mtu, PPP_MAX_MTU) : PPP_DFLT_MTU; + + card->wandev.bps = conf->bps; + card->wandev.interface = conf->interface; + card->wandev.clocking = conf->clocking; + card->wandev.station = conf->station; + card->isr = &wpp_isr; + card->poll = NULL; + card->exec = &wpp_exec; + card->wandev.update = &update; + card->wandev.new_if = &new_if; + card->wandev.del_if = &del_if; + card->wandev.state = WAN_DISCONNECTED; + card->wandev.udp_port = conf->udp_port; + card->wandev.ttl = conf->ttl; card->irq_dis_if_send_count = 0; - card->irq_dis_poll_count = 0; - TracingEnabled = 0; - card->wandev.enable_IPX = conf->enable_IPX; - if (conf->network_number) - card->wandev.network_number = conf->network_number; - else - card->wandev.network_number = 0xDEADBEEF; + card->irq_dis_poll_count = 0; + card->u.p.authenticator = conf->u.ppp.authenticator; + card->u.p.ip_mode = conf->u.ppp.ip_mode ? + conf->u.ppp.ip_mode : WANOPT_PPP_STATIC; + card->TracingEnabled = 0; + Read_connection_info = 1; + /* initialize global statistics */ - init_global_statistics(card); + init_global_statistics( card ); + return 0; } @@ -281,19 +371,43 @@ /*============================================================================ * Update device status & statistics. */ -static int update(wan_device_t * wandev) +static int update(wan_device_t *wandev) { - sdla_t *card; + sdla_t* card = wandev->private; + struct net_device* dev = card->wandev.dev; + volatile ppp_private_area_t *ppp_priv_area = dev->priv; + ppp_flags_t *flags = card->flags; + unsigned long timeout; + /* sanity checks */ if ((wandev == NULL) || (wandev->private == NULL)) return -EFAULT; + if (wandev->state == WAN_UNCONFIGURED) return -ENODEV; - if (test_and_set_bit(0, (void *) &wandev->critical)) + + //FIXME: Do we need this + if (test_bit(0, (void*)&wandev->critical)) return -EAGAIN; - card = wandev->private; - ppp_get_err_stats(card); - wandev->critical = 0; + + ppp_priv_area->update_comms_stats = 2; + ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_UPDATE; + flags->imask |= PPP_INTR_TIMER; + + /* wait a maximum of 1 second for the statistics to be updated */ + timeout = jiffies; + for(;;) { + if(ppp_priv_area->update_comms_stats == 0){ + break; + } + if ((jiffies - timeout) > (1 * HZ)){ + ppp_priv_area->update_comms_stats = 0; + ppp_priv_area->timer_int_enabled &= + ~TMR_INT_ENABLED_UPDATE; + return -EAGAIN; + } + } + return 0; } @@ -309,46 +423,98 @@ * Return: 0 o.k. * < 0 failure (channel will not be created) */ - -static int new_if(wan_device_t * wandev, struct net_device *dev, wanif_conf_t * conf) +static int new_if(wan_device_t *wandev, struct net_device *dev, wanif_conf_t *conf) { sdla_t *card = wandev->private; ppp_private_area_t *ppp_priv_area; + if (wandev->ndev) return -EEXIST; + if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) { + printk(KERN_INFO "%s: invalid interface name!\n", - card->devname); + card->devname); return -EINVAL; + } + /* allocate and initialize private data */ ppp_priv_area = kmalloc(sizeof(ppp_private_area_t), GFP_KERNEL); - if (ppp_priv_area == NULL) - return -ENOMEM; + + if( ppp_priv_area == NULL ) + return -ENOMEM; + memset(ppp_priv_area, 0, sizeof(ppp_private_area_t)); - ppp_priv_area->card = card; + + ppp_priv_area->card = card; + /* initialize data */ strcpy(card->u.p.if_name, conf->name); + /* initialize data in ppp_private_area structure */ - init_ppp_priv_struct(ppp_priv_area); + + init_ppp_priv_struct( ppp_priv_area ); + ppp_priv_area->mc = conf->mc; + ppp_priv_area->pap = conf->pap; + ppp_priv_area->chap = conf->chap; + + /* If no user ids are specified */ + if(!strlen(conf->userid) && (ppp_priv_area->pap||ppp_priv_area->chap)){ + kfree(ppp_priv_area); + return -EINVAL; + } + + /* If no passwords are specified */ + if(!strlen(conf->passwd) && (ppp_priv_area->pap||ppp_priv_area->chap)){ + kfree(ppp_priv_area); + return -EINVAL; + } + + if(strlen(conf->sysname) > 31){ + kfree(ppp_priv_area); + return -EINVAL; + } + + /* If no system name is specified */ + if(!strlen(conf->sysname) && (card->u.p.authenticator)){ + kfree(ppp_priv_area); + return -EINVAL; + } + + /* copy the data into the ppp private structure */ + memcpy(ppp_priv_area->userid, conf->userid, strlen(conf->userid)); + memcpy(ppp_priv_area->passwd, conf->passwd, strlen(conf->passwd)); + memcpy(ppp_priv_area->sysname, conf->sysname, strlen(conf->sysname)); + + + ppp_priv_area->enable_IPX = conf->enable_IPX; + if (conf->network_number) + ppp_priv_area->network_number = conf->network_number; + else + ppp_priv_area->network_number = 0xDEADBEEF; + + /* prepare network device data space for registration */ dev->name = card->u.p.if_name; dev->init = &if_init; dev->priv = ppp_priv_area; + return 0; } /*============================================================================ * Delete logical channel. */ - -static int del_if(wan_device_t * wandev, struct net_device *dev) +static int del_if(wan_device_t *wandev, struct net_device *dev) { if (dev->priv) { - kfree(dev->priv); - dev->priv = NULL; - } + + kfree(dev->priv); + dev->priv = NULL; + } + return 0; } @@ -358,26 +524,36 @@ * Execute adapter interface command. */ +//FIXME: Why do we need this ???? static int wpp_exec(struct sdla *card, void *u_cmd, void *u_data) { ppp_mbox_t *mbox = card->mbox; int len; - if(copy_from_user((void *) &mbox->cmd, u_cmd, sizeof(ppp_cmd_t))) + + if (copy_from_user((void*)&mbox->cmd, u_cmd, sizeof(ppp_cmd_t))) return -EFAULT; + len = mbox->cmd.length; + if (len) { - if(copy_from_user((void *) &mbox->data, u_data, len)) + + if( copy_from_user((void*)&mbox->data, u_data, len)) return -EFAULT; + } + /* execute command */ if (!sdla_exec(mbox)) return -EIO; + /* return result */ - if(copy_to_user(u_cmd, (void *) &mbox->cmd, sizeof(ppp_cmd_t))) + if( copy_to_user(u_cmd, (void*)&mbox->cmd, sizeof(ppp_cmd_t))) return -EFAULT; len = mbox->cmd.length; - if (len && u_data && copy_to_user(u_data, (void *) &mbox->data, len)) + + if (len && u_data && copy_to_user(u_data, (void*)&mbox->data, len)) return -EFAULT; + return 0; } @@ -390,32 +566,49 @@ * interface registration. Returning anything but zero will fail interface * registration. */ - static int if_init(struct net_device *dev) { ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card = ppp_priv_area->card; wan_device_t *wandev = &card->wandev; +#ifndef LINUX_2_1 + int i; +#endif /* Initialize device driver entry points */ - dev->open = &if_open; - dev->stop = &if_close; - dev->hard_header = &if_header; - dev->rebuild_header = &if_rebuild_hdr; - dev->hard_start_xmit = &if_send; - dev->get_stats = &if_stats; + dev->open = &if_open; + dev->stop = &if_close; + dev->hard_header = &if_header; + dev->rebuild_header = &if_rebuild_hdr; + dev->hard_start_xmit = &if_send; + dev->get_stats = &if_stats; + + /* Initialize media-specific parameters */ - dev->type = ARPHRD_PPP; /* ARP h/w type */ - dev->mtu = wandev->mtu; - dev->hard_header_len = PPP_HDR_LEN; /* media header length */ + dev->type = ARPHRD_PPP; /* ARP h/w type */ + dev->flags |= IFF_POINTOPOINT; + + /* Enable Mulitcasting if specified by user*/ + if (ppp_priv_area->mc == WANOPT_YES){ + dev->flags |= IFF_MULTICAST; + } + +#ifndef LINUX_2_1 + dev->family = AF_INET; +#endif + dev->mtu = wandev->mtu; + dev->hard_header_len = PPP_HDR_LEN; /* media header length */ + /* Initialize hardware parameters (just for reference) */ - dev->irq = wandev->irq; - dev->dma = wandev->dma; - dev->base_addr = wandev->ioport; - dev->mem_start = (unsigned long)wandev->maddr; - dev->mem_end = dev->mem_start + wandev->msize - 1; - /* Set transmit buffer queue length */ - dev->tx_queue_len = 100; + dev->irq = wandev->irq; + dev->dma = wandev->dma; + dev->base_addr = wandev->ioport; + dev->mem_start = wandev->maddr; + dev->mem_end = wandev->maddr + wandev->msize - 1; + + /* Set transmit buffer queue length */ + dev->tx_queue_len = 100; + /* Initialize socket buffers */ dev_init_buffers(dev); return 0; @@ -428,7 +621,6 @@ * * Return 0 if O.k. or errno. */ - static int if_open(struct net_device *dev) { ppp_private_area_t *ppp_priv_area = dev->priv; @@ -436,48 +628,100 @@ ppp_flags_t *flags = card->flags; struct timeval tv; int err = 0; + if (dev->start) - return -EBUSY; /* only one open is allowed */ - if (test_and_set_bit(0, (void *) &card->wandev.critical)) + return -EBUSY; /* only one open is allowed */ + + if (test_and_set_bit(0, (void*)&card->wandev.critical)) return -EAGAIN; - if ((card->hw.fwid == SFID_PPP502) ? config502(card) : config508(card)) { - err = -EIO; - card->wandev.critical = 0; - return err; - } - Intr_test_counter = 0; - err = intr_test(card); - if ((err) || (Intr_test_counter != (MAX_INTR_TEST_COUNTER + 1))) { - printk(KERN_INFO "%s: Interrupt Test Failed, Counter: %i\n", - card->devname, Intr_test_counter); - err = -EIO; - card->wandev.critical = 0; - return err; + + if (!card->configured){ + + if (config508(ppp_priv_area, card)){ + + err = -EIO; + card->wandev.critical = 0; + return err; + } + + Intr_test_counter = 0; + err = intr_test( card ); + + if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) { + printk("%s: Interrupt Test Failed, Counter: %i\n", + card->devname, Intr_test_counter); + printk( "%s: Please choose another interrupt\n",card->devname); + err = -EIO; + card->wandev.critical = 0; + return err; + } + + printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n", + card->devname, Intr_test_counter); + card->configured = 1; + } - printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n", - card->devname, Intr_test_counter); + /* Initialize Rx/Tx buffer control fields */ - init_ppp_tx_rx_buff(card); - if (ppp_set_intr_mode(card, 0x03)) { + init_ppp_tx_rx_buff( card ); + + if (ppp_set_intr_mode(card, PPP_INTR_RXRDY| + PPP_INTR_TXRDY| + PPP_INTR_MODEM| + PPP_INTR_CMD | + PPP_INTR_DISC | + PPP_INTR_OPEN | + PPP_INTR_DROP_DTR | + PPP_INTR_TIMER)) { + err = -EIO; card->wandev.critical = 0; return err; + + } + + /* Turn off the transmit and timer interrupt */ + flags->imask &= ~(PPP_INTR_TXRDY | PPP_INTR_TIMER) ; + + /* If you are not the authenticator and any one of the protocol is + * enabled then we call the set_out_bound_authentication. + */ + if ( !card->u.p.authenticator && (ppp_priv_area->pap || ppp_priv_area->chap)) { + if ( ppp_set_outbnd_auth(card, ppp_priv_area) ){ + err = -EIO; + card->wandev.critical = 0; + return err; + } + } + + /* If you are the authenticator and any one of the protocol is enabled + * then we call the set_in_bound_authentication. + */ + if ( card->u.p.authenticator && (ppp_priv_area->pap || ppp_priv_area->chap)) { + if ( ppp_set_inbnd_auth(card, ppp_priv_area) ){ + err = -EIO; + card->wandev.critical = 0; + return err; + } } - flags->imask &= ~0x02; + if (ppp_comm_enable(card)) { err = -EIO; card->wandev.critical = 0; return err; } + + wanpipe_set_state(card, WAN_CONNECTING); wanpipe_open(card); dev->mtu = min(dev->mtu, card->wandev.mtu); dev->interrupt = 0; dev->tbusy = 0; dev->start = 1; - do_gettimeofday(&tv); + do_gettimeofday( &tv ); ppp_priv_area->router_start_time = tv.tv_sec; card->wandev.critical = 0; + return err; } @@ -486,13 +730,14 @@ * o if this is the last open, then disable communications and interrupts. * o reset flags. */ - static int if_close(struct net_device *dev) { ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card = ppp_priv_area->card; - if (test_and_set_bit(0, (void *) &card->wandev.critical)) + + if (test_and_set_bit(0, (void*)&card->wandev.critical)) return -EAGAIN; + dev->start = 0; wanpipe_close(card); wanpipe_set_state(card, WAN_DISCONNECTED); @@ -511,19 +756,21 @@ * * Return: media header length. */ - static int if_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, unsigned len) + unsigned short type, void *daddr, void *saddr, unsigned len) { - switch (type) + switch (type) { case ETH_P_IP: + case ETH_P_IPX: - skb->protocol = type; + skb->protocol = htons(type); break; + default: skb->protocol = 0; } + return PPP_HDR_LEN; } @@ -534,13 +781,14 @@ * 0 physical address not resolved */ -static int if_rebuild_hdr(struct sk_buff *skb) +static int if_rebuild_hdr (struct sk_buff *skb) { - struct net_device *dev=skb->dev; + struct net_device *dev = skb->dev; ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card = ppp_priv_area->card; + printk(KERN_INFO "%s: rebuild_header() called for interface %s!\n", - card->devname, dev->name); + card->devname, dev->name); return 1; } @@ -561,303 +809,355 @@ * 2. Setting tbusy flag will inhibit further transmit requests from the * protocol stack and can be used for flow control with protocol layer. */ - -static int if_send(struct sk_buff *skb, struct net_device *dev) +static int if_send (struct sk_buff *skb, struct net_device *dev) { ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card = ppp_priv_area->card; unsigned char *sendpacket; - unsigned long check_braddr, check_mcaddr; - unsigned long host_cpu_flags; + unsigned long smp_flags; ppp_flags_t *flags = card->flags; int retry = 0; - int err, udp_type; - ++ppp_priv_area->if_send_entry; + int udp_type; + + + ++ppp_priv_area->if_send_stat.if_send_entry; + if (skb == NULL) { + /* If we get here, some higher layer thinks we've missed an * tx-done interrupt. */ printk(KERN_INFO "%s: interface %s got kicked!\n", - card->devname, dev->name); - ++ppp_priv_area->if_send_skb_null; + card->devname, dev->name); + + ++ppp_priv_area->if_send_stat.if_send_skb_null; + mark_bh(NET_BH); return 0; + } + if (dev->tbusy) { + /* If our device stays busy for at least 5 seconds then we will * kick start the device by making dev->tbusy = 0. We expect * that our device never stays busy more than 5 seconds. So this * is only used as a last resort. */ - ++ppp_priv_area->if_send_busy; - ++card->wandev.stats.collisions; - if ((jiffies - ppp_priv_area->tick_counter) < (5 * HZ)) { + + ++ppp_priv_area->if_send_stat.if_send_tbusy; + ++card->wandev.stats.collisions; + + if ((jiffies - ppp_priv_area->tick_counter) < (5*HZ)) { return 1; } - printk(KERN_INFO "%s: Transmit times out\n", card->devname); - ++ppp_priv_area->if_send_busy_timeout; - /* unbusy the card (because only one interface per card) */ + + printk (KERN_INFO "%s: Transmit times out\n",card->devname); + + ++ppp_priv_area->if_send_stat.if_send_tbusy_timeout; + ++card->wandev.stats.collisions; + + /* unbusy the card (because only one interface per card)*/ dev->tbusy = 0; - } + } sendpacket = skb->data; - udp_type = udp_pkt_type(skb, card); - if (udp_type == UDP_DRVSTATS_TYPE) { - ++ppp_priv_area->if_send_DRVSTATS_request; - process_udp_driver_call(UDP_PKT_FRM_STACK, card, skb, dev, - ppp_priv_area); - dev_kfree_skb(skb); - return 0; - } else if (udp_type == UDP_PTPIPE_TYPE) - ++ppp_priv_area->if_send_PTPIPE_request; - /* retreive source address in two forms: broadcast & multicast */ - check_braddr = sendpacket[15]; - check_mcaddr = sendpacket[12]; - check_braddr = check_braddr << 8; - check_mcaddr = check_mcaddr << 8; - check_braddr |= sendpacket[14]; - check_mcaddr |= sendpacket[13]; - check_braddr = check_braddr << 8; - check_mcaddr = check_mcaddr << 8; - check_braddr |= sendpacket[13]; - check_mcaddr |= sendpacket[14]; - check_braddr = check_braddr << 8; - check_mcaddr = check_mcaddr << 8; - check_braddr |= sendpacket[12]; - check_mcaddr |= sendpacket[15]; - /* if the Source Address is a Multicast address */ - if ((ppp_priv_area->mc == WANOPT_NO) && (check_mcaddr >= 0xE0000001) - && (check_mcaddr <= 0xFFFFFFFE)) { - printk(KERN_INFO "%s: Mutlicast Src. Addr. silently discarded\n" - ,card->devname); - dev_kfree_skb(skb); - ++ppp_priv_area->if_send_multicast; - ++card->wandev.stats.tx_dropped; + + udp_type = udp_pkt_type( skb, card ); + + + if (udp_type == UDP_PTPIPE_TYPE){ + if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev, + ppp_priv_area)){ + flags->imask |= PPP_INTR_TIMER; + } + ++ppp_priv_area->if_send_stat.if_send_PIPE_request; return 0; + } - disable_irq(card->hw.irq); - ++card->irq_dis_if_send_count; - if (test_and_set_bit(0, (void *) &card->wandev.critical)) { - if (card->wandev.critical == CRITICAL_IN_ISR) { - /* If the critical flag is set due to an Interrupt - * then set enable transmit interrupt flag to enable - * transmit interrupt. (delay interrupt) - */ - card->wandev.enable_tx_int = 1; - dev->tbusy = 1; - /* set the counter to see if we get the interrupt in - * 5 seconds. - */ - ppp_priv_area->tick_counter = jiffies; - ++ppp_priv_area->if_send_critical_ISR; - save_flags(host_cpu_flags); - cli(); - if ((!(--card->irq_dis_if_send_count)) && - (!card->irq_dis_poll_count)) - enable_irq(card->hw.irq); - restore_flags(host_cpu_flags); - return 1; + + /* Check for broadcast and multicast addresses + * If found, drop (deallocate) a packet and return. + */ + if(chk_bcast_mcast_addr(card, dev, skb)){ + return 0; + } + + + if(card->hw.type != SDLA_S514){ + s508_lock(card,&smp_flags); + } + + if (test_and_set_bit(0, (void*)&card->wandev.critical)) { + + printk(KERN_INFO "%s: Critical in if_send: %x\n", + card->wandev.name,card->wandev.critical); + dev_kfree_skb(skb); + + ++card->wandev.stats.tx_dropped; + ++ppp_priv_area->if_send_stat.if_send_critical_non_ISR; + + if(card->hw.type != SDLA_S514){ + s508_unlock(card,&smp_flags); } - dev_kfree_skb(skb); - ++ppp_priv_area->if_send_critical_non_ISR; - save_flags(host_cpu_flags); - cli(); - if ((!(--card->irq_dis_if_send_count)) && - (!card->irq_dis_poll_count)) - enable_irq(card->hw.irq); - restore_flags(host_cpu_flags); + return 0; } - if (udp_type == UDP_PTPIPE_TYPE) { - err = process_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, - dev, ppp_priv_area); - } else if (card->wandev.state != WAN_CONNECTED) { - ++ppp_priv_area->if_send_wan_disconnected; - ++card->wandev.stats.tx_dropped; - } else if (!skb->protocol) { - ++ppp_priv_area->if_send_protocol_error; - ++card->wandev.stats.tx_errors; + + if (card->wandev.state != WAN_CONNECTED) { + + ++ppp_priv_area->if_send_stat.if_send_wan_disconnected; + ++card->wandev.stats.tx_dropped; + + } else if (!skb->protocol) { + ++ppp_priv_area->if_send_stat.if_send_protocol_error; + ++card->wandev.stats.tx_errors; + } else { - /*If it's IPX change the network numbers to 0 if they're ours. */ - if (skb->protocol == ETH_P_IPX) { - if (card->wandev.enable_IPX) { - switch_net_numbers(skb->data, - card->wandev.network_number, 0); + + /*If it's IPX change the network numbers to 0 if they're ours.*/ + if( skb->protocol == htons(ETH_P_IPX) ) { + if(ppp_priv_area->enable_IPX) { + switch_net_numbers( skb->data, + ppp_priv_area->network_number, 0); } else { ++card->wandev.stats.tx_dropped; goto tx_done; } } + if (ppp_send(card, skb->data, skb->len, skb->protocol)) { retry = 1; dev->tbusy = 1; - ++ppp_priv_area->if_send_adptr_bfrs_full; - ++ppp_priv_area->if_send_tx_int_enabled; + ++ppp_priv_area->if_send_stat.if_send_adptr_bfrs_full; + ++ppp_priv_area->if_send_stat.if_send_tx_int_enabled; ppp_priv_area->tick_counter = jiffies; - ++card->wandev.stats.tx_errors; flags->imask |= 0x02; /* unmask Tx interrupts */ } else { - ++ppp_priv_area->if_send_bfr_passed_to_adptr; + ++ppp_priv_area->if_send_stat.if_send_bfr_passed_to_adptr; ++card->wandev.stats.tx_packets; card->wandev.stats.tx_bytes += skb->len; } - } -tx_done: - if (!retry) { + } + +tx_done: + if (!retry){ dev_kfree_skb(skb); } + card->wandev.critical = 0; - save_flags(host_cpu_flags); - cli(); - if ((!(--card->irq_dis_if_send_count)) && (!card->irq_dis_poll_count)) - enable_irq(card->hw.irq); - restore_flags(host_cpu_flags); + + if(card->hw.type != SDLA_S514){ + s508_unlock(card,&smp_flags); + } + + return retry; } + +/*============================================================================= + * Store a UDP management packet for later processing. + */ + +static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card, + struct sk_buff *skb, struct net_device* dev, + ppp_private_area_t* ppp_priv_area ) +{ + int udp_pkt_stored = 0; + + if(!ppp_priv_area->udp_pkt_lgth && (skb->len<=MAX_LGTH_UDP_MGNT_PKT)){ + ppp_priv_area->udp_pkt_lgth = skb->len; + ppp_priv_area->udp_pkt_src = udp_pkt_src; + memcpy(ppp_priv_area->udp_pkt_data, skb->data, skb->len); + ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_UDP; + ppp_priv_area->protocol = skb->protocol; + udp_pkt_stored = 1; + }else{ + if (skb->len > MAX_LGTH_UDP_MGNT_PKT){ + printk(KERN_INFO "%s: PIPEMON UDP request too long : %i\n", + card->devname, skb->len); + }else{ + printk(KERN_INFO "%s: PIPEMON UPD request already pending\n", + card->devname); + } + ppp_priv_area->udp_pkt_lgth = 0; + } + + dev_kfree_skb(skb); + return(udp_pkt_stored); +} + + + /*============================================================================ * Reply to UDP Management system. * Return length of reply. */ - -static int reply_udp(unsigned char *data, unsigned int mbox_len) +static int reply_udp( unsigned char *data, unsigned int mbox_len ) { - unsigned short len, udp_length, temp, i, ip_length; - unsigned long sum; + unsigned short len, udp_length, temp, ip_length; + unsigned long ip_temp; + int even_bound = 0; + ppp_udp_pkt_t *p_udp_pkt = (ppp_udp_pkt_t *)data; + /* Set length of packet */ - len = mbox_len + 60; + len = sizeof(ip_pkt_t)+ + sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + mbox_len; + /* fill in UDP reply */ - data[36] = 0x02; + p_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY; + /* fill in UDP length */ - udp_length = mbox_len + 40; + udp_length = sizeof(udp_pkt_t)+ + sizeof(wp_mgmt_t)+ + sizeof(cblock_t)+ + mbox_len; + + /* put it on an even boundary */ - if (udp_length & 0x0001) { + if ( udp_length & 0x0001 ) { udp_length += 1; len += 1; - } - temp = (udp_length << 8) | (udp_length >> 8); - memcpy(&data[24], &temp, 2); + even_bound=1; + } + + temp = (udp_length<<8)|(udp_length>>8); + p_udp_pkt->udp_pkt.udp_length = temp; + + /* swap UDP ports */ - memcpy(&temp, &data[20], 2); - memcpy(&data[20], &data[22], 2); - memcpy(&data[22], &temp, 2); + temp = p_udp_pkt->udp_pkt.udp_src_port; + p_udp_pkt->udp_pkt.udp_src_port = + p_udp_pkt->udp_pkt.udp_dst_port; + p_udp_pkt->udp_pkt.udp_dst_port = temp; + + /* add UDP pseudo header */ temp = 0x1100; - memcpy(&data[udp_length + 20], &temp, 2); - temp = (udp_length << 8) | (udp_length >> 8); - memcpy(&data[udp_length + 22], &temp, 2); + *((unsigned short *)(p_udp_pkt->data+mbox_len+even_bound)) = temp; + temp = (udp_length<<8)|(udp_length>>8); + *((unsigned short *)(p_udp_pkt->data+mbox_len+even_bound+2)) = temp; + /* calculate UDP checksum */ - data[26] = data[27] = 0; - sum = 0; - for (i = 0; i < udp_length + 12; i += 2) { - memcpy(&temp, &data[12 + i], 2); - sum += (unsigned long) temp; - } - while (sum >> 16) { - sum = (sum & 0xffffUL) + (sum >> 16); - } - temp = (unsigned short) sum; - temp = ~temp; - if (temp == 0) - temp = 0xffff; - memcpy(&data[26], &temp, 2); + p_udp_pkt->udp_pkt.udp_checksum = 0; + p_udp_pkt->udp_pkt.udp_checksum = + calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET); + /* fill in IP length */ - ip_length = udp_length + 20; - temp = (ip_length << 8) | (ip_length >> 8); - memcpy(&data[2], &temp, 2); + ip_length = udp_length + sizeof(ip_pkt_t); + temp = (ip_length<<8)|(ip_length>>8); + p_udp_pkt->ip_pkt.total_length = temp; + /* swap IP addresses */ - memcpy(&temp, &data[12], 2); - memcpy(&data[12], &data[16], 2); - memcpy(&data[16], &temp, 2); - memcpy(&temp, &data[14], 2); - memcpy(&data[14], &data[18], 2); - memcpy(&data[18], &temp, 2); + ip_temp = p_udp_pkt->ip_pkt.ip_src_address; + p_udp_pkt->ip_pkt.ip_src_address = p_udp_pkt->ip_pkt.ip_dst_address; + p_udp_pkt->ip_pkt.ip_dst_address = ip_temp; + /* fill in IP checksum */ - data[10] = data[11] = 0; - sum = 0; - for (i = 0; i < 20; i += 2) { - memcpy(&temp, &data[i], 2); - sum += (unsigned long) temp; + p_udp_pkt->ip_pkt.hdr_checksum = 0; + p_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data,sizeof(ip_pkt_t)); + + return len; + +} /* reply_udp */ + +unsigned short calc_checksum (char *data, int len) +{ + unsigned short temp; + unsigned long sum=0; + int i; + + for( i = 0; i > 16) { + + while (sum >> 16 ) { sum = (sum & 0xffffUL) + (sum >> 16); } - temp = (unsigned short) sum; + + temp = (unsigned short)sum; temp = ~temp; - if (temp == 0) + + if( temp == 0 ) temp = 0xffff; - memcpy(&data[10], &temp, 2); - return len; -} /* reply_udp */ + + return temp; +} /* If incoming is 0 (outgoing)- if the net numbers is ours make it 0 if incoming is 1 - if the net number is 0 make it ours - */ +*/ static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming) { unsigned long pnetwork_number; - pnetwork_number = (unsigned long) ((sendpacket[6] << 24) + - (sendpacket[7] << 16) + (sendpacket[8] << 8) + - sendpacket[9]); + + pnetwork_number = (unsigned long)((sendpacket[6] << 24) + + (sendpacket[7] << 16) + (sendpacket[8] << 8) + + sendpacket[9]); + if (!incoming) { - /* If the destination network number is ours, make it 0 */ - if (pnetwork_number == network_number) { - sendpacket[6] = sendpacket[7] = sendpacket[8] = - sendpacket[9] = 0x00; + //If the destination network number is ours, make it 0 + if( pnetwork_number == network_number) { + sendpacket[6] = sendpacket[7] = sendpacket[8] = + sendpacket[9] = 0x00; } } else { - /* If the incoming network is 0, make it ours */ - if (pnetwork_number == 0) { - sendpacket[6] = (unsigned char) (network_number >> 24); - sendpacket[7] = (unsigned char) ((network_number & - 0x00FF0000) >> 16); - sendpacket[8] = (unsigned char) ((network_number & - 0x0000FF00) >> 8); - sendpacket[9] = (unsigned char) (network_number & - 0x000000FF); + //If the incoming network is 0, make it ours + if( pnetwork_number == 0) { + sendpacket[6] = (unsigned char)(network_number >> 24); + sendpacket[7] = (unsigned char)((network_number & + 0x00FF0000) >> 16); + sendpacket[8] = (unsigned char)((network_number & + 0x0000FF00) >> 8); + sendpacket[9] = (unsigned char)(network_number & + 0x000000FF); } } - pnetwork_number = (unsigned long) ((sendpacket[18] << 24) + - (sendpacket[19] << 16) + (sendpacket[20] << 8) + - sendpacket[21]); - if (!incoming) { - /* If the source network is ours, make it 0 */ - if (pnetwork_number == network_number) { - sendpacket[18] = sendpacket[19] = sendpacket[20] = - sendpacket[21] = 0x00; + + + pnetwork_number = (unsigned long)((sendpacket[18] << 24) + + (sendpacket[19] << 16) + (sendpacket[20] << 8) + + sendpacket[21]); + + if( !incoming ) { + //If the source network is ours, make it 0 + if( pnetwork_number == network_number) { + sendpacket[18] = sendpacket[19] = sendpacket[20] = + sendpacket[21] = 0x00; } } else { - /* If the source network is 0, make it ours */ - if (pnetwork_number == 0) { - sendpacket[18] = (unsigned char) (network_number >> 24); - sendpacket[19] = (unsigned char) ((network_number & - 0x00FF0000) >> 16); - sendpacket[20] = (unsigned char) ((network_number & - 0x0000FF00) >> 8); - sendpacket[21] = (unsigned char) (network_number & - 0x000000FF); + //If the source network is 0, make it ours + if( pnetwork_number == 0 ) { + sendpacket[18] = (unsigned char)(network_number >> 24); + sendpacket[19] = (unsigned char)((network_number & + 0x00FF0000) >> 16); + sendpacket[20] = (unsigned char)((network_number & + 0x0000FF00) >> 8); + sendpacket[21] = (unsigned char)(network_number & + 0x000000FF); } } -} /* switch_net_numbers */ +} /* switch_net_numbers */ /*============================================================================ - * Get Ethernet-style interface statistics. - * Return a pointer to struct enet_statistics. + * Get ethernet-style interface statistics. + * Return a pointer to struct net_device_stats. */ - -static struct enet_statistics *if_stats(struct net_device *dev) +static struct net_device_stats *if_stats(struct net_device *dev) { + ppp_private_area_t *ppp_priv_area = dev->priv; - sdla_t *card; + sdla_t* card; - /* - * Device is down:No statistics - */ - - if(ppp_priv_area==NULL) + if( ppp_priv_area == NULL ) return NULL; - + card = ppp_priv_area->card; return &card->wandev.stats; } @@ -868,122 +1168,257 @@ * Read firmware code version. * Put code version as ASCII string in str. */ - -static int ppp_read_version(sdla_t * card, char *str) +static int ppp_read_version(sdla_t *card, char *str) { ppp_mbox_t *mb = card->mbox; int err; + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); mb->cmd.command = PPP_READ_CODE_VERSION; err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + if (err != CMD_OK) + ppp_error(card, err, mb); + else if (str) { + int len = mb->cmd.length; + memcpy(str, mb->data, len); str[len] = '\0'; + + } + + return err; +} +/*=========================================================================== + * Set Out-Bound Authentication. +*/ +static int ppp_set_outbnd_auth (sdla_t *card, ppp_private_area_t *ppp_priv_area) +{ + ppp_mbox_t *mb = card->mbox; + int err; + + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); + memset(&mb->data, 0, (strlen(ppp_priv_area->userid) + + strlen(ppp_priv_area->passwd) + 2 ) ); + memcpy(mb->data, ppp_priv_area->userid, strlen(ppp_priv_area->userid)); + memcpy((mb->data + strlen(ppp_priv_area->userid) + 1), + ppp_priv_area->passwd, strlen(ppp_priv_area->passwd)); + + mb->cmd.length = strlen(ppp_priv_area->userid) + + strlen(ppp_priv_area->passwd) + 2 ; + + mb->cmd.command = PPP_SET_OUTBOUND_AUTH; + + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK) + ppp_error(card, err, mb); + + return err; +} + +/*=========================================================================== + * Set In-Bound Authentication. +*/ +static int ppp_set_inbnd_auth (sdla_t *card, ppp_private_area_t *ppp_priv_area) +{ + ppp_mbox_t *mb = card->mbox; + int err, i; + char* user_tokens[32]; + char* pass_tokens[32]; + int userids, passwds; + int add_ptr; + + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); + memset(&mb->data, 0, 1008); + memcpy(mb->data, ppp_priv_area->sysname, + strlen(ppp_priv_area->sysname)); + + /* Parse the userid string and the password string and build a string + to copy it to the data area of the command structure. The string + will look like "SYS_NAMEUSER1PASS1USER2PASS2 + .... " + */ + userids = tokenize( ppp_priv_area->userid, user_tokens); + passwds = tokenize( ppp_priv_area->passwd, pass_tokens); + + if (userids != passwds){ + printk(KERN_INFO "%s: Number of passwords does not equal the number of user ids\n", card->devname); + return 1; + } + + add_ptr = strlen(ppp_priv_area->sysname) + 1; + for (i=0; idata + add_ptr), user_tokens[i], + strlen(user_tokens[i])); + memcpy((mb->data + add_ptr + strlen(user_tokens[i]) + 1), + pass_tokens[i], strlen(pass_tokens[i])); + add_ptr = add_ptr + strlen(user_tokens[i]) + 1 + + strlen(pass_tokens[i]) + 1; } + + mb->cmd.length = add_ptr + 1; + mb->cmd.command = PPP_SET_INBOUND_AUTH; + + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK) + ppp_error(card, err, mb); + return err; } + +/*============================================================================ + * Tokenize string. + * Parse a string of the following syntax: + * ,,... + * and fill array of tokens with pointers to string elements. + * + */ +static int tokenize (char *str, char **tokens) +{ + int cnt = 0; + + tokens[0] = strtok(str, "/"); + while (tokens[cnt] && (cnt < 32 - 1)) + { + tokens[cnt] = strstrip(tokens[cnt], " \t"); + tokens[++cnt] = strtok(NULL, "/"); + } + return cnt; +} + /*============================================================================ - * Configure PPP firmware. + * Strip leading and trailing spaces off the string str. */ +static char* strstrip (char *str, char* s) +{ + char *eos = str + strlen(str); /* -> end of string */ -static int ppp_configure(sdla_t * card, void *data) + while (*str && strchr(s, *str)) + ++str /* strip leading spaces */ + ; + while ((eos > str) && strchr(s, *(eos - 1))) + --eos /* strip trailing spaces */ + ; + *eos = '\0'; + return str; +} +/*============================================================================ + * Configure PPP firmware. + */ +static int ppp_configure(sdla_t *card, void *data) { ppp_mbox_t *mb = card->mbox; - int data_len = (card->hw.fwid == SFID_PPP502) ? - sizeof(ppp502_conf_t) : sizeof(ppp508_conf_t); + int data_len = sizeof(ppp508_conf_t); int err; + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); memcpy(mb->data, data, data_len); - mb->cmd.length = data_len; + mb->cmd.length = data_len; mb->cmd.command = PPP_SET_CONFIG; err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; - if (err != CMD_OK) + + if (err != CMD_OK) ppp_error(card, err, mb); + return err; } /*============================================================================ * Set interrupt mode. */ - -static int ppp_set_intr_mode(sdla_t * card, unsigned mode) +static int ppp_set_intr_mode(sdla_t *card, unsigned char mode) { ppp_mbox_t *mb = card->mbox; + ppp_intr_info_t *ppp_intr_data = (ppp_intr_info_t *) &mb->data[0]; int err; + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); - mb->data[0] = mode; - switch (card->hw.fwid) { - case SFID_PPP502: - mb->cmd.length = 1; - break; - case SFID_PPP508: - default: - mb->data[1] = card->hw.irq; - mb->cmd.length = 2; - } + ppp_intr_data->i_enable = mode; + + ppp_intr_data->irq = card->hw.irq; + mb->cmd.length = 2; + + /* If timer has been enabled, set the timer delay to 1sec */ + if (mode & 0x80){ + ppp_intr_data->timer_len = 5;//100; //250; + mb->cmd.length = 4; + } + mb->cmd.command = PPP_SET_INTR_FLAGS; err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; - if (err != CMD_OK) + + if (err != CMD_OK) ppp_error(card, err, mb); + + return err; } /*============================================================================ * Enable communications. */ - -static int ppp_comm_enable(sdla_t * card) +static int ppp_comm_enable(sdla_t *card) { ppp_mbox_t *mb = card->mbox; int err; + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); mb->cmd.command = PPP_COMM_ENABLE; err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; - if (err != CMD_OK) + + if (err != CMD_OK) ppp_error(card, err, mb); + return err; } /*============================================================================ * Disable communications. */ - -static int ppp_comm_disable(sdla_t * card) +static int ppp_comm_disable(sdla_t *card) { ppp_mbox_t *mb = card->mbox; int err; + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); mb->cmd.command = PPP_COMM_DISABLE; err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; - if (err != CMD_OK) + if (err != CMD_OK) ppp_error(card, err, mb); + return err; } /*============================================================================ * Get communications error statistics. */ - -static int ppp_get_err_stats(sdla_t * card) +static int ppp_get_err_stats(sdla_t *card) { ppp_mbox_t *mb = card->mbox; int err; + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); mb->cmd.command = PPP_READ_ERROR_STATS; err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + if (err == CMD_OK) { - ppp_err_stats_t *stats = (void *) mb->data; - card->wandev.stats.rx_over_errors = stats->rx_overrun; - card->wandev.stats.rx_crc_errors = stats->rx_bad_crc; - card->wandev.stats.rx_missed_errors = stats->rx_abort; - card->wandev.stats.rx_length_errors = stats->rx_lost; + + ppp_err_stats_t* stats = (void*)mb->data; + card->wandev.stats.rx_over_errors = stats->rx_overrun; + card->wandev.stats.rx_crc_errors = stats->rx_bad_crc; + card->wandev.stats.rx_missed_errors = stats->rx_abort; + card->wandev.stats.rx_length_errors = stats->rx_lost; card->wandev.stats.tx_aborted_errors = stats->tx_abort; - } else + + } else ppp_error(card, err, mb); + return err; } @@ -992,27 +1427,30 @@ * Return: 0 - o.k. * 1 - no transmit buffers available */ - -static int ppp_send(sdla_t * card, void *data, unsigned len, unsigned proto) +static int ppp_send (sdla_t *card, void *data, unsigned len, unsigned proto) { ppp_buf_ctl_t *txbuf = card->u.p.txbuf; - unsigned long addr; + if (txbuf->flag) - return 1 - ; - if (card->hw.fwid == SFID_PPP502) - addr = (txbuf->buf.o_p[1] << 8) + txbuf->buf.o_p[0]; - else - addr = txbuf->buf.ptr; - sdla_poke(&card->hw, addr, data, len); - txbuf->length = len; /* frame length */ - if (proto == ETH_P_IPX) + return 1; + + sdla_poke(&card->hw, txbuf->buf.ptr, data, len); + + txbuf->length = len; /* frame length */ + + if (proto == htons(ETH_P_IPX)) txbuf->proto = 0x01; /* protocol ID */ - txbuf->flag = 1; /* start transmission */ + else + txbuf->proto = 0x00; /* protocol ID */ + + txbuf->flag = 1; /* start transmission */ + /* Update transmit buffer control fields */ card->u.p.txbuf = ++txbuf; - if ((void *) txbuf > card->u.p.txbuf_last) + + if ((void*)txbuf > card->u.p.txbuf_last) card->u.p.txbuf = card->u.p.txbuf_base; + return 0; } @@ -1025,19 +1463,22 @@ * * Return zero if previous command has to be cancelled. */ - -static int ppp_error(sdla_t * card, int err, ppp_mbox_t * mb) +static int ppp_error(sdla_t *card, int err, ppp_mbox_t *mb) { unsigned cmd = mb->cmd.command; + switch (err) { - case CMD_TIMEOUT: - printk(KERN_ERR "%s: command 0x%02X timed out!\n", - card->devname, cmd); - break; - default: - printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n" - ,card->devname, cmd, err); + + case CMD_TIMEOUT: + printk(KERN_ERR "%s: command 0x%02X timed out!\n", + card->devname, cmd); + break; + + default: + printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n" + , card->devname, cmd, err); } + return 0; } @@ -1046,81 +1487,89 @@ /*============================================================================ * PPP interrupt service routine. */ - -STATIC void wpp_isr(sdla_t * card) +STATIC void wpp_isr(sdla_t *card) { ppp_flags_t *flags = card->flags; char *ptr = &flags->iflag; - unsigned long host_cpu_flags; struct net_device *dev = card->wandev.dev; + + int i; + card->in_isr = 1; + ++card->statistics.isr_entry; - if (test_and_set_bit(0, (void *) &card->wandev.critical)) { - ++card->statistics.isr_already_critical; - printk(KERN_INFO "%s: Critical while in ISR!\n", card->devname); - card->in_isr = 0; - return; + + //FIXME: Do we need this + card->force_enable_irq = 0; + + if(card->hw.type != SDLA_S514){ + if (test_and_set_bit(0, (void*)&card->wandev.critical)) { + + ++card->statistics.isr_already_critical; + printk (KERN_INFO "%s: Critical while in ISR!\n", + card->devname); + card->in_isr = 0; + return; + + } } - /* For all interrupts set the critical flag to CRITICAL_IN_ISR. - * If the if_send routine is called with this flag set it will set - * the enable transmit flag to 1. (for a delayed interrupt) - */ - card->wandev.critical = CRITICAL_IN_ISR; + card->buff_int_mode_unbusy = 0; + switch (flags->iflag) { - case 0x01: /* receive interrupt */ - ++card->statistics.isr_rx; - rx_intr(card); - break; - case 0x02: /* transmit interrupt */ - ++card->statistics.isr_tx; - flags->imask &= ~0x02; - dev->tbusy = 0; - card->buff_int_mode_unbusy = 1; - break; - case 0x08: - ++Intr_test_counter; - ++card->statistics.isr_intr_test; - break; - default: /* unexpected interrupt */ - ++card->statistics.isr_spurious; - printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n", - card->devname, flags->iflag); - printk(KERN_INFO "%s: ID Bytes = ", card->devname); - for (i = 0; i < 8; i++) - printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i)); - printk(KERN_INFO "\n"); - } - /* The critical flag is set to CRITICAL_INTR_HANDLED to let the - * if_send call know that the interrupt is handled so that - * transmit interrupts are not enabled again. - */ - card->wandev.critical = CRITICAL_INTR_HANDLED; - /* If the enable transmit interrupt flag is set then enable transmit - * interrupt on the board. This only goes through if if_send is called - * and the critical flag is set due to an Interrupt. - */ - if (card->wandev.enable_tx_int) { - flags->imask |= 0x02; - card->wandev.enable_tx_int = 0; - ++card->statistics.isr_enable_tx_int; + + case PPP_INTR_RXRDY: /* receive interrupt 0x01 (bit 0)*/ + ++card->statistics.isr_rx; + rx_intr(card); + break; + + case PPP_INTR_TXRDY: /* transmit interrupt 0x02 (bit 1)*/ + ++card->statistics.isr_tx; + flags->imask &= ~PPP_INTR_TXRDY; + dev->tbusy = 0; + card->buff_int_mode_unbusy = 1; + break; + + case PPP_INTR_CMD: /* interface command completed */ + ++Intr_test_counter; + ++card->statistics.isr_intr_test; + break; + + case PPP_INTR_MODEM: /* modem status change (DCD, CTS) 0x04 (bit 2)*/ + case PPP_INTR_DISC: /* Data link disconnected 0x10 (bit 4)*/ + case PPP_INTR_OPEN: /* Data link open 0x20 (bit 5)*/ + case PPP_INTR_DROP_DTR: /* DTR drop timeout expired 0x40 bit 6 */ + event_intr(card); + break; + + case PPP_INTR_TIMER: + timer_intr(card); + break; + + default: /* unexpected interrupt */ + ++card->statistics.isr_spurious; + printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n", + card->devname, flags->iflag); + printk(KERN_INFO "%s: ID Bytes = ",card->devname); + for(i = 0; i < 8; i ++) + printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i)); + printk(KERN_INFO "\n"); } - save_flags(host_cpu_flags); - cli(); + card->in_isr = 0; flags->iflag = 0; card->wandev.critical = 0; - restore_flags(host_cpu_flags); - if (card->buff_int_mode_unbusy) + + if(card->buff_int_mode_unbusy) { mark_bh(NET_BH); + } } /*============================================================================ * Receive interrupt handler. */ - -static void rx_intr(sdla_t * card) +static void rx_intr(sdla_t *card) { ppp_buf_ctl_t *rxbuf = card->rxmb; struct net_device *dev = card->wandev.dev; @@ -1128,160 +1577,338 @@ struct sk_buff *skb; unsigned len; void *buf; - int i, err; - ppp_flags_t *flags = card->flags; - char *ptr = &flags->iflag; + int i; + ppp_flags_t *flags = card->flags; + char *ptr = &flags->iflag; int udp_type; + + if (rxbuf->flag != 0x01) { - printk(KERN_INFO - "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n", - card->devname, (unsigned) rxbuf, rxbuf->flag); - printk(KERN_INFO "%s: ID Bytes = ", card->devname); - for (i = 0; i < 8; i++) + + printk(KERN_INFO + "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n", + card->devname, (unsigned)rxbuf, rxbuf->flag); + + printk(KERN_INFO "%s: ID Bytes = ",card->devname); + + for(i = 0; i < 8; i ++) printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i)); - printk(KERN_INFO "\n"); + printk(KERN_INFO "\n"); + ++card->statistics.rx_intr_corrupt_rx_bfr; return; + } + if (dev && dev->start) { - len = rxbuf->length; + + len = rxbuf->length; ppp_priv_area = dev->priv; + /* Allocate socket buffer */ skb = dev_alloc_skb(len); + if (skb != NULL) { + /* Copy data to the socket buffer */ - if (card->hw.fwid == SFID_PPP502) { - unsigned addr = (rxbuf->buf.o_p[1] << 8) + - rxbuf->buf.o_p[0]; - buf = skb_put(skb, len); - sdla_peek(&card->hw, addr, buf, len); - } else { - unsigned addr = rxbuf->buf.ptr; - if ((addr + len) > card->u.p.rx_top + 1) { - unsigned tmp = card->u.p.rx_top - addr - + 1; - buf = skb_put(skb, tmp); - sdla_peek(&card->hw, addr, buf, tmp); - addr = card->u.p.rx_base; - len -= tmp; - } - buf = skb_put(skb, len); - sdla_peek(&card->hw, addr, buf, len); + unsigned addr = rxbuf->buf.ptr; + + if ((addr + len) > card->u.p.rx_top + 1) { + + unsigned tmp = card->u.p.rx_top - addr + 1; + buf = skb_put(skb, tmp); + sdla_peek(&card->hw, addr, buf, tmp); + addr = card->u.p.rx_base; + len -= tmp; } + buf = skb_put(skb, len); + sdla_peek(&card->hw, addr, buf, len); + /* Decapsulate packet */ - switch (rxbuf->proto) { - case 0x00: - skb->protocol = htons(ETH_P_IP); - break; - case 0x01: - skb->protocol = htons(ETH_P_IPX); - break; + switch (rxbuf->proto) { + + case 0x00: + skb->protocol = htons(ETH_P_IP); + break; + + case 0x01: + skb->protocol = htons(ETH_P_IPX); + break; } - udp_type = udp_pkt_type(skb, card); - if (udp_type == UDP_DRVSTATS_TYPE) { - ++ppp_priv_area->rx_intr_DRVSTATS_request; - process_udp_driver_call( - UDP_PKT_FRM_NETWORK, card, skb, - dev, ppp_priv_area); - dev_kfree_skb(skb); - } else if (udp_type == UDP_PTPIPE_TYPE) { - ++ppp_priv_area->rx_intr_PTPIPE_request; - err = process_udp_mgmt_pkt( - UDP_PKT_FRM_NETWORK, card, - skb, dev, ppp_priv_area); - dev_kfree_skb(skb); - } else if (handle_IPXWAN(skb->data, card->devname, card->wandev.enable_IPX, card->wandev.network_number, skb->protocol)) { - if (card->wandev.enable_IPX) { - ppp_send(card, skb->data, skb->len, ETH_P_IPX); - dev_kfree_skb(skb); + + udp_type = udp_pkt_type( skb, card ); + + if (udp_type == UDP_PTPIPE_TYPE){ + + /* Handle a UDP Request in Timer Interrupt */ + if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK, card, skb, dev, + ppp_priv_area)){ + flags->imask |= PPP_INTR_TIMER; + } + ++ppp_priv_area->rx_intr_stat.rx_intr_PIPE_request; + + + } else if (handle_IPXWAN(skb->data,card->devname, + ppp_priv_area->enable_IPX, + ppp_priv_area->network_number, + skb->protocol)) { + + /* Handle an IPXWAN packet */ + if( ppp_priv_area->enable_IPX) { + ppp_send(card, skb->data, skb->len, htons(ETH_P_IPX)); + dev_kfree_skb(skb); + + } else { ++card->wandev.stats.rx_dropped; } } else { - /* Pass it up the protocol stack */ - skb->dev = dev; - skb->mac.raw = skb->data; + /* Pass data up the protocol stack */ + skb->dev = dev; + skb->mac.raw = skb->data; + + ++card->wandev.stats.rx_packets; + card->wandev.stats.rx_bytes += skb->len; + ++ppp_priv_area->rx_intr_stat.rx_intr_bfr_passed_to_stack; netif_rx(skb); - ++card->wandev.stats.rx_packets; - card->wandev.stats.rx_bytes += skb->len; - ++ppp_priv_area->rx_intr_bfr_passed_to_stack; } + } else { + printk(KERN_INFO "%s: no socket buffers available!\n", - card->devname); + card->devname); ++card->wandev.stats.rx_dropped; - ++ppp_priv_area->rx_intr_no_socket; + ++ppp_priv_area->rx_intr_stat.rx_intr_no_socket; + + dev_kfree_skb(skb); } - } else + + } else { ++card->statistics.rx_intr_dev_not_started; + } + /* Release buffer element and calculate a pointer to the next one */ - rxbuf->flag = (card->hw.fwid == SFID_PPP502) ? 0xFF : 0x00; + rxbuf->flag = 0x00; card->rxmb = ++rxbuf; - if ((void *) rxbuf > card->u.p.rxbuf_last) + if ((void*)rxbuf > card->u.p.rxbuf_last) card->rxmb = card->u.p.rxbuf_base; } -/*============================================================================ - * Transmit interrupt handler. - */ -static void tx_intr(sdla_t * card) +void event_intr (sdla_t *card) { - struct net_device *dev = card->wandev.dev; - if (!dev || !dev->start) { - ++card->statistics.tx_intr_dev_not_started; - return; + + struct net_device* dev = card->wandev.dev; + ppp_private_area_t* ppp_priv_area = dev->priv; + volatile ppp_flags_t *flags = card->flags; + + switch (flags->iflag){ + + case PPP_INTR_MODEM: /* modem status change (DCD, CTS) 0x04 (bit 2)*/ + printk (KERN_INFO "%s: Modem status: DCD=%s CTS=%s\n", + card->devname, DCD(flags->mstatus), CTS(flags->mstatus)); + + break; + + case PPP_INTR_DISC: /* Data link disconnected 0x10 (bit 4)*/ + + NEX_PRINTK (KERN_INFO "Data link disconnected intr Cause %X\n", + flags->disc_cause); + + if (flags->disc_cause & + (PPP_LOCAL_TERMINATION | PPP_DCD_CTS_DROP | + PPP_REMOTE_TERMINATION)) { + if (card->u.p.ip_mode == WANOPT_PPP_PEER) { + Read_connection_info = 1; + remove_route (card); + } + wanpipe_set_state(card, WAN_DISCONNECTED); + show_disc_cause(card, flags->disc_cause); + ppp_priv_area->timer_int_enabled |= + TMR_INT_ENABLED_PPP_EVENT; + flags->imask |= PPP_INTR_TIMER; + } + break; + + case PPP_INTR_OPEN: /* Data link open 0x20 (bit 5)*/ + + NEX_PRINTK (KERN_INFO "%s: PPP Link Open, LCP=%s IP=%s\n", + card->devname,LCP(flags->lcp_state), + IP(flags->ip_state)); + + if (flags->lcp_state == 0x09 && + (flags->ip_state == 0x09 || flags->ipx_state == 0x09)){ + /* Initialize the polling timer and set the state + * to WAN_CONNNECTED + */ + card->state_tick = jiffies; + wanpipe_set_state(card, WAN_CONNECTED); + ppp_priv_area->timer_int_enabled |= + TMR_INT_ENABLED_PPP_EVENT; + flags->imask |= PPP_INTR_TIMER; + + } + break; + + case PPP_INTR_DROP_DTR: /* DTR drop timeout expired 0x40 bit 6 */ + + NEX_PRINTK(KERN_INFO "DTR Drop Timeout Interrrupt \n"); + if (card->u.p.ip_mode == WANOPT_PPP_PEER) { + Read_connection_info = 1; + remove_route (card); + } + wanpipe_set_state(card, WAN_DISCONNECTED); + show_disc_cause(card, flags->disc_cause); + ppp_priv_area->timer_int_enabled |= + TMR_INT_ENABLED_PPP_EVENT; + flags->imask |= PPP_INTR_TIMER; + break; + + default: + printk(KERN_INFO "%s: Error, Invalid PPP Event\n",card->devname); } - dev->tbusy = 0; - mark_bh(NET_BH); } + + +/* TIMER INTERRUPT */ + +void timer_intr (sdla_t *card) +{ + + struct net_device* dev = card->wandev.dev; + ppp_private_area_t* ppp_priv_area = dev->priv; + ppp_flags_t *flags = card->flags; + + /* Update statistics */ + if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE){ + ppp_get_err_stats(card); + if(!(--ppp_priv_area->update_comms_stats)){ + ppp_priv_area->timer_int_enabled &= + ~TMR_INT_ENABLED_UPDATE; + } + } + + /* PPIPEMON UDP request */ + + if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP){ + process_udp_mgmt_pkt(card,dev, ppp_priv_area); + ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP; + } + + + /* PPP Event */ + if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_PPP_EVENT){ + + if (card->wandev.state == WAN_DISCONNECTED){ + poll_disconnected(card); + } + + /* If the state is CONNECTING, it means that communicatins were + * enabled. When the remote side enables its comminication we + * should get an interrupt PPP_INTR_OPEN, thus turn off polling + */ + + else if (card->wandev.state == WAN_CONNECTING){ + /* Turn off the timer interrupt */ + ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_PPP_EVENT; + } + + /* If state is connected and we are in PEER mode + * poll for an IP address which will be provided by remote end. + */ + else if ((card->wandev.state == WAN_CONNECTED && + card->u.p.ip_mode == WANOPT_PPP_PEER) && + Read_connection_info){ + + card->state_tick = jiffies; + if (!read_connection_info (card)){ + card->poll = &process_route; + } + + }else{ + /* If we are using Static IP,no need to poll for + * an IP address. + */ + NEX_PRINTK(KERN_INFO "Turning off TIMER \n"); + ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_PPP_EVENT; + } + + }/* End of PPP_EVENT */ + + + /* Only disable the timer interrupt if there are no udp, statistic */ + /* updates or events pending */ + if(!ppp_priv_area->timer_int_enabled) { + flags->imask &= ~PPP_INTR_TIMER; + } +} + + static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number, unsigned short proto) { int i; - if (proto == htons(ETH_P_IPX)) { - /* It's an IPX packet */ - if (!enable_IPX) { - /* Return 1 so we don't pass it up the stack. */ + + if( proto == htons(ETH_P_IPX) ) { + //It's an IPX packet + if(!enable_IPX) { + //Return 1 so we don't pass it up the stack. return 1; } } else { - /* It's not IPX so pass it up the stack. */ + //It's not IPX so pass it up the stack. return 0; } - if (sendpacket[16] == 0x90 && - sendpacket[17] == 0x04) { - /* It's IPXWAN */ - if (sendpacket[2] == 0x02 && - sendpacket[34] == 0x00) { - /* It's a timer request packet */ - printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n", devname); - /* Go through the routing options and answer no to every */ - /* option except Unnumbered RIP/SAP */ - for (i = 41; sendpacket[i] == 0x00; i += 5) { - /* 0x02 is the option for Unnumbered RIP/SAP */ - if (sendpacket[i + 4] != 0x02) { + + if( sendpacket[16] == 0x90 && + sendpacket[17] == 0x04) + { + //It's IPXWAN + + if( sendpacket[2] == 0x02 && + sendpacket[34] == 0x00) + { + //It's a timer request packet + printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n",devname); + + //Go through the routing options and answer no to every + //option except Unnumbered RIP/SAP + for(i = 41; sendpacket[i] == 0x00; i += 5) + { + //0x02 is the option for Unnumbered RIP/SAP + if( sendpacket[i + 4] != 0x02) + { sendpacket[i + 1] = 0; } } - /* Skip over the extended Node ID option */ - if (sendpacket[i] == 0x04) { + + //Skip over the extended Node ID option + if( sendpacket[i] == 0x04 ) + { i += 8; } - /* We also want to turn off all header compression opt. */ - for (; sendpacket[i] == 0x80;) { + + //We also want to turn off all header compression opt. + for(; sendpacket[i] == 0x80 ;) + { sendpacket[i + 1] = 0; i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4; } - /* Set the packet type to timer response */ + + //Set the packet type to timer response sendpacket[34] = 0x01; - printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n", devname); - } else if (sendpacket[34] == 0x02) { - /* This is an information request packet */ - printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n", devname); - /* Set the packet type to information response */ + + printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n",devname); + } + else if( sendpacket[34] == 0x02 ) + { + //This is an information request packet + printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n",devname); + + //Set the packet type to information response sendpacket[34] = 0x03; - /* Set the router name */ + + //Set the router name sendpacket[51] = 'P'; sendpacket[52] = 'T'; sendpacket[53] = 'P'; @@ -1290,136 +1917,81 @@ sendpacket[56] = 'E'; sendpacket[57] = '-'; sendpacket[58] = CVHexToAscii(network_number >> 28); - sendpacket[59] = CVHexToAscii((network_number & 0x0F000000) >> 24); - sendpacket[60] = CVHexToAscii((network_number & 0x00F00000) >> 20); - sendpacket[61] = CVHexToAscii((network_number & 0x000F0000) >> 16); - sendpacket[62] = CVHexToAscii((network_number & 0x0000F000) >> 12); - sendpacket[63] = CVHexToAscii((network_number & 0x00000F00) >> 8); - sendpacket[64] = CVHexToAscii((network_number & 0x000000F0) >> 4); + sendpacket[59] = CVHexToAscii((network_number & 0x0F000000)>> 24); + sendpacket[60] = CVHexToAscii((network_number & 0x00F00000)>> 20); + sendpacket[61] = CVHexToAscii((network_number & 0x000F0000)>> 16); + sendpacket[62] = CVHexToAscii((network_number & 0x0000F000)>> 12); + sendpacket[63] = CVHexToAscii((network_number & 0x00000F00)>> 8); + sendpacket[64] = CVHexToAscii((network_number & 0x000000F0)>> 4); sendpacket[65] = CVHexToAscii(network_number & 0x0000000F); - for (i = 66; i < 99; i += 1) + for(i = 66; i < 99; i+= 1) + { sendpacket[i] = 0; - printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n", devname); - } else { - printk(KERN_INFO "%s: Unknown IPXWAN packet!\n", devname); + } + + printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n",devname); + } + else + { + printk(KERN_INFO "%s: Unknown IPXWAN packet!\n",devname); return 0; } - /* Set the WNodeID to our network address */ - sendpacket[35] = (unsigned char) (network_number >> 24); - sendpacket[36] = (unsigned char) ((network_number & 0x00FF0000) >> 16); - sendpacket[37] = (unsigned char) ((network_number & 0x0000FF00) >> 8); - sendpacket[38] = (unsigned char) (network_number & 0x000000FF); + + //Set the WNodeID to our network address + sendpacket[35] = (unsigned char)(network_number >> 24); + sendpacket[36] = (unsigned char)((network_number & 0x00FF0000) >> 16); + sendpacket[37] = (unsigned char)((network_number & 0x0000FF00) >> 8); + sendpacket[38] = (unsigned char)(network_number & 0x000000FF); + return 1; } else { - /* If we get here's its an IPX-data packet, so it'll get passed up the stack. */ - /* switch the network numbers */ - switch_net_numbers(sendpacket, network_number, 1); + //If we get here's its an IPX-data packet, so it'll get passed up the stack. + + //switch the network numbers + switch_net_numbers(sendpacket, network_number, 1); return 0; } } /****** Background Polling Routines ****************************************/ -/*============================================================================ - * Main polling routine. - * This routine is repeatedly called by the WANPIPE 'thread' to allow for - * time-dependent housekeeping work. - * - * Notes: - * 1. This routine may be called on interrupt context with all interrupts - * enabled. Beware! +/* All polling functions are invoked by the TIMER interrupt in the wpp_isr + * routine. */ -static void wpp_poll(sdla_t * card) +/*============================================================================ + * Monitor active link phase. + */ +static void process_route (sdla_t *card) { + ppp_flags_t *flags = card->flags; struct net_device *dev = card->wandev.dev; - ppp_flags_t *adptr_flags = card->flags; - unsigned long host_cpu_flags; - ++card->statistics.poll_entry; - /* The wpp_poll is called continously by the WANPIPE thread to allow - * for line state housekeeping. However if we are in a connected state - * then we do not need to go through all the checks everytime. When in - * connected state execute wpp_poll once every second. - */ - if (card->wandev.state == WAN_CONNECTED) { - if ((jiffies - card->state_tick) < HZ) - return; - } - disable_irq(card->hw.irq); - ++card->irq_dis_poll_count; - if (test_and_set_bit(0, (void *) &card->wandev.critical)) { - ++card->statistics.poll_already_critical; - printk(KERN_INFO "%s: critical inside wpp_poll\n", - card->devname); - save_flags(host_cpu_flags); - cli(); - if ((!card->irq_dis_if_send_count) && - (!(--card->irq_dis_poll_count))) - enable_irq(card->hw.irq); - restore_flags(host_cpu_flags); - return; - } - ++card->statistics.poll_processed; - if (dev && dev->tbusy && !(adptr_flags->imask & 0x02)) { - ++card->statistics.poll_tbusy_bad_status; - printk(KERN_INFO "%s: Wpp_Poll: tbusy = 0x01, imask = 0x%02X\n" - ,card->devname, adptr_flags->imask); - } - switch (card->wandev.state) { - case WAN_CONNECTED: - card->state_tick = jiffies; - poll_active(card); - break; - case WAN_CONNECTING: - poll_connecting(card); - break; - case WAN_DISCONNECTED: - poll_disconnected(card); - break; - default: - printk(KERN_INFO "%s: Unknown Poll State 0x%02X\n", - card->devname, card->wandev.state); - break; - } - card->wandev.critical = 0; - save_flags(host_cpu_flags); - cli(); - if ((!card->irq_dis_if_send_count) && (!(--card->irq_dis_poll_count))) - enable_irq(card->hw.irq); - restore_flags(host_cpu_flags); -} - -/*============================================================================ - * Monitor active link phase. - */ - -static void poll_active(sdla_t * card) -{ - ppp_flags_t *flags = card->flags; - /* We check the lcp_state to see if we are in DISCONNECTED state. - * We are considered to be connected for lcp states 0x06, 0x07, 0x08 - * and 0x09. - */ - if ((flags->lcp_state <= 0x05) || (flags->disc_cause & 0x03)) { - wanpipe_set_state(card, WAN_DISCONNECTED); - show_disc_cause(card, flags->disc_cause); + struct in_device *in_dev = dev->ip_ptr; + + if (in_dev != NULL ) { + if ((card->u.p.ip_mode == WANOPT_PPP_PEER) && + (Read_connection_info && flags->ip_state == 0x09)){ + + printk(KERN_INFO "%s: IPCP State Opened.\n", card->devname); + if (read_info( card )) { + printk(KERN_INFO + "%s: An error occurred in IP assignment.\n", + card->devname); + } else { + struct in_ifaddr *ifa = in_dev->ifa_list; + printk(KERN_INFO "%s: Assigned Lcl. Addr: %s\n", + card->devname, in_ntoa(ifa->ifa_local)); + printk(KERN_INFO "%s: Assigned Rmt. Addr: %s\n", + card->devname, in_ntoa(ifa->ifa_address)); + } + Read_connection_info = 0; + } + }else{ + printk(KERN_INFO "%s: Error: Null pointer in Poll Active\n", + card->devname); } -} - -/*============================================================================ - * Monitor link establishment phase. - * o if connection timed out, disconnect the link. - */ + card->poll = NULL; -static void poll_connecting(sdla_t * card) -{ - ppp_flags_t *flags = card->flags; - if (flags->lcp_state == 0x09) { - wanpipe_set_state(card, WAN_CONNECTED); - } else if (flags->disc_cause & 0x03) { - wanpipe_set_state(card, WAN_DISCONNECTED); - show_disc_cause(card, flags->disc_cause); - } } /*============================================================================ @@ -1427,794 +1999,796 @@ * o if interface is up and the hold-down timeout has expired, then retry * connection. */ - -static void poll_disconnected(sdla_t * card) +static void poll_disconnected(sdla_t *card) { struct net_device *dev = card->wandev.dev; + if (dev && dev->start && ((jiffies - card->state_tick) > HOLD_DOWN_TIME)) { + wanpipe_set_state(card, WAN_CONNECTING); - if (ppp_comm_enable(card) == CMD_OK) - init_ppp_tx_rx_buff(card); + + if(ppp_comm_enable(card) == CMD_OK){ + init_ppp_tx_rx_buff( card ); + } + } } /****** Miscellaneous Functions *********************************************/ /*============================================================================ - * Configure S502 adapter. - */ - -static int config502(sdla_t * card) -{ - ppp502_conf_t cfg; - /* Prepare PPP configuration structure */ - memset(&cfg, 0, sizeof(ppp502_conf_t)); - if (card->wandev.clocking) - cfg.line_speed = bps_to_speed_code(card->wandev.bps); - cfg.txbuf_num = 4; - cfg.mtu_local = card->wandev.mtu; - cfg.mtu_remote = card->wandev.mtu; - cfg.restart_tmr = 30; - cfg.auth_rsrt_tmr = 30; - cfg.auth_wait_tmr = 300; - cfg.mdm_fail_tmr = 5; - cfg.dtr_drop_tmr = 1; - cfg.connect_tmout = 0; /* changed it from 900 */ - cfg.conf_retry = 10; - cfg.term_retry = 2; - cfg.fail_retry = 5; - cfg.auth_retry = 10; - cfg.ip_options = 0x80; - cfg.ipx_options = 0xA0; - cfg.conf_flags |= 0x0E; -/* - cfg.ip_local = dev->pa_addr; - cfg.ip_remote = dev->pa_dstaddr; - */ - return ppp_configure(card, &cfg); -} - -/*============================================================================ * Configure S508 adapter. */ - -static int config508(sdla_t * card) +static int config508(ppp_private_area_t *ppp_priv_area, sdla_t *card) { ppp508_conf_t cfg; + struct net_device *dev = card->wandev.dev; + struct in_device *in_dev = dev->ip_ptr; + /* Prepare PPP configuration structure */ memset(&cfg, 0, sizeof(ppp508_conf_t)); + if (card->wandev.clocking) cfg.line_speed = card->wandev.bps; + if (card->wandev.interface == WANOPT_RS232) - cfg.conf_flags |= 0x0020; - cfg.conf_flags |= 0x300; /*send Configure-Request packets forever */ - cfg.txbuf_percent = 60; /* % of Tx bufs */ - cfg.mtu_local = card->wandev.mtu; - cfg.mtu_remote = card->wandev.mtu; - cfg.restart_tmr = 30; - cfg.auth_rsrt_tmr = 30; - cfg.auth_wait_tmr = 300; - cfg.mdm_fail_tmr = 100; - cfg.dtr_drop_tmr = 1; - cfg.connect_tmout = 0; /* changed it from 900 */ - cfg.conf_retry = 10; - cfg.term_retry = 2; - cfg.fail_retry = 5; - cfg.auth_retry = 10; - cfg.ip_options = 0x80; - cfg.ipx_options = 0xA0; -/* - cfg.ip_local = dev->pa_addr; - cfg.ip_remote = dev->pa_dstaddr; - */ + cfg.conf_flags |= INTERFACE_LEVEL_RS232; + + cfg.conf_flags |= DONT_TERMINATE_LNK_MAX_CONFIG; /*send Configure-Request packets forever*/ + cfg.txbuf_percent = PERCENT_TX_BUFF; /* % of Tx bufs */ + cfg.mtu_local = card->wandev.mtu; + cfg.mtu_remote = card->wandev.mtu; /* Default */ + cfg.restart_tmr = TIME_BETWEEN_CONF_REQ; /* 30 = 3sec */ + cfg.auth_rsrt_tmr = TIME_BETWEEN_PAP_CHAP_REQ; /* 30 = 3sec */ + cfg.auth_wait_tmr = WAIT_PAP_CHAP_WITHOUT_REPLY; /* 300 = 30s */ + cfg.mdm_fail_tmr = WAIT_AFTER_DCD_CTS_LOW; /* 5 = 0.5s */ + cfg.dtr_drop_tmr = TIME_DCD_CTS_LOW_AFTER_LNK_DOWN; /* 10 = 1s */ + cfg.connect_tmout = WAIT_DCD_HIGH_AFTER_ENABLE_COMM; /* 900 = 90s */ + cfg.conf_retry = MAX_CONF_REQ_WITHOUT_REPLY; /* 10 = 1s */ + cfg.term_retry = MAX_TERM_REQ_WITHOUT_REPLY; /* 2 times */ + cfg.fail_retry = NUM_CONF_NAK_WITHOUT_REPLY; /* 5 times */ + cfg.auth_retry = NUM_AUTH_REQ_WITHOUT_REPLY; /* 10 times */ + + + if( !card->u.p.authenticator ) { + printk(KERN_INFO "%s: Device is not configured as an authenticator\n", + card->devname); + cfg.auth_options = NO_AUTHENTICATION; + }else{ + printk(KERN_INFO "%s: Device is configured as an authenticator\n", + card->devname); + cfg.auth_options = INBOUND_AUTH; + } + if( ppp_priv_area->pap == WANOPT_YES){ + cfg.auth_options |=PAP_AUTH; + printk(KERN_INFO "%s: Pap enabled\n", card->devname); + } + if( ppp_priv_area->chap == WANOPT_YES){ + cfg.auth_options |= CHAP_AUTH; + printk(KERN_INFO "%s: Chap enabled\n", card->devname); + } + + + if (ppp_priv_area->enable_IPX == WANOPT_YES){ + cfg.ipx_options = ENABLE_IPX | ROUTING_PROT_DEFAULT; + }else{ + cfg.ipx_options = DISABLE_IPX; + } + + switch (card->u.p.ip_mode) { + + case WANOPT_PPP_STATIC: + + cfg.ip_options = L_AND_R_IP_NO_ASSIG | + ENABLE_IP; + cfg.ip_local = in_dev->ifa_list->ifa_local; + cfg.ip_remote = in_dev->ifa_list->ifa_address; + NEX_PRINTK(KERN_INFO "Local %s Remote %s Name %s\n", + in_ntoa(cfg.ip_local), + in_ntoa(cfg.ip_remote), + dev->name); + break; + + case WANOPT_PPP_PEER: + cfg.ip_options = L_IP_REMOTE_ASSIG | + R_IP_REMOTE_ASSIG | + ENABLE_IP; + cfg.ip_local = 0x00; + cfg.ip_remote = 0x00; + break; + + } return ppp_configure(card, &cfg); } /*============================================================================ * Show disconnection cause. */ - -static void show_disc_cause(sdla_t * card, unsigned cause) +static void show_disc_cause(sdla_t *card, unsigned cause) { - if (cause & 0x0002) - printk(KERN_INFO "%s: link terminated by peer\n", - card->devname); - else if (cause & 0x0004) - printk(KERN_INFO "%s: link terminated by user\n", - card->devname); - else if (cause & 0x0008) + if (cause & 0x0802) + + printk(KERN_INFO "%s: link terminated by peer\n", + card->devname); + + else if (cause & 0x0004) + + printk(KERN_INFO "%s: link terminated by user\n", + card->devname); + + else if (cause & 0x0008) + printk(KERN_INFO "%s: authentication failed\n", card->devname); - else if (cause & 0x0010) - printk(KERN_INFO - "%s: authentication protocol negotiation failed\n", - card->devname); - else if (cause & 0x0020) - printk(KERN_INFO - "%s: peer's request for authentication rejected\n", - card->devname); - else if (cause & 0x0040) - printk(KERN_INFO "%s: MRU option rejected by peer\n", - card->devname); - else if (cause & 0x0080) - printk(KERN_INFO "%s: peer's MRU was too small\n", - card->devname); - else if (cause & 0x0100) - printk(KERN_INFO "%s: failed to negotiate peer's LCP options\n", - card->devname); - else if (cause & 0x0200) - printk(KERN_INFO "%s: failed to negotiate peer's IPCP options\n" - ,card->devname); - else if (cause & 0x0400) + + else if (cause & 0x0010) + + printk(KERN_INFO + "%s: authentication protocol negotiation failed\n", + card->devname); + + else if (cause & 0x0020) + printk(KERN_INFO - "%s: failed to negotiate peer's IPXCP options\n", - card->devname); -} + "%s: peer's request for authentication rejected\n", + card->devname); -/*============================================================================ - * Convert line speed in bps to a number used by S502 code. - */ + else if (cause & 0x0040) + + printk(KERN_INFO "%s: MRU option rejected by peer\n", + card->devname); -static unsigned char bps_to_speed_code(unsigned long bps) -{ - unsigned char number; - if (bps <= 1200) - number = 0x01; - else if (bps <= 2400) - number = 0x02; - else if (bps <= 4800) - number = 0x03; - else if (bps <= 9600) - number = 0x04; - else if (bps <= 19200) - number = 0x05; - else if (bps <= 38400) - number = 0x06; - else if (bps <= 45000) - number = 0x07; - else if (bps <= 56000) - number = 0x08; - else if (bps <= 64000) - number = 0x09; - else if (bps <= 74000) - number = 0x0A; - else if (bps <= 112000) - number = 0x0B; - else if (bps <= 128000) - number = 0x0C; - else - number = 0x0D; - return number; -} + else if (cause & 0x0080) + + printk(KERN_INFO "%s: peer's MRU was too small\n", + card->devname); -/*============================================================================ - * Process UDP call of type DRVSTATS. - */ + else if (cause & 0x0100) -static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, ppp_private_area_t * ppp_priv_area) -{ - unsigned char *sendpacket; - unsigned char buf2[5]; - unsigned char *data; - unsigned char *buf; - unsigned int len; - ppp_mbox_t *mbox = card->mbox; - struct sk_buff *new_skb; - int err; - sendpacket = skb->data; - memcpy(&buf2, &card->wandev.udp_port, 2); - if ((data = kmalloc(2000, GFP_ATOMIC)) == NULL) { - printk(KERN_INFO - "%s: Error allocating memory for UDP DRIVER STATS cmnd0x%02X" - ,card->devname, data[45]); - ++ppp_priv_area->UDP_DRVSTATS_mgmt_kmalloc_err; - return 1; - } - memcpy(data, sendpacket, skb->len); - switch (data[45]) { - /* PPIPE_DRIVER_STATISTICS */ - case 0x26: - *(unsigned long *) &data[60] = - ppp_priv_area->if_send_entry; - *(unsigned long *) &data[64] = - ppp_priv_area->if_send_skb_null; - *(unsigned long *) &data[68] = - ppp_priv_area->if_send_broadcast; - *(unsigned long *) &data[72] = - ppp_priv_area->if_send_multicast; - *(unsigned long *) &data[76] = - ppp_priv_area->if_send_critical_ISR; - *(unsigned long *) &data[80] = - ppp_priv_area->if_send_critical_non_ISR; - *(unsigned long *) &data[84] = - ppp_priv_area->if_send_busy; - *(unsigned long *) &data[88] = - ppp_priv_area->if_send_busy_timeout; - *(unsigned long *) &data[92] = - ppp_priv_area->if_send_DRVSTATS_request; - *(unsigned long *) &data[96] = - ppp_priv_area->if_send_PTPIPE_request; - *(unsigned long *) &data[100] = - ppp_priv_area->if_send_wan_disconnected; - *(unsigned long *) &data[104] = - ppp_priv_area->if_send_adptr_bfrs_full; - *(unsigned long *) &data[108] = - ppp_priv_area->if_send_protocol_error; - *(unsigned long *) &data[112] = - ppp_priv_area->if_send_tx_int_enabled; - *(unsigned long *) &data[116] = - ppp_priv_area->if_send_bfr_passed_to_adptr; - *(unsigned long *) &data[118] = - card->irq_dis_if_send_count; - mbox->cmd.length = 62; - break; - case 0x27: - *(unsigned long *) &data[60] = card->statistics.isr_entry; - *(unsigned long *) &data[64] = - card->statistics.isr_already_critical; - *(unsigned long *) &data[68] = card->statistics.isr_rx; - *(unsigned long *) &data[72] = card->statistics.isr_tx; - *(unsigned long *) &data[76] = - card->statistics.isr_intr_test; - *(unsigned long *) &data[80] = - card->statistics.isr_spurious; - *(unsigned long *) &data[84] = - card->statistics.isr_enable_tx_int; - *(unsigned long *) &data[88] = - card->statistics.rx_intr_corrupt_rx_bfr; - *(unsigned long *) &data[92] = - ppp_priv_area->rx_intr_no_socket; - *(unsigned long *) &data[96] = - ppp_priv_area->rx_intr_DRVSTATS_request; - *(unsigned long *) &data[100] = - ppp_priv_area->rx_intr_PTPIPE_request; - *(unsigned long *) &data[104] = - ppp_priv_area->rx_intr_bfr_passed_to_stack; - *(unsigned long *) &data[108] = - card->statistics.rx_intr_dev_not_started; - *(unsigned long *) &data[112] = - card->statistics.tx_intr_dev_not_started; - mbox->cmd.length = 56; - break; - case 0x28: - *(unsigned long *) &data[60] = - ppp_priv_area->UDP_PTPIPE_mgmt_kmalloc_err; - *(unsigned long *) &data[64] = - ppp_priv_area->UDP_PTPIPE_mgmt_adptr_type_err; - *(unsigned long *) &data[68] = - ppp_priv_area->UDP_PTPIPE_mgmt_direction_err; - *(unsigned long *) &data[72] = - ppp_priv_area-> - UDP_PTPIPE_mgmt_adptr_cmnd_timeout; - *(unsigned long *) &data[76] = - ppp_priv_area->UDP_PTPIPE_mgmt_adptr_cmnd_OK; - *(unsigned long *) &data[80] = - ppp_priv_area->UDP_PTPIPE_mgmt_passed_to_adptr; - *(unsigned long *) &data[84] = - ppp_priv_area->UDP_PTPIPE_mgmt_passed_to_stack; - *(unsigned long *) &data[88] = - ppp_priv_area->UDP_PTPIPE_mgmt_no_socket; - *(unsigned long *) &data[92] = - ppp_priv_area->UDP_DRVSTATS_mgmt_kmalloc_err; - *(unsigned long *) &data[96] = - ppp_priv_area-> - UDP_DRVSTATS_mgmt_adptr_cmnd_timeout; - *(unsigned long *) &data[100] = - ppp_priv_area->UDP_DRVSTATS_mgmt_adptr_cmnd_OK; - *(unsigned long *) &data[104] = - ppp_priv_area-> - UDP_DRVSTATS_mgmt_passed_to_adptr; - *(unsigned long *) &data[108] = - ppp_priv_area-> - UDP_DRVSTATS_mgmt_passed_to_stack; - *(unsigned long *) &data[112] = - ppp_priv_area->UDP_DRVSTATS_mgmt_no_socket; - *(unsigned long *) &data[116] = - card->statistics.poll_entry; - *(unsigned long *) &data[120] = - card->statistics.poll_already_critical; - *(unsigned long *) &data[124] = - card->statistics.poll_processed; - *(unsigned long *) &data[126] = - card->irq_dis_poll_count; - mbox->cmd.length = 70; - break; - default: - /* it's a board command */ - memcpy(&mbox->cmd, &sendpacket[45], sizeof(ppp_cmd_t)); - if (mbox->cmd.length) { - memcpy(&mbox->data, &sendpacket[60], - mbox->cmd.length); - } - /* run the command on the board */ - err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; - if (err != CMD_OK) { - ppp_error(card, err, mbox); - ++ppp_priv_area-> - UDP_DRVSTATS_mgmt_adptr_cmnd_timeout; - break; - } - ++ppp_priv_area->UDP_DRVSTATS_mgmt_adptr_cmnd_OK; - /* copy the result back to our buffer */ - memcpy(data, sendpacket, skb->len); - memcpy(&data[45], &mbox->cmd, sizeof(ppp_cmd_t)); - if (mbox->cmd.length) { - memcpy(&data[60], &mbox->data, mbox->cmd.length); - } - } - /* Fill UDP TTL */ - data[8] = card->wandev.ttl; - len = reply_udp(data, mbox->cmd.length); - if (udp_pkt_src == UDP_PKT_FRM_NETWORK) { - ++ppp_priv_area->UDP_DRVSTATS_mgmt_passed_to_adptr; - ppp_send(card, data, len, skb->protocol); - } else { - /* Pass it up the stack - Allocate socket buffer */ - if ((new_skb = dev_alloc_skb(len)) != NULL) { - /* copy data into new_skb */ - buf = skb_put(new_skb, len); - memcpy(buf, data, len); - ++ppp_priv_area->UDP_DRVSTATS_mgmt_passed_to_stack; - /* Decapsulate packet and pass it up the protocol - stack */ - new_skb->protocol = htons(ETH_P_IP); - new_skb->dev = dev; - new_skb->mac.raw = new_skb->data; - netif_rx(new_skb); - } else { - ++ppp_priv_area->UDP_DRVSTATS_mgmt_no_socket; - printk(KERN_INFO "no socket buffers available!\n"); - } - } - kfree(data); - return 0; + printk(KERN_INFO "%s: failed to negotiate peer's LCP options\n", + card->devname); + + else if (cause & 0x0200) + + printk(KERN_INFO "%s: failed to negotiate peer's IPCP options\n" + , card->devname); + + else if (cause & 0x0400) + + printk(KERN_INFO + "%s: failed to negotiate peer's IPXCP options\n", + card->devname); } /*============================================================================= * Process UDP call of type PTPIPEAB. */ - -static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, - struct sk_buff *skb, struct net_device *dev, - ppp_private_area_t * ppp_priv_area) +static void process_udp_mgmt_pkt(sdla_t *card, struct net_device *dev, + ppp_private_area_t *ppp_priv_area ) { - unsigned char *sendpacket; unsigned char buf2[5]; - unsigned char *data; unsigned char *buf; unsigned int frames, len; struct sk_buff *new_skb; - unsigned short buffer_length, real_len; + unsigned short data_length, buffer_length, real_len; unsigned long data_ptr; int udp_mgmt_req_valid = 1; ppp_mbox_t *mbox = card->mbox; struct timeval tv; int err; - sendpacket = skb->data; - memcpy(&buf2, &card->wandev.udp_port, 2); - if ((data = kmalloc(2000, GFP_ATOMIC)) == NULL) { - printk(KERN_INFO - "%s: Error allocating memory for UDP management cmnd0x%02X" - ,card->devname, data[45]); - ++ppp_priv_area->UDP_PTPIPE_mgmt_kmalloc_err; - return 1; - } - memcpy(data, sendpacket, skb->len); - switch (data[45]) { + ppp_udp_pkt_t *ppp_udp_pkt = (ppp_udp_pkt_t*)&ppp_priv_area->udp_pkt_data; + + memcpy(&buf2, &card->wandev.udp_port, 2 ); + + + switch(ppp_udp_pkt->cblock.command) { + /* FT1 MONITOR STATUS */ - case 0x80: - if (card->hw.fwid != SFID_PPP508) { - ++ppp_priv_area->UDP_PTPIPE_mgmt_adptr_type_err; - udp_mgmt_req_valid = 0; - break; - } + case FT1_MONITOR_STATUS_CTRL: + /* PPIPE_ENABLE_TRACING */ - case 0x20: + case PPIPE_ENABLE_TRACING: + /* PPIPE_DISABLE_TRACING */ - case 0x21: + case PPIPE_DISABLE_TRACING: + /* PPIPE_GET_TRACE_INFO */ - case 0x22: + case PPIPE_GET_TRACE_INFO: + /* SET FT1 MODE */ - case 0x81: - if (udp_pkt_src == UDP_PKT_FRM_NETWORK) { - ++ppp_priv_area->UDP_PTPIPE_mgmt_direction_err; - udp_mgmt_req_valid = 0; - } - break; - default: - break; - } - if (!udp_mgmt_req_valid) { + case SET_FT1_MODE: + if(ppp_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) { + + ++ppp_priv_area->pipe_mgmt_stat. + UDP_PIPE_mgmt_direction_err; + udp_mgmt_req_valid = 0; + } + break; + + default: + break; + } + + if(!udp_mgmt_req_valid) { + /* set length to 0 */ - data[46] = data[47] = 0; - /* set return code */ - data[48] = 0xCD; - } else { - switch (data[45]) { - /* PPIPE_ENABLE_TRACING */ - case 0x20: - if (!TracingEnabled) { + ppp_udp_pkt->cblock.length = 0x00; + + /* set return code */ + ppp_udp_pkt->cblock.result = 0xCD; + + } else { + /* Initialize the trace element */ + trace_element_t trace_element; + + switch (ppp_udp_pkt->cblock.command){ + + /* PPIPE_ENABLE_TRACING */ + case PPIPE_ENABLE_TRACING: + if (!card->TracingEnabled) { + /* OPERATE_DATALINE_MONITOR */ - mbox->cmd.command = 0x33; - mbox->cmd.length = 1; - mbox->data[0] = 0x03; - err = sdla_exec(mbox) ? - mbox->cmd.result : CMD_TIMEOUT; - if (err != CMD_OK) { + mbox->cmd.command = PPP_DATALINE_MONITOR; + mbox->cmd.length = 0x01; + mbox->data[0] = ppp_udp_pkt->data[0]; + err = sdla_exec(mbox) ? + mbox->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK) { + ppp_error(card, err, mbox); - TracingEnabled = 0; + card->TracingEnabled = 0; + /* set the return code */ - data[48] = mbox->cmd.result; - mbox->cmd.length = 0; - break; - } - if (card->hw.fwid == SFID_PPP502) { - sdla_peek(&card->hw, 0x9000, &buf2, 2); - } else { - sdla_peek(&card->hw, 0xC000, &buf2, 2); - } - curr_trace_addr = 0; - memcpy(&curr_trace_addr, &buf2, 2); - start_trace_addr = curr_trace_addr; - /* MAX_SEND_BUFFER_SIZE -sizeof(UDP_MGMT_PACKET) - - 41 */ - available_buffer_space = 1926; - } - data[48] = 0; - mbox->cmd.length = 0; - TracingEnabled = 1; - break; - /* PPIPE_DISABLE_TRACING */ - case 0x21: - if (TracingEnabled) { + + ppp_udp_pkt->cblock.result = mbox->cmd.result; + mbox->cmd.length = 0; + break; + } + + sdla_peek(&card->hw, 0xC000, &buf2, 2); + + ppp_priv_area->curr_trace_addr = 0; + memcpy(&ppp_priv_area->curr_trace_addr, &buf2, 2); + ppp_priv_area->start_trace_addr = + ppp_priv_area->curr_trace_addr; + ppp_priv_area->end_trace_addr = + ppp_priv_area->start_trace_addr + END_OFFSET; + + /* MAX_SEND_BUFFER_SIZE - 28 (IP header) + - 32 (ppipemon CBLOCK) */ + available_buffer_space = MAX_LGTH_UDP_MGNT_PKT - + sizeof(ip_pkt_t)- + sizeof(udp_pkt_t)- + sizeof(wp_mgmt_t)- + sizeof(cblock_t); + } + ppp_udp_pkt->cblock.result = 0; + mbox->cmd.length = 0; + card->TracingEnabled = 1; + break; + + /* PPIPE_DISABLE_TRACING */ + case PPIPE_DISABLE_TRACING: + + if(card->TracingEnabled) { + /* OPERATE_DATALINE_MONITOR */ - mbox->cmd.command = 0x3; - mbox->cmd.length = 1; - mbox->data[0] = 0x00; - err = sdla_exec(mbox) ? - mbox->cmd.result : CMD_TIMEOUT; - } - /*set return code */ - data[48] = 0; + mbox->cmd.command = 0x33; + mbox->cmd.length = 1; + mbox->data[0] = 0x00; + err = sdla_exec(mbox) ? + mbox->cmd.result : CMD_TIMEOUT; + + } + + /*set return code*/ + ppp_udp_pkt->cblock.result = 0; mbox->cmd.length = 0; - TracingEnabled = 0; + card->TracingEnabled = 0; break; - /* PPIPE_GET_TRACE_INFO */ - case 0x22: - if (TracingEnabled) { - buffer_length = 0; - /* frames < NUM_TRACE_FRAMES */ - for (frames = 0; frames < 62; frames += 1) { - sdla_peek(&card->hw, curr_trace_addr, - &buf2, 1); - /* no data on board so exit */ - if (buf2[0] == 0x00) - break; - /*1+sizeof(FRAME_DATA) = 9 */ - if ((available_buffer_space - - buffer_length) < 9) { - /*indicate we have more frames - on board and exit */ - data[60] |= 0x02; + + /* PPIPE_GET_TRACE_INFO */ + case PPIPE_GET_TRACE_INFO: + + if(!card->TracingEnabled) { + /* set return code */ + ppp_udp_pkt->cblock.result = 1; + mbox->cmd.length = 0; + } + + buffer_length = 0; + + /* frames < 62, where 62 is the number of trace + information elements. There is in total 496 + bytes of space and each trace information + element is 8 bytes. + */ + for ( frames=0; frames<62; frames++) { + + trace_pkt_t *trace_pkt = (trace_pkt_t *) + &ppp_udp_pkt->data[buffer_length]; + + /* Read the whole trace packet */ + sdla_peek(&card->hw, ppp_priv_area->curr_trace_addr, + &trace_element, sizeof(trace_element_t)); + + /* no data on board so exit */ + if( trace_element.opp_flag == 0x00 ) + break; + + data_ptr = trace_element.trace_data_ptr; + + /* See if there is actual data on the trace buffer */ + if (data_ptr){ + data_length = trace_element.trace_length; + }else{ + data_length = 0; + ppp_udp_pkt->data[0] |= 0x02; + } + + //FIXME: Do we need this check + if ((available_buffer_space - buffer_length) + < (sizeof(trace_element_t)+1)){ + + /*indicate we have more frames + * on board and exit + */ + ppp_udp_pkt->data[0] |= 0x02; + break; + } + + trace_pkt->status = trace_element.trace_type; + trace_pkt->time_stamp = trace_element.trace_time_stamp; + trace_pkt->real_length = trace_element.trace_length; + + real_len = trace_element.trace_length; + + if(data_ptr == 0){ + trace_pkt->data_avail = 0x00; + }else{ + /* we can take it next time */ + if ((available_buffer_space - buffer_length)< + (real_len + sizeof(trace_pkt_t))){ + + ppp_udp_pkt->data[0] |= 0x02; break; - } - /* get frame status */ - sdla_peek(&card->hw, curr_trace_addr + - 0x01, &data[60 + buffer_length], 1); - /* get time stamp */ - sdla_peek(&card->hw, curr_trace_addr + - 0x06, &data[64 + buffer_length], 2); - /* get frame length */ - sdla_peek(&card->hw, curr_trace_addr + - 0x02, &data[62 + buffer_length], 2); - /* get pointer to real data */ - sdla_peek(&card->hw, curr_trace_addr + - 0x04, &buf2, 2); - data_ptr = 0; - memcpy(&data_ptr, &buf2, 2); - /* see if we can fit the frame into the - user buffer */ - memcpy(&real_len, - &data[62 + buffer_length], 2); - if ((data_ptr == 0) || - ((real_len + 8) > - available_buffer_space)) { - data[61 + buffer_length] = 0x00; - } else { - /* we can take it next time */ - if ((available_buffer_space - - buffer_length) < - (real_len + 8)) { - data[60] |= 0x02; - break; - } - /* ok, get the frame */ - data[61 + buffer_length] = 0x01; - /* get the data */ - sdla_peek(&card->hw, data_ptr, - &data[66 + buffer_length], - real_len); - /* zero the opp flag to - show we got the frame */ - buf2[0] = 0x00; - sdla_poke(&card->hw, - curr_trace_addr, &buf2, 1); - /* now move onto the next - frame */ - curr_trace_addr += 8; - /* check if we passed the last - address */ - if (curr_trace_addr >= - start_trace_addr + 0x1F0) { - curr_trace_addr = - start_trace_addr; - } - /* update buffer length and make sure its even */ - if (data[61 + buffer_length] - == 0x01) { - buffer_length += - real_len - 1; - } - /* for the header */ - buffer_length += 8; - if (buffer_length & 0x0001) - buffer_length += 1; - } + } + trace_pkt->data_avail = 0x01; + + /* get the data */ + sdla_peek(&card->hw, data_ptr, + &trace_pkt->data, + real_len); + } + /* zero the opp flag to + show we got the frame */ + buf2[0] = 0x00; + sdla_poke(&card->hw, ppp_priv_area->curr_trace_addr, + &buf2, 1); + + /* now move onto the next + frame */ + ppp_priv_area->curr_trace_addr += 8; + + /* check if we passed the last address */ + if ( ppp_priv_area->curr_trace_addr >= + ppp_priv_area->end_trace_addr){ + + ppp_priv_area->curr_trace_addr = + ppp_priv_area->start_trace_addr; } - /* ok now set the total number of frames passed - in the high 5 bits */ - data[60] = (frames << 2) | data[60]; - /* set the data length */ - mbox->cmd.length = buffer_length; - memcpy(&data[46], &buffer_length, 2); - /* set return code */ - data[48] = 0; - } else { - /* set return code */ - data[48] = 1; - mbox->cmd.length = 0; + + /* update buffer length and make sure its even */ + + if ( trace_pkt->data_avail == 0x01 ) { + buffer_length += real_len - 1; + } + + /* for the header */ + buffer_length += 8; + + if( buffer_length & 0x0001 ) + buffer_length += 1; } - break; - /* PPIPE_GET_IBA_DATA */ - case 0x23: + + /* ok now set the total number of frames passed + in the high 5 bits */ + ppp_udp_pkt->data[0] |= (frames << 2); + + /* set the data length */ + mbox->cmd.length = buffer_length; + ppp_udp_pkt->cblock.length = buffer_length; + + /* set return code */ + ppp_udp_pkt->cblock.result = 0; + break; + + /* PPIPE_GET_IBA_DATA */ + case PPIPE_GET_IBA_DATA: + mbox->cmd.length = 0x09; - if (card->hw.fwid == SFID_PPP502) { - sdla_peek(&card->hw, 0xA003, &data[60], - mbox->cmd.length); - } else { - sdla_peek(&card->hw, 0xF003, &data[60], - mbox->cmd.length); - } + + sdla_peek(&card->hw, 0xF003, &ppp_udp_pkt->data, + mbox->cmd.length); + /* set the length of the data */ - data[46] = 0x09; + ppp_udp_pkt->cblock.length = 0x09; + /* set return code */ - data[48] = 0x00; + ppp_udp_pkt->cblock.result = 0x00; + break; - /* PPIPE_KILL_BOARD */ - case 0x24: + + /* PPIPE_KILL_BOARD */ + case PPIPE_KILL_BOARD: break; - /* PPIPE_FT1_READ_STATUS */ - case 0x25: - sdla_peek(&card->hw, 0xF020, &data[60], 2); - data[46] = 2; - data[47] = 0; - data[48] = 0; + + /* PPIPE_FT1_READ_STATUS */ + case PPIPE_FT1_READ_STATUS: + sdla_peek(&card->hw, 0xF020, &ppp_udp_pkt->data, 2); + ppp_udp_pkt->cblock.length = 2; + ppp_udp_pkt->cblock.result = 0; mbox->cmd.length = 2; break; - case 0x29: - init_ppp_priv_struct(ppp_priv_area); - init_global_statistics(card); + + case PPIPE_FLUSH_DRIVER_STATS: + init_ppp_priv_struct( ppp_priv_area ); + init_global_statistics( card ); mbox->cmd.length = 0; break; - case 0x30: - do_gettimeofday(&tv); - ppp_priv_area->router_up_time = tv.tv_sec - - ppp_priv_area->router_start_time; - *(unsigned long *) &data[60] = - ppp_priv_area->router_up_time; + + case PPIPE_ROUTER_UP_TIME: + + do_gettimeofday( &tv ); + ppp_priv_area->router_up_time = tv.tv_sec - + ppp_priv_area->router_start_time; + *(unsigned long *)&ppp_udp_pkt->data = ppp_priv_area->router_up_time; mbox->cmd.length = 4; break; - /* FT1 MONITOR STATUS */ - case 0x80: + + /* FT1 MONITOR STATUS */ + case FT1_MONITOR_STATUS_CTRL: + /* Enable FT1 MONITOR STATUS */ - if (data[60] == 1) { - if (rCount++ != 0) { - data[48] = 0; - mbox->cmd.length = 1; - break; - } - } - /* Disable FT1 MONITOR STATUS */ - if (data[60] == 0) { - if (--rCount != 0) { - data[48] = 0; - mbox->cmd.length = 1; - break; - } - } + if( ppp_udp_pkt->data[0] == 1) { + + if( rCount++ != 0 ) { + ppp_udp_pkt->cblock.result = 0; + mbox->cmd.length = 1; + break; + } + } + + /* Disable FT1 MONITOR STATUS */ + if( ppp_udp_pkt->data[0] == 0) { + + if( --rCount != 0) { + ppp_udp_pkt->cblock.result = 0; + mbox->cmd.length = 1; + break; + } + } + + /* PPIPE_DRIVER_STATISTICS */ + case PPIPE_DRIVER_STAT_IFSEND: + printk(KERN_INFO "Getting IF_SEND Drivers Statistics\n"); + memcpy(&ppp_udp_pkt->data, &ppp_priv_area->if_send_stat, + sizeof(if_send_stat_t)); + + + ppp_udp_pkt->cblock.result = 0; + ppp_udp_pkt->cblock.length = sizeof(if_send_stat_t); + mbox->cmd.length = sizeof(if_send_stat_t); + break; + + case PPIPE_DRIVER_STAT_INTR: + memcpy(&ppp_udp_pkt->data, &card->statistics, + sizeof(global_stats_t)); + + memcpy(&ppp_udp_pkt->data+sizeof(global_stats_t), + &ppp_priv_area->rx_intr_stat, + sizeof(rx_intr_stat_t)); + + ppp_udp_pkt->cblock.result = 0; + ppp_udp_pkt->cblock.length = sizeof(global_stats_t)+ + sizeof(rx_intr_stat_t); + mbox->cmd.length = ppp_udp_pkt->cblock.length; + break; + + case PPIPE_DRIVER_STAT_GEN: + memcpy( &ppp_udp_pkt->data, + &ppp_priv_area->pipe_mgmt_stat, + sizeof(pipe_mgmt_stat_t)); + + memcpy(&ppp_udp_pkt->data+sizeof(pipe_mgmt_stat_t), + &card->statistics, sizeof(global_stats_t)); + + ppp_udp_pkt->cblock.result = 0; + ppp_udp_pkt->cblock.length = sizeof(global_stats_t)+ + sizeof(rx_intr_stat_t); + mbox->cmd.length = ppp_udp_pkt->cblock.length; + break; + + default: + /* it's a board command */ - memcpy(&mbox->cmd, &sendpacket[45], sizeof(ppp_cmd_t)); - if (mbox->cmd.length) { - memcpy(&mbox->data, &sendpacket[60], + mbox->cmd.command = ppp_udp_pkt->cblock.command; + mbox->cmd.length = ppp_udp_pkt->cblock.length; + + if(mbox->cmd.length) { + memcpy(&mbox->data,(unsigned char *)ppp_udp_pkt->data, mbox->cmd.length); - } + } + /* run the command on the board */ err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; + if (err != CMD_OK) { - ppp_error(card, err, mbox); - ++ppp_priv_area-> - UDP_PTPIPE_mgmt_adptr_cmnd_timeout; + + ppp_error(card, err, mbox); + ++ppp_priv_area->pipe_mgmt_stat. + UDP_PIPE_mgmt_adptr_cmnd_timeout; break; } - ++ppp_priv_area->UDP_PTPIPE_mgmt_adptr_cmnd_OK; + + ++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_adptr_cmnd_OK; + /* copy the result back to our buffer */ - memcpy(data, sendpacket, skb->len); - memcpy(&data[45], &mbox->cmd, sizeof(ppp_cmd_t)); - if (mbox->cmd.length) { - memcpy(&data[60], &mbox->data, mbox->cmd.length); - } - } /* end of switch */ - } /* end of else */ - /* Fill UDP TTL */ - data[8] = card->wandev.ttl; - len = reply_udp(data, mbox->cmd.length); - if (udp_pkt_src == UDP_PKT_FRM_NETWORK) { - ++ppp_priv_area->UDP_PTPIPE_mgmt_passed_to_adptr; - ppp_send(card, data, len, skb->protocol); - } else { + memcpy(&ppp_udp_pkt->cblock,mbox, sizeof(cblock_t)); + + if(mbox->cmd.length) { + memcpy(&ppp_udp_pkt->data,&mbox->data,mbox->cmd.length); + } + + } /* end of switch */ + } /* end of else */ + + /* Fill UDP TTL */ + ppp_udp_pkt->ip_pkt.ttl = card->wandev.ttl; + len = reply_udp(ppp_priv_area->udp_pkt_data, mbox->cmd.length); + + if (ppp_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) { + + ++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_passed_to_adptr; + ppp_send(card,ppp_priv_area->udp_pkt_data,len,ppp_priv_area->protocol); + + } else { + /* Pass it up the stack - Allocate socket buffer */ + Allocate socket buffer */ if ((new_skb = dev_alloc_skb(len)) != NULL) { + /* copy data into new_skb */ - buf = skb_put(new_skb, len); - memcpy(buf, data, len); - ++ppp_priv_area->UDP_PTPIPE_mgmt_passed_to_stack; - /* Decapsulate packet and pass it up the protocol + + buf = skb_put(new_skb, len); + memcpy(buf,ppp_priv_area->udp_pkt_data, len); + + ++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_passed_to_stack; + + /* Decapsulate packet and pass it up the protocol stack */ - new_skb->protocol = htons(ETH_P_IP); - new_skb->dev = dev; - new_skb->mac.raw = new_skb->data; + new_skb->protocol = htons(ETH_P_IP); + new_skb->dev = dev; + new_skb->mac.raw = new_skb->data; netif_rx(new_skb); + } else { - ++ppp_priv_area->UDP_PTPIPE_mgmt_no_socket; + + ++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_no_socket; printk(KERN_INFO "no socket buffers available!\n"); - } - } - kfree(data); - return 0; + } + } + + ppp_priv_area->udp_pkt_lgth = 0; + + return; } /*============================================================================= * Initial the ppp_private_area structure. */ - -static void init_ppp_priv_struct(ppp_private_area_t * ppp_priv_area) +static void init_ppp_priv_struct( ppp_private_area_t *ppp_priv_area ) { - ppp_priv_area->if_send_entry = 0; - ppp_priv_area->if_send_skb_null = 0; - ppp_priv_area->if_send_broadcast = 0; - ppp_priv_area->if_send_multicast = 0; - ppp_priv_area->if_send_critical_ISR = 0; - ppp_priv_area->if_send_critical_non_ISR = 0; - ppp_priv_area->if_send_busy = 0; - ppp_priv_area->if_send_busy_timeout = 0; - ppp_priv_area->if_send_DRVSTATS_request = 0; - ppp_priv_area->if_send_PTPIPE_request = 0; - ppp_priv_area->if_send_wan_disconnected = 0; - ppp_priv_area->if_send_adptr_bfrs_full = 0; - ppp_priv_area->if_send_bfr_passed_to_adptr = 0; - ppp_priv_area->rx_intr_no_socket = 0; - ppp_priv_area->rx_intr_DRVSTATS_request = 0; - ppp_priv_area->rx_intr_PTPIPE_request = 0; - ppp_priv_area->rx_intr_bfr_not_passed_to_stack = 0; - ppp_priv_area->rx_intr_bfr_passed_to_stack = 0; - ppp_priv_area->UDP_PTPIPE_mgmt_kmalloc_err = 0; - ppp_priv_area->UDP_PTPIPE_mgmt_adptr_type_err = 0; - ppp_priv_area->UDP_PTPIPE_mgmt_direction_err = 0; - ppp_priv_area->UDP_PTPIPE_mgmt_adptr_cmnd_timeout = 0; - ppp_priv_area->UDP_PTPIPE_mgmt_adptr_cmnd_OK = 0; - ppp_priv_area->UDP_PTPIPE_mgmt_passed_to_adptr = 0; - ppp_priv_area->UDP_PTPIPE_mgmt_passed_to_stack = 0; - ppp_priv_area->UDP_PTPIPE_mgmt_no_socket = 0; - ppp_priv_area->UDP_DRVSTATS_mgmt_kmalloc_err = 0; - ppp_priv_area->UDP_DRVSTATS_mgmt_adptr_type_err = 0; - ppp_priv_area->UDP_DRVSTATS_mgmt_direction_err = 0; - ppp_priv_area->UDP_DRVSTATS_mgmt_adptr_cmnd_timeout = 0; - ppp_priv_area->UDP_DRVSTATS_mgmt_adptr_cmnd_OK = 0; - ppp_priv_area->UDP_DRVSTATS_mgmt_passed_to_adptr = 0; - ppp_priv_area->UDP_DRVSTATS_mgmt_passed_to_stack = 0; - ppp_priv_area->UDP_DRVSTATS_mgmt_no_socket = 0; + + memset(&ppp_priv_area->if_send_stat, 0, sizeof(if_send_stat_t)); + memset(&ppp_priv_area->rx_intr_stat, 0, sizeof(rx_intr_stat_t)); + memset(&ppp_priv_area->pipe_mgmt_stat, 0, sizeof(pipe_mgmt_stat_t)); } /*============================================================================ * Initialize Global Statistics */ - -static void init_global_statistics(sdla_t * card) +static void init_global_statistics( sdla_t *card ) { - card->statistics.isr_entry = 0; - card->statistics.isr_already_critical = 0; - card->statistics.isr_tx = 0; - card->statistics.isr_rx = 0; - card->statistics.isr_intr_test = 0; - card->statistics.isr_spurious = 0; - card->statistics.isr_enable_tx_int = 0; - card->statistics.rx_intr_corrupt_rx_bfr = 0; - card->statistics.rx_intr_dev_not_started = 0; - card->statistics.tx_intr_dev_not_started = 0; - card->statistics.poll_entry = 0; - card->statistics.poll_already_critical = 0; - card->statistics.poll_processed = 0; - card->statistics.poll_tbusy_bad_status = 0; + memset(&card->statistics, 0, sizeof(global_stats_t)); } /*============================================================================ * Initialize Receive and Transmit Buffers. */ - -static void init_ppp_tx_rx_buff(sdla_t * card) +static void init_ppp_tx_rx_buff( sdla_t *card ) { - if (card->hw.fwid == SFID_PPP502) { - ppp502_buf_info_t *info = - (void *) (card->hw.dpmbase + PPP502_BUF_OFFS); - card->u.p.txbuf_base = - (void *) (card->hw.dpmbase + info->txb_offs); - card->u.p.txbuf_last = (ppp_buf_ctl_t *) card->u.p.txbuf_base + - (info->txb_num - 1); - card->u.p.rxbuf_base = - (void *) (card->hw.dpmbase + info->rxb_offs); - card->u.p.rxbuf_last = (ppp_buf_ctl_t *) card->u.p.rxbuf_base + - (info->rxb_num - 1); + ppp508_buf_info_t* info; + + if (card->hw.type == SDLA_S514) { + + info = (void*)(card->hw.dpmbase + PPP514_BUF_OFFS); + + card->u.p.txbuf_base = (void*)(card->hw.dpmbase + + info->txb_ptr); + + card->u.p.txbuf_last = (ppp_buf_ctl_t*)card->u.p.txbuf_base + + (info->txb_num - 1); + + card->u.p.rxbuf_base = (void*)(card->hw.dpmbase + + info->rxb_ptr); + + card->u.p.rxbuf_last = (ppp_buf_ctl_t*)card->u.p.rxbuf_base + + (info->rxb_num - 1); + } else { - ppp508_buf_info_t *info = - (void *) (card->hw.dpmbase + PPP508_BUF_OFFS); - card->u.p.txbuf_base = (void *) (card->hw.dpmbase + - (info->txb_ptr - PPP508_MB_VECT)); - card->u.p.txbuf_last = (ppp_buf_ctl_t *) card->u.p.txbuf_base + - (info->txb_num - 1); - card->u.p.rxbuf_base = (void *) (card->hw.dpmbase + - (info->rxb_ptr - PPP508_MB_VECT)); - card->u.p.rxbuf_last = (ppp_buf_ctl_t *) card->u.p.rxbuf_base + - (info->rxb_num - 1); - card->u.p.rx_base = info->rxb_base; - card->u.p.rx_top = info->rxb_end; + + info = (void*)(card->hw.dpmbase + PPP508_BUF_OFFS); + + card->u.p.txbuf_base = (void*)(card->hw.dpmbase + + (info->txb_ptr - PPP508_MB_VECT)); + + card->u.p.txbuf_last = (ppp_buf_ctl_t*)card->u.p.txbuf_base + + (info->txb_num - 1); + + card->u.p.rxbuf_base = (void*)(card->hw.dpmbase + + (info->rxb_ptr - PPP508_MB_VECT)); + + card->u.p.rxbuf_last = (ppp_buf_ctl_t*)card->u.p.rxbuf_base + + (info->rxb_num - 1); } + + card->u.p.rx_base = info->rxb_base; + card->u.p.rx_top = info->rxb_end; + card->u.p.txbuf = card->u.p.txbuf_base; card->rxmb = card->u.p.rxbuf_base; + +} + +/*============================================================================= + * Read Connection Information (ie for Remote IP address assginment). + * Called when ppp interface connected. + */ +static int read_info( sdla_t *card ) +{ + struct net_device *dev = card->wandev.dev; + ppp_private_area_t *ppp_priv_area = dev->priv; + int err; + struct ifreq if_info; + struct sockaddr_in *if_data1, *if_data2; + mm_segment_t fs; + + /* Set Local and remote addresses */ + memset(&if_info, 0, sizeof(if_info)); + strcpy(if_info.ifr_name, dev->name); + + fs = get_fs(); + set_fs(get_ds()); /* get user space block */ + + + /* Change the local and remote ip address of the interface. + * This will also add in the destination route. + */ + if_data1 = (struct sockaddr_in *)&if_info.ifr_addr; + if_data1->sin_addr.s_addr = ppp_priv_area->ip_local; + if_data1->sin_family = AF_INET; + err = devinet_ioctl( SIOCSIFADDR, &if_info ); + if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr; + if_data2->sin_addr.s_addr = ppp_priv_area->ip_remote; + if_data2->sin_family = AF_INET; + err = devinet_ioctl( SIOCSIFDSTADDR, &if_info ); + + set_fs(fs); /* restore old block */ + + + if (err) { + printk (KERN_INFO "%s: Adding of route failed:\n", + card->devname); + printk (KERN_INFO "%s: Local : %s\n", + card->devname,in_ntoa(ppp_priv_area->ip_local)); + printk (KERN_INFO "%s: Remote: %s\n", + card->devname,in_ntoa(ppp_priv_area->ip_remote)); + } + return err; +} + +/*============================================================================= + * Remove Dynamic Route. + * Called when ppp interface disconnected. + */ + +static int remove_route( sdla_t *card ) +{ + + struct net_device *dev = card->wandev.dev; + long ip_addr; + int err; + + mm_segment_t fs; + struct ifreq if_info; + struct sockaddr_in *if_data1; + struct in_device *in_dev = dev->ip_ptr; + struct in_ifaddr *ifa = in_dev->ifa_list; + + + ip_addr = ifa->ifa_local; + + /* Set Local and remote addresses */ + memset(&if_info, 0, sizeof(if_info)); + strcpy(if_info.ifr_name, dev->name); + + + fs = get_fs(); + set_fs(get_ds()); /* get user space block */ + + + /* Change the local ip address of the interface to 0. + * This will also delete the destination route. + */ + if_data1 = (struct sockaddr_in *)&if_info.ifr_addr; + if_data1->sin_addr.s_addr = 0; + if_data1->sin_family = AF_INET; + err = devinet_ioctl( SIOCSIFADDR, &if_info ); + + set_fs(fs); /* restore old block */ + + + if (err) { + printk (KERN_INFO "%s: Deleting dynamic route failed %d!\n", + card->devname, err); + return err; + }else + printk (KERN_INFO "%s: PPP Deleting dynamic route %s successfuly\n", + card->devname, in_ntoa(ip_addr)); + + + return 0; } /*============================================================================= * Perform the Interrupt Test by running the READ_CODE_VERSION command MAX_INTR * _TEST_COUNTER times. */ - -static int intr_test(sdla_t * card) +static int intr_test( sdla_t *card ) { ppp_mbox_t *mb = card->mbox; - int err, i; - /* The critical flag is unset because during initialization (if_open) + int err,i; + + /* The critical flag is unset because during intialization (if_open) * we want the interrupts to be enabled so that when the wpp_isr is * called it does not exit due to critical flag set. - */ + */ + card->wandev.critical = 0; - err = ppp_set_intr_mode(card, 0x08); - if (err == CMD_OK) { - for (i = 0; i < MAX_INTR_TEST_COUNTER; i++) { + + err = ppp_set_intr_mode( card, 0x08 ); + + if (err == CMD_OK) { + + for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) { /* Run command READ_CODE_VERSION */ memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); - mb->cmd.length = 0; - mb->cmd.command = 0x10; + mb->cmd.length = 0; + mb->cmd.command = PPP_READ_CODE_VERSION; err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; - if (err != CMD_OK) + if (err != CMD_OK) ppp_error(card, err, mb); } - } else - return err; - err = ppp_set_intr_mode(card, 0); - if (err != CMD_OK) + } + else return err; + + err = ppp_set_intr_mode( card, 0 ); + if (err != CMD_OK) return err; + card->wandev.critical = 1; return 0; } @@ -2222,40 +2796,140 @@ /*============================================================================== * Determine what type of UDP call it is. DRVSTATS or PTPIPEAB ? */ - -static int udp_pkt_type(struct sk_buff *skb, sdla_t * card) +static int udp_pkt_type( struct sk_buff *skb, sdla_t *card ) { unsigned char *sendpacket; - unsigned char buf2[5]; + unsigned char buf2[5]; + //FIXME: Use the structure + ppp_udp_pkt_t *ppp_udp_pkt = (ppp_udp_pkt_t *)skb->data; + sendpacket = skb->data; memcpy(&buf2, &card->wandev.udp_port, 2); - if (sendpacket[0] == 0x45 && /* IP packet */ - sendpacket[9] == 0x11 && /* UDP packet */ - sendpacket[22] == buf2[1] && /* UDP Port */ - sendpacket[23] == buf2[0] && - sendpacket[36] == 0x01) { - if (sendpacket[28] == 0x50 && /* PTPIPEAB: Signature */ - sendpacket[29] == 0x54 && - sendpacket[30] == 0x50 && - sendpacket[31] == 0x49 && - sendpacket[32] == 0x50 && - sendpacket[33] == 0x45 && - sendpacket[34] == 0x41 && - sendpacket[35] == 0x42) { + + if( ppp_udp_pkt->ip_pkt.ver_inet_hdr_length == 0x45 && /* IP packet */ + sendpacket[9] == 0x11 && /* UDP packet */ + sendpacket[22] == buf2[1] && /* UDP Port */ + sendpacket[23] == buf2[0] && + sendpacket[36] == 0x01 ) { + + if ( sendpacket[28] == 0x50 && /* PTPIPEAB: Signature */ + sendpacket[29] == 0x54 && + sendpacket[30] == 0x50 && + sendpacket[31] == 0x49 && + sendpacket[32] == 0x50 && + sendpacket[33] == 0x45 && + sendpacket[34] == 0x41 && + sendpacket[35] == 0x42 ){ + return UDP_PTPIPE_TYPE; - } else if (sendpacket[28] == 0x44 && /* DRVSTATS: Signature */ - sendpacket[29] == 0x52 && - sendpacket[30] == 0x56 && - sendpacket[31] == 0x53 && - sendpacket[32] == 0x54 && - sendpacket[33] == 0x41 && - sendpacket[34] == 0x54 && - sendpacket[35] == 0x53) { + + } else if(sendpacket[28] == 0x44 && /* DRVSTATS: Signature */ + sendpacket[29] == 0x52 && + sendpacket[30] == 0x56 && + sendpacket[31] == 0x53 && + sendpacket[32] == 0x54 && + sendpacket[33] == 0x41 && + sendpacket[34] == 0x54 && + sendpacket[35] == 0x53 ){ + return UDP_DRVSTATS_TYPE; + } else return UDP_INVALID_TYPE; + } else return UDP_INVALID_TYPE; + +} + +/*============================================================================ + * Check to see if the packet to be transmitted contains a broadcast or + * multicast source IP address. + */ + +static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev, + struct sk_buff *skb) +{ + u32 src_ip_addr; + u32 broadcast_ip_addr = 0; + struct in_device *in_dev; + /* read the IP source address from the outgoing packet */ + src_ip_addr = *(u32 *)(skb->data + 12); + + /* read the IP broadcast address for the device */ + in_dev = dev->ip_ptr; + if(in_dev != NULL) { + struct in_ifaddr *ifa= in_dev->ifa_list; + if(ifa != NULL) + broadcast_ip_addr = ifa->ifa_broadcast; + else + return 0; + } + + /* check if the IP Source Address is a Broadcast address */ + if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) { + printk(KERN_INFO "%s: Broadcast Source Address silently discarded\n", + card->devname); + dev_kfree_skb(skb); + ++card->wandev.stats.tx_dropped; + return 1; + } + + /* check if the IP Source Address is a Multicast address */ + if((ntohl(src_ip_addr) >= 0xE0000001) && + (ntohl(src_ip_addr) <= 0xFFFFFFFE)) { + printk(KERN_INFO "%s: Multicast Source Address silently discarded\n", + card->devname); + dev_kfree_skb(skb); + ++card->wandev.stats.tx_dropped; + return 1; + } + + return 0; +} + +void s508_lock (sdla_t *card, unsigned long *smp_flags) +{ +#ifdef __SMP__ + spin_lock_irqsave(&card->lock, *smp_flags); +#else + disable_irq(card->hw.irq); +#endif +} + +void s508_unlock (sdla_t *card, unsigned long *smp_flags) +{ +#ifdef __SMP__ + spin_unlock_irqrestore(&card->lock, *smp_flags); +#else + enable_irq(card->hw.irq); +#endif +} + +static int read_connection_info (sdla_t *card) +{ + ppp_mbox_t *mb = card->mbox; + struct net_device *dev = card->wandev.dev; + ppp_private_area_t *ppp_priv_area = dev->priv; + ppp508_connect_info_t *ppp508_connect_info; + int err; + + memset(&mb->cmd, 0, sizeof(ppp_cmd_t)); + mb->cmd.length = 0; + mb->cmd.command = PPP_GET_CONNECTION_INFO; + err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT; + + if (err != CMD_OK) { + ppp_error(card, err, mb); + } + else { + ppp508_connect_info = (ppp508_connect_info_t *)mb->data; + + ppp_priv_area->ip_remote = ppp508_connect_info->ip_remote; + ppp_priv_area->ip_local = ppp508_connect_info->ip_local; + } + + return err; } /****** End *****************************************************************/ diff -ur --new-file old/linux/drivers/net/wan/sdladrv.c new/linux/drivers/net/wan/sdladrv.c --- old/linux/drivers/net/wan/sdladrv.c Mon Oct 11 19:13:25 1999 +++ new/linux/drivers/net/wan/sdladrv.c Fri Jan 28 17:04:58 2000 @@ -4,17 +4,18 @@ * This module is a library of common hardware-specific functions * used by all Sangoma drivers. * -* Author: Gene Kozin -* Fixes: Arnaldo Carvalho de Melo +* Author: Gideon Hack * -* Copyright: (c) 1995-1996 Sangoma Technologies Inc. +* Copyright: (c) 1995-1999 Sangoma Technologies 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. * ============================================================================ -* May 19, 1999 Arnaldo Melo wanpipe_init belongs to sdlamain.c +* Jun 02, 1999 Gideon Hack Added support for the S514 adapter. +* Updates for Linux 2.2.X kernels. +* Sep 17, 1998 Jaspreet Singh Updates for linux 2.2.X kernels * Dec 20, 1996 Gene Kozin Version 3.0.0. Complete overhaul. * Jul 12, 1996 Gene Kozin Changes for Linux 2.0 compatibility. * Jun 12, 1996 Gene Kozin Added support for S503 card. @@ -83,6 +84,8 @@ #if defined(_LINUX_) /****** Linux *******************************/ +#include +#include #include /* printk(), and other useful stuff */ #include /* offsetof(), etc. */ #include /* return codes */ @@ -91,12 +94,18 @@ #include /* for jiffies, HZ, etc. */ #include /* API definitions */ #include /* SDLA firmware module definitions */ +#include /* SDLA PCI hardware definitions */ +#include /* PCI defines and function prototypes */ #include /* for inb(), outb(), etc. */ + #define _INB(port) (inb(port)) #define _OUTB(port, byte) (outb((byte),(port))) #define SYSTEM_TICK jiffies +#include + #elif defined(_SCO_UNIX_) /****** SCO Unix ****************************/ + #if !defined(INKERNEL) #error This code MUST be compiled in kernel mode! #endif @@ -136,6 +145,11 @@ #define S503_MINMEM 0x8000L #define S507_MINMEM 0x20000L #define S508_MINMEM 0x20000L +#define NO_PORT -1 + + + + /****** Function Prototypes *************************************************/ @@ -159,14 +173,18 @@ static int init_s503 (sdlahw_t* hw); static int init_s507 (sdlahw_t* hw); static int init_s508 (sdlahw_t* hw); - + static int detect_s502a (int port); static int detect_s502e (int port); static int detect_s503 (int port); static int detect_s507 (int port); static int detect_s508 (int port); +static int detect_s514 (sdlahw_t* hw); +static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card); /* Miscellaneous functions */ +static void peek_by_4 (unsigned long src, void* buf, unsigned len); +static void poke_by_4 (unsigned long dest, void* buf, unsigned len); static int calibrate_delay (int mks); static int get_option_index (unsigned* optlist, unsigned optval); static unsigned check_memregion (void* ptr, unsigned len); @@ -180,7 +198,7 @@ /* private data */ static char modname[] = "sdladrv"; static char fullname[] = "SDLA Support Module"; -static char copyright[] = "(c) 1995-1996 Sangoma Technologies Inc."; +static char copyright[] = "(c) 1995-1999 Sangoma Technologies Inc."; static unsigned exec_idle; /* Hardware configuration options. @@ -289,6 +307,9 @@ #ifdef MODULE int init_module (void) +#else +__initfunc(int wanpipe_init(void)) +#endif { printk(KERN_INFO "%s v%u.%u %s\n", fullname, MOD_VERSION, MOD_RELEASE, copyright); @@ -299,6 +320,7 @@ return 0; } +#ifdef MODULE /*============================================================================ * Module 'remove' entry point. * o release all remaining system resources @@ -321,7 +343,7 @@ * Return: 0 ok. * < 0 error */ - + EXPORT_SYMBOL(sdla_setup); int sdla_setup (sdlahw_t* hw, void* sfm, unsigned len) @@ -329,118 +351,123 @@ unsigned* irq_opt = NULL; /* IRQ options */ unsigned* dpmbase_opt = NULL; /* DPM window base options */ unsigned* pclk_opt = NULL; /* CPU clock rate options */ - int err; + int err=0; - if (sdla_detect(hw)) - { - printk(KERN_ERR "%s: adapter S%04u not found at port 0x%X!\n", - modname, hw->type, hw->port) - ; - return -EINVAL; - } - printk(KERN_INFO "%s: found S%04u card at port 0x%X.\n", - modname, hw->type, hw->port) - ; - - hw->dpmsize = SDLA_WINDOWSIZE; - switch (hw->type) - { - case SDLA_S502A: - hw->io_range = S502A_IORANGE; - irq_opt = s502a_irq_options; - dpmbase_opt = s502a_dpmbase_options; - pclk_opt = s502a_pclk_options; - break; - - case SDLA_S502E: - hw->io_range = S502E_IORANGE; - irq_opt = s502e_irq_options; - dpmbase_opt = s508_dpmbase_options; - pclk_opt = s502e_pclk_options; - break; - - case SDLA_S503: - hw->io_range = S503_IORANGE; - irq_opt = s503_irq_options; - dpmbase_opt = s508_dpmbase_options; - pclk_opt = s503_pclk_options; - break; - - case SDLA_S507: - hw->io_range = S507_IORANGE; - irq_opt = s508_irq_options; - dpmbase_opt = s507_dpmbase_options; - pclk_opt = s507_pclk_options; - break; - - case SDLA_S508: - hw->io_range = S508_IORANGE; - irq_opt = s508_irq_options; - dpmbase_opt = s508_dpmbase_options; - pclk_opt = s508_pclk_options; - break; - } - - /* Verify IRQ configuration options */ - if (!get_option_index(irq_opt, hw->irq)) - { - printk(KERN_ERR "%s: IRQ %d is illegal!\n", - modname, hw->irq) - ; - return -EINVAL; - } - - /* Verify CPU clock rate configuration options */ - if (hw->pclk == 0) - hw->pclk = pclk_opt[1] /* use default */ - ; - else if (!get_option_index(pclk_opt, hw->pclk)) - { - printk(KERN_ERR "%s: CPU clock %u is illegal!\n", - modname, hw->pclk) - ; - return -EINVAL; - } - printk(KERN_INFO "%s: assuming CPU clock rate of %u kHz.\n", - modname, hw->pclk) - ; - - /* Setup adapter dual-port memory window and test memory */ - if (hw->dpmbase == 0) - { - err = sdla_autodpm(hw); - if (err) - { - printk(KERN_ERR + if (sdla_detect(hw)) { + if(hw->type != SDLA_S514) + printk(KERN_ERR "%s: no SDLA card found at port 0x%X\n", + modname, hw->port); + return -EINVAL; + } + + if(hw->type != SDLA_S514) { + printk(KERN_INFO "%s: found S%04u card at port 0x%X.\n", + modname, hw->type, hw->port); + + hw->dpmsize = SDLA_WINDOWSIZE; + switch (hw->type) { + case SDLA_S502A: + hw->io_range = S502A_IORANGE; + irq_opt = s502a_irq_options; + dpmbase_opt = s502a_dpmbase_options; + pclk_opt = s502a_pclk_options; + break; + + case SDLA_S502E: + hw->io_range = S502E_IORANGE; + irq_opt = s502e_irq_options; + dpmbase_opt = s508_dpmbase_options; + pclk_opt = s502e_pclk_options; + break; + + case SDLA_S503: + hw->io_range = S503_IORANGE; + irq_opt = s503_irq_options; + dpmbase_opt = s508_dpmbase_options; + pclk_opt = s503_pclk_options; + break; + + case SDLA_S507: + hw->io_range = S507_IORANGE; + irq_opt = s508_irq_options; + dpmbase_opt = s507_dpmbase_options; + pclk_opt = s507_pclk_options; + break; + + case SDLA_S508: + hw->io_range = S508_IORANGE; + irq_opt = s508_irq_options; + dpmbase_opt = s508_dpmbase_options; + pclk_opt = s508_pclk_options; + break; + } + + /* Verify IRQ configuration options */ + if (!get_option_index(irq_opt, hw->irq)) { + printk(KERN_ERR "%s: IRQ %d is illegal!\n", + modname, hw->irq); + return -EINVAL; + } + + /* Verify CPU clock rate configuration options */ + if (hw->pclk == 0) + hw->pclk = pclk_opt[1]; /* use default */ + + else if (!get_option_index(pclk_opt, hw->pclk)) { + printk(KERN_ERR "%s: CPU clock %u is illegal!\n", + modname, hw->pclk); + return -EINVAL; + } + printk(KERN_INFO "%s: assuming CPU clock rate of %u kHz.\n", + modname, hw->pclk); + + /* Setup adapter dual-port memory window and test memory */ + if (hw->dpmbase == 0) { + err = sdla_autodpm(hw); + if (err) { + printk(KERN_ERR "%s: can't find available memory region!\n", - modname) - ; - return err; + modname); + return err; + } + } + else if (!get_option_index(dpmbase_opt, + virt_to_phys(hw->dpmbase))) { + printk(KERN_ERR + "%s: memory address 0x%lX is illegal!\n", + modname, virt_to_phys(hw->dpmbase)); + return -EINVAL; + } + else if (sdla_setdpm(hw)) { + printk(KERN_ERR + "%s: 8K memory region at 0x%lX is not available!\n", + modname, virt_to_phys(hw->dpmbase)); + return -EINVAL; + } + printk(KERN_INFO + "%s: dual-port memory window is set at 0x%lX.\n", + modname, virt_to_phys(hw->dpmbase)); + } + + else { + hw->memory = test_memregion((void*)hw->dpmbase, + MAX_SIZEOF_S514_MEMORY); + if(hw->memory < (256 * 1024)) { + printk(KERN_ERR + "%s: error in testing S514 memory (0x%lX)\n", + modname, hw->memory); + sdla_down(hw); + return -EINVAL; } } - else if (!get_option_index(dpmbase_opt, virt_to_phys(hw->dpmbase))) - { - printk(KERN_ERR "%s: memory address 0x%lX is illegal!\n", - modname, virt_to_phys(hw->dpmbase)) - ; - return -EINVAL; - } - else if (sdla_setdpm(hw)) - { - printk(KERN_ERR - "%s: 8K memory region at 0x%lX is not available!\n", - modname, virt_to_phys(hw->dpmbase)); - return -EINVAL; - } - printk(KERN_INFO "%s: dual-port memory window is set at 0x%lX.\n", - modname, virt_to_phys(hw->dpmbase)); - - printk(KERN_INFO "%s: found %luK bytes of on-board memory.\n", + + printk(KERN_INFO "%s: found %luK bytes of on-board memory\n", modname, hw->memory / 1024); /* Load firmware. If loader fails then shut down adapter */ err = sdla_load(hw, sfm, len); if (err) sdla_down(hw); /* shutdown adapter */ + return err; } @@ -454,11 +481,13 @@ { unsigned port = hw->port; int i; + unsigned char CPU_no; + u32 int_config, int_status; - if (!port) return -EFAULT; + if(!port && (hw->type != SDLA_S514)) + return -EFAULT; - switch (hw->type) - { + switch (hw->type) { case SDLA_S502A: _OUTB(port, 0x08); /* halt CPU */ _OUTB(port, 0x08); @@ -483,6 +512,30 @@ hw->regs[0] = 0; break; + case SDLA_S514: + /* halt the adapter */ + *(char *)hw->vector = S514_CPU_HALT; + CPU_no = hw->S514_cpu_no[0]; + + /* disable the PCI IRQ and disable memory access */ + pci_read_config_dword(hw->pci_dev, PCI_INT_CONFIG, &int_config); + int_config &= (CPU_no == S514_CPU_A) ? ~PCI_DISABLE_IRQ_CPU_A : ~PCI_DISABLE_IRQ_CPU_B; + pci_write_config_dword(hw->pci_dev, PCI_INT_CONFIG, int_config); + read_S514_int_stat(hw, &int_status); + S514_intack(hw, int_status); + if(CPU_no == S514_CPU_A) + pci_write_config_dword(hw->pci_dev, PCI_MAP0_DWORD, + PCI_CPU_A_MEM_DISABLE); + else + pci_write_config_dword(hw->pci_dev, PCI_MAP1_DWORD, + PCI_CPU_B_MEM_DISABLE); + + /* free up the allocated virtual memory */ + iounmap((void *)hw->dpmbase); + iounmap((void *)hw->vector); + break; + + default: return -EINVAL; } @@ -500,12 +553,10 @@ unsigned port = hw->port; register int tmp; - switch (hw->type) - { + switch (hw->type) { case SDLA_S502A: case SDLA_S502E: - if (addr < S502_MAXMEM) /* verify parameter */ - { + if (addr < S502_MAXMEM) { /* verify parameter */ tmp = addr >> 13; /* convert to register mask */ _OUTB(port + 2, tmp); hw->regs[2] = tmp; @@ -514,8 +565,7 @@ break; case SDLA_S503: - if (addr < S503_MAXMEM) /* verify parameter */ - { + if (addr < S503_MAXMEM) { /* verify parameter */ tmp = (hw->regs[0] & 0x8F) | ((addr >> 9) & 0x70); _OUTB(port, tmp); hw->regs[0] = tmp; @@ -524,11 +574,9 @@ break; case SDLA_S507: - if (addr < S507_MAXMEM) - { + if (addr < S507_MAXMEM) { if (!(_INB(port) & 0x02)) - return -EIO - ; + return -EIO; tmp = addr >> 13; /* convert to register mask */ _OUTB(port + 2, tmp); hw->regs[2] = tmp; @@ -537,8 +585,7 @@ break; case SDLA_S508: - if (addr < S508_MAXMEM) - { + if (addr < S508_MAXMEM) { tmp = addr >> 13; /* convert to register mask */ _OUTB(port + 2, tmp); hw->regs[2] = tmp; @@ -546,7 +593,10 @@ else return -EINVAL; break; - default: + case SDLA_S514: + return 0; + + default: return -EINVAL; } hw->vector = addr & 0xFFFFE000L; @@ -556,7 +606,7 @@ /*============================================================================ * Enable interrupt generation. */ - + EXPORT_SYMBOL(sdla_inten); int sdla_inten (sdlahw_t* hw) @@ -564,14 +614,12 @@ unsigned port = hw->port; int tmp, i; - switch (hw->type) - { + switch (hw->type) { case SDLA_S502E: /* Note thar interrupt control operations on S502E are allowed * only if CPU is enabled (bit 0 of status register is set). */ - if (_INB(port) & 0x01) - { + if (_INB(port) & 0x01) { _OUTB(port, 0x02); /* bit1 = 1, bit2 = 0 */ _OUTB(port, 0x06); /* bit1 = 1, bit2 = 1 */ hw->regs[0] = 0x06; @@ -585,8 +633,7 @@ hw->regs[0] = tmp; /* update mirror */ for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if (!(_INB(port) & 0x02)) /* verify */ - return -EIO - ; + return -EIO; break; case SDLA_S508: @@ -595,14 +642,16 @@ hw->regs[0] = tmp; /* update mirror */ for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if (!(_INB(port + 1) & 0x10)) /* verify */ - return -EIO - ; + return -EIO; break; case SDLA_S502A: case SDLA_S507: break; + case SDLA_S514: + break; + default: return -EINVAL; @@ -621,8 +670,7 @@ unsigned port = hw->port; int tmp, i; - switch (hw->type) - { + switch (hw->type) { case SDLA_S502E: /* Notes: * 1) interrupt control operations are allowed only if CPU is @@ -631,8 +679,7 @@ * causes IRQ line go high, therefore we are going to use * 0x04 instead: lower it to inhibit interrupts to PC. */ - if (_INB(port) & 0x01) - { + if (_INB(port) & 0x01) { _OUTB(port, hw->regs[0] & ~0x04); hw->regs[0] &= ~0x04; } @@ -645,8 +692,7 @@ hw->regs[0] = tmp; /* update mirror */ for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if (_INB(port) & 0x02) /* verify */ - return -EIO - ; + return -EIO; break; case SDLA_S508: @@ -655,8 +701,7 @@ hw->regs[0] = tmp; /* update mirror */ for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if (_INB(port) & 0x10) /* verify */ - return -EIO - ; + return -EIO; break; case SDLA_S502A: @@ -680,16 +725,14 @@ unsigned port = hw->port; int tmp; - switch (hw->type) - { + switch (hw->type) { case SDLA_S502E: /* To acknoledge hardware interrupt we have to toggle bit 3 of * control register: \_/ * Note that interrupt control operations on S502E are allowed * only if CPU is enabled (bit 1 of status register is set). */ - if (_INB(port) & 0x01) - { + if (_INB(port) & 0x01) { tmp = hw->regs[0] & ~0x04; _OUTB(port, tmp); tmp |= 0x04; @@ -700,8 +743,7 @@ break; case SDLA_S503: - if (_INB(port) & 0x04) - { + if (_INB(port) & 0x04) { tmp = hw->regs[0] & ~0x08; _OUTB(port, tmp); tmp |= 0x08; @@ -721,6 +763,31 @@ return 0; } + +/*============================================================================ + * Acknowledge S514 hardware interrupt. + */ + +EXPORT_SYMBOL(S514_intack); + +void S514_intack (sdlahw_t* hw, u32 int_status) +{ + pci_write_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status); +} + + +/*============================================================================ + * Read the S514 hardware interrupt status. + */ + +EXPORT_SYMBOL(read_S514_int_stat); + +void read_S514_int_stat (sdlahw_t* hw, u32* int_status) +{ + pci_read_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status); +} + + /*============================================================================ * Generate an interrupt to adapter's CPU. */ @@ -731,11 +798,9 @@ { unsigned port = hw->port; - switch (hw->type) - { + switch (hw->type) { case SDLA_S502A: - if (!(_INB(port) & 0x40)) - { + if (!(_INB(port) & 0x40)) { _OUTB(port, 0x10); /* issue NMI to CPU */ hw->regs[0] = 0x10; } @@ -743,16 +808,14 @@ break; case SDLA_S507: - if ((_INB(port) & 0x06) == 0x06) - { + if ((_INB(port) & 0x06) == 0x06) { _OUTB(port + 3, 0); } else return -EIO; break; case SDLA_S508: - if (_INB(port + 1) & 0x02) - { + if (_INB(port + 1) & 0x02) { _OUTB(port, 0x08); } else return -EIO; @@ -781,14 +844,19 @@ unsigned long tstop; int nloops; - if (*flag) return 0; /* ???? */ + if(readb(flag) != 0x00) { + printk(KERN_INFO + "WANPIPE: opp flag set on entry to sdla_exec\n"); + return 0; + } + + writeb(0x01, flag); - *flag = 1; tstop = SYSTEM_TICK + EXEC_TIMEOUT; - for (nloops = 1; *flag; ++nloops) - { + + for (nloops = 1; (readb(flag) == 0x01); ++ nloops) { unsigned delay = exec_idle; - while (--delay); /* delay */ + while (-- delay); /* delay */ if (SYSTEM_TICK > tstop) return 0; /* time is up! */ } return nloops; @@ -803,39 +871,79 @@ * This function is not atomic, so caller must disable interrupt if * interrupt routines are accessing adapter shared memory. */ - + EXPORT_SYMBOL(sdla_peek); int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len) { - unsigned long oldvec = hw->vector; - unsigned winsize = hw->dpmsize; - unsigned curpos, curlen; /* current offset and block size */ - unsigned long curvec; /* current DPM window vector */ - int err = 0; if (addr + len > hw->memory) /* verify arguments */ - return -EINVAL - ; - while (len && !err) - { - curpos = addr % winsize; /* current window offset */ - curvec = addr - curpos; /* current window vector */ - curlen = (len > (winsize - curpos)) ? (winsize - curpos) : len; - - /* Relocate window and copy block of data */ - err = sdla_mapmem(hw, curvec); - memcpy(buf, (void *)((u8 *)hw->dpmbase + curpos), curlen); - addr += curlen; - (char*)buf += curlen; - len -= curlen; - } + return -EINVAL; - /* Restore DPM window position */ - sdla_mapmem(hw, oldvec); - return err; + if(hw->type == SDLA_S514) { /* copy data for the S514 adapter */ + peek_by_4 ((unsigned long)hw->dpmbase + addr, buf, len); + return 0; + } + + else { /* copy data for the S508 adapter */ + unsigned long oldvec = hw->vector; + unsigned winsize = hw->dpmsize; + unsigned curpos, curlen; /* current offset and block size */ + unsigned long curvec; /* current DPM window vector */ + int err = 0; + + while (len && !err) { + curpos = addr % winsize; /* current window offset */ + curvec = addr - curpos; /* current window vector */ + curlen = (len > (winsize - curpos)) ? + (winsize - curpos) : len; + /* Relocate window and copy block of data */ + err = sdla_mapmem(hw, curvec); + peek_by_4 ((unsigned long)hw->dpmbase + curpos, buf, + curlen); + addr += curlen; + (char*)buf += curlen; + len -= curlen; + } + + /* Restore DPM window position */ + sdla_mapmem(hw, oldvec); + return err; + } +} + + +/*============================================================================ + * Read data from adapter's memory to a data buffer in 4-byte chunks. + * Note that we ensure that the SDLA memory address is on a 4-byte boundary + * before we begin moving the data in 4-byte chunks. +*/ + +static void peek_by_4 (unsigned long src, void* buf, unsigned len) +{ + + /* byte copy data until we get to a 4-byte boundary */ + while (len && (src & 0x03)) { + *(char *)buf ++ = readb(src ++); + len --; + } + + /* copy data in 4-byte chunks */ + while (len >= 4) { + *(unsigned long *)buf = readl(src); + buf += 4; + src += 4; + len -= 4; + } + + /* byte copy any remaining data */ + while (len) { + *(char *)buf ++ = readb(src ++); + len --; + } } + /*============================================================================ * Write Absolute Adapter Memory. * Transfer data from data buffer to adapter's memory. @@ -845,39 +953,79 @@ * This function is not atomic, so caller must disable interrupt if * interrupt routines are accessing adapter shared memory. */ - + EXPORT_SYMBOL(sdla_poke); int sdla_poke (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len) { - unsigned long oldvec = hw->vector; - unsigned winsize = hw->dpmsize; - unsigned curpos, curlen; /* current offset and block size */ - unsigned long curvec; /* current DPM window vector */ - int err = 0; if (addr + len > hw->memory) /* verify arguments */ - return -EINVAL - ; - while (len && !err) - { - curpos = addr % winsize; /* current window offset */ - curvec = addr - curpos; /* current window vector */ - curlen = (len > (winsize - curpos)) ? (winsize - curpos) : len; - - /* Relocate window and copy block of data */ - sdla_mapmem(hw, curvec); - memcpy((void*)((u8 *)hw->dpmbase + curpos), buf, curlen); - addr += curlen; - (char*)buf += curlen; - len -= curlen; - } + return -EINVAL; + + if(hw->type == SDLA_S514) { /* copy data for the S514 adapter */ + poke_by_4 ((unsigned long)hw->dpmbase + addr, buf, len); + return 0; + } + + else { /* copy data for the S508 adapter */ + unsigned long oldvec = hw->vector; + unsigned winsize = hw->dpmsize; + unsigned curpos, curlen; /* current offset and block size */ + unsigned long curvec; /* current DPM window vector */ + int err = 0; + + while (len && !err) { + curpos = addr % winsize; /* current window offset */ + curvec = addr - curpos; /* current window vector */ + curlen = (len > (winsize - curpos)) ? + (winsize - curpos) : len; + /* Relocate window and copy block of data */ + sdla_mapmem(hw, curvec); + poke_by_4 ((unsigned long)hw->dpmbase + curpos, buf, + curlen); + addr += curlen; + (char*)buf += curlen; + len -= curlen; + } + + /* Restore DPM window position */ + sdla_mapmem(hw, oldvec); + return err; + } +} - /* Restore DPM window position */ - sdla_mapmem(hw, oldvec); - return err; + +/*============================================================================ + * Write from a data buffer to adapter's memory in 4-byte chunks. + * Note that we ensure that the SDLA memory address is on a 4-byte boundary + * before we begin moving the data in 4-byte chunks. +*/ + +static void poke_by_4 (unsigned long dest, void* buf, unsigned len) +{ + + /* byte copy data until we get to a 4-byte boundary */ + while (len && (dest & 0x03)) { + writeb (*(char *)buf ++, dest ++); + len --; + } + + /* copy data in 4-byte chunks */ + while (len >= 4) { + writel (*(unsigned long *)buf, dest); + dest += 4; + buf += 4; + len -= 4; + } + + /* byte copy any remaining data */ + while (len) { + writeb (*(char *)buf ++ , dest ++); + len --; + } } + #ifdef DONT_COMPIPLE_THIS #endif /* DONT_COMPIPLE_THIS */ @@ -898,11 +1046,10 @@ unsigned port = hw->port; int err = 0; - if (!port) - return -EFAULT - ; - switch (hw->type) - { + if (!port && (hw->type != SDLA_S514)) + return -EFAULT; + + switch (hw->type) { case SDLA_S502A: if (!detect_s502a(port)) err = -ENODEV; break; @@ -923,22 +1070,21 @@ if (!detect_s508(port)) err = -ENODEV; break; + case SDLA_S514: + if (!detect_s514(hw)) err = -ENODEV; + break; + default: if (detect_s502a(port)) - hw->type = SDLA_S502A - ; + hw->type = SDLA_S502A; else if (detect_s502e(port)) - hw->type = SDLA_S502E - ; + hw->type = SDLA_S502E; else if (detect_s503(port)) - hw->type = SDLA_S503 - ; + hw->type = SDLA_S503; else if (detect_s507(port)) - hw->type = SDLA_S507 - ; + hw->type = SDLA_S507; else if (detect_s508(port)) - hw->type = SDLA_S508 - ; + hw->type = SDLA_S508; else err = -ENODEV; } return err; @@ -953,8 +1099,7 @@ int i, err = -EINVAL; unsigned* opt; - switch (hw->type) - { + switch (hw->type) { case SDLA_S502A: opt = s502a_dpmbase_options; break; @@ -973,8 +1118,7 @@ return -EINVAL; } - for (i = opt[0]; i && err; --i) - { + for (i = opt[0]; i && err; --i) { hw->dpmbase = phys_to_virt(opt[i]); err = sdla_setdpm(hw); } @@ -997,8 +1141,7 @@ /* Shut down card and verify memory region */ sdla_down(hw); if (check_memregion(hw->dpmbase, hw->dpmsize)) - return -EINVAL - ; + return -EINVAL; /* Initialize adapter and test on-board memory segment by segment. * If memory size appears to be less than shared memory window size, @@ -1007,8 +1150,7 @@ err = sdla_init(hw); if (err) return err; - if (sdla_memtest(hw) < hw->dpmsize) /* less than window size */ - { + if (sdla_memtest(hw) < hw->dpmsize) { /* less than window size */ sdla_down(hw); return -EIO; } @@ -1023,32 +1165,28 @@ */ static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len) { + int i; /* Verify firmware signature */ - if (strcmp(sfm->signature, SFM_SIGNATURE)) - { + if (strcmp(sfm->signature, SFM_SIGNATURE)) { printk(KERN_ERR "%s: not SDLA firmware!\n", - modname) - ; + modname); return -EINVAL; } /* Verify firmware module format version */ - if (sfm->version != SFM_VERSION) - { + if (sfm->version != SFM_VERSION) { printk(KERN_ERR "%s: firmware format %u rejected! Expecting %u.\n", - modname, sfm->version, SFM_VERSION) - ; + modname, sfm->version, SFM_VERSION); return -EINVAL; } /* Verify firmware module length and checksum */ if ((len - offsetof(sfm_t, image) != sfm->info.codesize) || (checksum((void*)&sfm->info, - sizeof(sfm_info_t) + sfm->info.codesize) != sfm->checksum)) - { + sizeof(sfm_info_t) + sfm->info.codesize) != sfm->checksum)) { printk(KERN_ERR "%s: firmware corrupted!\n", modname); return -EINVAL; } @@ -1056,8 +1194,11 @@ /* Announce */ printk(KERN_INFO "%s: loading %s (ID=%u)...\n", modname, (sfm->descr[0] != '\0') ? sfm->descr : "unknown firmware", - sfm->info.codeid) - ; + sfm->info.codeid); + + if(hw->type == SDLA_S514) + printk(KERN_INFO "%s: loading S514 adapter, CPU %c\n", + modname, hw->S514_cpu_no[0]); /* Scan through the list of compatible adapters and make sure our * adapter type is listed. @@ -1066,49 +1207,41 @@ (i < SFM_MAX_SDLA) && (sfm->info.adapter[i] != hw->type); ++i) ; - if (i == SFM_MAX_SDLA) - { + if (i == SFM_MAX_SDLA) { printk(KERN_ERR "%s: firmware is not compatible with S%u!\n", - modname, hw->type) + modname, hw->type); ; return -EINVAL; } + /* Make sure there is enough on-board memory */ - if (hw->memory < sfm->info.memsize) - { + if (hw->memory < sfm->info.memsize) { printk(KERN_ERR "%s: firmware needs %lu bytes of on-board memory!\n", - modname, sfm->info.memsize) - ; + modname, sfm->info.memsize); return -EINVAL; } /* Move code onto adapter */ - if (sdla_poke(hw, sfm->info.codeoffs, sfm->image, sfm->info.codesize)) - { + if (sdla_poke(hw, sfm->info.codeoffs, sfm->image, sfm->info.codesize)) { printk(KERN_ERR "%s: failed to load code segment!\n", - modname) - ; + modname); return -EIO; } /* Prepare boot-time configuration data and kick-off CPU */ sdla_bootcfg(hw, &sfm->info); - if (sdla_start(hw, sfm->info.startoffs)) - { + if (sdla_start(hw, sfm->info.startoffs)) { printk(KERN_ERR "%s: Damn... Adapter won't start!\n", - modname) - ; + modname); return -EIO; } /* position DPM window over the mailbox and enable interrupts */ - if (sdla_mapmem(hw, sfm->info.winoffs) || sdla_inten(hw)) - { + if (sdla_mapmem(hw, sfm->info.winoffs) || sdla_inten(hw)) { printk(KERN_ERR "%s: adapter hardware failure!\n", - modname) - ; + modname); return -EIO; } hw->fwid = sfm->info.codeid; /* set firmware ID */ @@ -1123,10 +1256,9 @@ int i; for (i = 0; i < SDLA_MAXIORANGE; ++i) - hw->regs[i] = 0 - ; - switch (hw->type) - { + hw->regs[i] = 0; + + switch (hw->type) { case SDLA_S502A: return init_s502a(hw); case SDLA_S502E: return init_s502e(hw); case SDLA_S503: return init_s503(hw); @@ -1169,23 +1301,28 @@ if (!sfminfo->datasize) return 0; /* nothing to do */ if (sdla_mapmem(hw, sfminfo->dataoffs) != 0) - return -EIO - ; - data = (void*)((u8 *)hw->dpmbase + (sfminfo->dataoffs - hw->vector)); - memset(data, 0, sfminfo->datasize); + return -EIO; + + if(hw->type == SDLA_S514) + data = (void*)(hw->dpmbase + sfminfo->dataoffs); + else + data = (void*)((u8 *)hw->dpmbase + + (sfminfo->dataoffs - hw->vector)); + + memset_io (data, 0, sfminfo->datasize); + + writeb (make_config_byte(hw), &data[0x00]); - data[0x00] = make_config_byte(hw); - switch (sfminfo->codeid) - { + switch (sfminfo->codeid) { case SFID_X25_502: case SFID_X25_508: - data[0x01] = 3; /* T1 timer */ - data[0x03] = 10; /* N2 */ - data[0x06] = 7; /* HDLC window size */ - data[0x0B] = 1; /* DTE */ - data[0x0C] = 2; /* X.25 packet window size */ - *(short*)&data[0x0D] = 128; /* default X.25 data size */ - *(short*)&data[0x0F] = 128; /* maximum X.25 data size */ + writeb (3, &data[0x01]); /* T1 timer */ + writeb (10, &data[0x03]); /* N2 */ + writeb (7, &data[0x06]); /* HDLC window size */ + writeb (1, &data[0x0B]); /* DTE */ + writeb (2, &data[0x0C]); /* X.25 packet window size */ + writew (128, &data[0x0D]); /* default X.25 data size */ + writew (128, &data[0x0F]); /* maximum X.25 data size */ break; } return 0; @@ -1198,16 +1335,15 @@ { unsigned char byte = 0; - switch (hw->pclk) - { + switch (hw->pclk) { case 5000: byte = 0x01; break; case 7200: byte = 0x02; break; case 8000: byte = 0x03; break; case 10000: byte = 0x04; break; case 16000: byte = 0x05; break; } - switch (hw->type) - { + + switch (hw->type) { case SDLA_S502E: byte |= 0x80; break; case SDLA_S503: byte |= 0x40; break; } @@ -1227,10 +1363,9 @@ unsigned char *bootp; int err, tmp, i; - if (!port) return -EFAULT; + if (!port && (hw->type != SDLA_S514)) return -EFAULT; - switch (hw->type) - { + switch (hw->type) { case SDLA_S502A: bootp = hw->dpmbase; bootp += 0x66; @@ -1240,6 +1375,7 @@ case SDLA_S503: case SDLA_S507: case SDLA_S508: + case SDLA_S514: bootp = hw->dpmbase; break; @@ -1250,12 +1386,11 @@ err = sdla_mapmem(hw, 0); if (err) return err; - *bootp = 0xC3; /* Z80: 'jp' opcode */ - bootp++; - *((unsigned short*)(bootp)) = addr; + writeb (0xC3, bootp); /* Z80: 'jp' opcode */ + bootp ++; + writew (addr, bootp); - switch (hw->type) - { + switch (hw->type) { case SDLA_S502A: _OUTB(port, 0x10); /* issue NMI to CPU */ hw->regs[0] = 0x10; @@ -1265,8 +1400,7 @@ _OUTB(port + 3, 0x01); /* start CPU */ hw->regs[3] = 0x01; for (i = 0; i < SDLA_IODELAY; ++i); - if (_INB(port) & 0x01) /* verify */ - { + if (_INB(port) & 0x01) { /* verify */ /* * Enabling CPU changes functionality of the * control register, so we have to reset its @@ -1284,8 +1418,7 @@ hw->regs[0] = tmp; /* update mirror */ for (i = 0; i < SDLA_IODELAY; ++i); if (!(_INB(port) & 0x01)) /* verify */ - return -EIO - ; + return -EIO; break; case SDLA_S507: @@ -1294,8 +1427,7 @@ hw->regs[0] = tmp; /* update mirror */ for (i = 0; i < SDLA_IODELAY; ++i); if (!(_INB(port) & 0x04)) /* verify */ - return -EIO - ; + return -EIO; break; case SDLA_S508: @@ -1304,8 +1436,11 @@ hw->regs[0] = tmp; /* update mirror */ for (i = 0; i < SDLA_IODELAY; ++i); if (!(_INB(port + 1) & 0x02)) /* verify */ - return -EIO - ; + return -EIO; + break; + + case SDLA_S514: + writeb (S514_CPU_START, hw->vector); break; default: @@ -1323,20 +1458,18 @@ int tmp, i; if (!detect_s502a(port)) - return -ENODEV - ; + return -ENODEV; + hw->regs[0] = 0x08; hw->regs[1] = 0xFF; /* Verify configuration options */ i = get_option_index(s502a_dpmbase_options, virt_to_phys(hw->dpmbase)); if (i == 0) - return -EINVAL - ; + return -EINVAL; tmp = s502a_hmcr[i - 1]; - switch (hw->dpmsize) - { + switch (hw->dpmsize) { case 0x2000: tmp |= 0x01; break; @@ -1364,18 +1497,15 @@ int tmp, i; if (!detect_s502e(port)) - return -ENODEV - ; + return -ENODEV; /* Verify configuration options */ i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase)); if (i == 0) - return -EINVAL - ; + return -EINVAL; tmp = s502e_hmcr[i - 1]; - switch (hw->dpmsize) - { + switch (hw->dpmsize) { case 0x2000: tmp |= 0x01; break; @@ -1408,18 +1538,15 @@ int tmp, i; if (!detect_s503(port)) - return -ENODEV - ; + return -ENODEV; /* Verify configuration options */ i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase)); if (i == 0) - return -EINVAL - ; + return -EINVAL; tmp = s502e_hmcr[i - 1]; - switch (hw->dpmsize) - { + switch (hw->dpmsize) { case 0x2000: tmp |= 0x01; break; @@ -1450,18 +1577,15 @@ int tmp, i; if (!detect_s507(port)) - return -ENODEV - ; + return -ENODEV; /* Verify configuration options */ i = get_option_index(s507_dpmbase_options, virt_to_phys(hw->dpmbase)); if (i == 0) - return -EINVAL - ; + return -EINVAL; tmp = s507_hmcr[i - 1]; - switch (hw->dpmsize) - { + switch (hw->dpmsize) { case 0x2000: tmp |= 0x01; break; @@ -1478,8 +1602,7 @@ hw->regs[0] = 0x01; for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if (!(_INB(port) & 0x20)) - return -EIO - ; + return -EIO; /* Setup dual-port memory window */ _OUTB(port + 1, tmp); @@ -1487,8 +1610,7 @@ /* Enable memory access */ tmp = hw->regs[0] | 0x04; - if (hw->irq) - { + if (hw->irq) { i = get_option_index(s508_irq_options, hw->irq); if (i) tmp |= s507_irqmask[i - 1]; } @@ -1507,14 +1629,12 @@ int tmp, i; if (!detect_s508(port)) - return -ENODEV - ; + return -ENODEV; /* Verify configuration options */ i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase)); if (i == 0) - return -EINVAL - ; + return -EINVAL; /* Setup memory configuration */ tmp = s508_hmcr[i - 1]; @@ -1547,13 +1667,11 @@ int i, j; if (!get_option_index(s502_port_options, port)) - return 0 - ; - for (j = 1; j < SDLA_MAXIORANGE; ++j) - { + return 0; + + for (j = 1; j < SDLA_MAXIORANGE; ++j) { if (_INB(port + j) != 0xFF) - return 0 - ; + return 0; for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ } @@ -1562,18 +1680,15 @@ _OUTB(port, 0x08); for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if (_INB(port) != 0x40) - return 0 - ; + return 0; _OUTB(port, 0x00); for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if (_INB(port) != 0x40) - return 0 - ; + return 0; _OUTB(port, 0x04); for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if (_INB(port) != 0x44) - return 0 - ; + return 0; /* Reset adapter */ _OUTB(port, 0x08); @@ -1600,26 +1715,21 @@ int i, j; if (!get_option_index(s502_port_options, port)) - return 0 - ; - for (j = 1; j < SDLA_MAXIORANGE; ++j) - { + return 0; + for (j = 1; j < SDLA_MAXIORANGE; ++j) { if (_INB(port + j) != 0xFF) - return 0 - ; + return 0; for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ } _OUTB(port + 3, 0); /* CPU control reg. */ for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if (_INB(port) != 0xF8) /* read status */ - return 0 - ; + return 0; _OUTB(port, 0x04); /* set bit 2 */ for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if (_INB(port) != 0xFC) /* verify */ - return 0 - ; + return 0; /* Reset adapter */ _OUTB(port, 0); @@ -1643,26 +1753,21 @@ int i, j; if (!get_option_index(s503_port_options, port)) - return 0 - ; - for (j = 1; j < SDLA_MAXIORANGE; ++j) - { + return 0; + for (j = 1; j < SDLA_MAXIORANGE; ++j) { if (_INB(port + j) != 0xFF) - return 0 - ; + return 0; for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ } _OUTB(port, 0); /* reset control reg.*/ for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if (_INB(port) != 0xF0) /* read status */ - return 0 - ; + return 0; _OUTB(port, 0x04); /* set bit 2 */ for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if (_INB(port) != 0xF2) /* verify */ - return 0 - ; + return 0; /* Reset adapter */ _OUTB(port, 0); @@ -1686,27 +1791,22 @@ int tmp, i, j; if (!get_option_index(s508_port_options, port)) - return 0 - ; + return 0; tmp = _INB(port); - for (j = 1; j < S507_IORANGE; ++j) - { + for (j = 1; j < S507_IORANGE; ++j) { if (_INB(port + j) != tmp) - return 0 - ; + return 0; for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ } _OUTB(port, 0x00); for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if ((_INB(port) & 0x7E) != 0x30) - return 0 - ; + return 0; _OUTB(port, 0x01); for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if ((_INB(port) & 0x7E) != 0x32) - return 0 - ; + return 0; /* Reset adapter */ _OUTB(port, 0x00); @@ -1729,24 +1829,205 @@ int i; if (!get_option_index(s508_port_options, port)) - return 0 - ; + return 0; _OUTB(port, 0x00); for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if ((_INB(port + 1) & 0x3F) != 0x00) - return 0 - ; + return 0; _OUTB(port, 0x10); for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ if ((_INB(port + 1) & 0x3F) != 0x10) - return 0 - ; + return 0; /* Reset adapter */ _OUTB(port, 0x00); return 1; } +/*============================================================================ + * Detect s514 PCI adapter. + * Return 1 if detected o.k. or 0 if failed. + * Note: This test is destructive! Adapter will be left in shutdown + * state after the test. + */ +static int detect_s514 (sdlahw_t* hw) +{ + unsigned char CPU_no, slot_no; + int number_S514_cards = 0; + u32 S514_mem_base_addr = 0; + u32 ut_u32; + + struct pci_dev *pci_dev; + + +#ifdef CONFIG_PCI + if(!pci_present()) + { + printk(KERN_ERR "%s: PCI BIOS not present!\n", modname); + return 0; + } +#else + printk(KERN_ERR "%s: Linux not compiled for PCI usage!\n", modname); + return 0; +#endif + + /* + The 'setup()' procedure in 'sdlamain.c' passes the CPU number and the + slot number defined in 'router.conf' via the 'port' definition. + */ + CPU_no = hw->S514_cpu_no[0]; + slot_no = hw->S514_slot_no; + + printk(KERN_INFO "%s: detecting S514 card, CPU %c, slot #%d\n", + modname, CPU_no, slot_no); + + /* check to see that CPU A or B has been selected in 'router.conf' */ + switch(CPU_no) { + case S514_CPU_A: + case S514_CPU_B: + break; + + default: + printk(KERN_ERR "%s: S514 CPU definition invalid.\n", + modname); + printk(KERN_ERR "Must be 'A' or 'B'\n"); + return 0; + } + + number_S514_cards = find_s514_adapter(hw, 0); + if(!number_S514_cards) + return 0; + + /* we are using a single S514 adapter with a slot of 0 so re-read the */ /* location of this adapter */ + if((number_S514_cards == 1) && !slot_no) { + number_S514_cards = find_s514_adapter(hw, 1); + if(!number_S514_cards) { + printk(KERN_ERR "%s: Error finding PCI card\n", + modname); + return 0; + } + } + + pci_dev = hw->pci_dev; + /* read the physical memory base address */ + S514_mem_base_addr = (CPU_no == S514_CPU_A) ? + (pci_dev->resource[1].start) : + (pci_dev->resource[2].start); + + printk(KERN_INFO "%s: S514 PCI memory at 0x%X\n", + modname, S514_mem_base_addr); + if(!S514_mem_base_addr) { + if(CPU_no == S514_CPU_B) + printk(KERN_ERR "%s: CPU #B not present on the card\n", modname); + else + printk(KERN_ERR "%s: No PCI memory allocated to card\n", modname); + return 0; + } + + /* enable the PCI memory */ + pci_read_config_dword(pci_dev, + (CPU_no == S514_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD, + &ut_u32); + pci_write_config_dword(pci_dev, + (CPU_no == S514_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD, + (ut_u32 | PCI_MEMORY_ENABLE)); + + /* check the IRQ allocated and enable IRQ usage */ + if(!(hw->irq = pci_dev->irq)) { + printk(KERN_ERR "%s: IRQ not allocated to S514 adapter\n", + modname); + return 0; + } + pci_read_config_dword(pci_dev, PCI_INT_CONFIG, &ut_u32); + ut_u32 |= (CPU_no == S514_CPU_A) ? + PCI_ENABLE_IRQ_CPU_A : PCI_ENABLE_IRQ_CPU_B; + pci_write_config_dword(pci_dev, PCI_INT_CONFIG, ut_u32); + + printk(KERN_INFO "%s: IRQ %d allocated to the S514 card\n", + modname, hw->irq); + + /* map the physical PCI memory to virtual memory */ + (void *)hw->dpmbase = ioremap((unsigned long)S514_mem_base_addr, + (unsigned long)MAX_SIZEOF_S514_MEMORY); + /* map the physical control register memory to virtual memory */ + (void *)hw->vector = ioremap( + (unsigned long)(S514_mem_base_addr + S514_CTRL_REG_BYTE), + (unsigned long)16); + + if(!hw->dpmbase || !hw->vector) { + printk(KERN_ERR "%s: PCI virtual memory allocation failed\n", + modname); + return 0; + } + + /* halt the adapter */ + writeb (S514_CPU_HALT, hw->vector); + + return 1; +} + +/*============================================================================ + * Find the S514 PCI adapter in the PCI bus. + * Return the number of S514 adapters found (0 if no adapter found). + */ +static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card) +{ + unsigned char slot_no; + int number_S514_cards = 0; + char S514_found_in_slot = 0; + u16 PCI_subsys_vendor; + + struct pci_dev *pci_dev = NULL; + + slot_no = hw->S514_slot_no; + + while ((pci_dev = pci_find_device(V3_VENDOR_ID, V3_DEVICE_ID, pci_dev)) + != NULL) { + pci_read_config_word(pci_dev, PCI_SUBSYS_VENDOR_WORD, + &PCI_subsys_vendor); + if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR) + continue; + hw->pci_dev = pci_dev; + if(find_first_S514_card) + return(1); + number_S514_cards ++; + printk(KERN_INFO + "%s: S514 card found, slot #%d (devfn 0x%X)\n", + modname, ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), + pci_dev->devfn); + if(slot_no && (((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK) == + slot_no)) { + S514_found_in_slot = 1; + break; + } + } + + /* if no S514 adapter has been found, then exit */ + if(!number_S514_cards) { + printk(KERN_ERR "%s: no S514 adapters found\n", modname); + return 0; + } + /* if more than one S514 card has been found, then the user must have */ /* defined a slot number so that the correct adapter is used */ + else if((number_S514_cards > 1) && !slot_no) { + printk(KERN_ERR "%s: More than one S514 adapter found\n", + modname); + printk(KERN_ERR "Define a PCI slot number for this adapter\n"); + return 0; + } + /* if the user has specified a slot number and the S514 adapter has */ + /* not been found in that slot, then exit */ + else if (slot_no && !S514_found_in_slot) { + printk(KERN_ERR + "%s: S514 card not found in specified slot #%d\n", + modname, slot_no); + return 0; + } + + return (number_S514_cards); +} + + + /******* Miscellaneous ******************************************************/ /*============================================================================ @@ -1772,8 +2053,8 @@ int i; for (i = 1; i <= optlist[0]; ++i) - if ( optlist[i] == optval) return i - ; + if ( optlist[i] == optval) + return i; return 0; } @@ -1785,15 +2066,14 @@ { volatile unsigned char* p = ptr; - for (; len && (*p == 0xFF); --len, ++p) - { - *p = 0; /* attempt to write 0 */ - if (*p != 0xFF) /* still has to read 0xFF */ - { - *p = 0xFF; /* restore original value */ - break; /* not good */ - } - } + for (; len && (readb (p) == 0xFF); --len, ++p) { + writeb (0, p); /* attempt to write 0 */ + if (readb(p) != 0xFF) { /* still has to read 0xFF */ + writeb (0xFF, p);/* restore original value */ + break; /* not good */ + } + } + return len; } @@ -1808,28 +2088,28 @@ unsigned len_w = len >> 1; /* region len in words */ unsigned i; + for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) + writew (0xAA55, w_ptr); + for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) - *w_ptr = 0xAA55 - ; - for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) - if (*w_ptr != 0xAA55) - { - len_w = i; - break; - } - ; - for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) - *w_ptr = 0x55AA - ; - for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) - if (*w_ptr != 0x55AA) - { - len_w = i; - break; - } - ; - for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) *w_ptr = 0; - return len_w << 1; + if (readw (w_ptr) != 0xAA55) { + len_w = i; + break; + } + + for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) + writew (0x55AA, w_ptr); + + for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) + if (readw(w_ptr) != 0x55AA) { + len_w = i; + break; + } + + for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) + writew (0, w_ptr); + + return len_w << 1; } /*============================================================================ @@ -1840,10 +2120,8 @@ unsigned short crc = 0; unsigned mask, flag; - for (; len; --len, ++buf) - { - for (mask = 0x80; mask; mask >>= 1) - { + for (; len; --len, ++buf) { + for (mask = 0x80; mask; mask >>= 1) { flag = (crc & 0x8000); crc <<= 1; crc |= ((*buf & mask) ? 1 : 0); diff -ur --new-file old/linux/drivers/net/wan/sdlamain.c new/linux/drivers/net/wan/sdlamain.c --- old/linux/drivers/net/wan/sdlamain.c Mon Oct 11 19:13:25 1999 +++ new/linux/drivers/net/wan/sdlamain.c Wed Jan 26 22:25:58 2000 @@ -1,18 +1,21 @@ /***************************************************************************** * sdlamain.c WANPIPE(tm) Multiprotocol WAN Link Driver. Main module. * -* Author: Gene Kozin -* Jaspreet Singh -* Fixes: Arnaldo Carvalho de Melo +* Author: Nenad Corbic +* Gideon Hack * -* Copyright: (c) 1995-1997 Sangoma Technologies Inc. +* Copyright: (c) 1995-1999 Sangoma Technologies 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. * ============================================================================ -* May 19, 1999 Arnaldo Melo __init for wanpipe_init +* Sep 23, 1999 Nenad Corbic Added support for SMP +* Sep 13, 1999 Nenad Corbic Each port is treated as a separate device. +* Jun 02, 1999 Gideon Hack Added support for the S514 adapter. +* Updates for Linux 2.2.X kernels. +* Sep 17, 1998 Jaspreet Singh Updated for 2.1.121+ kernel * Nov 28, 1997 Jaspreet Singh Changed DRV_RELEASE to 1 * Nov 10, 1997 Jaspreet Singh Changed sti() to restore_flags(); * Nov 06, 1997 Jaspreet Singh Changed DRV_VERSION to 4 and DRV_RELEASE to 0 @@ -31,6 +34,7 @@ * Jan 02, 1997 Gene Kozin Initial version. *****************************************************************************/ +#include #include /* OS configuration options */ #include /* offsetof(), etc. */ #include /* return codes */ @@ -44,8 +48,8 @@ #include /* WANPIPE common user API definitions */ #include /* kernel <-> user copy */ #include /* phys_to_virt() */ -#include /* __init (when not using as a module) */ - +#include +#include /****** Defines & Macros ****************************************************/ @@ -55,8 +59,8 @@ #define STATIC static #endif -#define DRV_VERSION 4 /* version number */ -#define DRV_RELEASE 1 /* release (minor version) number */ +#define DRV_VERSION 5 /* version number */ +#define DRV_RELEASE 0 /* release (minor version) number */ #define MAX_CARDS 8 /* max number of adapters */ #ifndef CONFIG_WANPIPE_CARDS /* configurable option */ @@ -66,9 +70,11 @@ #define CMD_OK 0 /* normal firmware return code */ #define CMD_TIMEOUT 0xFF /* firmware command timed out */ #define MAX_CMD_RETRY 10 /* max number of firmware retries */ - /****** Function Prototypes *************************************************/ +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + /* Module entry points */ int init_module (void); void cleanup_module (void); @@ -78,13 +84,14 @@ static int shutdown (wan_device_t* wandev); static int ioctl (wan_device_t* wandev, unsigned cmd, unsigned long arg); -/* IOCTL hanlers */ +/* IOCTL handlers */ static int ioctl_dump (sdla_t* card, sdla_dump_t* u_dump); static int ioctl_exec (sdla_t* card, sdla_exec_t* u_exec); /* Miscellaneous functions */ STATIC void sdla_isr (int irq, void* dev_id, struct pt_regs *regs); STATIC void sdla_poll (void* data); +static void release_hw (sdla_t *card); /****** Global Data ********************************************************** * Note: All data must be explicitly initialized!!! @@ -93,7 +100,7 @@ /* private data */ static char drvname[] = "wanpipe"; static char fullname[] = "WANPIPE(tm) Multiprotocol Driver"; -static char copyright[] = "(c) 1995-1996 Sangoma Technologies Inc."; +static char copyright[] = "(c) 1995-1999 Sangoma Technologies Inc."; static int ncards = CONFIG_WANPIPE_CARDS; static int active = 0; /* number of active cards */ static sdla_t* card_array = NULL; /* adapter data space */ @@ -107,6 +114,7 @@ NULL /* .data */ }; + /******* Kernel Loadable Module Entry Points ********************************/ /*============================================================================ @@ -125,30 +133,29 @@ #ifdef MODULE int init_module (void) #else -int __init wanpipe_init(void) +int wanpipe_init2(void) #endif { int cnt, err = 0; printk(KERN_INFO "%s v%u.%u %s\n", - fullname, DRV_VERSION, DRV_RELEASE, copyright) - ; + fullname, DRV_VERSION, DRV_RELEASE, copyright); /* Verify number of cards and allocate adapter data space */ ncards = min(ncards, MAX_CARDS); ncards = max(ncards, 1); card_array = kmalloc(sizeof(sdla_t) * ncards, GFP_KERNEL); if (card_array == NULL) - return -ENOMEM - ; + return -ENOMEM; + memset(card_array, 0, sizeof(sdla_t) * ncards); /* Register adapters with WAN router */ - for (cnt = 0; cnt < ncards; ++cnt) - { + for (cnt = 0; cnt < ncards; ++ cnt) { sdla_t* card = &card_array[cnt]; wan_device_t* wandev = &card->wandev; + card->next = NULL; sprintf(card->devname, "%s%d", drvname, cnt + 1); wandev->magic = ROUTER_MAGIC; wandev->name = card->devname; @@ -158,20 +165,18 @@ wandev->shutdown = &shutdown; wandev->ioctl = &ioctl; err = register_wan_device(wandev); - if (err) - { + if (err) { printk(KERN_ERR "%s: %s registration failed with error %d!\n", - drvname, card->devname, err) - ; + drvname, card->devname, err); break; } } - if (cnt) + if (cnt){ ncards = cnt; /* adjust actual number of cards */ - else - { + }else { kfree(card_array); + printk(KERN_INFO "IN Init Module: NO Cards registered\n"); err = -ENODEV; } return err; @@ -187,8 +192,7 @@ { int i; - for (i = 0; i < ncards; ++i) - { + for (i = 0; i < ncards; ++i) { sdla_t* card = &card_array[i]; unregister_wan_device(card->devname); } @@ -200,7 +204,7 @@ /******* WAN Device Driver Entry Points *************************************/ /*============================================================================ - * Setup/confugure WAN link driver. + * Setup/configure WAN link driver. * o check adapter state * o make sure firmware is present in configuration * o make sure I/O port and IRQ are specified @@ -220,7 +224,8 @@ { sdla_t* card; int err = 0; - int irq; + int irq=0; + int i; /* Sanity checks */ if ((wandev == NULL) || (wandev->private == NULL) || (conf == NULL)) @@ -230,80 +235,187 @@ if (wandev->state != WAN_UNCONFIGURED) return -EBUSY; /* already configured */ - if (!conf->data_size || (conf->data == NULL)) - { + printk(KERN_INFO "\nProcessing WAN device %s...\n", wandev->name); + + /* Initialize the counters for each wandev + * Used for counting number of times new_if and + * del_if get called. + */ + wandev->del_if_cnt = 0; + wandev->new_if_cnt = 0; + wandev->config_id = conf->config_id; + + if (!conf->data_size || (conf->data == NULL)) { printk(KERN_ERR "%s: firmware not found in configuration data!\n", wandev->name); return -EINVAL; } - if (conf->ioport <= 0) - { - printk(KERN_ERR + + /* only check I/O port and IRQ if not an S514 adapter */ + if(!conf->S514_CPU_no[0]) { + + if (conf->ioport <= 0) { + printk(KERN_ERR "%s: can't configure without I/O port address!\n", wandev->name); - return -EINVAL; - } + return -EINVAL; + } - if (conf->irq <= 0) - { - printk(KERN_ERR "%s: can't configure without IRQ!\n", + if (conf->irq <= 0) { + printk(KERN_ERR "%s: can't configure without IRQ!\n", wandev->name); - return -EINVAL; - } + return -EINVAL; + } - /* Make sure I/O port region is available */ - if (check_region(conf->ioport, SDLA_MAXIORANGE)) - { - printk(KERN_ERR "%s: I/O region 0x%X - 0x%X is in use!\n", - wandev->name, conf->ioport, - conf->ioport + SDLA_MAXIORANGE); - return -EINVAL; + /* Check for already loaded card with the same IO port and IRQ + * If found, copy its hardware configuration and use its + * resources (i.e. piggybacking) + */ + if (!card->configured){ + for (i = 0; i < ncards; i ++) { + sdla_t *nxt_card = &card_array[i]; + if (nxt_card->hw.port == conf->ioport && + nxt_card != card && + conf->config_id == WANCONFIG_CHDLC && + nxt_card->wandev.config_id == WANCONFIG_CHDLC){ + irq = nxt_card->hw.irq; + memcpy(&card->hw, &nxt_card->hw, sizeof(sdlahw_t)); + nxt_card->next = card; + card->next = nxt_card; + card->wandev.piggyback = WANOPT_YES; + } + } + + + /* Make sure I/O port region is available */ + if (check_region(conf->ioport, SDLA_MAXIORANGE) && + !card->wandev.piggyback) { + printk(KERN_ERR + "%s: I/O region 0x%X - 0x%X is in use!\n", + wandev->name, conf->ioport, + conf->ioport + SDLA_MAXIORANGE); + return -EINVAL; + } + } } - /* Allocate IRQ */ - irq = (conf->irq == 2) ? 9 : conf->irq; /* IRQ2 -> IRQ9 */ - if (request_irq(irq, sdla_isr, 0, wandev->name, card)) - { - printk(KERN_ERR "%s: can't reserve IRQ %d!\n", - wandev->name, irq); - return -EINVAL; + /* + For a S514 adapter, check for a possible configuration error in that + we are loading an adapter in the same slot as a previously loaded S514 + card. + */ + else { + if (!card->configured){ + for (i = 0; i < ncards; i ++) { + sdla_t* nxt_card = &card_array[i]; + if(nxt_card == card) + continue; + if((nxt_card->hw.type == SDLA_S514) && + (nxt_card->hw.S514_slot_no == conf->PCI_slot_no) && + (nxt_card->hw.S514_cpu_no[0] == conf->S514_CPU_no[0])&& + (conf->config_id == WANCONFIG_CHDLC)&& + (nxt_card->wandev.config_id == WANCONFIG_CHDLC)){ + + irq = nxt_card->hw.irq; + memcpy(&card->hw, &nxt_card->hw, sizeof(sdlahw_t)); + nxt_card->next = card; + card->next = nxt_card; + card->wandev.piggyback = WANOPT_YES; + } + } + } } - /* Configure hardware, load firmware, etc. */ - memset(&card->hw, 0, sizeof(sdlahw_t)); - card->hw.port = conf->ioport; - card->hw.irq = (conf->irq == 9) ? 2 : conf->irq; - /* Compute the virtual address of the card in kernel space */ - if(conf->maddr) - card->hw.dpmbase = phys_to_virt(conf->maddr); - else /* But 0 means NULL */ - card->hw.dpmbase = (void *)conf->maddr; - - card->hw.dpmsize = SDLA_WINDOWSIZE; - card->hw.type = conf->hw_opt[0]; - card->hw.pclk = conf->hw_opt[1]; - err = sdla_setup(&card->hw, conf->data, conf->data_size); - if (err) - { - free_irq(irq, card); - return err; - } + /* If the current card has already been configured + * or its a piggyback card, do not try to allocate + * resources. + */ + if (!card->wandev.piggyback && !card->configured){ + + /* Configure hardware, load firmware, etc. */ + memset(&card->hw, 0, sizeof(sdlahw_t)); + + /* for an S514 adapter, pass the CPU number and the slot number read */ + /* from 'router.conf' to the 'sdla_setup()' function via the 'port' */ + /* parameter */ + if (conf->S514_CPU_no[0]){ + + card->hw.S514_cpu_no[0] = conf->S514_CPU_no[0]; + card->hw.S514_slot_no = conf->PCI_slot_no; + printk(KERN_INFO "Setting CPU to %c and Slot to %i\n", + card->hw.S514_cpu_no[0], card->hw.S514_slot_no); + + }else{ + /* 508 Card io port and irq initialization */ + card->hw.port = conf->ioport; + card->hw.irq = (conf->irq == 9) ? 2 : conf->irq; + } + + + /* Compute the virtual address of the card in kernel space */ + if(conf->maddr) + card->hw.dpmbase = phys_to_virt(conf->maddr); + else /* But 0 means NULL */ + card->hw.dpmbase = (void *)conf->maddr; + + card->hw.dpmsize = SDLA_WINDOWSIZE; + /* set the adapter type if using an S514 adapter */ + card->hw.type = (conf->S514_CPU_no[0]) ? SDLA_S514 : conf->hw_opt[0]; + card->hw.pclk = conf->hw_opt[1]; + + err = sdla_setup(&card->hw, conf->data, conf->data_size); + if (err){ + return err; + } + + if(card->hw.type != SDLA_S514) + irq = (conf->irq == 2) ? 9 : conf->irq; /* IRQ2 -> IRQ9 */ + else + irq = card->hw.irq; + + /* request an interrupt vector - note that interrupts may be shared */ + /* when using the S514 PCI adapter */ + if(request_irq(irq, sdla_isr, + (card->hw.type == SDLA_S514) ? SA_SHIRQ : 0, wandev->name, card)){ - /* Intialize WAN device data space */ - wandev->irq = irq; - wandev->dma = 0; - wandev->ioport = card->hw.port; - wandev->maddr = card->hw.dpmbase; - wandev->msize = card->hw.dpmsize; - wandev->hw_opt[0] = card->hw.type; - wandev->hw_opt[1] = card->hw.pclk; - wandev->hw_opt[2] = card->hw.memory; - wandev->hw_opt[3] = card->hw.fwid; + printk(KERN_ERR "%s: Can't reserve IRQ %d!\n", wandev->name, irq); + return -EINVAL; + } + + }else{ + printk(KERN_INFO "%s: Card Configured %i or Piggybacking %i!\n", + wandev->name,card->configured,card->wandev.piggyback); + } + + + if (!card->configured){ + + #ifdef __SMP__ + /* Initialize the Spin lock */ + printk(KERN_INFO "%s: Initializing SMP\n",wandev->name); + spin_lock_init(&card->lock); + #endif + + /* Intialize WAN device data space */ + wandev->irq = irq; + wandev->dma = 0; + if(card->hw.type != SDLA_S514){ + wandev->ioport = card->hw.port; + }else{ + wandev->S514_cpu_no[0] = card->hw.S514_cpu_no[0]; + wandev->S514_slot_no = card->hw.S514_slot_no; + } + wandev->maddr = (unsigned long)card->hw.dpmbase; + wandev->msize = card->hw.dpmsize; + wandev->hw_opt[0] = card->hw.type; + wandev->hw_opt[1] = card->hw.pclk; + wandev->hw_opt[2] = card->hw.memory; + wandev->hw_opt[3] = card->hw.fwid; + } /* Protocol-specific initialization */ - switch (card->hw.fwid) - { + switch (card->hw.fwid) { #ifdef CONFIG_WANPIPE_X25 case SFID_X25_502: case SFID_X25_508: @@ -325,22 +437,49 @@ break; #endif +#ifdef CONFIG_WANPIPE_CHDLC + case SFID_CHDLC508: + case SFID_CHDLC514: +// if (conf->ft1){ +// printk(KERN_INFO "%s: Starting FT1 Configurator\n", +// card->devname); +// err = wpft1_init(card, conf); +// }else{ + err = wpc_init(card, conf); +// } + break; +#endif + +#ifdef CONFIG_WANPIPE_BSTRM + case SFID_BSC502: + err = bsc_init(card, conf); + break; +#endif + +#ifdef CONFIG_WANPIPE_HDLC + case SFID_HDLC508: + err = hdlc_init(card, conf); + break; +#endif + default: - printk(KERN_ERR "%s: this firmware is not supported!\n", - wandev->name) - ; + printk(KERN_ERR "%s: this firmware is not supported %X %X!\n", + wandev->name,card->hw.fwid,SFID_CHDLC508); err = -EINVAL; } - if (err) - { - sdla_down(&card->hw); - free_irq(irq, card); + + + if (err){ + release_hw(card); return err; + } + + /* Reserve I/O region and schedule background task */ -/* printk(KERN_INFO "about to request\n");*/ - request_region(card->hw.port, card->hw.io_range, wandev->name); -/* printk(KERN_INFO "request done\n");*/ + if(card->hw.type != SDLA_S514 && !card->wandev.piggyback) + request_region(card->hw.port, card->hw.io_range, wandev->name); + if (++active == 1) queue_task(&sdla_tq, &tq_scheduler); @@ -358,7 +497,7 @@ */ static int shutdown (wan_device_t* wandev) { - sdla_t* card; + sdla_t *card; /* sanity checks */ if ((wandev == NULL) || (wandev->private == NULL)) @@ -367,7 +506,7 @@ if (wandev->state == WAN_UNCONFIGURED) return 0; - /* If wee are in a critical section we lose */ + /* If we are in a critical section we lose */ if (test_and_set_bit(0, (void*)&wandev->critical)) return -EAGAIN; @@ -376,22 +515,67 @@ if (--active == 0) schedule(); /* stop background thread */ - -/* printk(KERN_INFO "active now %d\n", active); - printk(KERN_INFO "About to call sdla_down\n");*/ - sdla_down(&card->hw); -/* printk(KERN_INFO "sdla_down done\n"); - printk(KERN_INFO "About to call free_irq\n");*/ - free_irq(wandev->irq, card); -/* printk(KERN_INFO "free_irq done\n"); - printk(KERN_INFO "About to call release_region\n");*/ - release_region(card->hw.port, card->hw.io_range); -/* printk(KERN_INFO "release_region done\n");*/ + /* Release Resources */ + release_hw(card); + + /* only free the allocated I/O range if not an S514 adapter */ + if (wandev->hw_opt[0] != SDLA_S514 && !card->configured){ + release_region(card->hw.port, card->hw.io_range); + } + + if (!card->configured){ + memset(&card->hw, 0, sizeof(sdlahw_t)); + if (card->next){ + memset(&card->next->hw, 0, sizeof(sdlahw_t)); + } + } + wandev->critical = 0; return 0; } +static void release_hw (sdla_t *card) +{ + sdla_t *nxt_card; + + /* Check if next device exists */ + if (card->next){ + nxt_card = card->next; + /* If next device is down then release resources */ + if (nxt_card->wandev.state == WAN_UNCONFIGURED){ + if (card->wandev.piggyback){ + /* If this device is piggyback then use + * information of the master device + */ + printk(KERN_INFO "%s: Piggyback shutting down\n",card->devname); + sdla_down(&card->next->hw); + free_irq(card->wandev.irq, card->next); + card->configured = 0; + card->next->configured = 0; + card->wandev.piggyback = 0; + }else{ + /* Master device shutting down */ + printk(KERN_INFO "%s: Master shutting down\n",card->devname); + sdla_down(&card->hw); + free_irq(card->wandev.irq, card); + card->configured = 0; + card->next->configured = 0; + } + }else{ + printk(KERN_INFO "%s: Device still running\n", + nxt_card->devname); + card->configured = 1; + } + }else{ + printk(KERN_INFO "%s: Master shutting down\n",card->devname); + sdla_down(&card->hw); + free_irq(card->wandev.irq, card); + card->configured = 0; + } +} + + /*============================================================================ * Driver I/O control. * o verify arguments @@ -402,20 +586,29 @@ */ static int ioctl (wan_device_t* wandev, unsigned cmd, unsigned long arg) { + sdla_t* card; int err; /* sanity checks */ if ((wandev == NULL) || (wandev->private == NULL)) - return -EFAULT - ; + return -EFAULT; if (wandev->state == WAN_UNCONFIGURED) - return -ENODEV - ; - if (test_and_set_bit(0, (void*)&wandev->critical)) - return -EAGAIN - ; - switch (cmd) - { + return -ENODEV; + + card = wandev->private; + + if(card->hw.type != SDLA_S514){ + disable_irq(card->hw.irq); + } + + if (test_and_set_bit(0, (void*)&wandev->critical)) { + if(card->hw.type != SDLA_S514){ + enable_irq(card->hw.irq); + } + return -EAGAIN; + } + + switch (cmd) { case WANPIPE_DUMP: err = ioctl_dump(wandev->private, (void*)arg); break; @@ -427,11 +620,16 @@ default: err = -EINVAL; } - wandev->critical = 0; + + clear_bit(0, (void*)&wandev->critical); + if(card->hw.type != SDLA_S514){ + enable_irq(card->hw.irq); + } + return err; } -/****** Driver IOCTL Hanlers ************************************************/ +/****** Driver IOCTL Handlers ***********************************************/ /*============================================================================ * Dump adapter memory to user buffer. @@ -458,34 +656,47 @@ if ((dump.magic != WANPIPE_MAGIC) || (dump.offset + dump.length > card->hw.memory)) return -EINVAL; - + winsize = card->hw.dpmsize; save_flags(flags); cli(); /* >>> critical section start <<< */ - oldvec = card->hw.vector; - while (dump.length) - { - unsigned pos = dump.offset % winsize; /* current offset */ - unsigned long vec = dump.offset - pos; /* current vector */ - unsigned len = (dump.length > (winsize - pos)) ? - (winsize - pos) : dump.length - ; - if (sdla_mapmem(&card->hw, vec) != 0) /* relocate window */ - { - err = -EIO; - break; - } + + if(card->hw.type != SDLA_S514) { + oldvec = card->hw.vector; + while (dump.length) { + /* current offset */ + unsigned pos = dump.offset % winsize; + /* current vector */ + unsigned long vec = dump.offset - pos; + unsigned len = (dump.length > (winsize - pos)) ? + (winsize - pos) : dump.length; + /* relocate window */ + if (sdla_mapmem(&card->hw, vec) != 0) { + err = -EIO; + break; + } + /* FIXME::: COPY TO KERNEL BUFFER FIRST ?? */ + sti(); /* Not ideal but tough we have to do this */ + if(copy_to_user((void *)dump.ptr, + (u8 *)card->hw.dpmbase + pos, len)) + return -EFAULT; + cli(); + dump.length -= len; + dump.offset += len; + (char*)dump.ptr += len; + } + sdla_mapmem(&card->hw, oldvec);/* restore DPM window position */ + } + + else { /* FIXME::: COPY TO KERNEL BUFFER FIRST ?? */ - sti(); /* Not ideal but tough we have to do this */ - if(copy_to_user((void *)dump.ptr, - (u8 *)card->hw.dpmbase + pos, len)) - return -EFAULT; - cli(); - dump.length -= len; - dump.offset += len; - (char*)dump.ptr += len; + sti(); /* Not ideal but tough we have to do this */ + if(copy_to_user((void *)dump.ptr, + (u8 *)card->hw.dpmbase + dump.offset, dump.length)) + return -EFAULT; + cli(); } - sdla_mapmem(&card->hw, oldvec); /* restore DPM window position */ + restore_flags(flags); /* >>> critical section end <<< */ return err; } @@ -502,9 +713,10 @@ if (card->exec == NULL) return -ENODEV; - + if(copy_from_user((void*)&exec, (void*)u_exec, sizeof(sdla_exec_t))) return -EFAULT; + if ((exec.magic != WANPIPE_MAGIC) || (exec.cmd == NULL)) return -EINVAL; return card->exec(card, exec.cmd, exec.data); @@ -521,21 +733,110 @@ { #define card ((sdla_t*)dev_id) - if (!card || (card->wandev.state == WAN_UNCONFIGURED)) - return - ; - if (card->in_isr) - { - printk(KERN_WARNING "%s: interrupt re-entrancy on IRQ %d!\n", - card->devname, card->wandev.irq) - ; - return; + if(card->hw.type == SDLA_S514) { /* handle interrrupt on S514 */ + u32 int_status; + unsigned char CPU_no = card->hw.S514_cpu_no[0]; + unsigned char card_found_for_IRQ; + u8 IRQ_count = 0; + + for(;;) { + + read_S514_int_stat(&card->hw, &int_status); + + /* check if the interrupt is for this device */ + if(!((unsigned char)int_status & + (IRQ_CPU_A | IRQ_CPU_B))) + return; + + /* if the IRQ is for both CPUs on the same adapter, */ + /* then alter the interrupt status so as to handle */ + /* one CPU at a time */ + if(((unsigned char)int_status & (IRQ_CPU_A | IRQ_CPU_B)) + == (IRQ_CPU_A | IRQ_CPU_B)) { + int_status &= (CPU_no == S514_CPU_A) ? + ~IRQ_CPU_B : ~IRQ_CPU_A; + } + + card_found_for_IRQ = 0; + + /* check to see that the CPU number for this device */ + /* corresponds to the interrupt status read */ + switch (CPU_no) { + case S514_CPU_A: + if((unsigned char)int_status & + IRQ_CPU_A) + card_found_for_IRQ = 1; + break; + + case S514_CPU_B: + if((unsigned char)int_status & + IRQ_CPU_B) + card_found_for_IRQ = 1; + break; + } + + /* exit if the interrupt is for another CPU on the */ + /* same IRQ */ + if(!card_found_for_IRQ) + return; + + if (!card || + (card->wandev.state == WAN_UNCONFIGURED && !card->configured)){ + printk(KERN_INFO + "Received IRQ %d for CPU #%c\n", + irq, CPU_no); + printk(KERN_INFO + "IRQ for unconfigured adapter\n"); + S514_intack(&card->hw, int_status); + return; + } + + if (card->in_isr) { + printk(KERN_INFO + "%s: interrupt re-entrancy on IRQ %d\n", + card->devname, card->wandev.irq); + S514_intack(&card->hw, int_status); + return; + } + + S514_intack(&card->hw, int_status); + + if (card->isr) + card->isr(card); + + /* handle a maximum of two interrupts (one for each */ + /* CPU on the adapter) before returning */ + if((++ IRQ_count) == 2) + return; + } } - sdla_intack(&card->hw); - if (card->isr) - card->isr(card); + else { /* handle interrupt on S508 adapter */ + + if (!card || ((card->wandev.state == WAN_UNCONFIGURED) && !card->configured)) + return; + if (card->in_isr) { + printk(KERN_INFO + "%s: interrupt re-entrancy on IRQ %d!\n", + card->devname, card->wandev.irq); + return; + } + + /* Use spin lock only for S508 */ + +#ifdef __SMP__ + spin_lock(&card->lock); +#endif + sdla_intack(&card->hw); + if (card->isr) + card->isr(card); +#ifdef __SMP__ + spin_unlock(&card->lock); +#endif + + } + #undef card } @@ -550,13 +851,11 @@ { int i; - for (i = 0; i < ncards; ++i) - { + for (i = 0; i < ncards; ++i) { sdla_t* card = &card_array[i]; if ((card->wandev.state != WAN_UNCONFIGURED) && card->poll && - !card->wandev.critical) - { + !card->wandev.critical) { card->poll(card); } } @@ -597,26 +896,21 @@ save_flags(flags); cli(); - if (card->wandev.state != state) - { - switch (state) - { + if (card->wandev.state != state) { + switch (state) { case WAN_CONNECTED: printk (KERN_INFO "%s: link connected!\n", - card->devname) - ; + card->devname); break; case WAN_CONNECTING: printk (KERN_INFO "%s: link connecting...\n", - card->devname) - ; + card->devname); break; case WAN_DISCONNECTED: printk (KERN_INFO "%s: link disconnected!\n", - card->devname) - ; + card->devname); break; } card->wandev.state = state; diff -ur --new-file old/linux/drivers/parport/init.c new/linux/drivers/parport/init.c --- old/linux/drivers/parport/init.c Mon Nov 8 19:40:40 1999 +++ new/linux/drivers/parport/init.c Wed Jan 26 21:45:20 2000 @@ -26,6 +26,8 @@ extern int parport_pc_init(int *io, int *io_hi, int *irq, int *dma); extern int parport_sunbpp_init(void); +extern int parport_amiga_init(void); +extern int parport_mfc3_init(void); static int parport_setup_ptr __initdata = 0; diff -ur --new-file old/linux/drivers/parport/parport_amiga.c new/linux/drivers/parport/parport_amiga.c --- old/linux/drivers/parport/parport_amiga.c Thu Aug 26 23:29:50 1999 +++ new/linux/drivers/parport/parport_amiga.c Wed Jan 26 21:45:20 2000 @@ -1,6 +1,6 @@ /* Low-level parallel port routines for the Amiga buildin port * - * Author: Joerg Dorchain + * Author: Joerg Dorchain * * This is a complete rewrite of the code, but based heaviy upon the old * lp_intern. code. @@ -25,7 +25,7 @@ #ifdef DEBUG #define DPRINTK printk #else -#define DPRINTK(format, args...) +static inline void DPRINTK(void *nothing, ...) {} #endif static struct parport *this_port = NULL; @@ -90,7 +90,7 @@ return old; } - +#if 0 /* currently unused */ static unsigned char status_pc_to_amiga(unsigned char status) { unsigned char ret = 1; @@ -107,6 +107,7 @@ /* not connected */; return ret; } +#endif static unsigned char status_amiga_to_pc(unsigned char status) { @@ -138,6 +139,28 @@ parport_generic_irq(irq, (struct parport *) dev_id, regs); } +static void amiga_enable_irq(struct parport *p) +{ + enable_irq(IRQ_AMIGA_CIAA_FLG); +} + +static void amiga_disable_irq(struct parport *p) +{ + disable_irq(IRQ_AMIGA_CIAA_FLG); +} + +static void amiga_data_forward(struct parport *p) +{ + DPRINTK("forward\n"); + ciaa.ddrb = 0xff; /* all pins output */ +} + +static void amiga_data_reverse(struct parport *p) +{ + DPRINTK("reverse\n"); + ciaa.ddrb = 0; /* all pins input */ +} + static void amiga_init_state(struct pardevice *dev, struct parport_state *s) { s->u.amiga.data = 0; @@ -162,16 +185,6 @@ ciab.ddra |= (ciab.ddra & 0xf8) | s->u.amiga.statusdir; } -static void amiga_enable_irq(struct parport *p) -{ - enable_irq(IRQ_AMIGA_CIAA_FLG); -} - -static void amiga_disable_irq(struct parport *p) -{ - disable_irq(IRQ_AMIGA_CIAA_FLG); -} - static void amiga_inc_use_count(void) { MOD_INC_USE_COUNT; @@ -195,8 +208,8 @@ amiga_enable_irq, amiga_disable_irq, - NULL, /* data_forward */ - NULL, /* data_reverse */ + amiga_data_forward, + amiga_data_reverse, amiga_init_state, amiga_save_state, @@ -205,18 +218,18 @@ amiga_inc_use_count, amiga_dec_use_count, - NULL, /* epp_write_data */ - NULL, /* epp_read_data */ - NULL, /* epp_write_addr */ - NULL, /* epp_read_addr */ - - NULL, /* ecp_write_data */ - NULL, /* ecp_read_data */ - NULL, /* ecp_write_addr */ - - NULL, /* compat_write_data */ - NULL, /* nibble_read_data */ - NULL, /* byte_read_data */ + parport_ieee1284_epp_write_data, + parport_ieee1284_epp_read_data, + parport_ieee1284_epp_write_addr, + parport_ieee1284_epp_read_addr, + + parport_ieee1284_ecp_write_data, + parport_ieee1284_ecp_read_data, + parport_ieee1284_ecp_write_addr, + + parport_ieee1284_write_compat, + parport_ieee1284_read_nibble, + parport_ieee1284_read_byte, }; /* ----------- Initialisation code --------------------------------- */ @@ -252,7 +265,7 @@ #ifdef MODULE -MODULE_AUTHOR("Joerg Dorchain"); +MODULE_AUTHOR("Joerg Dorchain "); MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port"); MODULE_SUPPORTED_DEVICE("Amiga builtin Parallel Port"); diff -ur --new-file old/linux/drivers/parport/parport_mfc3.c new/linux/drivers/parport/parport_mfc3.c --- old/linux/drivers/parport/parport_mfc3.c Thu Aug 26 21:42:33 1999 +++ new/linux/drivers/parport/parport_mfc3.c Wed Jan 26 21:45:20 2000 @@ -1,6 +1,6 @@ /* Low-level parallel port routines for the Multiface 3 card * - * Author: Joerg Dorchain + * Author: Joerg Dorchain * * (C) The elitist m68k Users(TM) * @@ -46,6 +46,10 @@ * -------+-----+-----+--------------------------------------------------------- * * Should be enough to understand some of the driver. + * + * Per convention for normal use the port registers are visible. + * If you need the data direction registers, restore the value in the + * control register. */ #include "multiface.h" @@ -67,7 +71,7 @@ #ifdef DEBUG #define DPRINTK printk #else -static inline int DPRINTK() {return 0;} +static inline int DPRINTK(void *nothing, ...) {return 0;} #endif static struct parport *this_port[MAX_MFC] = {NULL, }; @@ -95,10 +99,6 @@ { unsigned char ret = 32|64; - if (control & PARPORT_CONTROL_DIRECTION) /* XXX: What is this? */ - ; - if (control & PARPORT_CONTROL_INTEN) /* XXX: What is INTEN? */ - ; if (control & PARPORT_CONTROL_SELECT) /* XXX: What is SELECP? */ ret &= ~32; /* /SELECT_IN */ if (control & PARPORT_CONTROL_INIT) /* INITP */ @@ -112,7 +112,7 @@ static unsigned char control_mfc3_to_pc(unsigned char control) { - unsigned char ret = PARPORT_CONTROL_INTEN | PARPORT_CONTROL_STROBE + unsigned char ret = PARPORT_CONTROL_STROBE | PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_SELECT; if (control & 128) /* /INITP */ @@ -146,7 +146,7 @@ return old; } - +#if 0 /* currently unused */ static unsigned char status_pc_to_mfc3(unsigned char status) { unsigned char ret = 1; @@ -163,6 +163,7 @@ ret |= 16; return ret; } +#endif static unsigned char status_mfc3_to_pc(unsigned char status) { @@ -182,11 +183,13 @@ return ret; } +#if 0 /* currently unused */ static void mfc3_write_status( struct parport *p, unsigned char status) { DPRINTK("write_status %02x\n",status); pia(p)->ppra = (pia(p)->ppra & 0xe0) | status_pc_to_mfc3(status); } +#endif static unsigned char mfc3_read_status(struct parport *p) { @@ -197,11 +200,13 @@ return status; } +#if 0 /* currently unused */ static void mfc3_change_mode( struct parport *p, int m) { /* XXX: This port only has one mode, and I am not sure about the corresponding PC-style mode*/ } +#endif static int use_cnt = 0; @@ -217,12 +222,33 @@ } } -static int mfc3_claim_resources(struct parport *p) +static void mfc3_enable_irq(struct parport *p) +{ + pia(p)->crb |= PIA_C1_ENABLE_IRQ; +} + +static void mfc3_disable_irq(struct parport *p) +{ + pia(p)->crb &= ~PIA_C1_ENABLE_IRQ; +} + +static void mfc3_data_forward(struct parport *p) { -DPRINTK("claim_resources\n"); + DPRINTK("forward\n"); + pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */ + pia(p)->pddrb = 255; /* all pins output */ + pia(p)->crb |= PIA_DDR; /* make data register visible - default */ } -static void mfc3_init_state(struct parport_state *s) +static void mfc3_data_reverse(struct parport *p) +{ + DPRINTK("reverse\n"); + pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */ + pia(p)->pddrb = 0; /* all pins input */ + pia(p)->crb |= PIA_DDR; /* make data register visible - default */ +} + +static void mfc3_init_state(struct pardevice *dev, struct parport_state *s) { s->u.amiga.data = 0; s->u.amiga.datadir = 255; @@ -254,16 +280,6 @@ pia(p)->cra |= PIA_DDR; } -static void mfc3_enable_irq(struct parport *p) -{ - pia(p)->crb |= PIA_C1_ENABLE_IRQ; -} - -static void mfc3_disable_irq(struct parport *p) -{ - pia(p)->crb &= ~PIA_C1_ENABLE_IRQ; -} - static void mfc3_inc_use_count(void) { MOD_INC_USE_COUNT; @@ -287,8 +303,8 @@ mfc3_enable_irq, mfc3_disable_irq, - NULL, /* data_forward - FIXME */ - NULL, /* data_reverse - FIXME */ + mfc3_data_forward, + mfc3_data_reverse, mfc3_init_state, mfc3_save_state, @@ -318,43 +334,43 @@ struct parport *p; int pias = 0; struct pia *pp; - unsigned int key = 0; - const struct ConfigDev *cd; + struct zorro_dev *z = NULL; + + if (!MACH_IS_AMIGA) + return 0; + + while ((z = zorro_find_device(ZORRO_PROD_BSC_MULTIFACE_III, z))) { + unsigned long piabase = z->resource.start+PIABASE; + if (!request_mem_region(piabase, sizeof(struct pia), "PIA")) + continue; + strcpy(z->name, "MultiFace III MC6821 PIA"); + pp = (struct pia *)ZTWO_VADDR(piabase); + if (pias < MAX_MFC) { + pp->crb = 0; + pp->pddrb = 255; /* all data pins output */ + pp->crb = PIA_DDR|32|8; + dummy = pp->pddrb; /* reading clears interrupt */ + pp->cra = 0; + pp->pddra = 0xe0; /* /RESET, /DIR ,/AUTO-FEED output */ + pp->cra = PIA_DDR; + pp->ppra = 0; /* reset printer */ + udelay(10); + pp->ppra = 128; + if ((p = parport_register_port((unsigned long)pp, + IRQ_AMIGA_PORTS, PARPORT_DMA_NONE, + &pp_mfc3_ops))) { + this_port[pias++] = p; + printk(KERN_INFO "%s: Multiface III port using irq\n", p->name); + /* XXX: set operating mode */ + parport_proc_register(p); + + if (p->irq != PARPORT_IRQ_NONE) + if (use_cnt++ == 0) + if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, SA_SHIRQ, p->name, &pp_mfc3_ops)) + use_cnt--; - if (MACH_IS_AMIGA) { - while ((key = zorro_find(ZORRO_PROD_BSC_MULTIFACE_III, 0, key))) { - cd = zorro_get_board(key); - pp = (struct pia *)ZTWO_VADDR((((u_char *)cd->cd_BoardAddr)+PIABASE)); - if (pias < MAX_MFC) { - pp->crb = 0; - pp->pddrb = 255; /* all data pins output */ - pp->crb = PIA_DDR|32|8; - dummy = pp->pddrb; /* reading clears interrupt */ - pp->cra = 0; - pp->pddra = 0xe0; /* /RESET, /DIR ,/AUTO-FEED output */ - pp->cra = PIA_DDR; - pp->ppra = 0; /* reset printer */ - udelay(10); - pp->ppra = 128; - if ((p = parport_register_port((unsigned long)pp, - IRQ_AMIGA_PORTS, PARPORT_DMA_NONE, - &pp_mfc3_ops))) { - this_port[pias++] = p; - printk(KERN_INFO "%s: Multiface III port using irq\n", p->name); - /* XXX: set operating mode */ - parport_proc_register(p); - - if (p->irq != PARPORT_IRQ_NONE) - if (use_cnt++ == 0) - if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, SA_SHIRQ, p->name, &pp_mfc3_ops)) - use_cnt--; - - if (parport_probe_hook) - (*parport_probe_hook)(p); - zorro_config_board(key, 0); - p->private_data = (void *)key; - parport_announce_port (p); - } + p->private_data = (void *)piabase; + parport_announce_port (p); } } } @@ -363,7 +379,7 @@ #ifdef MODULE -MODULE_AUTHOR("Joerg Dorchain"); +MODULE_AUTHOR("Joerg Dorchain "); MODULE_DESCRIPTION("Parport Driver for Multiface 3 expansion cards Paralllel Port"); MODULE_SUPPORTED_DEVICE("Multiface 3 Parallel Port"); @@ -383,7 +399,7 @@ free_irq(IRQ_AMIGA_PORTS, &pp_mfc3_ops); parport_proc_unregister(this_port[i]); parport_unregister_port(this_port[i]); - zorro_unconfig_board((unsigned int)this_port[i]->private_data, 0); + release_mem_region(ZTWO_PADDR(this_port[i]->private_data), sizeof(struct pia)); } } #endif diff -ur --new-file old/linux/drivers/parport/parport_pc.c new/linux/drivers/parport/parport_pc.c --- old/linux/drivers/parport/parport_pc.c Thu Jan 13 21:03:00 2000 +++ new/linux/drivers/parport/parport_pc.c Thu Jan 27 18:00:29 2000 @@ -549,8 +549,24 @@ { int ret = 0; unsigned long dmaflag; - size_t left = length; + size_t left = length; const struct parport_pc_private *priv = port->physport->private_data; + unsigned long dma_addr; + size_t maxlen = 0x10000; /* max 64k per DMA transfer */ + unsigned long start = (unsigned long) buf; + unsigned long end = (unsigned long) buf + length - 1; + + /* above 16 MB we use a bounce buffer as ISA-DMA is not possible */ + if (end <= MAX_DMA_ADDRESS) { + /* If it would cross a 64k boundary, cap it at the end. */ + if ((start ^ end) & ~0xffff) + maxlen = (0x10000 - start) & 0xffff; + + dma_addr = virt_to_bus(buf); + } else { + dma_addr = priv->dma_handle; + maxlen = PAGE_SIZE; /* sizeof(priv->dma_buf) */ + } port = port->physport; @@ -566,16 +582,17 @@ size_t count = left; - if (count > PAGE_SIZE) - count = PAGE_SIZE; + if (count > maxlen) + count = maxlen; - memcpy(priv->dma_buf, buf, count); + if (maxlen == PAGE_SIZE) /* bounce buffer ! */ + memcpy(priv->dma_buf, buf, count); dmaflag = claim_dma_lock(); disable_dma(port->dma); clear_dma_ff(port->dma); set_dma_mode(port->dma, DMA_MODE_WRITE); - set_dma_addr(port->dma, virt_to_bus((volatile char *) priv->dma_buf)); + set_dma_addr(port->dma, dma_addr); set_dma_count(port->dma, count); /* Set DMA mode */ @@ -1499,7 +1516,8 @@ struct parport *__maybe_init parport_pc_probe_port (unsigned long int base, unsigned long int base_hi, - int irq, int dma) + int irq, int dma, + struct pci_dev *dev) { struct parport_pc_private *priv; struct parport_operations *ops; @@ -1525,6 +1543,8 @@ priv->ecr = 0; priv->fifo_depth = 0; priv->dma_buf = 0; + priv->dma_handle = 0; + priv->dev = dev; p->base = base; p->base_hi = base_hi; p->irq = irq; @@ -1649,7 +1669,9 @@ p->dma = PARPORT_DMA_NONE; } else { priv->dma_buf = - (char *)__get_dma_pages(GFP_KERNEL, 0); + pci_alloc_consistent(priv->dev, + PAGE_SIZE, + &priv->dma_handle); if (! priv->dma_buf) { printk (KERN_WARNING "%s: " "cannot get buffer for DMA, " @@ -1805,10 +1827,12 @@ if (parport_pc_probe_port (io_lo, io_hi, pcidev->irq, - dma)) + dma, + pcidev)) count++; } else if (parport_pc_probe_port (io_lo, io_hi, - irq, dma)) + irq, dma, + pcidev)) count++; } } @@ -1913,7 +1937,9 @@ release_region(p->base_hi, 3); parport_proc_unregister(p); if (priv->dma_buf) - free_page((unsigned long) priv->dma_buf); + pci_free_consistent(priv->dev, PAGE_SIZE, + priv->dma_buf, + priv->dma_handle); kfree (p->private_data); parport_unregister_port(p); kfree (ops); /* hope no-one cached it */ diff -ur --new-file old/linux/drivers/parport/procfs.c new/linux/drivers/parport/procfs.c --- old/linux/drivers/parport/procfs.c Thu Aug 12 19:19:59 1999 +++ new/linux/drivers/parport/procfs.c Mon Jan 24 20:54:30 2000 @@ -224,7 +224,7 @@ #endif /* IEEE 1284 support */ {0} }, - { {DEV_PARPORT_DEVICES_ACTIVE, "active", NULL, 0, 444, NULL, + { {DEV_PARPORT_DEVICES_ACTIVE, "active", NULL, 0, 0444, NULL, &do_active_device }, {0}}, { PARPORT_PORT_DIR(NULL), {0}}, { PARPORT_PARPORT_DIR(NULL), {0}}, diff -ur --new-file old/linux/drivers/pci/compat.c new/linux/drivers/pci/compat.c --- old/linux/drivers/pci/compat.c Fri Jan 7 20:53:06 2000 +++ new/linux/drivers/pci/compat.c Mon Jan 24 20:04:36 2000 @@ -19,7 +19,7 @@ int pcibios_find_class(unsigned int class, unsigned short index, unsigned char *bus, unsigned char *devfn) { - struct pci_dev *dev = NULL; + const struct pci_dev *dev = NULL; int cnt = 0; while ((dev = pci_find_class(class, dev))) @@ -36,7 +36,7 @@ pcibios_find_device(unsigned short vendor, unsigned short device, unsigned short index, unsigned char *bus, unsigned char *devfn) { - struct pci_dev *dev = NULL; + const struct pci_dev *dev = NULL; int cnt = 0; while ((dev = pci_find_device(vendor, device, dev))) diff -ur --new-file old/linux/drivers/pci/gen-devlist.c new/linux/drivers/pci/gen-devlist.c --- old/linux/drivers/pci/gen-devlist.c Wed Dec 8 00:37:17 1999 +++ new/linux/drivers/pci/gen-devlist.c Mon Jan 24 20:04:36 2000 @@ -8,7 +8,7 @@ #include static void -pq(FILE *f, char *c) +pq(FILE *f, const char *c) { while (*c) { if (*c == '"') diff -ur --new-file old/linux/drivers/pci/pci.c new/linux/drivers/pci/pci.c --- old/linux/drivers/pci/pci.c Thu Jan 20 18:55:23 2000 +++ new/linux/drivers/pci/pci.c Thu Jan 27 17:58:15 2000 @@ -47,7 +47,7 @@ struct pci_dev * pci_find_subsys(unsigned int vendor, unsigned int device, unsigned int ss_vendor, unsigned int ss_device, - struct pci_dev *from) + const struct pci_dev *from) { struct list_head *n = from ? from->global_list.next : pci_devices.next; @@ -65,14 +65,14 @@ struct pci_dev * -pci_find_device(unsigned int vendor, unsigned int device, struct pci_dev *from) +pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from) { return pci_find_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); } struct pci_dev * -pci_find_class(unsigned int class, struct pci_dev *from) +pci_find_class(unsigned int class, const struct pci_dev *from) { struct list_head *n = from ? from->global_list.next : pci_devices.next; @@ -116,9 +116,9 @@ * it should be allocated from. */ struct resource * -pci_find_parent_resource(struct pci_dev *dev, struct resource *res) +pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) { - struct pci_bus *bus = dev->bus; + const struct pci_bus *bus = dev->bus; int i; struct resource *best = NULL; @@ -203,7 +203,7 @@ static LIST_HEAD(pci_drivers); const struct pci_device_id * -pci_match_device(const struct pci_device_id *ids, struct pci_dev *dev) +pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { while (ids->vendor || ids->subvendor || ids->class_mask) { if ((ids->vendor == PCI_ANY_ID || ids->vendor == dev->vendor) && @@ -315,7 +315,7 @@ }; struct pci_driver * -pci_dev_driver(struct pci_dev *dev) +pci_dev_driver(const struct pci_dev *dev) { if (dev->driver) return dev->driver; @@ -808,6 +808,10 @@ memcpy(dev, temp, sizeof(*dev)); dev->vendor = l & 0xffff; dev->device = (l >> 16) & 0xffff; + + /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) + set this higher, assuming the system even supports it. */ + dev->dma_mask = 0xffffffff; if (pci_setup_device(dev) < 0) { kfree(dev); dev = NULL; @@ -902,12 +906,12 @@ return max; } -static int __init pci_bus_exists(struct list_head *list, int nr) +static int __init pci_bus_exists(const struct list_head *list, int nr) { - struct list_head *l; + const struct list_head *l; for(l=list->next; l != list; l = l->next) { - struct pci_bus *b = pci_bus_b(l); + const struct pci_bus *b = pci_bus_b(l); if (b->number == nr || pci_bus_exists(&b->children, nr)) return 1; } diff -ur --new-file old/linux/drivers/pci/pcisyms.c new/linux/drivers/pci/pcisyms.c --- old/linux/drivers/pci/pcisyms.c Wed Jan 12 18:21:23 2000 +++ new/linux/drivers/pci/pcisyms.c Tue Jan 25 23:13:46 2000 @@ -28,6 +28,7 @@ EXPORT_SYMBOL(pci_assign_resource); EXPORT_SYMBOL(pci_register_driver); EXPORT_SYMBOL(pci_unregister_driver); +EXPORT_SYMBOL(pci_match_device); #ifdef CONFIG_HOTPLUG EXPORT_SYMBOL(pci_setup_device); diff -ur --new-file old/linux/drivers/pci/proc.c new/linux/drivers/pci/proc.c --- old/linux/drivers/pci/proc.c Sat Jan 8 21:43:56 2000 +++ new/linux/drivers/pci/proc.c Mon Jan 24 20:04:36 2000 @@ -43,8 +43,8 @@ static ssize_t proc_bus_pci_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) { - struct inode *ino = file->f_dentry->d_inode; - struct proc_dir_entry *dp = ino->u.generic_ip; + const struct inode *ino = file->f_dentry->d_inode; + const struct proc_dir_entry *dp = ino->u.generic_ip; struct pci_dev *dev = dp->data; int pos = *ppos; int cnt, size; @@ -125,8 +125,8 @@ static ssize_t proc_bus_pci_write(struct file *file, const char *buf, size_t nbytes, loff_t *ppos) { - struct inode *ino = file->f_dentry->d_inode; - struct proc_dir_entry *dp = ino->u.generic_ip; + const struct inode *ino = file->f_dentry->d_inode; + const struct proc_dir_entry *dp = ino->u.generic_ip; struct pci_dev *dev = dp->data; int pos = *ppos; int cnt; @@ -192,17 +192,9 @@ } static struct file_operations proc_bus_pci_operations = { - proc_bus_pci_lseek, - proc_bus_pci_read, - proc_bus_pci_write, - NULL, /* readdir */ - NULL, /* poll */ - NULL, /* ioctl */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* flush */ - NULL, /* no special release code */ - NULL /* can't fsync */ + llseek: proc_bus_pci_lseek, + read: proc_bus_pci_read, + write: proc_bus_pci_write, }; static struct inode_operations proc_bus_pci_inode_operations = { @@ -218,13 +210,13 @@ static int get_pci_dev_info(char *buf, char **start, off_t pos, int count) { - struct pci_dev *dev; + const struct pci_dev *dev; off_t at = 0; int len, i, cnt; cnt = 0; pci_for_each_dev(dev) { - struct pci_driver *drv = pci_dev_driver(dev); + const struct pci_driver *drv = pci_dev_driver(dev); len = sprintf(buf, "%02x%02x\t%04x%04x\t%x", dev->bus->number, dev->devfn, diff -ur --new-file old/linux/drivers/pcmcia/ricoh.h new/linux/drivers/pcmcia/ricoh.h --- old/linux/drivers/pcmcia/ricoh.h Wed Jan 19 07:29:17 2000 +++ new/linux/drivers/pcmcia/ricoh.h Tue Jan 25 20:41:20 2000 @@ -30,7 +30,6 @@ #ifndef _LINUX_RICOH_H #define _LINUX_RICOH_H -#include #define RF5C_MODE_CTL 0x1f /* Mode control */ #define RF5C_PWR_CTL 0x2f /* Mixed voltage control */ diff -ur --new-file old/linux/drivers/pnp/Makefile new/linux/drivers/pnp/Makefile --- old/linux/drivers/pnp/Makefile Fri Jan 14 01:53:52 2000 +++ new/linux/drivers/pnp/Makefile Wed Jan 26 21:35:07 2000 @@ -25,7 +25,7 @@ endif ifeq ($(CONFIG_ISAPNP),y) - O_TARGET := isa-pnp.o + O_TARGET := pnp.o OX_OBJS := isapnp.o O_OBJS := quirks.o $(PROC_OBJS) endif @@ -33,5 +33,5 @@ include $(TOPDIR)/Rules.make -isa-pnp.o: isapnp.o quirks.o $(PROC_OBJS) - $(LD) $(LD_RFLAG) -r -o $@ isapnp.o quirks.o $(PROC_OBJS) +isa-pnp.o: $(MIX_OBJS) $(MI_OBJS) + $(LD) $(LD_RFLAG) -r -o $@ $(MIX_OBJS) $(MI_OBJS) diff -ur --new-file old/linux/drivers/pnp/isapnp.c new/linux/drivers/pnp/isapnp.c --- old/linux/drivers/pnp/isapnp.c Sat Jan 15 00:44:26 2000 +++ new/linux/drivers/pnp/isapnp.c Thu Jan 27 17:58:15 2000 @@ -436,6 +436,7 @@ dev = isapnp_alloc(sizeof(struct pci_dev)); if (!dev) return NULL; + dev->dma_mask = 0x00ffffff; dev->devfn = number; dev->vendor = (tmp[1] << 8) | tmp[0]; dev->device = (tmp[3] << 8) | tmp[2]; diff -ur --new-file old/linux/drivers/sbus/audio/amd7930.c new/linux/drivers/sbus/audio/amd7930.c --- old/linux/drivers/sbus/audio/amd7930.c Tue Dec 21 07:06:42 1999 +++ new/linux/drivers/sbus/audio/amd7930.c Mon Jan 24 04:48:47 2000 @@ -1,4 +1,4 @@ -/* $Id: amd7930.c,v 1.23 1999/11/19 09:55:58 davem Exp $ +/* $Id: amd7930.c,v 1.24 2000/01/22 05:10:27 anton Exp $ * drivers/sbus/audio/amd7930.c * * Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu) @@ -1375,7 +1375,7 @@ /* Enable B channel transmit */ sbus_writeb(AMR_LIU_LMR1, info->regs + CR); tmp = sbus_readb(info->regs + DR); - tmp |= AM_LIU_LMR1_B1_ENBL + chan; + tmp |= AM_LIU_LMR1_B1_ENABL + chan; sbus_writeb(tmp, info->regs + DR); /* Enable B channel interrupts */ @@ -1701,7 +1701,7 @@ continue; if (amd7930_attach(&drivers[num_drivers], - sdev->prom_node, sdev->my_bus, sdev) == 0) + sdev->prom_node, sdev->bus, sdev) == 0) num_drivers++; } } diff -ur --new-file old/linux/drivers/sbus/audio/cs4231.c new/linux/drivers/sbus/audio/cs4231.c --- old/linux/drivers/sbus/audio/cs4231.c Tue Dec 21 07:06:42 1999 +++ new/linux/drivers/sbus/audio/cs4231.c Thu Jan 27 17:58:15 2000 @@ -1170,25 +1170,28 @@ static void cs4231_release(struct inode * inode, struct file * file, struct sparcaudio_driver *drv) { - struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private; + struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private; + void (*dma_unmap_single)(struct sbus_dev *, dma_addr_t, size_t) = sbus_unmap_single; +#ifdef EB4231_SUPPORT + if (cs4231_chip->status & CS_STATUS_IS_EBUS) + dma_unmap_single = (void (*)(struct sbus_dev *, dma_addr_t, size_t)) pci_unmap_single; +#endif /* zero out any info about what data we have as well */ if (file->f_mode & FMODE_READ) { /* stop capture here or midlevel? */ cs4231_chip->perchip_info.record.open = 0; if (cs4231_chip->input_dma_handle) { - if(!(cs4231_chip->status & CS_STATUS_IS_EBUS)) - sbus_unmap_single(drv->dev, - cs4231_chip->input_dma_handle, - cs4231_chip->input_dma_size); + dma_unmap_single(drv->dev, + cs4231_chip->input_dma_handle, + cs4231_chip->input_dma_size); cs4231_chip->input_dma_handle = 0; cs4231_chip->input_dma_size = 0; } if (cs4231_chip->input_next_dma_handle) { - if(!(cs4231_chip->status & CS_STATUS_IS_EBUS)) - sbus_unmap_single(drv->dev, - cs4231_chip->input_next_dma_handle, - cs4231_chip->input_next_dma_size); + dma_unmap_single(drv->dev, + cs4231_chip->input_next_dma_handle, + cs4231_chip->input_next_dma_size); cs4231_chip->input_next_dma_handle = 0; cs4231_chip->input_next_dma_size = 0; } @@ -1198,18 +1201,16 @@ cs4231_chip->perchip_info.play.active = cs4231_chip->perchip_info.play.open = 0; if (cs4231_chip->output_dma_handle) { - if(!(cs4231_chip->status & CS_STATUS_IS_EBUS)) - sbus_unmap_single(drv->dev, - cs4231_chip->output_dma_handle, - cs4231_chip->output_dma_size); + dma_unmap_single(drv->dev, + cs4231_chip->output_dma_handle, + cs4231_chip->output_dma_size); cs4231_chip->output_dma_handle = 0; cs4231_chip->output_dma_size = 0; } if (cs4231_chip->output_next_dma_handle) { - if(!(cs4231_chip->status & CS_STATUS_IS_EBUS)) - sbus_unmap_single(drv->dev, - cs4231_chip->output_next_dma_handle, - cs4231_chip->output_next_dma_size); + dma_unmap_single(drv->dev, + cs4231_chip->output_next_dma_handle, + cs4231_chip->output_next_dma_size); cs4231_chip->output_next_dma_handle = 0; cs4231_chip->output_next_dma_size = 0; } @@ -1294,6 +1295,9 @@ cs4231_chip->playlen = cs4231_chip->output_size; if (cs4231_chip->output_dma_handle) { + pci_unmap_single((struct pci_dev *)drv->dev, + cs4231_chip->output_dma_handle, + cs4231_chip->output_dma_size); cs4231_chip->output_dma_handle = 0; cs4231_chip->output_dma_size = 0; cs4231_chip->playing_count--; @@ -1310,7 +1314,9 @@ if ((cs4231_chip->output_ptr && cs4231_chip->output_size > 0) && !(cs4231_chip->perchip_info.play.pause)) { cs4231_chip->output_next_dma_handle = - virt_to_bus(cs4231_chip->output_ptr); + pci_map_single((struct pci_dev *)drv->dev, + (char *)cs4231_chip->output_ptr, + cs4231_chip->output_size); cs4231_chip->output_next_dma_size = cs4231_chip->output_size; writel(cs4231_chip->output_next_dma_size, @@ -1410,6 +1416,9 @@ } if (cs4231_chip->input_dma_handle) { + pci_unmap_single((struct pci_dev *)drv->dev, + cs4231_chip->input_dma_handle, + cs4231_chip->input_dma_size); cs4231_chip->input_dma_handle = 0; cs4231_chip->input_dma_size = 0; cs4231_chip->recording_count--; @@ -1430,7 +1439,9 @@ cs4231_chip->input_size); cs4231_chip->input_next_dma_handle = - virt_to_bus(cs4231_chip->input_ptr); + pci_map_single((struct pci_dev *)drv->dev, + (char *)cs4231_chip->input_ptr, + cs4231_chip->input_size); cs4231_chip->input_next_dma_size = cs4231_chip->input_size; writel(cs4231_chip->input_next_dma_size, @@ -1543,11 +1554,17 @@ cs4231_chip->output_size = 0; if (cs4231_chip->output_dma_handle) { + pci_unmap_single((struct pci_dev *)drv->dev, + cs4231_chip->output_dma_handle, + cs4231_chip->output_dma_size); cs4231_chip->output_dma_handle = 0; cs4231_chip->output_dma_size = 0; } if (cs4231_chip->output_next_dma_handle) { + pci_unmap_single((struct pci_dev *)drv->dev, + cs4231_chip->output_next_dma_handle, + cs4231_chip->output_next_dma_size); cs4231_chip->output_next_dma_handle = 0; cs4231_chip->output_next_dma_size = 0; } @@ -1746,11 +1763,17 @@ cs4231_chip->input_size = 0; if (cs4231_chip->input_dma_handle) { + pci_unmap_single((struct pci_dev *)drv->dev, + cs4231_chip->input_dma_handle, + cs4231_chip->input_dma_size); cs4231_chip->input_dma_handle = 0; cs4231_chip->input_dma_size = 0; } if (cs4231_chip->input_next_dma_handle) { + pci_unmap_single((struct pci_dev *)drv->dev, + cs4231_chip->input_next_dma_handle, + cs4231_chip->input_next_dma_size); cs4231_chip->input_next_dma_handle = 0; cs4231_chip->input_next_dma_size = 0; } @@ -2235,6 +2258,8 @@ cs4231_chip->input_ptr = cs4231_chip->output_ptr = NULL; cs4231_chip->input_size = cs4231_chip->output_size = 0; cs4231_chip->status = 0; + + drv->dev = (struct sbus_dev *)edev->bus->self; len = prom_getproperty(edev->prom_node, "reg", (void *)regs, sizeof(regs)); if ((len % sizeof(regs[0])) != 0) { diff -ur --new-file old/linux/drivers/sbus/audio/dbri.c new/linux/drivers/sbus/audio/dbri.c --- old/linux/drivers/sbus/audio/dbri.c Tue Dec 21 07:06:42 1999 +++ new/linux/drivers/sbus/audio/dbri.c Thu Jan 27 17:58:15 2000 @@ -1,4 +1,4 @@ -/* $Id: dbri.c,v 1.16 1999/11/19 09:56:05 davem Exp $ +/* $Id: dbri.c,v 1.17 2000/01/20 07:57:47 anton Exp $ * drivers/sbus/audio/dbri.c * * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) @@ -225,8 +225,8 @@ dbri_reset(dbri); free_irq(dbri->irq, dbri); sbus_iounmap(dbri->regs, dbri->regs_size); - sbus_free_consistant(dbri->sdev, sizeof(struct dbri_dma), - dbri->dma, dbry->dma_dvma); + sbus_free_consistent(dbri->sdev, sizeof(struct dbri_dma), + dbri->dma, dbri->dma_dvma); kfree(dbri); } @@ -999,7 +999,7 @@ /* Make sure buffer size is multiple of four */ len &= ~3; - buf_buffer_base = buf_buffer = sbus_map_single(dbri->sdev, buffer, len); + bus_buffer_base = bus_buffer = sbus_map_single(dbri->sdev, buffer, len); while (len > 0) { int rd, mylen; @@ -2232,7 +2232,7 @@ dbri = (struct dbri *) drv->private; memset(dbri, 0, sizeof(*dbri)); - dbri->dma = sbus_alloc_consistant(sdev, + dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma), &dbri->dma_dvma); @@ -2251,7 +2251,7 @@ "DBRI Registers"); if (!dbri->regs) { printk(KERN_ERR "DBRI: could not allocate registers\n"); - sbus_free_consistant(sdev, sizeof(struct dbri_dma), + sbus_free_consistent(sdev, sizeof(struct dbri_dma), dbri->dma, dbri->dma_dvma); kfree(drv->private); return -EIO; @@ -2265,7 +2265,7 @@ if (err) { printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq); sbus_iounmap(dbri->regs, dbri->regs_size); - sbus_free_consistant(sdev, sizeof(struct dbri_dma), + sbus_free_consistent(sdev, sizeof(struct dbri_dma), dbri->dma, dbri->dma_dvma); kfree(drv->private); return err; diff -ur --new-file old/linux/drivers/sbus/char/Makefile new/linux/drivers/sbus/char/Makefile --- old/linux/drivers/sbus/char/Makefile Wed Sep 8 20:14:32 1999 +++ new/linux/drivers/sbus/char/Makefile Mon Jan 24 04:48:47 2000 @@ -103,6 +103,13 @@ endif endif +ifeq ($(CONFIG_SUN_JSFLASH),y) +O_OBJS += jsflash.o +endif +ifeq ($(CONFIG_SUN_JSFLASH),m) +M_OBJS += jsflash.o +endif + include $(TOPDIR)/Rules.make sunkbdmap.o: sunkeymap.c diff -ur --new-file old/linux/drivers/sbus/char/jsflash.c new/linux/drivers/sbus/char/jsflash.c --- old/linux/drivers/sbus/char/jsflash.c Tue Jan 4 18:41:45 2000 +++ new/linux/drivers/sbus/char/jsflash.c Fri Jan 28 17:04:58 2000 @@ -191,12 +191,21 @@ } if (p < JSF_BASE_ALL && togo != 0) { +#if 0 /* __bzero XXX */ size_t x = JSF_BASE_ALL - p; if (x > togo) x = togo; clear_user(tmp, x); tmp += x; p += x; togo -= x; +#else + /* + * Implementation of clear_user() calls __bzero + * without regard to modversions, + * so we cannot build a module. + */ + return 0; +#endif } while (togo >= 4) { diff -ur --new-file old/linux/drivers/sbus/char/uctrl.c new/linux/drivers/sbus/char/uctrl.c --- old/linux/drivers/sbus/char/uctrl.c Tue Dec 21 07:06:42 1999 +++ new/linux/drivers/sbus/char/uctrl.c Mon Jan 24 04:48:47 2000 @@ -1,4 +1,4 @@ -/* $Id: uctrl.c,v 1.5 1999/12/15 15:48:24 davem Exp $ +/* $Id: uctrl.c,v 1.6 2000/01/22 05:22:07 anton Exp $ * uctrl.c: TS102 Microcontroller interface on Tadpole Sparcbook 3 * * Copyright 1999 Derrick J Brashear (shadow@dementia.org) @@ -380,7 +380,7 @@ #ifdef MODULE int init_module(void) #else -int __init uctrl_init(void) +int __init ts102_uctrl_init(void) #endif { struct uctrl_driver *driver = &drv; diff -ur --new-file old/linux/drivers/sbus/char/vfc_i2c.c new/linux/drivers/sbus/char/vfc_i2c.c --- old/linux/drivers/sbus/char/vfc_i2c.c Tue Dec 21 07:06:42 1999 +++ new/linux/drivers/sbus/char/vfc_i2c.c Mon Jan 24 04:48:47 2000 @@ -115,7 +115,7 @@ { VFC_I2C_DEBUG_PRINTK((KERN_DEBUG "vfc%d: Resetting the i2c bus\n", dev->instance)); - if(dev == NULl) + if(dev == NULL) return -EINVAL; if(dev->regs == NULL) return -EINVAL; diff -ur --new-file old/linux/drivers/scsi/3w-xxxx.c new/linux/drivers/scsi/3w-xxxx.c --- old/linux/drivers/scsi/3w-xxxx.c Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/scsi/3w-xxxx.c Wed Jan 26 22:28:09 2000 @@ -0,0 +1,2223 @@ +/* + 3w-xxxx.c -- 3ware Storage Controller device driver for Linux. + + Written By: Adam Radford + Copyright (C) 1999-2000 3ware Inc. + + Kernel compatablity By: Andre Hedrick + Non-Copyright (C) 2000 Andre Hedrick + + Further tiny build fixes and trivial hoovering Alan Cox + + 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. + + NO WARRANTY + THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT + LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is + solely responsible for determining the appropriateness of using and + distributing the Program and assumes all risks associated with its + exercise of rights under this Agreement, including but not limited to + the risks and costs of program errors, damage to or loss of data, + programs or equipment, and unavailability or interruption of operations. + + DISCLAIMER OF LIABILITY + NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED + HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES + + 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 + + Bugs/Comments/Suggestions should be mailed to: + linux@3ware.com + + For more information, goto: + http://www.3ware.com +*/ + +#include + +MODULE_AUTHOR ("3ware Inc."); +MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define __3W_C /* let 3w-xxxx.h know it is use */ + +#include "sd.h" +#include "scsi.h" +#include "hosts.h" + +#include "3w-xxxx.h" + +static int tw_copy_info(TW_Info *info, char *fmt, ...); +static void tw_copy_mem_info(TW_Info *info, char *data, int len); +static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs); + +/* Globals */ +char *tw_driver_version="0.4.001"; +TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT]; +int tw_device_extension_count = 0; + +/* Functions */ + +/* This function will complete an aen request from the isr */ +int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id) +{ + TW_Param *param; + unsigned short aen, aen_code; + + if (tw_dev->alignment_virtual_address[request_id] == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n"); + return 1; + } + param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; + aen = *(unsigned short *)(param->data); + aen_code = (aen & 0x0ff); + dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen_code); + /* Now queue the code */ + tw_dev->aen_queue[tw_dev->aen_tail] = aen_code; + if (tw_dev->aen_tail == TW_Q_LENGTH - 1) { + tw_dev->aen_tail = TW_Q_START; + } else { + tw_dev->aen_tail = tw_dev->aen_tail + 1; + } + if (tw_dev->aen_head == tw_dev->aen_tail) { + if (tw_dev->aen_head == TW_Q_LENGTH - 1) { + tw_dev->aen_head = TW_Q_START; + } else { + tw_dev->aen_head = tw_dev->aen_head + 1; + } + } + tw_dev->state[request_id] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, request_id); + + return 0; +} /* End tw_aen_complete() */ + +/* This function will drain the aen queue after a soft reset */ +int tw_aen_drain_queue(TW_Device_Extension *tw_dev) +{ + TW_Command *command_packet; + TW_Param *param; + int tries = 0; + int request_id = 0; + u32 command_que_value = 0, command_que_addr; + u32 status_reg_value = 0, status_reg_addr; + u32 param_value; + TW_Response_Queue response_queue; + u32 response_que_addr; + unsigned short aen; + unsigned short aen_code; + int finished = 0; + int first_reset = 0; + int queue = 0; + int imax, i; + int found = 0; + + dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue()\n"); + + command_que_addr = tw_dev->registers.command_que_addr; + status_reg_addr = tw_dev->registers.status_reg_addr; + response_que_addr = tw_dev->registers.response_que_addr; + + if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT, 15)) { + printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d\n", tw_dev->host->host_no); + return 1; + } + + /* Initialize command packet */ + if (tw_dev->command_packet_virtual_address[request_id] == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet virtual address.\n"); + return 1; + } + command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id]; + memset(command_packet, 0, sizeof(TW_Sector)); + command_packet->byte0.opcode = TW_OP_GET_PARAM; + command_packet->byte0.sgl_offset = 2; + command_packet->size = 4; + command_packet->request_id = request_id; + command_packet->byte3.unit = 0; + command_packet->byte3.host_id = 0; + command_packet->status = 0; + command_packet->flags = 0; + command_packet->byte6.parameter_count = 1; + command_que_value = tw_dev->command_packet_physical_address[request_id]; + if (command_que_value == 0) { + printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet physical address.\n"); + return 1; + } + + /* Now setup the param */ + if (tw_dev->alignment_virtual_address[request_id] == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment virtual address.\n"); + return 1; + } + param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; + memset(param, 0, sizeof(TW_Sector)); + param->table_id = 0x401; /* AEN table */ + param->parameter_id = 2; /* Unit code */ + param->parameter_size_bytes = 2; + param_value = tw_dev->alignment_physical_address[request_id]; + if (param_value == 0) { + printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment physical address.\n"); + return 1; + } + command_packet->byte8.param.sgl[0].address = param_value; + command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector); + + imax = TW_POLL_MAX_RETRIES; + + /* Now drain the controller's aen queue */ + do { + /* Post command packet */ + outl(command_que_value, command_que_addr); + + /* Now poll for completion */ + for (i=0;istatus != 0) { + if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) { + /* Bad response */ + printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad response, flags = 0x%x.\n", command_packet->flags); + return 1; + } else { + /* We know this is a 3w-1x00, and doesn't support aen's */ + return 0; + } + } + + /* Now check the aen */ + aen = *(unsigned short *)(param->data); + aen_code = (aen & 0x0ff); + queue = 0; + switch (aen_code) { + case TW_AEN_QUEUE_EMPTY: + dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_QUEUE_EMPTY.\n"); + if (first_reset != 1) { + continue; + } else { + finished = 1; + } + break; + case TW_AEN_SOFT_RESET: + dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_SOFT_RESET.\n"); + if (first_reset == 0) { + first_reset = 1; + } else { + queue = 1; + } + break; + case TW_AEN_DEGRADED_MIRROR: + dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_DEGRADED_MIRROR.\n"); + queue = 1; + break; + case TW_AEN_CONTROLLER_ERROR: + dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_CONTROLLER_ERROR.\n"); + queue = 1; + break; + case TW_AEN_REBUILD_FAIL: + dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_REBUILD_FAIL.\n"); + queue = 1; + break; + case TW_AEN_REBUILD_DONE: + dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_REBUILD_DONE.\n"); + queue = 1; + break; + case TW_AEN_QUEUE_FULL: + dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_QUEUE_FULL.\n"); + queue = 1; + break; + default: + dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unknown AEN code 0x%x.\n", aen_code); + queue = 1; + } + + /* Now put the aen on the aen_queue */ + if (queue == 1) { + tw_dev->aen_queue[tw_dev->aen_tail] = aen_code; + if (tw_dev->aen_tail == TW_Q_LENGTH - 1) { + tw_dev->aen_tail = TW_Q_START; + } else { + tw_dev->aen_tail = tw_dev->aen_tail + 1; + } + if (tw_dev->aen_head == tw_dev->aen_tail) { + if (tw_dev->aen_head == TW_Q_LENGTH - 1) { + tw_dev->aen_head = TW_Q_START; + } else { + tw_dev->aen_head = tw_dev->aen_head + 1; + } + } + } + found = 1; + break; + } + } + if (found == 0) { + printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Response never received.\n"); + return 1; + } + tries++; + } while ((tries < TW_MAX_AEN_TRIES) && (finished == 0)); + + if (tries >=TW_MAX_AEN_TRIES) { + printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Aen queue error.\n"); + return 1; + } + + return 0; +} /* End tw_aen_drain_queue() */ + +/* This function will read the aen queue from the isr */ +int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id) +{ + TW_Command *command_packet; + TW_Param *param; + u32 command_que_value = 0, command_que_addr; + u32 status_reg_value = 0, status_reg_addr; + u32 param_value = 0; + + dprintk(KERN_NOTICE "3w-xxxx: tw_aen_read_queue()\n"); + command_que_addr = tw_dev->registers.command_que_addr; + status_reg_addr = tw_dev->registers.status_reg_addr; + + status_reg_value = inl(status_reg_addr); + if (tw_check_bits(status_reg_value)) { + printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n"); + return 1; + } + if (tw_dev->command_packet_virtual_address[request_id] == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet virtual address.\n"); + return 1; + } + command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id]; + memset(command_packet, 0, sizeof(TW_Sector)); + command_packet->byte0.opcode = TW_OP_GET_PARAM; + command_packet->byte0.sgl_offset = 2; + command_packet->size = 4; + command_packet->request_id = request_id; + command_packet->byte3.unit = 0; + command_packet->byte3.host_id = 0; + command_packet->status = 0; + command_packet->flags = 0; + command_packet->byte6.parameter_count = 1; + command_que_value = tw_dev->command_packet_physical_address[request_id]; + if (command_que_value == 0) { + printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet physical address.\n"); + return 1; + } + /* Now setup the param */ + if (tw_dev->alignment_virtual_address[request_id] == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment virtual address.\n"); + return 1; + } + param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; + memset(param, 0, sizeof(TW_Sector)); + param->table_id = 0x401; /* AEN table */ + param->parameter_id = 2; /* Unit code */ + param->parameter_size_bytes = 2; + param_value = tw_dev->alignment_physical_address[request_id]; + if (param_value == 0) { + printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment physical address.\n"); + return 1; + } + command_packet->byte8.param.sgl[0].address = param_value; + command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector); + + /* Now post the command packet */ + if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) { + dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post succeeded.\n"); + tw_dev->srb[request_id] = 0; /* Flag internal command */ + tw_dev->state[request_id] = TW_S_POSTED; + outl(command_que_value, command_que_addr); + } else { + printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post failed, will retry.\n"); + return 1; + } + + return 0; +} /* End tw_aen_read_queue() */ + +/* This function will allocate memory and check if it is 16 d-word aligned */ +int tw_allocate_memory(TW_Device_Extension *tw_dev, int request_id, int size, int which) +{ + u32 *virt_addr; + + dprintk(KERN_NOTICE "3w-xxxx: tw_allocate_memory()\n"); + + if (which == 0) { + /* Allocate command packet memory */ + virt_addr = kmalloc(size, GFP_ATOMIC); + if (virt_addr == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): kmalloc() failed.\n"); + return 1; + } + if ((u32)virt_addr % TW_ALIGNMENT) { + printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): Found unaligned address.\n"); + return 1; + } + tw_dev->command_packet_virtual_address[request_id] = virt_addr; + tw_dev->command_packet_physical_address[request_id] = + virt_to_bus(virt_addr); + } else { + /* Allocate generic buffer */ + virt_addr = kmalloc(size, GFP_ATOMIC); + if (virt_addr == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): kmalloc() failed.\n"); + return 1; + } + if ((u32)virt_addr % TW_ALIGNMENT) { + printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): Found unaligned address.\n"); + return 1; + } + tw_dev->alignment_virtual_address[request_id] = virt_addr; + tw_dev->alignment_physical_address[request_id] = virt_to_bus(virt_addr); + } + return 0; +} /* End tw_allocate_memory() */ + +/* This function will check the status register for unexpected bits */ +int tw_check_bits(u32 status_reg_value) +{ + if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) { + printk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value); + return 1; + } + if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0) { + printk(KERN_WARNING "3w-xxxx: tw_check_bits(): Found unexpected bits (0x%x).\n", status_reg_value); + return 1; + } + + return 0; +} /* End tw_check_bits() */ + +/* This function will report controller error status */ +int tw_check_errors(TW_Device_Extension *tw_dev) +{ + u32 status_reg_addr, status_reg_value; + + status_reg_addr = tw_dev->registers.status_reg_addr; + status_reg_value = inl(status_reg_addr); + + if (TW_STATUS_ERRORS(status_reg_value) || tw_check_bits(status_reg_value)) + return 1; + + return 0; +} /* End tw_check_errors() */ + +/* This function will clear the attention interrupt */ +void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev) +{ + u32 control_reg_addr, control_reg_value; + + control_reg_addr = tw_dev->registers.control_reg_addr; + control_reg_value = TW_CONTROL_CLEAR_ATTENTION_INTERRUPT; + outl(control_reg_value, control_reg_addr); +} /* End tw_clear_attention_interrupt() */ + +/* This function will clear the host interrupt */ +void tw_clear_host_interrupt(TW_Device_Extension *tw_dev) +{ + u32 control_reg_addr, control_reg_value; + + control_reg_addr = tw_dev->registers.control_reg_addr; + control_reg_value = TW_CONTROL_CLEAR_HOST_INTERRUPT; + outl(control_reg_value, control_reg_addr); +} /* End tw_clear_host_interrupt() */ + +/* This function is called by tw_scsi_proc_info */ +static int tw_copy_info(TW_Info *info, char *fmt, ...) +{ + va_list args; + char buf[81]; + int len; + + va_start(args, fmt); + len = vsprintf(buf, fmt, args); + va_end(args); + tw_copy_mem_info(info, buf, len); + return len; +} /* End tw_copy_info() */ + +/* This function is called by tw_scsi_proc_info */ +static void tw_copy_mem_info(TW_Info *info, char *data, int len) +{ + if (info->position + len > info->length) + len = info->length - info->position; + + if (info->position + len < info->offset) { + info->position += len; + return; + } + if (info->position < info->offset) { + data += (info->offset - info->position); + len -= (info->offset - info->position); + } + if (len > 0) { + memcpy(info->buffer + info->position, data, len); + info->position += len; + } +} /* End tw_copy_mem_info() */ + +/* This function will disable interrupts on the controller */ +void tw_disable_interrupts(TW_Device_Extension *tw_dev) +{ + u32 control_reg_value, control_reg_addr; + + control_reg_addr = tw_dev->registers.control_reg_addr; + control_reg_value = TW_CONTROL_DISABLE_INTERRUPTS; + outl(control_reg_value, control_reg_addr); +} /* End tw_disable_interrupts() */ + +/* This function will empty the response que */ +int tw_empty_response_que(TW_Device_Extension *tw_dev) +{ + u32 status_reg_addr, status_reg_value; + u32 response_que_addr, response_que_value; + + status_reg_addr = tw_dev->registers.status_reg_addr; + response_que_addr = tw_dev->registers.response_que_addr; + + status_reg_value = inl(status_reg_addr); + + if (tw_check_bits(status_reg_value)) { + printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 1.\n"); + return 1; + } + + while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) { + response_que_value = inl(response_que_addr); + status_reg_value = inl(status_reg_addr); + if (tw_check_bits(status_reg_value)) { + printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 2.\n"); + return 1; + } + } + return 0; +} /* End tw_empty_response_que() */ + +/* This function will enable interrupts on the controller */ +void tw_enable_interrupts(TW_Device_Extension *tw_dev) +{ + u32 control_reg_value, control_reg_addr; + + control_reg_addr = tw_dev->registers.control_reg_addr; + control_reg_value = (TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | + TW_CONTROL_UNMASK_RESPONSE_INTERRUPT | + TW_CONTROL_ENABLE_INTERRUPTS); + outl(control_reg_value, control_reg_addr); +} /* End tw_enable_interrupts() */ + +/* This function will find and initialize all cards */ +int tw_findcards(Scsi_Host_Template *tw_host) +{ + int numcards = 0, tries = 0, error = 0; + struct Scsi_Host *host; + TW_Device_Extension *tw_dev; + TW_Device_Extension *tw_dev2; + struct pci_dev *tw_pci_dev = NULL; + u32 status_reg_value; + + dprintk(KERN_NOTICE "3w-xxxx: tw_findcards()\n"); + while ((tw_pci_dev = pci_find_device(TW_VENDOR_ID, TW_DEVICE_ID, tw_pci_dev))) { + /* Prepare temporary device extension */ + tw_dev=(TW_Device_Extension *)kmalloc(sizeof(TW_Device_Extension), GFP_ATOMIC); + if (tw_dev == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_findcards(): kmalloc() failed for card %d.\n", numcards); + continue; + } + memset(tw_dev, 0, sizeof(TW_Device_Extension)); + + error = tw_initialize_device_extension(tw_dev); + if (error) { + printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize device extension for card %d.\n", numcards); + tw_free_device_extension(tw_dev); + kfree(tw_dev); + continue; + } + + /* Calculate the cards register addresses */ + tw_dev->registers.base_addr = tw_pci_dev->resource[0].start; + tw_dev->registers.control_reg_addr = (tw_pci_dev->resource[0].start & ~15); + tw_dev->registers.status_reg_addr = ((tw_pci_dev->resource[0].start & ~15) + 0x4); + tw_dev->registers.command_que_addr = ((tw_pci_dev->resource[0].start & ~15) + 0x8); + tw_dev->registers.response_que_addr = ((tw_pci_dev->resource[0].start & ~15) + 0xC); + /* Save pci_dev struct to device extension */ + tw_dev->tw_pci_dev = tw_pci_dev; + + /* Poll status register for 60 secs for 'Controller Ready' flag */ + if (tw_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY, 60)) { + printk(KERN_WARNING "3w-xxxx: tw_findcards(): Microcontroller not ready for card %d.\n", numcards); + tw_free_device_extension(tw_dev); + kfree(tw_dev); + continue; + } + + /* Disable interrupts on the card */ + tw_disable_interrupts(tw_dev); + + while (tries < TW_MAX_RESET_TRIES) { + /* Do soft reset */ + tw_soft_reset(tw_dev); + + error = tw_aen_drain_queue(tw_dev); + if (error) { + printk(KERN_WARNING "3w-xxxx: tw_findcards(): No attention interrupt for card %d.\n", numcards); + tries++; + continue; + } + + /* Check for controller errors */ + if (tw_check_errors(tw_dev)) { + printk(KERN_WARNING "3w-xxxx: tw_findcards(): Controller errors found, soft resetting card %d.\n", numcards); + tries++; + continue; + } + + /* Empty the response queue */ + error = tw_empty_response_que(tw_dev); + if (error) { + printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't empty response queue for card %d.\n", numcards); + tries++; + continue; + } + + /* Now the controller is in a good state */ + break; + } + + if (tries >= TW_MAX_RESET_TRIES) { + printk(KERN_WARNING "3w-xxxx: tw_findcards(): Controller error or no attention interrupt: giving up for card %d.\n", numcards); + tw_free_device_extension(tw_dev); + kfree(tw_dev); + continue; + } + + /* Make sure that io region isn't already taken */ + if (check_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE)) { + printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't get io range 0x%lx-0x%lx for card %d.\n", + (tw_dev->tw_pci_dev->resource[0].start), + (tw_dev->tw_pci_dev->resource[0].start) + + TW_IO_ADDRESS_RANGE, numcards); + tw_free_device_extension(tw_dev); + kfree(tw_dev); + continue; + } + + /* Reserve the io address space */ + request_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE, TW_DEVICE_NAME); + error = tw_initialize_units(tw_dev); + if (error) { + printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize units for card %d.\n", numcards); + release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE); + tw_free_device_extension(tw_dev); + kfree(tw_dev); + continue; + } + + error = tw_initconnection(tw_dev); + if (error) { + printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initconnection for card %d.\n", numcards); + release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE); + tw_free_device_extension(tw_dev); + kfree(tw_dev); + continue; + } + + /* Calculate max cmds per lun */ + if (tw_dev->num_units > 0) + tw_host->cmd_per_lun = (TW_Q_LENGTH-2)/tw_dev->num_units; + + /* Register the card with the kernel SCSI layer */ + host = scsi_register(tw_host, sizeof(TW_Device_Extension)); + + /* FIXME - check for NULL */ + + status_reg_value = inl(tw_dev->registers.status_reg_addr); + + dprintk(KERN_NOTICE "scsi%d : Found a 3ware Storage Controller at 0x%x, IRQ: %d P-chip: %d.%d\n", host->host_no, + (u32)(tw_pci_dev->resource[0].start), tw_pci_dev->irq, + (status_reg_value & TW_STATUS_MAJOR_VERSION_MASK) >> 28, + (status_reg_value & TW_STATUS_MINOR_VERSION_MASK) >> 24); + + if (host->hostdata) { + tw_dev2 = (TW_Device_Extension *)host->hostdata; + memcpy(tw_dev2, tw_dev, sizeof(TW_Device_Extension)); + tw_device_extension_list[tw_device_extension_count] = tw_dev2; + numcards++; + tw_device_extension_count = numcards; + tw_dev2->host = host; + } else { + printk(KERN_WARNING "3w-xxxx: tw_findcards(): Bad scsi host data for card %d.\n", numcards-1); + scsi_unregister(host); + release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE); + tw_free_device_extension(tw_dev); + kfree(tw_dev); + continue; + } + + /* Re-enable interrupts on the card */ + tw_enable_interrupts(tw_dev2); + + /* Now setup the interrupt handler */ + error = tw_setup_irq(tw_dev2); + if (error) { + printk(KERN_WARNING "3w-xxxx: tw_findcards(): Error requesting irq for card %d.\n", numcards-1); + scsi_unregister(host); + release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE); + + tw_free_device_extension(tw_dev); + kfree(tw_dev); + numcards--; + continue; + } + + /* Free the temporary device extension */ + if (tw_dev) + kfree(tw_dev); + } + + if (numcards == 0) + printk(KERN_WARNING "3w-xxxx: tw_findcards(): No cards found.\n"); + + return numcards; +} /* End tw_findcards() */ + +/* This function will free up device extension resources */ +void tw_free_device_extension(TW_Device_Extension *tw_dev) +{ + int i, imax; + imax = TW_Q_LENGTH; + + dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n"); + /* Free command packet and generic buffer memory */ + for (i=0;icommand_packet_virtual_address[i]) + kfree(tw_dev->command_packet_virtual_address[i]); + + if (tw_dev->alignment_virtual_address[i]) + kfree(tw_dev->alignment_virtual_address[i]); + } +} /* End tw_free_device_extension() */ + +/* This function will send an initconnection command to controller */ +int tw_initconnection(TW_Device_Extension *tw_dev) +{ + u32 command_que_addr, command_que_value; + u32 status_reg_addr, status_reg_value; + u32 response_que_addr; + TW_Command *command_packet; + TW_Response_Queue response_queue; + int request_id = 0; + int i = 0; + int imax = 0; + + dprintk(KERN_NOTICE "3w-xxxx: tw_initconnection()\n"); + command_que_addr = tw_dev->registers.command_que_addr; + status_reg_addr = tw_dev->registers.status_reg_addr; + response_que_addr = tw_dev->registers.response_que_addr; + + /* Initialize InitConnection command packet */ + if (tw_dev->command_packet_virtual_address[request_id] == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet virtual address.\n"); + return 1; + } + + command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id]; + memset(command_packet, 0, sizeof(TW_Sector)); + command_packet->byte0.opcode = TW_OP_INIT_CONNECTION; + command_packet->byte0.sgl_offset = 0x0; + command_packet->size = TW_INIT_COMMAND_PACKET_SIZE; + command_packet->request_id = request_id; + command_packet->byte3.unit = 0x0; + command_packet->byte3.host_id = 0x0; + command_packet->status = 0x0; + command_packet->flags = 0x0; + command_packet->byte6.message_credits = TW_INIT_MESSAGE_CREDITS; + command_packet->byte8.init_connection.response_queue_pointer = 0x0; + command_que_value = tw_dev->command_packet_physical_address[request_id]; + + if (command_que_value == 0) { + printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet physical address.\n"); + return 1; + } + + /* Send command packet to the board */ + outl(command_que_value, command_que_addr); + + /* Poll for completion */ + imax = TW_POLL_MAX_RETRIES; + for (i=0;istatus != 0) { + /* bad response */ + printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad response, flags = 0x%x.\n", command_packet->flags); + return 1; + } + break; /* Response was okay, so we exit */ + } + } + return 0; +} /* End tw_initconnection() */ + +/* This function will initialize the fields of a device extension */ +int tw_initialize_device_extension(TW_Device_Extension *tw_dev) +{ + int i, imax; + + dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_device_extension()\n"); + imax = TW_Q_LENGTH; + + for (i=0; icommand_packet_virtual_address[i] == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_initialize_device_extension(): Bad command packet virtual address.\n"); + return 1; + } + memset(tw_dev->command_packet_virtual_address[i], 0, sizeof(TW_Sector)); + + /* Initialize generic buffer */ + tw_allocate_memory(tw_dev, i, sizeof(TW_Sector), 1); + if (tw_dev->alignment_virtual_address[i] == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_initialize_device_extension(): Bad alignment virtual address.\n"); + return 1; + } + memset(tw_dev->alignment_virtual_address[i], 0, sizeof(TW_Sector)); + + tw_dev->free_queue[i] = i; + tw_dev->state[i] = TW_S_INITIAL; + tw_dev->ioctl_size[i] = 0; + tw_dev->aen_queue[i] = 0; + } + + for (i=0;iis_unit_present[i] = 0; + + tw_dev->num_units = 0; + tw_dev->num_aborts = 0; + tw_dev->num_resets = 0; + tw_dev->free_head = TW_Q_START; + tw_dev->free_tail = TW_Q_LENGTH - 1; + tw_dev->posted_request_count = 0; + tw_dev->max_posted_request_count = 0; + tw_dev->max_sgl_entries = 0; + tw_dev->sgl_entries = 0; + tw_dev->host = NULL; + tw_dev->pending_head = TW_Q_START; + tw_dev->pending_tail = TW_Q_START; + tw_dev->aen_head = 0; + tw_dev->aen_tail = 0; + tw_dev->sector_count = 0; + tw_dev->max_sector_count = 0; + spin_lock_init(&tw_dev->tw_lock); + tw_dev->flags = 0; + return 0; +} /* End tw_initialize_device_extension() */ + +/* This function will get unit info from the controller */ +int tw_initialize_units(TW_Device_Extension *tw_dev) +{ + int found = 0; + unsigned char request_id = 0; + TW_Command *command_packet; + TW_Param *param; + int i, imax, num_units = 0; + u32 status_reg_addr, status_reg_value; + u32 command_que_addr, command_que_value; + u32 response_que_addr; + TW_Response_Queue response_queue; + u32 param_value; + unsigned char *is_unit_present; + + dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units()\n"); + + status_reg_addr = tw_dev->registers.status_reg_addr; + command_que_addr = tw_dev->registers.command_que_addr; + response_que_addr = tw_dev->registers.response_que_addr; + + /* Setup the command packet */ + command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id]; + if (command_packet == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet virtual address.\n"); + return 1; + } + memset(command_packet, 0, sizeof(TW_Sector)); + command_packet->byte0.opcode = TW_OP_GET_PARAM; + command_packet->byte0.sgl_offset = 2; + command_packet->size = 4; + command_packet->request_id = request_id; + command_packet->byte3.unit = 0; + command_packet->byte3.host_id = 0; + command_packet->status = 0; + command_packet->flags = 0; + command_packet->byte6.block_count = 1; + + /* Now setup the param */ + if (tw_dev->alignment_virtual_address[request_id] == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment virtual address.\n"); + return 1; + } + param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; + memset(param, 0, sizeof(TW_Sector)); + param->table_id = 3; /* unit summary table */ + param->parameter_id = 3; /* unitstatus parameter */ + param->parameter_size_bytes = TW_MAX_UNITS; + param_value = tw_dev->alignment_physical_address[request_id]; + if (param_value == 0) { + printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment physical address.\n"); + return 1; + } + + command_packet->byte8.param.sgl[0].address = param_value; + command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector); + + /* Post the command packet to the board */ + command_que_value = tw_dev->command_packet_physical_address[request_id]; + if (command_que_value == 0) { + printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet physical address.\n"); + return 1; + } + outl(command_que_value, command_que_addr); + + /* Poll for completion */ + imax = TW_POLL_MAX_RETRIES; + for(i=0; istatus != 0) { + /* bad response */ + printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, flags = 0x%x.\n", command_packet->flags); + return 1; + } + found = 1; + break; + } + } + if (found == 0) { + /* response never received */ + printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No response.\n"); + return 1; + } + + param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; + is_unit_present = (unsigned char *)&(param->data[0]); + + /* Show all units present */ + imax = TW_MAX_UNITS; + for(i=0; iis_unit_present[i] = FALSE; + } else { + dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): Unit %d found.\n", i); + tw_dev->is_unit_present[i] = TRUE; + num_units++; + } + } + tw_dev->num_units = num_units; + + if (num_units == 0) { + printk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): No units found.\n"); + return 1; + } + + return 0; +} /* End tw_initialize_units() */ + +/* This function is the interrupt service routine */ +static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs) +{ + int request_id; + u32 status_reg_addr, status_reg_value; + u32 response_que_addr; + TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance; + TW_Response_Queue response_que; + int error = 0; + int do_response_interrupt=0; + int do_attention_interrupt=0; + int do_host_interrupt=0; + int do_command_interrupt=0; + int flags = 0; + int flags2 = 0; + TW_Command *command_packet; + if (test_and_set_bit(TW_IN_INTR, &tw_dev->flags)) + return; + spin_lock_irqsave(&io_request_lock, flags); + + if (tw_dev->tw_pci_dev->irq == irq) { + spin_lock_irqsave(&tw_dev->tw_lock, flags2); + dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt()\n"); + + /* Read the registers */ + status_reg_addr = tw_dev->registers.status_reg_addr; + response_que_addr = tw_dev->registers.response_que_addr; + status_reg_value = inl(status_reg_addr); + + /* Check which interrupt */ + if (status_reg_value & TW_STATUS_HOST_INTERRUPT) + do_host_interrupt=1; + if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) + do_attention_interrupt=1; + if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) + do_command_interrupt=1; + if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) + do_response_interrupt=1; + + /* Handle host interrupt */ + if (do_host_interrupt) { + dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received host interrupt.\n"); + tw_clear_host_interrupt(tw_dev); + } + + /* Handle attention interrupt */ + if (do_attention_interrupt) { + dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received attention interrupt.\n"); + tw_state_request_start(tw_dev, &request_id); + error = tw_aen_read_queue(tw_dev, request_id); + if (error) { + printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Error reading aen queue.\n"); + tw_dev->state[request_id] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, request_id); + } else { + dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Clearing attention interrupt.\n"); + tw_clear_attention_interrupt(tw_dev); + } + } + + /* Handle command interrupt */ + if (do_command_interrupt) { + /* Drain as many pending commands as we can */ + while (tw_dev->pending_request_count > 0) { + request_id = tw_dev->pending_queue[tw_dev->pending_head]; + if (tw_dev->state[request_id] != TW_S_PENDING) { + printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found request id that wasn't pending.\n"); + break; + } + if (tw_post_command_packet(tw_dev, request_id)==0) { + if (tw_dev->pending_head == TW_Q_LENGTH-1) { + tw_dev->pending_head = TW_Q_START; + } else { + tw_dev->pending_head = tw_dev->pending_head + 1; + } + tw_dev->pending_request_count--; + } else { + break; + } + } + /* If there are no more pending requests, we mask command interrupt */ + if (tw_dev->pending_request_count == 0) + tw_mask_command_interrupt(tw_dev); + } + + /* Handle response interrupt */ + if (do_response_interrupt) { + /* Drain the response queue from the board */ + while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) { + response_que.value = inl(response_que_addr); + request_id = response_que.u.response_id; + command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id]; + if (command_packet->status != 0) { + printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, flags = 0x%x.\n", command_packet->flags); + } + if (tw_dev->state[request_id] != TW_S_POSTED) { + printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", request_id, command_packet->byte0.opcode); + } + error = 0; + dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id); + /* Check for internal command */ + if (tw_dev->srb[request_id] == 0) { + dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n"); + error = tw_aen_complete(tw_dev, request_id); + if (error) { + printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Error completing aen.\n"); + } + status_reg_value = inl(status_reg_addr); + if (tw_check_bits(status_reg_value)) { + printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n"); + } + } else { + switch (tw_dev->srb[request_id]->cmnd[0]) { + case READ_10: + dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10\n"); + case READ_6: + dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_6\n"); + break; + case WRITE_10: + dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10\n"); + case WRITE_6: + dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_6\n"); + break; + case INQUIRY: + dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n"); + error = tw_scsiop_inquiry_complete(tw_dev, request_id); + break; + case READ_CAPACITY: + dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n"); + error = tw_scsiop_read_capacity_complete(tw_dev, request_id); + break; + case TW_IOCTL: + dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TW_IOCTL\n"); + error = tw_ioctl_complete(tw_dev, request_id); + break; + default: + printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unknown scsi opcode: 0x%x.\n", tw_dev->srb[request_id]->cmnd[0]); + tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16); + tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); + } + if (error) { + /* Tell scsi layer there was an error */ + printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Scsi Error.\n"); + tw_dev->srb[request_id]->result = (DID_ERROR << 16); + } else { + /* Tell scsi layer command was a success */ + tw_dev->srb[request_id]->result = (DID_OK << 16); + } + tw_dev->state[request_id] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, request_id); + tw_dev->posted_request_count--; + tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); + status_reg_value = inl(status_reg_addr); + if (tw_check_bits(status_reg_value)) { + printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n"); + } + } + } + } + spin_unlock_irqrestore(&tw_dev->tw_lock, flags2); + } + spin_unlock_irqrestore(&io_request_lock, flags); + clear_bit(TW_IN_INTR, &tw_dev->flags); +} /* End tw_interrupt() */ + +/* This function handles ioctls from userspace to the driver */ +int tw_ioctl(TW_Device_Extension *tw_dev, int request_id) +{ + unsigned char opcode; + int bufflen; + TW_Param *param; + TW_Command *command_packet; + u32 param_value; + TW_Ioctl *ioctl = NULL; + int tw_aen_code; + + ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer; + if (ioctl == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Request buffer NULL.\n"); + tw_dev->state[request_id] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, request_id); + tw_dev->srb[request_id]->result = (DID_OK << 16); + tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); + return 0; + } + bufflen = tw_dev->srb[request_id]->request_bufflen; + + /* Initialize command packet */ + command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id]; + if (command_packet == NULL) { + printk(KERN_WARNING "3w-xxxx: twioctl(): Bad command packet virtual address.\n"); + tw_dev->state[request_id] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, request_id); + tw_dev->srb[request_id]->result = (DID_OK << 16); + tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); + return 0; + } + memset(command_packet, 0, sizeof(TW_Sector)); + + /* Initialize param */ + if (tw_dev->alignment_virtual_address[request_id] == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment virtual address.\n"); + tw_dev->state[request_id] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, request_id); + tw_dev->srb[request_id]->result = (DID_OK << 16); + tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); + return 0; + } + param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; + memset(param, 0, sizeof(TW_Sector)); + + dprintk(KERN_NOTICE "opcode = %d table_id = %d parameter_id = %d parameter_size_bytes = %d\n", ioctl->opcode, ioctl->table_id, ioctl->parameter_id,, ioctl->parameter_size_bytes); + opcode = ioctl->opcode; + + switch (opcode) { + case TW_OP_NOP: + dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_NOP.\n"); + command_packet->byte0.opcode = TW_OP_NOP; + break; + case TW_OP_GET_PARAM: + dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_GET_PARAM.\n"); + command_packet->byte0.opcode = TW_OP_GET_PARAM; + param->table_id = ioctl->table_id; + param->parameter_id = ioctl->parameter_id; + param->parameter_size_bytes = ioctl->parameter_size_bytes; + tw_dev->ioctl_size[request_id] = ioctl->parameter_size_bytes; + dprintk(KERN_NOTICE "table_id = %d parameter_id = %d parameter_size_bytes %d\n", param->table_id, param->parameter_id, param->parameter_size_bytes); + break; + case TW_OP_SET_PARAM: + dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_SET_PARAM: table_id = %d, parameter_id = %d, parameter_size_bytes = %d.\n", + ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes); + command_packet->byte0.opcode = TW_OP_SET_PARAM; + param->table_id = ioctl->table_id; + param->parameter_id = ioctl->parameter_id; + param->parameter_size_bytes = ioctl->parameter_size_bytes; + memcpy(param->data, ioctl->data, ioctl->parameter_size_bytes); + break; + case TW_OP_AEN_LISTEN: + dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_AEN_LISTEN.\n"); + if (tw_dev->aen_head == tw_dev->aen_tail) { + /* aen queue empty */ + dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Aen queue empty.\n"); + tw_aen_code = TW_AEN_QUEUE_EMPTY; + memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes); + } else { + /* Copy aen queue entry to request buffer */ + dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Returning aen 0x%x\n", tw_dev->aen_queue[tw_dev->aen_head]); + tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head]; + memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes); + if (tw_dev->aen_head == TW_Q_LENGTH - 1) { + tw_dev->aen_head = TW_Q_START; + } else { + tw_dev->aen_head = tw_dev->aen_head + 1; + } + } + tw_dev->state[request_id] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, request_id); + tw_dev->srb[request_id]->result = (DID_OK << 16); + tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); + return 0; + default: + printk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode); + tw_dev->state[request_id] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, request_id); + tw_dev->srb[request_id]->result = (DID_OK << 16); + tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); + return 0; + } + + param_value = tw_dev->alignment_physical_address[request_id]; + if (param_value == 0) { + printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n"); + tw_dev->state[request_id] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, request_id); + tw_dev->srb[request_id]->result = (DID_OK << 16); + tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); + } + + command_packet->byte8.param.sgl[0].address = param_value; + command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector); + + command_packet->byte0.sgl_offset = 2; + command_packet->size = 4; + command_packet->request_id = request_id; + command_packet->byte3.unit = 0; + command_packet->byte3.host_id = 0; + command_packet->status = 0; + command_packet->flags = 0; + command_packet->byte6.parameter_count = 1; + + /* Now try to post the command to the board */ + tw_post_command_packet(tw_dev, request_id); + + return 0; +} /* End tw_ioctl() */ + +/* This function is called by the isr to complete ioctl requests */ +int tw_ioctl_complete(TW_Device_Extension *tw_dev, int request_id) +{ + unsigned char *param_data; + unsigned char *buff; + TW_Param *param; + + dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete()\n"); + buff = tw_dev->srb[request_id]->request_buffer; + if (buff == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): Request buffer NULL.\n"); + return 1; + } + dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete(): Request_bufflen = %d\n", tw_dev->srb[request_id]->request_bufflen); + memset(buff, 0, tw_dev->srb[request_id]->request_bufflen); + param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; + if (param == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n"); + return 1; + } + param_data = &(param->data[0]); + + memcpy(buff, param_data, tw_dev->ioctl_size[request_id]); + + return 0; +} /* End tw_ioctl_complete() */ + +/* This function will mask the command interrupt */ +void tw_mask_command_interrupt(TW_Device_Extension *tw_dev) +{ + u32 control_reg_addr, control_reg_value; + + control_reg_addr = tw_dev->registers.control_reg_addr; + control_reg_value = TW_CONTROL_MASK_COMMAND_INTERRUPT; + outl(control_reg_value, control_reg_addr); +} /* End tw_mask_command_interrupt() */ + +/* This function will poll the status register for a flag */ +int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds) +{ + u32 status_reg_addr, status_reg_value; + struct timeval before, timeout; + + status_reg_addr = tw_dev->registers.status_reg_addr; + do_gettimeofday(&before); + status_reg_value = inl(status_reg_addr); + + while ((status_reg_value & flag) != flag) { + status_reg_value = inl(status_reg_addr); + do_gettimeofday(&timeout); + if (before.tv_sec + seconds < timeout.tv_sec) { + printk(KERN_WARNING "3w-xxxx: tw_poll_status(): Flag 0x%x not found.\n", flag); + return 1; + } + mdelay(1); + } + return 0; +} /* End tw_poll_status() */ + +/* This function will attempt to post a command packet to the board */ +int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id) +{ + u32 status_reg_addr, status_reg_value; + u32 command_que_addr, command_que_value; + + dprintk(KERN_NOTICE "3w-xxxx: tw_post_command_packet()\n"); + command_que_addr = tw_dev->registers.command_que_addr; + command_que_value = tw_dev->command_packet_physical_address[request_id]; + status_reg_addr = tw_dev->registers.status_reg_addr; + status_reg_value = inl(status_reg_addr); + + if (tw_check_bits(status_reg_value)) + printk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n"); + + if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) { + /* We successfully posted the command packet */ + outl(command_que_value, command_que_addr); + tw_dev->state[request_id] = TW_S_POSTED; + tw_dev->posted_request_count++; + if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) { + tw_dev->max_posted_request_count = tw_dev->posted_request_count; + } + } else { + /* Couldn't post the command packet, so we do it in the isr */ + if (tw_dev->state[request_id] != TW_S_PENDING) { + tw_dev->state[request_id] = TW_S_PENDING; + tw_dev->pending_request_count++; + if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) { + tw_dev->max_pending_request_count = tw_dev->pending_request_count; + } + tw_dev->pending_queue[tw_dev->pending_tail] = request_id; + if (tw_dev->pending_tail == TW_Q_LENGTH-1) { + tw_dev->pending_tail = TW_Q_START; + } else { + tw_dev->pending_tail = tw_dev->pending_tail + 1; + } + } + tw_unmask_command_interrupt(tw_dev); + return 1; + } + return 0; +} /* End tw_post_command_packet() */ + +/* This function will reset a device extension */ +int tw_reset_device_extension(TW_Device_Extension *tw_dev) +{ + int imax = 0; + int i = 0; + Scsi_Cmnd *srb; + + dprintk(KERN_NOTICE "3w-xxxx: tw_reset_device_extension()\n"); + imax = TW_Q_LENGTH; + + if (tw_reset_sequence(tw_dev)) { + printk(KERN_WARNING "3w-xxxx: tw_reset_device_extension(): Reset sequence failed for card %d.\n", tw_dev->host->host_no); + return 1; + } + + /* Abort all requests that are in progress */ + for (i=0;istate[i] != TW_S_FINISHED) && + (tw_dev->state[i] != TW_S_INITIAL) && + (tw_dev->state[i] != TW_S_COMPLETED)) { + srb = tw_dev->srb[i]; + srb->result = (DID_RESET << 16); + tw_dev->srb[i]->scsi_done(tw_dev->srb[i]); + } + } + + /* Reset queues and counts */ + for (i=0;ifree_queue[i] = i; + tw_dev->state[i] = TW_S_INITIAL; + } + tw_dev->free_head = TW_Q_START; + tw_dev->free_tail = TW_Q_LENGTH - 1; + tw_dev->posted_request_count = 0; + tw_dev->pending_request_count = 0; + tw_dev->pending_head = TW_Q_START; + tw_dev->pending_tail = TW_Q_START; + + return 0; +} /* End tw_reset_device_extension() */ + +/* This function will reset a controller */ +int tw_reset_sequence(TW_Device_Extension *tw_dev) +{ + int error = 0; + int tries = 0; + + /* Disable interrupts */ + tw_disable_interrupts(tw_dev); + + /* Reset the board */ + while (tries < TW_MAX_RESET_TRIES) { + tw_soft_reset(tw_dev); + + error = tw_aen_drain_queue(tw_dev); + if (error) { + printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): No attention interrupt for card %d.\n", tw_dev->host->host_no); + tries++; + continue; + } + + /* Check for controller errors */ + if (tw_check_errors(tw_dev)) { + printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Controller errors found, soft resetting card %d.\n", tw_dev->host->host_no); + tries++; + continue; + } + + /* Empty the response queue again */ + error = tw_empty_response_que(tw_dev); + if (error) { + printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Couldn't empty response queue for card %d.\n", tw_dev->host->host_no); + tries++; + continue; + } + + /* Now the controller is in a good state */ + break; + } + + if (tries >= TW_MAX_RESET_TRIES) { + printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Controller error or no attention interrupt: giving up for card %d.\n", tw_dev->host->host_no); + return 1; + } + + error = tw_initconnection(tw_dev); + if (error) { + printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no); + return 1; + } + + /* Re-enable interrupts */ + tw_enable_interrupts(tw_dev); + + return 0; +} /* End tw_reset_sequence() */ + +/* This funciton returns unit geometry in cylinders/heads/sectors */ +int tw_scsi_biosparam(Disk *disk, kdev_t dev, int geom[]) +{ + int heads, sectors, cylinders; + TW_Device_Extension *tw_dev; + + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam()\n"); + tw_dev = (TW_Device_Extension *)disk->device->host->hostdata; + + heads = 64; + sectors = 32; + cylinders = disk->capacity / (heads * sectors); + + if (disk->capacity >= 0x200000) { + heads = 255; + sectors = 63; + cylinders = disk->capacity / (heads * sectors); + } + + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam(): heads = %d, sectors = %d, cylinders = %d\n", heads, sectors, cylinders); + geom[0] = heads; + geom[1] = sectors; + geom[2] = cylinders; + + return 0; +} /* End tw_scsi_biosparam() */ + +/* This function will find and initialize any cards */ +int tw_scsi_detect(Scsi_Host_Template *tw_host) +{ + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_detect()\n"); + + /* Check if the kernel has PCI interface compiled in */ + if (!pci_present()) { + printk(KERN_WARNING "3w-xxxx: tw_scsi_detect(): No pci interface present.\n"); + return 0; + } + + return(tw_findcards(tw_host)); +} /* End tw_scsi_detect() */ + +/* This is the new scsi eh abort function */ +int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt) +{ + TW_Device_Extension *tw_dev=NULL; + int i = 0; + + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_abort()\n"); + + if (!SCpnt) { + printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid Scsi_Cmnd.\n"); + return (FAILED); + } + + tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata; + if (tw_dev == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid device extension.\n"); + return (FAILED); + } + + spin_lock(&tw_dev->tw_lock); + tw_dev->num_aborts++; + + /* If the command hasn't been posted yet, we can do the abort */ + for (i=0;isrb[i] == SCpnt) { + if (tw_dev->state[i] == TW_S_STARTED) { + printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Abort succeeded for started Scsi_Cmnd 0x%x\n", (u32)tw_dev->srb[i]); + tw_dev->state[i] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, i); + spin_unlock(&tw_dev->tw_lock); + return (SUCCESS); + } + if (tw_dev->state[i] == TW_S_PENDING) { + printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Abort succeeded for pending Scsi_Cmnd 0x%x\n", (u32)tw_dev->srb[i]); + if (tw_dev->pending_head == TW_Q_LENGTH-1) { + tw_dev->pending_head = TW_Q_START; + } else { + tw_dev->pending_head = tw_dev->pending_head + 1; + } + tw_dev->pending_request_count--; + tw_dev->state[i] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, i); + spin_unlock(&tw_dev->tw_lock); + return (SUCCESS); + } + } + } + + /* If the command has already been posted, we have to reset the card */ + printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Abort failed for unknown Scsi_Cmnd 0x%x, resetting card %d.\n", (u32)SCpnt, tw_dev->host->host_no); + + if (tw_reset_device_extension(tw_dev)) { + printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Reset failed for card %d.\n", tw_dev->host->host_no); + spin_unlock(&tw_dev->tw_lock); + return (FAILED); + } + spin_unlock(&tw_dev->tw_lock); + + return (SUCCESS); +} /* End tw_scsi_eh_abort() */ + +/* This is the new scsi eh reset function */ +int tw_scsi_eh_reset(Scsi_Cmnd *SCpnt) +{ + TW_Device_Extension *tw_dev=NULL; + int flags = 0; + + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_reset()\n"); + + if (!SCpnt) { + printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid Scsi_Cmnd.\n"); + return (FAILED); + } + + tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata; + if (tw_dev == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid device extension.\n"); + return (FAILED); + } + + spin_lock_irqsave(&tw_dev->tw_lock, flags); + tw_dev->num_resets++; + + /* Now reset the card and some of the device extension data */ + if (tw_reset_device_extension(tw_dev)) { + printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Reset failed for card %d.\n", tw_dev->host->host_no); + spin_unlock_irqrestore(&tw_dev->tw_lock, flags); + return (FAILED); + } + printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Reset succeeded for card %d.\n", tw_dev->host->host_no); + spin_unlock_irqrestore(&tw_dev->tw_lock, flags); + + return (SUCCESS); +} /* End tw_scsi_eh_reset() */ + +/* This function handles input and output from /proc/scsi/3w-xxxx/x */ +int tw_scsi_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout) +{ + TW_Device_Extension *tw_dev = NULL; + TW_Info info; + int i; + int j; + + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_proc_info()\n"); + + /* Find the correct device extension */ + for (i=0;ihost->host_no == hostno) + tw_dev = tw_device_extension_list[i]; + if (tw_dev == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_scsi_proc_info(): Couldn't locate device extension.\n"); + return (-EINVAL); + } + + info.buffer = buffer; + info.length = length; + info.offset = offset; + info.position = 0; + + if (inout) { + /* Write */ + if (strncmp(buffer, "debug", 5) == 0) { + printk(KERN_INFO "3w-xxxx: Posted commands:\n"); + for (j=0;jstate[j] == TW_S_POSTED) { + TW_Command *command = (TW_Command *)tw_dev->command_packet_virtual_address[j]; + printk(KERN_INFO "3w-xxxx: Request_id: %d\n", j); + printk(KERN_INFO "Opcode: 0x%x\n", command->byte0.opcode); + printk(KERN_INFO "Block_count: 0x%x\n", command->byte6.block_count); + printk(KERN_INFO "LBA: 0x%x\n", (u32)command->byte8.io.lba); + printk(KERN_INFO "Physical command packet addr: 0x%x\n", tw_dev->command_packet_physical_address[j]); + printk(KERN_INFO "Scsi_Cmnd: 0x%x\n", (u32)tw_dev->srb[j]); + } + } + printk(KERN_INFO "3w-xxxx: Free_head: %3d\n", tw_dev->free_head); + printk(KERN_INFO "3w-xxxx: Free_tail: %3d\n", tw_dev->free_tail); + } + return length; + } else { + /* Read */ + if (start) { + *start = buffer; + } + tw_copy_info(&info, "scsi%d: 3ware Storage Controller\n", hostno); + tw_copy_info(&info, "Driver version: %s\n", tw_driver_version); + tw_copy_info(&info, "Current commands posted: %3d\n", tw_dev->posted_request_count); + tw_copy_info(&info, "Max commands posted: %3d\n", tw_dev->max_posted_request_count); + tw_copy_info(&info, "Current pending commands: %3d\n", tw_dev->pending_request_count); + tw_copy_info(&info, "Max pending commands: %3d\n", tw_dev->max_pending_request_count); + tw_copy_info(&info, "Last sgl length: %3d\n", tw_dev->sgl_entries); + tw_copy_info(&info, "Max sgl length: %3d\n", tw_dev->max_sgl_entries); + tw_copy_info(&info, "Last sector count: %3d\n", tw_dev->sector_count); + tw_copy_info(&info, "Max sector count: %3d\n", tw_dev->max_sector_count); + tw_copy_info(&info, "Resets: %3d\n", tw_dev->num_resets); + tw_copy_info(&info, "Aborts: %3d\n", tw_dev->num_aborts); + } + if (info.position > info.offset) { + return (info.position - info.offset); + } else { + return 0; + } +} /* End tw_scsi_proc_info() */ + +/* This is the main scsi queue function to handle scsi opcodes */ +int tw_scsi_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) +{ + unsigned char *command = SCpnt->cmnd; + int request_id = 0; + int error = 0; + int flags = 0; + TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata; + + spin_lock_irqsave(&tw_dev->tw_lock, flags); + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue()\n"); + + /* Skip scsi command if it isn't for us */ + if ((tw_dev->is_unit_present[SCpnt->target] == FALSE) || (SCpnt->lun != 0)) { + SCpnt->result = (DID_BAD_TARGET << 16); + done(SCpnt); + spin_unlock_irqrestore(&tw_dev->tw_lock, flags); + return 0; + } + if (done == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_scsi_queue(): Invalid done function.\n"); + SCpnt->result = (DID_ERROR << 16); + done(SCpnt); + spin_unlock_irqrestore(&tw_dev->tw_lock, flags); + return 0; + } + if (tw_dev == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_scsi_queue(): Invalid device extension.\n"); + SCpnt->result = (DID_ERROR << 16); + done(SCpnt); + spin_unlock_irqrestore(&tw_dev->tw_lock, flags); + return 0; + } + + /* Save done function into Scsi_Cmnd struct */ + SCpnt->scsi_done = done; + + /* Queue the command and get a request id */ + tw_state_request_start(tw_dev, &request_id); + + /* Save the scsi command for use by the ISR */ + tw_dev->srb[request_id] = SCpnt; + + switch (*command) { + case READ_10: + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_10.\n"); + case READ_6: + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_6.\n"); + case WRITE_10: + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught WRITE_10.\n"); + case WRITE_6: + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught WRITE_6.\n"); + error = tw_scsiop_read_write(tw_dev, request_id); + break; + case TEST_UNIT_READY: + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n"); + error = tw_scsiop_test_unit_ready(tw_dev, request_id); + break; + case INQUIRY: + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n"); + error = tw_scsiop_inquiry(tw_dev, request_id); + break; + case READ_CAPACITY: + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n"); + error = tw_scsiop_read_capacity(tw_dev, request_id); + break; + case TW_IOCTL: + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TW_SCSI_IOCTL.\n"); + error = tw_ioctl(tw_dev, request_id); + break; + default: + printk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): Unknown scsi opcode: 0x%x\n", *command); + tw_dev->state[request_id] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, request_id); + SCpnt->result = (DID_BAD_TARGET << 16); + done(SCpnt); + } + if (error) { + tw_dev->state[request_id] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, request_id); + SCpnt->result = (DID_ERROR << 16); + done(SCpnt); + } + spin_unlock_irqrestore(&tw_dev->tw_lock, flags); + + return 0; +} /* End tw_scsi_queue() */ + +/* This function will release the resources on an rmmod call */ +int tw_scsi_release(struct Scsi_Host *tw_host) +{ + TW_Device_Extension *tw_dev; + tw_dev = (TW_Device_Extension *)tw_host->hostdata; + + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_release()\n"); + + /* Free up the IO region */ + release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE); + + /* Free up the IRQ */ + free_irq(tw_dev->tw_pci_dev->irq, tw_dev); + + /* Free up device extension resources */ + tw_free_device_extension(tw_dev); + + /* Tell kernel scsi-layer we are gone */ + scsi_unregister(tw_host); + + return 0; +} /* End tw_scsi_release() */ + +/* This function handles scsi inquiry commands */ +int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id) +{ + TW_Param *param; + TW_Command *command_packet; + u32 command_que_value, command_que_addr; + u32 param_value; + + dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry()\n"); + + /* Initialize command packet */ + command_que_addr = tw_dev->registers.command_que_addr; + command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id]; + if (command_packet == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet virtual address.\n"); + return 1; + } + memset(command_packet, 0, sizeof(TW_Sector)); + command_packet->byte0.opcode = TW_OP_GET_PARAM; + command_packet->byte0.sgl_offset = 2; + command_packet->size = 4; + command_packet->request_id = request_id; + command_packet->byte3.unit = 0; + command_packet->byte3.host_id = 0; + command_packet->status = 0; + command_packet->flags = 0; + command_packet->byte6.parameter_count = 1; + + /* Now setup the param */ + if (tw_dev->alignment_virtual_address[request_id] == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment virtual address.\n"); + return 1; + } + param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; + memset(param, 0, sizeof(TW_Sector)); + param->table_id = 3; /* unit summary table */ + param->parameter_id = 3; /* unitsstatus parameter */ + param->parameter_size_bytes = TW_MAX_UNITS; + param_value = tw_dev->alignment_physical_address[request_id]; + if (param_value == 0) { + printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment physical address.\n"); + return 1; + } + + command_packet->byte8.param.sgl[0].address = param_value; + command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector); + command_que_value = tw_dev->command_packet_physical_address[request_id]; + if (command_que_value == 0) { + printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet physical address.\n"); + return 1; + } + + /* Now try to post the command packet */ + tw_post_command_packet(tw_dev, request_id); + + return 0; +} /* End tw_scsiop_inquiry() */ + +/* This function is called by the isr to complete an inquiry command */ +int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id) +{ + unsigned char *is_unit_present; + unsigned char *request_buffer; + int i; + TW_Param *param; + + dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n"); + + /* Fill request buffer */ + if (tw_dev->srb[request_id]->request_buffer == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Request buffer NULL.\n"); + return 1; + } + request_buffer = tw_dev->srb[request_id]->request_buffer; + memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen); + request_buffer[0] = TYPE_DISK; /* Peripheral device type */ + request_buffer[1] = 0; /* Device type modifier */ + request_buffer[2] = 0; /* No ansi/iso compliance */ + request_buffer[4] = 31; /* Additional length */ + memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */ + memcpy(&request_buffer[16], "3w-xxxx ", 16); /* Product ID */ + memcpy(&request_buffer[32], tw_driver_version, 3); + + param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; + if (param == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Bad alignment virtual address.\n"); + return 1; + } + is_unit_present = &(param->data[0]); + + for (i=0 ; iis_unit_present[i] = FALSE; + } else { + tw_dev->is_unit_present[i] = TRUE; + dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete: Unit %d found.\n", i); + } + } + + return 0; +} /* End tw_scsiop_inquiry_complete() */ + +/* This function handles scsi read_capacity commands */ +int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id) +{ + TW_Param *param; + TW_Command *command_packet; + u32 command_que_addr, command_que_value; + u32 param_value; + + dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity()\n"); + + /* Initialize command packet */ + command_que_addr = tw_dev->registers.command_que_addr; + command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id]; + + if (command_packet == NULL) { + dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet virtual address.\n"); + return 1; + } + memset(command_packet, 0, sizeof(TW_Sector)); + command_packet->byte0.opcode = TW_OP_GET_PARAM; + command_packet->byte0.sgl_offset = 2; + command_packet->size = 4; + command_packet->request_id = request_id; + command_packet->byte3.unit = tw_dev->srb[request_id]->target; + command_packet->byte3.host_id = 0; + command_packet->status = 0; + command_packet->flags = 0; + command_packet->byte6.block_count = 1; + + /* Now setup the param */ + if (tw_dev->alignment_virtual_address[request_id] == NULL) { + dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment virtual address.\n"); + return 1; + } + param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; + memset(param, 0, sizeof(TW_Sector)); + param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + + tw_dev->srb[request_id]->target; + param->parameter_id = 4; /* unitcapacity parameter */ + param->parameter_size_bytes = 4; + param_value = tw_dev->alignment_physical_address[request_id]; + if (param_value == 0) { + dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment physical address.\n"); + return 1; + } + + command_packet->byte8.param.sgl[0].address = param_value; + command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector); + command_que_value = tw_dev->command_packet_physical_address[request_id]; + if (command_que_value == 0) { + dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet physical address.\n"); + return 1; + } + + /* Now try to post the command to the board */ + tw_post_command_packet(tw_dev, request_id); + + return 0; +} /* End tw_scsiop_read_capacity() */ + +/* This function is called by the isr to complete a readcapacity command */ +int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id) +{ + unsigned char *param_data; + u32 capacity; + char *buff; + TW_Param *param; + + dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n"); + + buff = tw_dev->srb[request_id]->request_buffer; + if (buff == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Request buffer NULL.\n"); + return 1; + } + memset(buff, 0, tw_dev->srb[request_id]->request_bufflen); + param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; + if (param == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n"); + return 1; + } + param_data = &(param->data[0]); + + capacity = (param_data[3] << 24) | (param_data[2] << 16) | + (param_data[1] << 8) | param_data[0]; + + dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete(): Capacity = 0x%x.\n", capacity); + + /* Number of LBA's */ + buff[0] = (capacity >> 24); + buff[1] = (capacity >> 16) & 0xff; + buff[2] = (capacity >> 8) & 0xff; + buff[3] = capacity & 0xff; + + /* Block size in bytes (512) */ + buff[4] = (TW_BLOCK_SIZE >> 24); + buff[5] = (TW_BLOCK_SIZE >> 16) & 0xff; + buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff; + buff[7] = TW_BLOCK_SIZE & 0xff; + + return 0; +} /* End tw_scsiop_read_capacity_complete() */ + +/* This function handles scsi read or write commands */ +int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id) +{ + TW_Command *command_packet; + u32 command_que_addr, command_que_value = 0; + u32 lba = 0x0, num_sectors = 0x0; + int i; + Scsi_Cmnd *srb; + struct scatterlist *sglist; + + dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n"); + + if (tw_dev->srb[request_id]->request_buffer == NULL) { + printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Request buffer NULL.\n"); + return 1; + } + sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer; + srb = tw_dev->srb[request_id]; + + /* Initialize command packet */ + command_que_addr = tw_dev->registers.command_que_addr; + command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id]; + if (command_packet == NULL) { + dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): Bad command packet virtual address.\n"); + return 1; + } + + if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == READ_10) { + command_packet->byte0.opcode = TW_OP_READ; + } else { + command_packet->byte0.opcode = TW_OP_WRITE; + } + + command_packet->byte0.sgl_offset = 3; + command_packet->size = 5; + command_packet->request_id = request_id; + command_packet->byte3.unit = srb->target; + command_packet->byte3.host_id = 0; + command_packet->status = 0; + command_packet->flags = 0; + + if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) { + lba = ((u32)srb->cmnd[1] << 16) | ((u32)srb->cmnd[2] << 8) | (u32)srb->cmnd[3]; + num_sectors = (u32)srb->cmnd[4]; + } else { + lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | + ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5]; + num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8); + } + + /* Update sector statistic */ + tw_dev->sector_count = num_sectors; + if (tw_dev->sector_count > tw_dev->max_sector_count) + tw_dev->max_sector_count = tw_dev->sector_count; + + dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): lba = 0x%x num_sectors = 0x%x\n", lba, num_sectors); + command_packet->byte8.io.lba = lba; + command_packet->byte6.block_count = num_sectors; + + /* Do this if there are no sg list entries */ + if (tw_dev->srb[request_id]->use_sg == 0) { + dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): SG = 0\n"); + command_packet->byte8.io.sgl[0].address = virt_to_bus(tw_dev->srb[request_id]->request_buffer); + command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen; + } + + /* Do this if we have multiple sg list entries */ + if (tw_dev->srb[request_id]->use_sg > 0) { + for (i=0;isrb[request_id]->use_sg; i++) { + command_packet->byte8.io.sgl[i].address = virt_to_bus(sglist[i].address); + command_packet->byte8.io.sgl[i].length = sglist[i].length; + command_packet->size+=2; + } + if (tw_dev->srb[request_id]->use_sg > 1) + command_packet->size-=2; + } + + /* Update SG statistics */ + tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg; + if (tw_dev->sgl_entries > tw_dev->max_sgl_entries) + tw_dev->max_sgl_entries = tw_dev->sgl_entries; + + command_que_value = tw_dev->command_packet_physical_address[request_id]; + if (command_que_value == 0) { + dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Bad command packet physical address.\n"); + return 1; + } + + /* Now try to post the command to the board */ + tw_post_command_packet(tw_dev, request_id); + + return 0; +} /* End tw_scsiop_read_write() */ + +/* This function will handle test unit ready scsi command */ +int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id) +{ + dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_test_unit_ready()\n"); + + /* Tell the scsi layer were done */ + tw_dev->state[request_id] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, request_id); + tw_dev->srb[request_id]->result = (DID_OK << 16); + tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); + + return 0; +} /* End tw_scsiop_test_unit_ready() */ + +/* This function will setup the interrupt handler */ +int tw_setup_irq(TW_Device_Extension *tw_dev) +{ + char *device = TW_DEVICE_NAME; + int error; + + dprintk(KERN_NOTICE "3w-xxxx: tw_setup_irq()\n"); + error = request_irq(tw_dev->tw_pci_dev->irq, tw_interrupt, SA_SHIRQ, device, tw_dev); + + if (error < 0) { + printk(KERN_WARNING "3w-xxxx: tw_setup_irq(): Error requesting IRQ: %d for card %d.\n", tw_dev->tw_pci_dev->irq, tw_dev->host->host_no); + return 1; + } + return 0; +} /* End tw_setup_irq() */ + +/* This function will soft reset the controller */ +void tw_soft_reset(TW_Device_Extension *tw_dev) +{ + u32 control_reg_addr, control_reg_value; + + control_reg_addr = tw_dev->registers.control_reg_addr; + control_reg_value = ( TW_CONTROL_ISSUE_SOFT_RESET | + TW_CONTROL_CLEAR_HOST_INTERRUPT | + TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | + TW_CONTROL_MASK_COMMAND_INTERRUPT | + TW_CONTROL_MASK_RESPONSE_INTERRUPT | + TW_CONTROL_CLEAR_ERROR_STATUS | + TW_CONTROL_DISABLE_INTERRUPTS); + outl(control_reg_value, control_reg_addr); +} /* End tw_soft_reset() */ + +/* This function will free a request_id */ +int tw_state_request_finish(TW_Device_Extension *tw_dev, int request_id) +{ + dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish()\n"); + + do { + if (tw_dev->free_tail == TW_Q_LENGTH-1) { + tw_dev->free_tail = TW_Q_START; + } else { + tw_dev->free_tail = tw_dev->free_tail + 1; + } + } while ((tw_dev->state[tw_dev->free_queue[tw_dev->free_tail]] != TW_S_COMPLETED)); + + tw_dev->free_queue[tw_dev->free_tail] = request_id; + + tw_dev->state[request_id] = TW_S_FINISHED; + dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish(): Freeing request_id %d\n", request_id); + + return 0; +} /* End tw_state_request_finish() */ + +/* This function will assign an available request_id */ +int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id) +{ + int id = 0; + + dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start()\n"); + + /* Obtain next free request_id */ + do { + if (tw_dev->free_head == TW_Q_LENGTH - 1) { + tw_dev->free_head = TW_Q_START; + } else { + tw_dev->free_head = tw_dev->free_head + 1; + } + } while ((tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_STARTED) || + (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_POSTED) || + (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_PENDING) || + (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_COMPLETED)); + + id = tw_dev->free_queue[tw_dev->free_head]; + + if (tw_dev->free_head == TW_Q_LENGTH - 1) { + tw_dev->free_head = TW_Q_START; + } else { + tw_dev->free_head = tw_dev->free_head + 1; + } + + dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start(): id = %d.\n", id); + *request_id = id; + tw_dev->state[id] = TW_S_STARTED; + + return 0; +} /* End tw_state_request_start() */ + +/* This function will unmask the command interrupt on the controller */ +void tw_unmask_command_interrupt(TW_Device_Extension *tw_dev) +{ + u32 control_reg_addr, control_reg_value; + + control_reg_addr = tw_dev->registers.control_reg_addr; + control_reg_value = TW_CONTROL_UNMASK_COMMAND_INTERRUPT; + outl(control_reg_value, control_reg_addr); +} /* End tw_unmask_command_interrupt() */ + +/* Now get things going */ + +#ifdef MODULE +Scsi_Host_Template driver_template = TWXXXX; +#include "scsi_module.c" +#endif diff -ur --new-file old/linux/drivers/scsi/3w-xxxx.h new/linux/drivers/scsi/3w-xxxx.h --- old/linux/drivers/scsi/3w-xxxx.h Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/scsi/3w-xxxx.h Fri Jan 28 17:03:11 2000 @@ -0,0 +1,369 @@ +/* + 3w-xxxx.h -- 3ware Storage Controller device driver for Linux. + + Written By: Adam Radford + Copyright (C) 1999 3ware Inc. + + Kernel compatablity By: Andre Hedrick + Non-Copyright (C) 2000 Andre Hedrick + + 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. + + NO WARRANTY + THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT + LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is + solely responsible for determining the appropriateness of using and + distributing the Program and assumes all risks associated with its + exercise of rights under this Agreement, including but not limited to + the risks and costs of program errors, damage to or loss of data, + programs or equipment, and unavailability or interruption of operations. + + DISCLAIMER OF LIABILITY + NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED + HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES + + 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 + + Bugs/Comments/Suggestions should be mailed to: + linux@3ware.com + + For more information, goto: + http://www.3ware.com +*/ + +#ifndef _3W_XXXX_H +#define _3W_XXXX_H + +#include +#include +#include + +/* Control register bit definitions */ +#define TW_CONTROL_CLEAR_HOST_INTERRUPT 0x00080000 +#define TW_CONTROL_CLEAR_ATTENTION_INTERRUPT 0x00040000 +#define TW_CONTROL_MASK_COMMAND_INTERRUPT 0x00020000 +#define TW_CONTROL_MASK_RESPONSE_INTERRUPT 0x00010000 +#define TW_CONTROL_UNMASK_COMMAND_INTERRUPT 0x00008000 +#define TW_CONTROL_UNMASK_RESPONSE_INTERRUPT 0x00004000 +#define TW_CONTROL_CLEAR_ERROR_STATUS 0x00000200 +#define TW_CONTROL_ISSUE_SOFT_RESET 0x00000100 +#define TW_CONTROL_ENABLE_INTERRUPTS 0x00000080 +#define TW_CONTROL_DISABLE_INTERRUPTS 0x00000040 +#define TW_CONTROL_ISSUE_HOST_INTERRUPT 0x00000020 + +/* Status register bit definitions */ +#define TW_STATUS_MAJOR_VERSION_MASK 0xF0000000 +#define TW_STATUS_MINOR_VERSION_MASK 0x0F000000 +#define TW_STATUS_PCI_PARITY_ERROR 0x00800000 +#define TW_STATUS_QUEUE_ERROR 0x00400000 +#define TW_STATUS_MICROCONTROLLER_ERROR 0x00200000 +#define TW_STATUS_PCI_ABORT 0x00100000 +#define TW_STATUS_HOST_INTERRUPT 0x00080000 +#define TW_STATUS_ATTENTION_INTERRUPT 0x00040000 +#define TW_STATUS_COMMAND_INTERRUPT 0x00020000 +#define TW_STATUS_RESPONSE_INTERRUPT 0x00010000 +#define TW_STATUS_COMMAND_QUEUE_FULL 0x00008000 +#define TW_STATUS_RESPONSE_QUEUE_EMPTY 0x00004000 +#define TW_STATUS_MICROCONTROLLER_READY 0x00002000 +#define TW_STATUS_COMMAND_QUEUE_EMPTY 0x00001000 +#define TW_STATUS_ALL_INTERRUPTS 0x000F0000 +#define TW_STATUS_CLEARABLE_BITS 0x00D00000 +#define TW_STATUS_EXPECTED_BITS 0x00002000 +#define TW_STATUS_UNEXPECTED_BITS 0x00F80000 + +/* RESPONSE QUEUE BIT DEFINITIONS */ +#define TW_RESPONSE_ID_MASK 0x00000FF0 + +/* PCI related defines */ +#define TW_IO_ADDRESS_RANGE 0xD +#define TW_DEVICE_NAME "3ware Storage Controller" +#define TW_VENDOR_ID (0x13C1) /* 3ware */ +#define TW_DEVICE_ID (0x1000) /* Storage Controller */ + +/* Command packet opcodes */ +#define TW_OP_NOP 0x0 +#define TW_OP_INIT_CONNECTION 0x1 +#define TW_OP_READ 0x2 +#define TW_OP_WRITE 0x3 +#define TW_OP_VERIFY 0x4 +#define TW_OP_GET_PARAM 0x12 +#define TW_OP_SET_PARAM 0x13 +#define TW_OP_SECTOR_INFO 0x1a +#define TW_OP_AEN_LISTEN 0x1c + +/* Asynchronous Event Notification (AEN) Codes */ +#define TW_AEN_QUEUE_EMPTY 0x0000 +#define TW_AEN_SOFT_RESET 0x0001 +#define TW_AEN_DEGRADED_MIRROR 0x0002 +#define TW_AEN_CONTROLLER_ERROR 0x0003 +#define TW_AEN_REBUILD_FAIL 0x0004 +#define TW_AEN_REBUILD_DONE 0x0005 +#define TW_AEN_QUEUE_FULL 0x00ff +#define TW_AEN_TABLE_UNDEFINED 0x15 + +/* Misc defines */ +#define TW_ALIGNMENT 0x200 /* 16 D-WORDS */ +#define TW_MAX_UNITS 16 +#define TW_COMMAND_ALIGNMENT_MASK 0x1ff +#define TW_INIT_MESSAGE_CREDITS 0x100 +#define TW_INIT_COMMAND_PACKET_SIZE 0x3 +#define TW_POLL_MAX_RETRIES 10000 +#define TW_MAX_SGL_LENGTH 62 +#define TW_Q_LENGTH 256 +#define TW_Q_START 0 +#define TW_MAX_SLOT 32 +#define TW_MAX_PCI_BUSES 255 +#define TW_MAX_RESET_TRIES 3 +#define TW_UNIT_INFORMATION_TABLE_BASE 0x300 +#define TW_MAX_CMDS_PER_LUN (TW_Q_LENGTH-2)/TW_MAX_UNITS +#define TW_BLOCK_SIZE 0x200 /* 512-byte blocks */ +#define TW_IOCTL 0x80 +#define TW_MAX_AEN_TRIES 100 + +#define TW_IN_INTR 1 + +/* Macros */ +#define TW_STATUS_ERRORS(x) \ + (((x & TW_STATUS_PCI_ABORT) || \ + (x & TW_STATUS_PCI_PARITY_ERROR) || \ + (x & TW_STATUS_QUEUE_ERROR) || \ + (x & TW_STATUS_MICROCONTROLLER_ERROR)) && \ + (x & TW_STATUS_MICROCONTROLLER_READY)) + +#ifdef TW_DEBUG +#define dprintk(msg...) printk(msg) +#else +#define dprintk(msg...) do { } while(0); +#endif + +/* Scatter Gather List Entry */ +typedef struct TAG_TW_SG_Entry { + unsigned long address; + unsigned long length; +} TW_SG_Entry; + +typedef unsigned char TW_Sector[512]; + +/* Command Packet */ +typedef struct TW_Command { + /* First DWORD */ + struct { + unsigned char opcode:5; + unsigned char sgl_offset:3; + } byte0; + unsigned char size; + unsigned char request_id; + struct { + unsigned char unit:4; + unsigned char host_id:4; + } byte3; + /* Second DWORD */ + unsigned char status; + unsigned char flags; + union { + unsigned short block_count; + unsigned short parameter_count; + unsigned short message_credits; + } byte6; + union { + struct { + unsigned long lba; + TW_SG_Entry sgl[TW_MAX_SGL_LENGTH]; + unsigned long padding; /* pad to 512 bytes */ + } io; + struct { + TW_SG_Entry sgl[TW_MAX_SGL_LENGTH]; + unsigned long padding[2]; + } param; + struct { + unsigned long response_queue_pointer; + unsigned long padding[125]; + } init_connection; + struct { + char version[504]; + } ioctl_miniport_version; + } byte8; +} TW_Command; + +typedef struct TAG_TW_Ioctl { + int buffer; + unsigned char opcode; + unsigned short table_id; + unsigned char parameter_id; + unsigned char parameter_size_bytes; + unsigned char data[1]; +} TW_Ioctl; + +/* GetParam descriptor */ +typedef struct { + unsigned short table_id; + unsigned char parameter_id; + unsigned char parameter_size_bytes; + unsigned char data[1]; +} TW_Param, *PTW_Param; + +/* Response queue */ +typedef union TAG_TW_Response_Queue { + struct { + u32 undefined_1: 4; + u32 response_id: 8; + u32 undefined_2: 20; + } u; + u32 value; +} TW_Response_Queue; + +typedef struct TAG_TW_Registers { + u32 base_addr; + u32 control_reg_addr; + u32 status_reg_addr; + u32 command_que_addr; + u32 response_que_addr; +} TW_Registers; + +typedef struct TAG_TW_Info { + char *buffer; + int length; + int offset; + int position; +} TW_Info; + +typedef enum TAG_TW_Cmd_State { + TW_S_INITIAL, /* Initial state */ + TW_S_STARTED, /* Id in use */ + TW_S_POSTED, /* Posted to the controller */ + TW_S_PENDING, /* Waiting to be posted in isr */ + TW_S_COMPLETED, /* Completed by isr */ + TW_S_FINISHED, /* I/O completely done */ +} TW_Cmd_State; + +typedef struct TAG_TW_Device_Extension { + TW_Registers registers; + u32 *alignment_virtual_address[TW_Q_LENGTH]; + u32 alignment_physical_address[TW_Q_LENGTH]; + int is_unit_present[TW_MAX_UNITS]; + int num_units; + u32 *command_packet_virtual_address[TW_Q_LENGTH]; + u32 command_packet_physical_address[TW_Q_LENGTH]; + struct pci_dev *tw_pci_dev; + Scsi_Cmnd *srb[TW_Q_LENGTH]; + unsigned char free_queue[TW_Q_LENGTH]; + unsigned char free_head; + unsigned char free_tail; + unsigned char pending_queue[TW_Q_LENGTH]; + unsigned char pending_head; + unsigned char pending_tail; + TW_Cmd_State state[TW_Q_LENGTH]; + u32 posted_request_count; + u32 max_posted_request_count; + u32 request_count_marked_pending; + u32 pending_request_count; + u32 max_pending_request_count; + u32 max_sgl_entries; + u32 sgl_entries; + u32 num_aborts; + u32 num_resets; + u32 sector_count; + u32 max_sector_count; + struct Scsi_Host *host; + spinlock_t tw_lock; + unsigned char ioctl_size[TW_Q_LENGTH]; + unsigned short aen_queue[TW_Q_LENGTH]; + unsigned char aen_head; + unsigned char aen_tail; + u32 flags; +} TW_Device_Extension; + +/* Function prototypes */ +int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id); +int tw_aen_drain_queue(TW_Device_Extension *tw_dev); +int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id); +int tw_allocate_memory(TW_Device_Extension *tw_dev, int request_id, int size, int which); +int tw_check_bits(u32 status_reg_value); +int tw_check_errors(TW_Device_Extension *tw_dev); +void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev); +void tw_clear_host_interrupt(TW_Device_Extension *tw_dev); +void tw_disable_interrupts(TW_Device_Extension *tw_dev); +int tw_empty_response_que(TW_Device_Extension *tw_dev); +void tw_enable_interrupts(TW_Device_Extension *tw_dev); +int tw_findcards(Scsi_Host_Template *tw_host); +void tw_free_device_extension(TW_Device_Extension *tw_dev); +int tw_initconnection(TW_Device_Extension *tw_dev); +int tw_initialize_device_extension(TW_Device_Extension *tw_dev); +int tw_initialize_units(TW_Device_Extension *tw_dev); +int tw_ioctl(TW_Device_Extension *tw_dev, int request_id); +int tw_ioctl_complete(TW_Device_Extension *tw_dev, int request_id); +void tw_mask_command_interrupt(TW_Device_Extension *tw_dev); +int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds); +int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id); +int tw_reset_device_extension(TW_Device_Extension *tw_dev); +int tw_reset_sequence(TW_Device_Extension *tw_dev); +int tw_scsi_biosparam(Disk *disk, kdev_t dev, int geom[]); +int tw_scsi_detect(Scsi_Host_Template *tw_host); +int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt); +int tw_scsi_eh_reset(Scsi_Cmnd *SCpnt); +int tw_scsi_proc_info(char *buffer, char **start, off_t offset, int length, int inode, int inout); +int tw_scsi_queue(Scsi_Cmnd *cmd, void (*done) (Scsi_Cmnd *)); +int tw_scsi_release(struct Scsi_Host *tw_host); +int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id); +int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id); +int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id); +int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id); +int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id); +int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id); +int tw_setup_irq(TW_Device_Extension *tw_dev); +void tw_soft_reset(TW_Device_Extension *tw_dev); +int tw_state_request_finish(TW_Device_Extension *tw_dev,int request_id); +int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id); +void tw_unmask_command_interrupt(TW_Device_Extension *tw_dev); + +#if defined(HOSTS_C) || defined(MODULE) +/* Scsi_Host_Template Initializer */ +#define TWXXXX { \ + next : NULL, \ + module : NULL, \ + proc_name : "3w-xxxx", \ + proc_info : tw_scsi_proc_info, \ + name : "3ware Storage Controller", \ + detect : tw_scsi_detect, \ + release : tw_scsi_release, \ + info : NULL, \ + ioctl : NULL, \ + command : NULL, \ + queuecommand : tw_scsi_queue, \ + eh_strategy_handler : NULL, \ + eh_abort_handler : tw_scsi_eh_abort, \ + eh_device_reset_handler : NULL, \ + eh_bus_reset_handler : NULL, \ + eh_host_reset_handler : tw_scsi_eh_reset, \ + abort : NULL, \ + reset : NULL, \ + slave_attach : NULL, \ + bios_param : tw_scsi_biosparam, \ + can_queue : TW_Q_LENGTH, \ + this_id: -1, \ + sg_tablesize : TW_MAX_SGL_LENGTH, \ + cmd_per_lun: TW_MAX_CMDS_PER_LUN, \ + present : 0, \ + unchecked_isa_dma : 0, \ + use_clustering : ENABLE_CLUSTERING, \ + use_new_eh_code : 1, \ + emulated : 1 \ +} +#endif /* HOSTS_C */ +#endif /* _3W_XXXX_H */ diff -ur --new-file old/linux/drivers/scsi/53c7xx.c new/linux/drivers/scsi/53c7xx.c --- old/linux/drivers/scsi/53c7xx.c Wed Sep 8 20:51:21 1999 +++ new/linux/drivers/scsi/53c7xx.c Mon Jan 24 20:04:37 2000 @@ -245,7 +245,6 @@ #include #include #include -#include #include #include #include diff -ur --new-file old/linux/drivers/scsi/Config.in new/linux/drivers/scsi/Config.in --- old/linux/drivers/scsi/Config.in Wed Dec 15 05:43:56 1999 +++ new/linux/drivers/scsi/Config.in Mon Jan 24 20:24:50 2000 @@ -30,9 +30,9 @@ dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then bool ' Enable Tagged Command Queueing (TCQ) by default' CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT - int 'Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 8 + int ' Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 8 bool ' Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS - int 'Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5 + int ' Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5 fi dep_tristate 'IBM ServeRAID support' CONFIG_SCSI_IPS $CONFIG_SCSI dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI @@ -49,7 +49,7 @@ if [ "$CONFIG_SCSI_EATA" != "n" ]; then bool ' enable tagged command queueing' CONFIG_SCSI_EATA_TAGGED_QUEUE bool ' enable elevator sorting' CONFIG_SCSI_EATA_LINKED_COMMANDS - int 'maximum number of queued commands' CONFIG_SCSI_EATA_MAX_TAGS 16 + int ' maximum number of queued commands' CONFIG_SCSI_EATA_MAX_TAGS 16 fi dep_tristate 'EATA-DMA [Obsolete] (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) support' CONFIG_SCSI_EATA_DMA $CONFIG_SCSI dep_tristate 'EATA-PIO (old DPT PM2001, PM2012A) support' CONFIG_SCSI_EATA_PIO $CONFIG_SCSI @@ -92,9 +92,9 @@ dep_tristate 'NCR53C8XX SCSI support' CONFIG_SCSI_NCR53C8XX $CONFIG_SCSI dep_tristate 'SYM53C8XX SCSI support' CONFIG_SCSI_SYM53C8XX $CONFIG_SCSI if [ "$CONFIG_SCSI_NCR53C8XX" != "n" -o "$CONFIG_SCSI_SYM53C8XX" != "n" ]; then - int 'default tagged command queue depth' CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS 8 - int 'maximum number of queued commands' CONFIG_SCSI_NCR53C8XX_MAX_TAGS 32 - int 'synchronous transfers frequency in MHz' CONFIG_SCSI_NCR53C8XX_SYNC 20 + int ' default tagged command queue depth' CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS 8 + int ' maximum number of queued commands' CONFIG_SCSI_NCR53C8XX_MAX_TAGS 32 + int ' synchronous transfers frequency in MHz' CONFIG_SCSI_NCR53C8XX_SYNC 20 bool ' enable profiling' CONFIG_SCSI_NCR53C8XX_PROFILE bool ' use normal IO' CONFIG_SCSI_NCR53C8XX_IOMAPPED if [ "$CONFIG_SCSI_SYM53C8XX" != "n" ]; then @@ -138,7 +138,7 @@ dep_tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F $CONFIG_SCSI if [ "$CONFIG_SCSI_U14_34F" != "n" ]; then bool ' enable elevator sorting' CONFIG_SCSI_U14_34F_LINKED_COMMANDS - int 'maximum number of queued commands' CONFIG_SCSI_U14_34F_MAX_TAGS 8 + int ' maximum number of queued commands' CONFIG_SCSI_U14_34F_MAX_TAGS 8 fi dep_tristate 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR $CONFIG_SCSI # @@ -155,7 +155,7 @@ if [ "$CONFIG_PPC" = "y" ]; then dep_tristate 'MESH (Power Mac internal SCSI) support' CONFIG_SCSI_MESH $CONFIG_SCSI if [ "$CONFIG_SCSI_MESH" != "n" ]; then - int 'maximum synchronous transfer rate (MB/s) (0 = async)' CONFIG_SCSI_MESH_SYNC_RATE 5 + int ' maximum synchronous transfer rate (MB/s) (0 = async)' CONFIG_SCSI_MESH_SYNC_RATE 5 fi dep_tristate '53C94 (Power Mac external SCSI) support' CONFIG_SCSI_MAC53C94 $CONFIG_SCSI fi @@ -165,4 +165,8 @@ if [ "$CONFIG_MIPS_JAZZ" = "y" ]; then bool 'MIPS JAZZ FAS216 SCSI support' CONFIG_JAZZ_ESP fi +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate '3Ware Hardware ATA-RAID support (EXPERIMENTAL)' CONFIG_BLK_DEV_3W_XXXX_RAID $CONFIG_SCSI +fi + endmenu diff -ur --new-file old/linux/drivers/scsi/Makefile new/linux/drivers/scsi/Makefile --- old/linux/drivers/scsi/Makefile Thu Dec 30 02:16:30 1999 +++ new/linux/drivers/scsi/Makefile Mon Jan 24 20:24:50 2000 @@ -41,7 +41,7 @@ endif L_OBJS += scsi_n_syms.o hosts.o scsi_ioctl.o constants.o scsicam.o L_OBJS += scsi_error.o scsi_obsolete.o scsi_queue.o scsi_lib.o - L_OBJS += scsi_merge.o scsi_proc.o + L_OBJS += scsi_merge.o scsi_proc.o scsi_dma.o scsi_scan.o else ifeq ($(CONFIG_SCSI),m) MIX_OBJS += scsi_syms.o @@ -675,6 +675,14 @@ L_OBJS += NCR53C9x.o sun3x_esp.o endif +ifeq ($(CONFIG_BLK_DEV_3W_XXXX_RAID),y) +L_OBJS += 3w-xxxx.o +else + ifeq ($(CONFIG_BLK_DEV_3W_XXXX_RAID),m) + M_OBJS += 3w-xxxx.o + endif +endif + include $(TOPDIR)/Rules.make 53c8xx_d.h: 53c7,8xx.scr script_asm.pl @@ -722,10 +730,11 @@ scsi_mod.o: $(MIX_OBJS) hosts.o scsi.o scsi_ioctl.o constants.o \ scsicam.o scsi_proc.o scsi_error.o scsi_obsolete.o \ - scsi_queue.o scsi_lib.o scsi_merge.o + scsi_queue.o scsi_lib.o scsi_merge.o scsi_dma.o scsi_scan.o $(LD) $(LD_RFLAG) -r -o $@ $(MIX_OBJS) hosts.o scsi.o scsi_ioctl.o \ constants.o scsicam.o scsi_proc.o scsi_merge.o \ - scsi_error.o scsi_obsolete.o scsi_queue.o scsi_lib.o + scsi_error.o scsi_obsolete.o scsi_queue.o scsi_lib.o \ + scsi_dma.o scsi_scan.o sr_mod.o: sr.o sr_ioctl.o sr_vendor.o $(LD) $(LD_RFLAG) -r -o $@ sr.o sr_ioctl.o sr_vendor.o diff -ur --new-file old/linux/drivers/scsi/a2091.c new/linux/drivers/scsi/a2091.c --- old/linux/drivers/scsi/a2091.c Fri Nov 12 01:57:30 1999 +++ new/linux/drivers/scsi/a2091.c Wed Jan 26 21:45:20 2000 @@ -188,9 +188,8 @@ { static unsigned char called = 0; struct Scsi_Host *instance; - caddr_t address; - unsigned int key; - const struct ConfigDev *cd; + unsigned long address; + struct zorro_dev *z = NULL; if (!MACH_IS_AMIGA || called) return 0; @@ -199,14 +198,19 @@ tpnt->proc_name = "A2091"; tpnt->proc_info = &wd33c93_proc_info; - while ((key = zorro_find(ZORRO_PROD_CBM_A590_A2091_1, 0, 0)) || - (key = zorro_find(ZORRO_PROD_CBM_A590_A2091_2, 0, 0))) { - cd = zorro_get_board(key); - address = cd->cd_BoardAddr; + while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { + if (z->id != ZORRO_PROD_CBM_A590_A2091_1 && + z->id != ZORRO_PROD_CBM_A590_A2091_2) + continue; + address = z->resource.start; + if (!request_mem_region(address, 256, "wd33c93")) + continue; + strcpy(z->name, "A590/A2091 SCSI Host Adapter"); + instance = scsi_register (tpnt, sizeof (struct WD33C93_hostdata)); - instance->base = (unsigned char *)ZTWO_VADDR(address); + instance->base = ZTWO_VADDR(address); instance->irq = IRQ_AMIGA_PORTS; - instance->unique_id = key; + instance->unique_id = z->slotaddr; DMA(instance)->DAWR = DAWR_A2091; wd33c93_init(instance, (wd33c93_regs *)&(DMA(instance)->SASR), dma_setup, dma_stop, WD33C93_FS_8_10); @@ -217,7 +221,6 @@ a2091_intr); } DMA(instance)->CNTR = CNTR_PDMD | CNTR_INTEN; - zorro_config_board(key, 0); } return num_a2091; @@ -239,7 +242,7 @@ { #ifdef MODULE DMA(instance)->CNTR = 0; - zorro_unconfig_board(instance->unique_id, 0); + release_mem_region(ZTWO_PADDR(instance->base), 256); if (--num_a2091 == 0) free_irq(IRQ_AMIGA_PORTS, a2091_intr); wd33c93_release(); diff -ur --new-file old/linux/drivers/scsi/a3000.c new/linux/drivers/scsi/a3000.c --- old/linux/drivers/scsi/a3000.c Fri Nov 12 01:57:30 1999 +++ new/linux/drivers/scsi/a3000.c Wed Jan 26 21:45:20 2000 @@ -175,7 +175,7 @@ tpnt->proc_info = &wd33c93_proc_info; a3000_host = scsi_register (tpnt, sizeof(struct WD33C93_hostdata)); - a3000_host->base = (unsigned char *)ZTWO_VADDR(0xDD0000); + a3000_host->base = ZTWO_VADDR(0xDD0000); a3000_host->irq = IRQ_AMIGA_PORTS; DMA(a3000_host)->DAWR = DAWR_A3000; wd33c93_init(a3000_host, (wd33c93_regs *)&(DMA(a3000_host)->SASR), diff -ur --new-file old/linux/drivers/scsi/aha1542.c new/linux/drivers/scsi/aha1542.c --- old/linux/drivers/scsi/aha1542.c Thu Dec 30 02:00:54 1999 +++ new/linux/drivers/scsi/aha1542.c Fri Jan 28 17:04:58 2000 @@ -21,8 +21,11 @@ * Modified by Chris Faulhaber * Added module command-line options * 19-Jul-99 + * Modified by Adam Fritzler + * Added proper detection of the AHA-1640 (MCA version of AHA-1540) */ +#include #include #include @@ -40,6 +43,8 @@ #include #include #include +#include + #include "scsi.h" #include "hosts.h" @@ -96,7 +101,7 @@ #define MAXBOARDS 4 /* Increase this and the sizes of the arrays below, if you need more.. */ -/* Boards 3,4 slots are reserved for ISAPnP scans */ +/* Boards 3,4 slots are reserved for ISAPnP/MCA scans */ static unsigned int bases[MAXBOARDS] = {0x330, 0x334, 0, 0}; @@ -1043,6 +1048,69 @@ setup_dmaspeed[0] = atbt; } #endif + + /* + * Find MicroChannel cards (AHA1640) + */ +#ifdef CONFIG_MCA + if(MCA_bus) { + int slot = 0; + int pos = 0; + + for (indx = 0; (slot != MCA_NOTFOUND) && + (indx < sizeof(bases)/sizeof(bases[0])); indx++) { + + if (bases[indx]) + continue; + + /* Detect only AHA-1640 cards -- MCA ID 0F1F */ + slot = mca_find_unused_adapter(0x0f1f, slot); + if (slot == MCA_NOTFOUND) + break; + + + /* Found one */ + pos = mca_read_stored_pos(slot, 3); + + /* Decode address */ + if (pos & 0x80) { + if (pos & 0x02) { + if (pos & 0x01) + bases[indx] = 0x334; + else + bases[indx] = 0x234; + } else { + if (pos & 0x01) + bases[indx] = 0x134; + } + } else { + if (pos & 0x02) { + if (pos & 0x01) + bases[indx] = 0x330; + else + bases[indx] = 0x230; + } else { + if (pos & 0x01) + bases[indx] = 0x130; + } + } + + /* No need to decode IRQ and Arb level -- those are + * read off the card later. + */ + printk(KERN_INFO "Found an AHA-1640 in MCA slot %d, I/O 0x%04x\n", slot, bases[indx]); + + mca_set_adapter_name(slot, "Adapter AHA-1640"); + mca_set_adapter_procfn(slot, NULL, NULL); + mca_mark_as_used(slot); + + /* Go on */ + slot++; + } + + } +#endif + /* * Hunt for ISA Plug'n'Pray Adaptecs (AHA1535) */ diff -ur --new-file old/linux/drivers/scsi/aic7xxx/aic7xxx.seq new/linux/drivers/scsi/aic7xxx/aic7xxx.seq --- old/linux/drivers/scsi/aic7xxx/aic7xxx.seq Fri Nov 19 06:13:47 1999 +++ new/linux/drivers/scsi/aic7xxx/aic7xxx.seq Fri Jan 21 18:48:12 2000 @@ -48,7 +48,7 @@ * a later time. This problem cannot be resolved by holding a single entry * in scratch ram since a reconnecting target can request sense and this will * create yet another SCB waiting for selection. The solution used here is to - * use byte 27 of the SCB as a psuedo-next pointer and to thread a list + * use byte 27 of the SCB as a pseudo-next pointer and to thread a list * of SCBs that are awaiting selection. Since 0-0xfe are valid SCB indexes, * SCB_LIST_NULL is 0xff which is out of range. An entry is also added to * this list everytime a request sense occurs or after completing a non-tagged diff -ur --new-file old/linux/drivers/scsi/amiga7xx.c new/linux/drivers/scsi/amiga7xx.c --- old/linux/drivers/scsi/amiga7xx.c Fri Nov 12 01:57:30 1999 +++ new/linux/drivers/scsi/amiga7xx.c Wed Jan 26 21:45:20 2000 @@ -38,107 +38,105 @@ int __init amiga7xx_detect(Scsi_Host_Template *tpnt) { static unsigned char called = 0; - unsigned int key; int num = 0, clock; long long options; - const struct ConfigDev *cd; + struct zorro_dev *z = NULL; + unsigned long address; if (called || !MACH_IS_AMIGA) return 0; tpnt->proc_name = "Amiga7xx"; -#ifdef CONFIG_BLZ603EPLUS_SCSI - if ((key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS, 0, 0))) - { - cd = zorro_get_board(key); - - options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT; - - clock = 50000000; /* 50MHz SCSI Clock */ - - ncr53c7xx_init(tpnt, 0, 710, (u32)ZTWO_VADDR(0xf40000), 0, - IRQ_AMIGA_PORTS, DMA_NONE, options, clock); - - zorro_config_board(key, 0); - num++; +#ifdef CONFIG_A4000T_SCSI + if (AMIGAHW_PRESENT(A4000_SCSI)) { + address = 0xdd0040; + if (request_mem_region(address, 0x1000, "ncr53c710")) { + address = ZTWO_VADDR(address); + options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | + OPTION_INTFLY | OPTION_SYNCHRONOUS | + OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; + clock = 50000000; /* 50MHz SCSI Clock */ + ncr53c7xx_init(tpnt, 0, 710, address, 0, IRQ_AMIGA_PORTS, DMA_NONE, + options, clock); + num++; + } } #endif -#ifdef CONFIG_WARPENGINE_SCSI - if ((key = zorro_find(ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx, 0, 0))) - { - unsigned long address; - cd = zorro_get_board(key); - address = (unsigned long)ioremap((unsigned long)cd->cd_BoardAddr, - cd->cd_BoardSize); - - options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT; - - clock = 50000000; /* 50MHz SCSI Clock */ - - ncr53c7xx_init(tpnt, 0, 710, (u32)(unsigned char *)(address + 0x40000), - 0, IRQ_AMIGA_PORTS, DMA_NONE, options, clock); - - zorro_config_board(key, 0); - num++; - } + while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { + unsigned long address = z->resource.start; + unsigned long size = z->resource.end-z->resource.start+1; + switch (z->id) { +#ifdef CONFIG_BLZ603EPLUS_SCSI + case ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS: + address = 0xf40000; + if (request_mem_region(address, 0x1000, "ncr53c710")) { + strcpy(z->name, + "Blizzard 603e+ Accelerator and SCSI Host Adapter"); + address = ZTWO_VADDR(address); + options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | + OPTION_INTFLY | OPTION_SYNCHRONOUS | + OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; + clock = 50000000; /* 50MHz SCSI Clock */ + ncr53c7xx_init(tpnt, 0, 710, address, 0, IRQ_AMIGA_PORTS, + DMA_NONE, options, clock); + num++; + } + break; #endif -#ifdef CONFIG_A4000T_SCSI - if (AMIGAHW_PRESENT(A4000_SCSI)) - { - options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT; - - clock = 50000000; /* 50MHz SCSI Clock */ - - ncr53c7xx_init(tpnt, 0, 710, (u32)ZTWO_VADDR(0xDD0040), 0, - IRQ_AMIGA_PORTS, DMA_NONE, options, clock); - num++; - } +#ifdef CONFIG_WARPENGINE_SCSI + case ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx: + if (request_mem_region(address+0x40000, 0x1000, "ncr53c710")) { + strcpy(z->name, "Warp Engine 40xx Accelerator, SCSI Host " + "Adapter and RAM Expansion"); + address = (unsigned long)ioremap(address, size); + options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | + OPTION_INTFLY | OPTION_SYNCHRONOUS | + OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; + clock = 50000000; /* 50MHz SCSI Clock */ + ncr53c7xx_init(tpnt, 0, 710, address+0x40000, 0, + IRQ_AMIGA_PORTS, DMA_NONE, options, clock); + num++; + } + break; #endif #ifdef CONFIG_A4091_SCSI - while ( (key = zorro_find(ZORRO_PROD_CBM_A4091_1, 0, 0)) || - (key = zorro_find(ZORRO_PROD_CBM_A4091_2, 0, 0)) ) - { - unsigned long address; - cd = zorro_get_board(key); - address = (unsigned long)ioremap((unsigned long)cd->cd_BoardAddr, - cd->cd_BoardSize); - - options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT; - - clock = 50000000; /* 50MHz SCSI Clock */ - - ncr53c7xx_init(tpnt, 0, 710, (u32)(unsigned char *)(address+0x800000), - 0, IRQ_AMIGA_PORTS, DMA_NONE, options, clock); - - zorro_config_board(key, 0); - num++; - } + case ZORRO_PROD_CBM_A4091_1: + case ZORRO_PROD_CBM_A4091_2: + if (request_mem_region(address+0x800000, 0x1000, "ncr53c710")) { + strcpy(z->name, "A4091 SCSI Host Adapter"); + address = (unsigned long)ioremap(address, size); + options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | + OPTION_INTFLY | OPTION_SYNCHRONOUS | + OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; + clock = 50000000; /* 50MHz SCSI Clock */ + ncr53c7xx_init(tpnt, 0, 710, address+0x800000, 0, + IRQ_AMIGA_PORTS, DMA_NONE, options, clock); + num++; + } + break; #endif #ifdef CONFIG_GVP_TURBO_SCSI - if((key = zorro_find(ZORRO_PROD_GVP_GFORCE_040_060, 0, 0))) - { - cd = zorro_get_board(key); - address = ZTWO_VADDR((unsigned long)cd->cd_BoardAddr); - - options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | - OPTION_INTFLY | OPTION_SYNCHRONOUS | - OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; - - clock = 50000000; /* 50MHz SCSI Clock */ - - ncr53c7xx_init(tpnt, 0, 710, - (u32)(unsigned char *)(address + 0x40000), - 0, IRQ_AMIGA_PORTS, DMA_NONE, options, clock); - - zorro_config_board(key, 0); - num++; - } + case ZORRO_PROD_GVP_GFORCE_040_060: + if (request_mem_region(address+0x40000, 0x1000, "ncr53c710")) { + strcpy(z->name, "GForce 040/060 Accelerator and SCSI Host " + "Adapter"); + address = ZTWO_VADDR(address); + options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | + OPTION_INTFLY | OPTION_SYNCHRONOUS | + OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; + clock = 50000000; /* 50MHz SCSI Clock */ + ncr53c7xx_init(tpnt, 0, 710, address+0x40000, 0, + IRQ_AMIGA_PORTS, DMA_NONE, options, clock); + num++; + } #endif + } + } called = 1; return num; diff -ur --new-file old/linux/drivers/scsi/blz1230.c new/linux/drivers/scsi/blz1230.c --- old/linux/drivers/scsi/blz1230.c Wed Aug 18 19:00:52 1999 +++ new/linux/drivers/scsi/blz1230.c Fri Jan 28 17:04:58 2000 @@ -16,6 +16,7 @@ #include +#include #include #include #include @@ -60,37 +61,41 @@ int __init blz1230_esp_detect(Scsi_Host_Template *tpnt) { struct NCR_ESP *esp; - const struct ConfigDev *esp_dev; - unsigned int key; + struct zorro_dev *z = NULL; unsigned long address; struct ESP_regs *eregs; #if MKIV - if ((key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_1230_IV_1260, 0, 0))){ +#define REAL_BLZ1230_ID ZORRO_PROD_PHASE5_BLIZZARD_1230_IV_1260 +#define REAL_BLZ1230_ESP_ADDR BLZ1230_ESP_ADDR +#define REAL_BLZ1230_DMA_ADDR BLZ1230_DMA_ADDR #else - if ((key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060, 0, 0))){ +#define REAL_BLZ1230_ID ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060 +#define REAL_BLZ1230_ESP_ADDR BLZ1230II_ESP_ADDR +#define REAL_BLZ1230_DMA_ADDR BLZ1230II_DMA_ADDR #endif - esp_dev = zorro_get_board(key); + if ((z = zorro_find_device(REAL_BLZ1230_ID, z))) { + unsigned long board = z->resource.start; + if (request_mem_region(board+REAL_BLZ1230_ESP_ADDR, + sizeof(struct ESP_regs), "NCR53C9x")) { /* Do some magic to figure out if the blizzard is * equipped with a SCSI controller */ - address = (unsigned long)ZTWO_VADDR(esp_dev->cd_BoardAddr); -#if MKIV - eregs = (struct ESP_regs *)(address + BLZ1230_ESP_ADDR); -#else - eregs = (struct ESP_regs *)(address + BLZ1230II_ESP_ADDR); -#endif - - esp = esp_allocate(tpnt, (void *) esp_dev); + address = ZTWO_VADDR(board); + eregs = (struct ESP_regs *)(address + REAL_BLZ1230_ESP_ADDR); + esp = esp_allocate(tpnt, (void *)board+REAL_BLZ1230_ESP_ADDR); esp_write(eregs->esp_cfg1, (ESP_CONFIG1_PENABLE | 7)); udelay(5); if(esp_read(eregs->esp_cfg1) != (ESP_CONFIG1_PENABLE | 7)){ esp_deallocate(esp); scsi_unregister(esp->ehost); + release_mem_region(board+REAL_BLZ1230_ESP_ADDR, + sizeof(struct ESP_regs)); return 0; /* Bail out if address did not hold data */ } + strcpy(z->name, "Blizzard 1230 SCSI IV"); /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; @@ -125,11 +130,7 @@ * relative to the device (i.e. in the same Zorro * I/O block). */ -#if MKIV - esp->dregs = (void *)(address + BLZ1230_DMA_ADDR); -#else - esp->dregs = (void *)(address + BLZ1230II_DMA_ADDR); -#endif + esp->dregs = (void *)(address + REAL_BLZ1230_DMA_ADDR); /* ESP register base */ esp->eregs = eregs; @@ -139,7 +140,7 @@ esp->esp_command_dvma = virt_to_bus(cmd_buffer); esp->irq = IRQ_AMIGA_PORTS; - esp->slot = key; + esp->slot = board+REAL_BLZ1230_ESP_ADDR; request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ, "Blizzard 1230 SCSI IV", esp_intr); @@ -151,11 +152,10 @@ esp_initialize(esp); - zorro_config_board(key, 0); - printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use); esps_running = esps_in_use; return esps_in_use; + } } return 0; } @@ -289,12 +289,10 @@ int blz1230_esp_release(struct Scsi_Host *instance) { #ifdef MODULE - unsigned int key; - - key = ((struct NCR_ESP *)instance->hostdata)->slot; + unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev; esp_deallocate((struct NCR_ESP *)instance->hostdata); esp_release(); - zorro_unconfig_board(key, 0); + release_mem_region(address, sizeof(struct ESP_regs)); free_irq(IRQ_AMIGA_PORTS, esp_intr); #endif return 1; diff -ur --new-file old/linux/drivers/scsi/blz2060.c new/linux/drivers/scsi/blz2060.c --- old/linux/drivers/scsi/blz2060.c Wed Aug 18 19:00:52 1999 +++ new/linux/drivers/scsi/blz2060.c Fri Jan 28 17:04:58 2000 @@ -16,6 +16,7 @@ #include +#include #include #include #include @@ -60,13 +61,16 @@ int __init blz2060_esp_detect(Scsi_Host_Template *tpnt) { struct NCR_ESP *esp; - const struct ConfigDev *esp_dev; - unsigned int key; + struct zorro_dev *z = NULL; unsigned long address; - if ((key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_2060, 0, 0))){ - esp_dev = zorro_get_board(key); - esp = esp_allocate(tpnt, (void *) esp_dev); + if ((z = zorro_find_device(ZORRO_PROD_PHASE5_BLIZZARD_2060, z))) { + unsigned long board = z->resource.start; + if (request_mem_region(board+BLZ2060_ESP_ADDR, + sizeof(struct ESP_regs), "NCR53C9x")) { + strcpy(z->name, "Blizzard 2060 Accelerator"); + + esp = esp_allocate(tpnt, (void *)board+BLZ2060_ESP_ADDR); /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; @@ -101,7 +105,7 @@ * relative to the device (i.e. in the same Zorro * I/O block). */ - address = (unsigned long)ZTWO_VADDR(esp_dev->cd_BoardAddr); + address = (unsigned long)ZTWO_VADDR(board); esp->dregs = (void *)(address + BLZ2060_DMA_ADDR); /* ESP register base */ @@ -112,7 +116,6 @@ esp->esp_command_dvma = virt_to_bus(cmd_buffer); esp->irq = IRQ_AMIGA_PORTS; - esp->slot = key; request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ, "Blizzard 2060 SCSI", esp_intr); @@ -124,11 +127,10 @@ esp_initialize(esp); - zorro_config_board(key, 0); - printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use); esps_running = esps_in_use; return esps_in_use; + } } return 0; } @@ -249,12 +251,11 @@ int blz2060_esp_release(struct Scsi_Host *instance) { #ifdef MODULE - unsigned int key; + unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev; - key = ((struct NCR_ESP *)instance->hostdata)->slot; esp_deallocate((struct NCR_ESP *)instance->hostdata); esp_release(); - zorro_unconfig_board(key, 0); + release_mem_region(address, sizeof(struct ESP_regs)); free_irq(IRQ_AMIGA_PORTS, esp_intr); #endif return 1; diff -ur --new-file old/linux/drivers/scsi/cyberstorm.c new/linux/drivers/scsi/cyberstorm.c --- old/linux/drivers/scsi/cyberstorm.c Wed Aug 18 19:00:52 1999 +++ new/linux/drivers/scsi/cyberstorm.c Fri Jan 28 17:04:58 2000 @@ -19,6 +19,7 @@ #include +#include #include #include #include @@ -69,24 +70,28 @@ int __init cyber_esp_detect(Scsi_Host_Template *tpnt) { struct NCR_ESP *esp; - const struct ConfigDev *esp_dev; - unsigned int key; + struct zorro_dev *z = NULL; unsigned long address; - - if ((key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM, 0, 0)) || - (key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060, 0, 0))){ - esp_dev = zorro_get_board(key); - + while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { + unsigned long board = z->resource.start; + if ((z->id == ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM || + z->id == ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060) && + request_mem_region(board+CYBER_ESP_ADDR, + sizeof(struct ESP_regs), "NCR53C9x")) { /* Figure out if this is a CyberStorm or really a * Fastlane/Blizzard Mk II by looking at the board size. * CyberStorm maps 64kB * (ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM does anyway) */ - if((unsigned long)esp_dev->cd_BoardSize != 0x10000) + if(z->resource.end-board != 0xffff) { + release_mem_region(board+CYBER_ESP_ADDR, + sizeof(struct ESP_regs)); return 0; + } + strcpy(z->name, "Cyberstorm SCSI Host Adapter"); - esp = esp_allocate(tpnt, (void *) esp_dev); + esp = esp_allocate(tpnt, (void *)board+CYBER_ESP_ADDR); /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; @@ -121,7 +126,7 @@ * relative to the device (i.e. in the same Zorro * I/O block). */ - address = (unsigned long)ZTWO_VADDR(esp_dev->cd_BoardAddr); + address = (unsigned long)ZTWO_VADDR(board); esp->dregs = (void *)(address + CYBER_DMA_ADDR); /* ESP register base */ @@ -132,7 +137,6 @@ esp->esp_command_dvma = virt_to_bus(cmd_buffer); esp->irq = IRQ_AMIGA_PORTS; - esp->slot = key; request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ, "CyberStorm SCSI", esp_intr); /* Figure out our scsi ID on the bus */ @@ -148,11 +152,10 @@ esp_initialize(esp); - zorro_config_board(key, 0); - printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use); esps_running = esps_in_use; return esps_in_use; + } } return 0; } @@ -314,12 +317,11 @@ int cyber_esp_release(struct Scsi_Host *instance) { #ifdef MODULE - unsigned int key; + unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev; - key = ((struct NCR_ESP *)instance->hostdata)->slot; esp_deallocate((struct NCR_ESP *)instance->hostdata); esp_release(); - zorro_unconfig_board(key, 0); + release_mem_region(address, sizeof(struct ESP_regs)); free_irq(IRQ_AMIGA_PORTS, esp_intr); #endif return 1; diff -ur --new-file old/linux/drivers/scsi/cyberstormII.c new/linux/drivers/scsi/cyberstormII.c --- old/linux/drivers/scsi/cyberstormII.c Wed Aug 18 19:00:52 1999 +++ new/linux/drivers/scsi/cyberstormII.c Fri Jan 28 17:04:58 2000 @@ -15,6 +15,7 @@ #include +#include #include #include #include @@ -59,29 +60,32 @@ int __init cyberII_esp_detect(Scsi_Host_Template *tpnt) { struct NCR_ESP *esp; - const struct ConfigDev *esp_dev; - unsigned int key; + struct zorro_dev *z = NULL; unsigned long address; struct ESP_regs *eregs; - if((key = zorro_find(ZORRO_PROD_PHASE5_CYBERSTORM_MK_II, 0, 0))){ - esp_dev = zorro_get_board(key); - + if ((z = zorro_find_device(ZORRO_PROD_PHASE5_CYBERSTORM_MK_II, z))) { + unsigned long board = z->resource.start; + if (request_mem_region(board+CYBERII_ESP_ADDR, + sizeof(struct ESP_regs), "NCR53C9x")) { /* Do some magic to figure out if the CyberStorm Mk II * is equipped with a SCSI controller */ - address = (unsigned long)ZTWO_VADDR(esp_dev->cd_BoardAddr); + address = (unsigned long)ZTWO_VADDR(board); eregs = (struct ESP_regs *)(address + CYBERII_ESP_ADDR); - esp = esp_allocate(tpnt, (void *) esp_dev); + esp = esp_allocate(tpnt, (void *)board+CYBERII_ESP_ADDR); esp_write(eregs->esp_cfg1, (ESP_CONFIG1_PENABLE | 7)); udelay(5); if(esp_read(eregs->esp_cfg1) != (ESP_CONFIG1_PENABLE | 7)) { esp_deallocate(esp); scsi_unregister(esp->ehost); + release_mem_region(board+CYBERII_ESP_ADDR, + sizeof(struct ESP_regs)); return 0; /* Bail out if address did not hold data */ } + strcpy(z->name, "CyberStorm Mk II SCSI Host Adapter"); /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; @@ -126,7 +130,6 @@ esp->esp_command_dvma = virt_to_bus(cmd_buffer); esp->irq = IRQ_AMIGA_PORTS; - esp->slot = key; request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ, "CyberStorm SCSI Mk II", esp_intr); @@ -138,11 +141,10 @@ esp_initialize(esp); - zorro_config_board(key, 0); - printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use); esps_running = esps_in_use; return esps_in_use; + } } return 0; } @@ -264,12 +266,11 @@ int cyberII_esp_release(struct Scsi_Host *instance) { #ifdef MODULE - unsigned int key; + unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev; - key = ((struct NCR_ESP *)instance->hostdata)->slot; esp_deallocate((struct NCR_ESP *)instance->hostdata); esp_release(); - zorro_unconfig_board(key, 0); + release_mem_region(address, sizeof(struct ESP_regs)); free_irq(IRQ_AMIGA_PORTS, esp_intr); #endif return 1; diff -ur --new-file old/linux/drivers/scsi/eata_dma.c new/linux/drivers/scsi/eata_dma.c --- old/linux/drivers/scsi/eata_dma.c Mon Dec 13 08:04:20 1999 +++ new/linux/drivers/scsi/eata_dma.c Fri Jan 21 18:48:11 2000 @@ -113,16 +113,6 @@ static ulong int_counter = 0; static ulong queue_counter = 0; -void eata_scsi_done (Scsi_Cmnd * scmd) -{ - scmd->request.rq_status = RQ_SCSI_DONE; - - if (scmd->request.sem != NULL) - up(scmd->request.sem); - - return; -} - void eata_fake_int_handler(s32 irq, void *dev_id, struct pt_regs * regs) { fake_int_result = inb((ulong)fake_int_base + HA_RSTATUS); diff -ur --new-file old/linux/drivers/scsi/eata_dma_proc.c new/linux/drivers/scsi/eata_dma_proc.c --- old/linux/drivers/scsi/eata_dma_proc.c Wed May 12 22:27:37 1999 +++ new/linux/drivers/scsi/eata_dma_proc.c Fri Jan 21 18:48:11 2000 @@ -67,10 +67,10 @@ int hostno, int inout) { - Scsi_Device *scd, SDev; + Scsi_Device *scd, *SDev; struct Scsi_Host *HBA_ptr; - Scsi_Cmnd scmd; - char cmnd[10]; + Scsi_Cmnd * scmd; + char cmnd[MAX_COMMAND_SIZE]; static u8 buff[512]; static u8 buff2[512]; hst_cmd_stat *rhcs, *whcs; @@ -152,13 +152,8 @@ pos = begin + len; } else { - memset(&SDev, 0, sizeof(Scsi_Device)); - memset(&scmd, 0, sizeof(Scsi_Cmnd)); - - SDev.host = HBA_ptr; - SDev.id = HBA_ptr->this_id; - SDev.lun = 0; - SDev.channel = 0; + SDev = scsi_get_host_dev(HBA_ptr); + scmd = scsi_allocate_device(SDev, 1, FALSE); cmnd[0] = LOG_SENSE; cmnd[1] = 0; @@ -171,26 +166,13 @@ cmnd[8] = 0x66; cmnd[9] = 0; - scmd.cmd_len = 10; + scmd->cmd_len = 10; - scmd.host = HBA_ptr; - scmd.device = &SDev; - scmd.target = HBA_ptr->this_id; - scmd.lun = 0; - scmd.channel = 0; - scmd.use_sg = 0; - /* * Do the command and wait for it to finish. */ - { - DECLARE_MUTEX_LOCKED(sem); - scmd.request.rq_status = RQ_SCSI_BUSY; - scmd.request.sem = &sem; - scsi_do_cmd (&scmd, cmnd, buff + 0x144, 0x66, - eata_scsi_done, 1 * HZ, 1); - down(&sem); - } + scsi_wait_cmd (scmd, cmnd, buff + 0x144, 0x66, + 1 * HZ, 1); size = sprintf(buffer + len, "IRQ: %2d, %s triggered\n", cc->interrupt, (cc->intt == TRUE)?"level":"edge"); @@ -308,19 +290,13 @@ cmnd[8] = 0x44; cmnd[9] = 0; - scmd.cmd_len = 10; + scmd->cmd_len = 10; /* * Do the command and wait for it to finish. */ - { - DECLARE_MUTEX_LOCKED(sem); - scmd.request.rq_status = RQ_SCSI_BUSY; - scmd.request.sem = &sem; - scsi_do_cmd (&scmd, cmnd, buff2, 0x144, - eata_scsi_done, 1 * HZ, 1); - down(&sem); - } + scsi_wait_cmd (scmd, cmnd, buff2, 0x144, + 1 * HZ, 1); swap_statistics(buff2); rhcs = (hst_cmd_stat *)(buff2 + 0x2c); @@ -354,6 +330,9 @@ len += size; pos = begin + len; } + + scsi_release_command(scmd); + scsi_free_host_dev(SDev); } if (pos < offset) { diff -ur --new-file old/linux/drivers/scsi/esp.c new/linux/drivers/scsi/esp.c --- old/linux/drivers/scsi/esp.c Thu Dec 23 04:55:38 1999 +++ new/linux/drivers/scsi/esp.c Thu Jan 27 17:58:15 2000 @@ -791,7 +791,7 @@ { struct sbus_dev *sdev = esp->sdev; - esp->esp_command = sbus_alloc_consistant(sdev, 16, + esp->esp_command = sbus_alloc_consistent(sdev, 16, &esp->esp_command_dvma); if (esp->esp_command == NULL || esp->esp_command_dvma == 0) @@ -1114,7 +1114,7 @@ return 0; fail_unmap_cmdarea: - sbus_free_consistant(esp->sdev, 16, + sbus_free_consistent(esp->sdev, 16, (void *) esp->esp_command, esp->esp_command_dvma); @@ -1420,8 +1420,8 @@ sp->SCp.buffers_residual = sbus_map_sg(esp->sdev, sp->SCp.buffer, sp->use_sg); - sp->SCp.this_residual = sp->SCp.buffer->dvma_length; - sp->SCp.ptr = (char *) ((unsigned long)sp->SCp.buffer->dvma_address); + sp->SCp.this_residual = sg_dma_len(sp->SCp.buffer); + sp->SCp.ptr = (char *) ((unsigned long)sg_dma_address(sp->SCp.buffer)); } } @@ -2537,8 +2537,8 @@ { ++sp->SCp.buffer; --sp->SCp.buffers_residual; - sp->SCp.this_residual = sp->SCp.buffer->dvma_length; - sp->SCp.ptr = (char *)((unsigned long)sp->SCp.buffer->dvma_address); + sp->SCp.this_residual = sg_dma_len(sp->SCp.buffer); + sp->SCp.ptr = (char *)((unsigned long)sg_dma_address(sp->SCp.buffer)); } /* Please note that the way I've coded these routines is that I _always_ diff -ur --new-file old/linux/drivers/scsi/fastlane.c new/linux/drivers/scsi/fastlane.c --- old/linux/drivers/scsi/fastlane.c Wed Aug 18 19:00:52 1999 +++ new/linux/drivers/scsi/fastlane.c Fri Jan 28 17:04:58 2000 @@ -24,6 +24,7 @@ #include +#include #include #include #include @@ -83,22 +84,25 @@ int __init fastlane_esp_detect(Scsi_Host_Template *tpnt) { struct NCR_ESP *esp; - const struct ConfigDev *esp_dev; - unsigned int key; + struct zorro_dev *z = NULL; unsigned long address; - if ((key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060, 0, 0))){ - - esp_dev = zorro_get_board(key); - + if ((z = zorro_find_device(ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060, z))) { + unsigned long board = z->resource.start; + if (request_mem_region(board+FASTLANE_ESP_ADDR, + sizeof(struct ESP_regs), "NCR53C9x")) { /* Check if this is really a fastlane controller. The problem * is that also the cyberstorm and blizzard controllers use * this ID value. Fortunately only Fastlane maps in Z3 space */ - if((unsigned long)esp_dev->cd_BoardAddr < 0x1000000) + if (board < 0x1000000) { + release_mem_region(board+FASTLANE_ESP_ADDR, + sizeof(struct ESP_regs)); return 0; + } + strcpy(z->name, "Fastlane Z3 SCSI Host Adapter"); - esp = esp_allocate(tpnt, (void *) esp_dev); + esp = esp_allocate(tpnt, (void *)board+FASTLANE_ESP_ADDR); /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; @@ -140,12 +144,13 @@ /* Map the physical address space into virtual kernel space */ address = (unsigned long) - ioremap_nocache((unsigned long)esp_dev->cd_BoardAddr, - esp_dev->cd_BoardSize); + ioremap_nocache(board, z->resource.end-board+1); if(!address){ printk("Could not remap Fastlane controller memory!"); scsi_unregister (esp->ehost); + release_mem_region(board+FASTLANE_ESP_ADDR, + sizeof(struct ESP_regs)); return 0; } @@ -167,7 +172,7 @@ esp->esp_command_dvma = virt_to_bus(cmd_buffer); esp->irq = IRQ_AMIGA_PORTS; - esp->slot = key; + esp->slot = board+FASTLANE_ESP_ADDR; request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ, "Fastlane SCSI", esp_intr); @@ -180,11 +185,10 @@ dma_clear(esp); esp_initialize(esp); - zorro_config_board(key, 0); - printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use); esps_running = esps_in_use; return esps_in_use; + } } return 0; } @@ -360,12 +364,10 @@ int fastlane_esp_release(struct Scsi_Host *instance) { #ifdef MODULE - unsigned int key; - - key = ((struct NCR_ESP *)instance->hostdata)->slot; + unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev; esp_deallocate((struct NCR_ESP *)instance->hostdata); esp_release(); - zorro_unconfig_board(key, 0); + release_mem_region(address, sizeof(struct ESP_regs)); free_irq(IRQ_AMIGA_PORTS, esp_intr); #endif return 1; diff -ur --new-file old/linux/drivers/scsi/gdth.c new/linux/drivers/scsi/gdth.c --- old/linux/drivers/scsi/gdth.c Fri Nov 12 01:57:30 1999 +++ new/linux/drivers/scsi/gdth.c Fri Jan 21 18:48:11 2000 @@ -3157,7 +3157,7 @@ NUMDATA(shp)->busnum= 0; ha->pccb = CMDDATA(shp); - ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA); + ha->pscratch = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, GDTH_SCRATCH_ORD); ha->scratch_busy = FALSE; ha->req_first = NULL; ha->tid_cnt = MAX_HDRIVES; @@ -3172,7 +3172,7 @@ --gdth_ctr_count; --gdth_ctr_vcount; if (ha->pscratch != NULL) - scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH); + free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD); free_irq(ha->irq,NULL); scsi_unregister(shp); continue; @@ -3223,7 +3223,7 @@ NUMDATA(shp)->hanum)); ha->pccb = CMDDATA(shp); - ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA); + ha->pscratch = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, GDTH_SCRATCH_ORD); ha->scratch_busy = FALSE; ha->req_first = NULL; ha->tid_cnt = MAX_HDRIVES; @@ -3238,7 +3238,7 @@ --gdth_ctr_count; --gdth_ctr_vcount; if (ha->pscratch != NULL) - scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH); + free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD); free_irq(ha->irq,NULL); scsi_unregister(shp); continue; @@ -3293,7 +3293,7 @@ NUMDATA(shp)->busnum= 0; ha->pccb = CMDDATA(shp); - ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA); + ha->pscratch = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, GDTH_SCRATCH_ORD); ha->scratch_busy = FALSE; ha->req_first = NULL; ha->tid_cnt = pcistr[ctr].device_id >= 0x200 ? MAXID : MAX_HDRIVES; @@ -3308,7 +3308,7 @@ --gdth_ctr_count; --gdth_ctr_vcount; if (ha->pscratch != NULL) - scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH); + free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD); free_irq(ha->irq,NULL); scsi_unregister(shp); continue; @@ -3359,7 +3359,7 @@ if (shp->dma_channel != 0xff) { free_dma(shp->dma_channel); } - scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH); + free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD); gdth_ctr_released++; TRACE2(("gdth_release(): HA %d of %d\n", gdth_ctr_released, gdth_ctr_count)); @@ -3561,21 +3561,18 @@ { int i; gdth_ha_str *ha; - Scsi_Cmnd scp; - Scsi_Device sdev; + Scsi_Cmnd * scp; + Scsi_Device * sdev; gdth_cmd_str gdtcmd; TRACE2(("gdth_flush() hanum %d\n",hanum)); ha = HADATA(gdth_ctr_tab[hanum]); - memset(&sdev,0,sizeof(Scsi_Device)); - memset(&scp, 0,sizeof(Scsi_Cmnd)); - sdev.host = gdth_ctr_tab[hanum]; - sdev.id = sdev.host->this_id; - scp.cmd_len = 12; - scp.host = gdth_ctr_tab[hanum]; - scp.target = sdev.host->this_id; - scp.device = &sdev; - scp.use_sg = 0; + + sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); + scp = scsi_allocate_device(sdev, 1, FALSE); + + scp->cmd_len = 12; + scp->use_sg = 0; for (i = 0; i < MAX_HDRIVES; ++i) { if (ha->hdr[i].present) { @@ -3586,9 +3583,11 @@ gdtcmd.u.cache.BlockNo = 1; gdtcmd.u.cache.sg_canz = 0; TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i)); - gdth_do_cmd(&scp, &gdtcmd, 30); + gdth_do_cmd(scp, &gdtcmd, 30); } } + scsi_release_command(scp); + scsi_free_host_dev(sdev); } /* shutdown routine */ @@ -3596,8 +3595,8 @@ { int hanum; #ifndef __alpha__ - Scsi_Cmnd scp; - Scsi_Device sdev; + Scsi_Cmnd * scp; + Scsi_Device * sdev; gdth_cmd_str gdtcmd; #endif @@ -3610,23 +3609,21 @@ #ifndef __alpha__ /* controller reset */ - memset(&sdev,0,sizeof(Scsi_Device)); - memset(&scp, 0,sizeof(Scsi_Cmnd)); - sdev.host = gdth_ctr_tab[hanum]; - sdev.id = sdev.host->this_id; - scp.cmd_len = 12; - scp.host = gdth_ctr_tab[hanum]; - scp.target = sdev.host->this_id; - scp.device = &sdev; - scp.use_sg = 0; + sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); + scp = scsi_allocate_device(sdev, 1, FALSE); + scp->cmd_len = 12; + scp->use_sg = 0; gdtcmd.BoardNode = LOCALBOARD; gdtcmd.Service = CACHESERVICE; gdtcmd.OpCode = GDT_RESET; TRACE2(("gdth_halt(): reset controller %d\n", hanum)); - gdth_do_cmd(&scp, &gdtcmd, 10); + gdth_do_cmd(scp, &gdtcmd, 10); + scsi_release_command(scp); + scsi_free_host_dev(sdev); #endif } + printk("Done.\n"); #ifdef GDTH_STATISTICS diff -ur --new-file old/linux/drivers/scsi/gdth.h new/linux/drivers/scsi/gdth.h --- old/linux/drivers/scsi/gdth.h Fri Jan 21 01:07:27 2000 +++ new/linux/drivers/scsi/gdth.h Fri Jan 28 17:03:08 2000 @@ -126,7 +126,8 @@ #endif /* limits */ -#define GDTH_SCRATCH 4096 /* 4KB scratch buffer */ +#define GDTH_SCRATCH PAGE_SIZE /* 4KB scratch buffer */ +#define GDTH_SCRATCH_ORD 0 /* order 0 means 1 page */ #define GDTH_MAXCMDS 124 #define GDTH_MAXC_P_L 16 /* max. cmds per lun */ #define GDTH_MAX_RAW 2 /* max. cmds per raw device */ diff -ur --new-file old/linux/drivers/scsi/gdth_proc.c new/linux/drivers/scsi/gdth_proc.c --- old/linux/drivers/scsi/gdth_proc.c Mon Dec 13 08:04:20 1999 +++ new/linux/drivers/scsi/gdth_proc.c Fri Jan 21 18:48:11 2000 @@ -31,22 +31,17 @@ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum) { int ret_val; - Scsi_Cmnd scp; - Scsi_Device sdev; + Scsi_Cmnd * scp; + Scsi_Device * sdev; gdth_iowr_str *piowr; TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum)); piowr = (gdth_iowr_str *)buffer; - memset(&sdev,0,sizeof(Scsi_Device)); - memset(&scp, 0,sizeof(Scsi_Cmnd)); - sdev.host = gdth_ctr_vtab[vh]; - sdev.id = sdev.host->this_id; - scp.cmd_len = 12; - scp.host = gdth_ctr_vtab[vh]; - scp.target = sdev.host->this_id; - scp.device = &sdev; - scp.use_sg = 0; + sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]); + scp = scsi_allocate_device(sdev, 1, FALSE); + scp->cmd_len = 12; + scp->use_sg = 0; if (length >= 4) { if (strncmp(buffer,"gdth",4) == 0) { @@ -62,10 +57,14 @@ } else { ret_val = -EINVAL; } + + scsi_release_command(scp); + scsi_free_host_dev(sdev); + return ret_val; } -static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) +static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd * scp) { int orig_length, drive, wb_mode; int i, found; @@ -105,7 +104,7 @@ gdtcmd.u.cache.DeviceNo = i; gdtcmd.u.cache.BlockNo = 1; gdtcmd.u.cache.sg_canz = 0; - gdth_do_cmd(&scp, &gdtcmd, 30); + gdth_do_cmd(scp, &gdtcmd, 30); } } if (!found) @@ -158,7 +157,7 @@ gdtcmd.u.ioctl.subfunc = CACHE_CONFIG; gdtcmd.u.ioctl.channel = INVALID_CHANNEL; pcpar->write_back = wb_mode==1 ? 0:1; - gdth_do_cmd(&scp, &gdtcmd, 30); + gdth_do_cmd(scp, &gdtcmd, 30); gdth_ioctl_free(hanum); printk("Done.\n"); return(orig_length); @@ -168,7 +167,7 @@ return(-EINVAL); } -static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) +static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd * scp) { unchar i, j; gdth_ha_str *ha; @@ -241,8 +240,8 @@ *ppadd2 = virt_to_bus(piord->iu.general.data+add_size); } /* do IOCTL */ - gdth_do_cmd(&scp, pcmd, piowr->timeout); - piord->status = (ulong32)scp.SCp.Message; + gdth_do_cmd(scp, pcmd, piowr->timeout); + piord->status = (ulong32)scp->SCp.Message; break; case GDTIOCTL_DRVERS: @@ -401,8 +400,8 @@ gdth_cmd_str gdtcmd; gdth_evt_str estr; - Scsi_Cmnd scp; - Scsi_Device sdev; + Scsi_Cmnd * scp; + Scsi_Device *sdev; char hrec[161]; struct timeval tv; @@ -417,15 +416,10 @@ ha = HADATA(gdth_ctr_tab[hanum]); id = length; - memset(&sdev,0,sizeof(Scsi_Device)); - memset(&scp, 0,sizeof(Scsi_Cmnd)); - sdev.host = gdth_ctr_vtab[vh]; - sdev.id = sdev.host->this_id; - scp.cmd_len = 12; - scp.host = gdth_ctr_vtab[vh]; - scp.target = sdev.host->this_id; - scp.device = &sdev; - scp.use_sg = 0; + sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]); + scp = scsi_allocate_device(sdev, 1, FALSE); + scp->cmd_len = 12; + scp->use_sg = 0; /* look for buffer ID in length */ if (id > 1) { @@ -531,11 +525,11 @@ sizeof(pds->list[0]); if (pds->entries > cnt) pds->entries = cnt; - gdth_do_cmd(&scp, &gdtcmd, 30); - if (scp.SCp.Message != S_OK) + gdth_do_cmd(scp, &gdtcmd, 30); + if (scp->SCp.Message != S_OK) pds->count = 0; TRACE2(("pdr_statistics() entries %d status %d\n", - pds->count, scp.SCp.Message)); + pds->count, scp->SCp.Message)); /* other IOCTLs must fit into area GDTH_SCRATCH/4 */ for (j = 0; j < ha->raw[i].pdev_cnt; ++j) { @@ -551,8 +545,8 @@ gdtcmd.u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN; gdtcmd.u.ioctl.channel = ha->raw[i].address | ha->raw[i].id_list[j]; - gdth_do_cmd(&scp, &gdtcmd, 30); - if (scp.SCp.Message == S_OK) { + gdth_do_cmd(scp, &gdtcmd, 30); + if (scp->SCp.Message == S_OK) { strncpy(hrec,pdi->vendor,8); strncpy(hrec+8,pdi->product,16); strncpy(hrec+24,pdi->revision,4); @@ -602,8 +596,8 @@ gdtcmd.u.ioctl.channel = ha->raw[i].address | ha->raw[i].id_list[j]; pdef->sddc_type = 0x08; - gdth_do_cmd(&scp, &gdtcmd, 30); - if (scp.SCp.Message == S_OK) { + gdth_do_cmd(scp, &gdtcmd, 30); + if (scp->SCp.Message == S_OK) { size = sprintf(buffer+len, " Grown Defects:\t%d\n", pdef->sddc_cnt); @@ -649,8 +643,8 @@ gdtcmd.u.ioctl.param_size = sizeof(gdth_cdrinfo_str); gdtcmd.u.ioctl.subfunc = CACHE_DRV_INFO; gdtcmd.u.ioctl.channel = drv_no; - gdth_do_cmd(&scp, &gdtcmd, 30); - if (scp.SCp.Message != S_OK) + gdth_do_cmd(scp, &gdtcmd, 30); + if (scp->SCp.Message != S_OK) break; pcdi->ld_dtype >>= 16; j++; @@ -746,8 +740,8 @@ gdtcmd.u.ioctl.param_size = sizeof(gdth_arrayinf_str); gdtcmd.u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN; gdtcmd.u.ioctl.channel = i; - gdth_do_cmd(&scp, &gdtcmd, 30); - if (scp.SCp.Message == S_OK) { + gdth_do_cmd(scp, &gdtcmd, 30); + if (scp->SCp.Message == S_OK) { if (pai->ai_state == 0) strcpy(hrec, "idle"); else if (pai->ai_state == 2) @@ -821,8 +815,8 @@ gdtcmd.u.ioctl.channel = i; phg->entries = MAX_HDRIVES; phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]); - gdth_do_cmd(&scp, &gdtcmd, 30); - if (scp.SCp.Message != S_OK) { + gdth_do_cmd(scp, &gdtcmd, 30); + if (scp->SCp.Message != S_OK) { ha->hdr[i].ldr_no = i; ha->hdr[i].rw_attribs = 0; ha->hdr[i].start_sec = 0; @@ -837,7 +831,7 @@ } } TRACE2(("host_get entries %d status %d\n", - phg->entries, scp.SCp.Message)); + phg->entries, scp->SCp.Message)); } gdth_ioctl_free(hanum); @@ -915,6 +909,10 @@ } stop_output: + + scsi_release_command(scp); + scsi_free_host_dev(sdev); + *start = buffer +(offset-begin); len -= (offset-begin); if (len > length) @@ -926,11 +924,11 @@ static void gdth_do_cmd(Scsi_Cmnd *scp,gdth_cmd_str *gdtcmd,int timeout) { - char cmnd[12]; + char cmnd[MAX_COMMAND_SIZE]; DECLARE_MUTEX_LOCKED(sem); TRACE2(("gdth_do_cmd()\n")); - memset(cmnd, 0, 12); + memset(cmnd, 0, MAX_COMMAND_SIZE); scp->request.rq_status = RQ_SCSI_BUSY; scp->request.sem = &sem; scp->SCp.this_residual = IOCTL_PRI; diff -ur --new-file old/linux/drivers/scsi/gdth_proc.h new/linux/drivers/scsi/gdth_proc.h --- old/linux/drivers/scsi/gdth_proc.h Mon Apr 12 18:56:16 1999 +++ new/linux/drivers/scsi/gdth_proc.h Fri Jan 21 18:48:11 2000 @@ -6,8 +6,8 @@ */ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum); -static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp); -static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp); +static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd * scp); +static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd * scp); static int gdth_get_info(char *buffer,char **start,off_t offset, int length,int vh,int hanum,int busnum); diff -ur --new-file old/linux/drivers/scsi/gvp11.c new/linux/drivers/scsi/gvp11.c --- old/linux/drivers/scsi/gvp11.c Fri Nov 12 01:57:30 1999 +++ new/linux/drivers/scsi/gvp11.c Wed Jan 26 21:45:20 2000 @@ -75,7 +75,8 @@ if ( scsi_alloc_out_of_range || !HDATA(cmd->host)->dma_bounce_buffer) { HDATA(cmd->host)->dma_bounce_buffer = - amiga_chip_alloc(HDATA(cmd->host)->dma_bounce_len); + amiga_chip_alloc(HDATA(cmd->host)->dma_bounce_len, + "GVP II SCSI Bounce Buffer"); if(!HDATA(cmd->host)->dma_bounce_buffer) { @@ -100,7 +101,8 @@ } HDATA(cmd->host)->dma_bounce_buffer = - amiga_chip_alloc(HDATA(cmd->host)->dma_bounce_len); + amiga_chip_alloc(HDATA(cmd->host)->dma_bounce_len, + "GVP II SCSI Bounce Buffer"); if(!HDATA(cmd->host)->dma_bounce_buffer) { @@ -180,10 +182,9 @@ { static unsigned char called = 0; struct Scsi_Host *instance; - caddr_t address; + unsigned long address; unsigned int epc; - unsigned int key = 0, skey; - const struct ConfigDev *cd; + struct zorro_dev *z = NULL; unsigned int default_dma_xfer_mask; #ifdef CHECK_WD33C93 volatile unsigned char *sasr_3393, *scmd_3393; @@ -198,38 +199,39 @@ tpnt->proc_name = "GVP11"; tpnt->proc_info = &wd33c93_proc_info; - while (1) { + while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { /* * This should (hopefully) be the correct way to identify * all the different GVP SCSI controllers (except for the * SERIES I though). */ - skey = key; - if ((key = zorro_find(ZORRO_PROD_GVP_COMBO_030_R3_SCSI, 0, skey)) || - (key = zorro_find(ZORRO_PROD_GVP_SERIES_II, 0, skey))) + if (z->id == ZORRO_PROD_GVP_COMBO_030_R3_SCSI || + z->id == ZORRO_PROD_GVP_SERIES_II) default_dma_xfer_mask = ~0x00ffffff; - else if ((key = zorro_find(ZORRO_PROD_GVP_GFORCE_030_SCSI, 0, skey)) || - (key = zorro_find(ZORRO_PROD_GVP_A530_SCSI, 0, skey)) || - (key = zorro_find(ZORRO_PROD_GVP_COMBO_030_R4_SCSI, 0, skey))) + else if (z->id == ZORRO_PROD_GVP_GFORCE_030_SCSI || + z->id == ZORRO_PROD_GVP_A530_SCSI || + z->id == ZORRO_PROD_GVP_COMBO_030_R4_SCSI) default_dma_xfer_mask = ~0x01ffffff; - else if ((key = zorro_find(ZORRO_PROD_GVP_A1291, 0, skey)) || - (key = zorro_find(ZORRO_PROD_GVP_GFORCE_040_SCSI_1, 0, skey))) + else if (z->id == ZORRO_PROD_GVP_A1291 || + z->id == ZORRO_PROD_GVP_GFORCE_040_SCSI_1) default_dma_xfer_mask = ~0x07ffffff; else - break; - - cd = zorro_get_board(key); - address = cd->cd_BoardAddr; + continue; /* * Rumors state that some GVP ram boards use the same product * code as the SCSI controllers. Therefore if the board-size * is not 64KB we asume it is a ram board and bail out. */ - if (cd->cd_BoardSize != 0x10000) + if (z->resource.end-z->resource.start != 0xffff) continue; + address = z->resource.start; + if (!request_mem_region(address, 256, "wd33c93")) + continue; + strcpy(z->name, "GVP Series II SCSI"); + #ifdef CHECK_WD33C93 /* @@ -251,18 +253,18 @@ q = *sasr_3393; /* read it */ if (q & 0x08) /* bit 3 should always be clear */ - continue; + goto release; *sasr_3393 = WD_AUXILIARY_STATUS; /* setup indirect address */ if (*sasr_3393 == WD_AUXILIARY_STATUS) { /* shouldn't retain the write */ *sasr_3393 = save_sasr; /* Oops - restore this byte */ - continue; + goto release; } if (*sasr_3393 != q) { /* should still read the same */ *sasr_3393 = save_sasr; /* Oops - restore this byte */ - continue; + goto release; } if (*scmd_3393 != q) /* and so should the image at 0x1f */ - continue; + goto release; /* Ok, we probably have a wd33c93, but let's check a few other places @@ -279,7 +281,7 @@ *sasr_3393 = WD_SCSI_STATUS; *scmd_3393 = q; if (qq != q) /* should be read only */ - continue; + goto release; *sasr_3393 = 0x1e; /* this register is unimplemented */ q = *scmd_3393; *sasr_3393 = 0x1e; @@ -289,7 +291,7 @@ *sasr_3393 = 0x1e; *scmd_3393 = q; if (qq != q || qq != 0xff) /* should be read only, all 1's */ - continue; + goto release; *sasr_3393 = WD_TIMEOUT_PERIOD; q = *scmd_3393; *sasr_3393 = WD_TIMEOUT_PERIOD; @@ -299,13 +301,13 @@ *sasr_3393 = WD_TIMEOUT_PERIOD; *scmd_3393 = q; if (qq != (~q & 0xff)) /* should be read/write */ - continue; + goto release; #endif instance = scsi_register (tpnt, sizeof (struct WD33C93_hostdata)); - instance->base = (unsigned char *)ZTWO_VADDR(address); + instance->base = ZTWO_VADDR(address); instance->irq = IRQ_AMIGA_PORTS; - instance->unique_id = key; + instance->unique_id = z->slotaddr; if (gvp11_xfer_mask) HDATA(instance)->dma_xfer_mask = gvp11_xfer_mask; @@ -340,7 +342,10 @@ "GVP11 SCSI", gvp11_intr); } DMA(instance)->CNTR = GVP11_DMAC_INT_ENABLE; - zorro_config_board(key, 0); + continue; + +release: + release_mem_region(ZTWO_PADDR(instance->base), 256); } return num_gvp11; @@ -363,7 +368,7 @@ { #ifdef MODULE DMA(instance)->CNTR = 0; - zorro_unconfig_board(instance->unique_id, 0); + release_mem_region(ZTWO_PADDR(instance->base), 256); if (--num_gvp11 == 0) free_irq(IRQ_AMIGA_PORTS, gvp11_intr); wd33c93_release(); diff -ur --new-file old/linux/drivers/scsi/hosts.c new/linux/drivers/scsi/hosts.c --- old/linux/drivers/scsi/hosts.c Mon Dec 13 08:04:20 1999 +++ new/linux/drivers/scsi/hosts.c Mon Jan 24 20:24:50 2000 @@ -347,6 +347,10 @@ #include "../net/fc/iph5526_scsi.h" #endif +#ifdef CONFIG_BLK_DEV_3W_XXXX_RAID +#include "3w-xxxx.h" +#endif + /* * Moved ppa driver to the end of the probe list * since it is a removable host adapter. @@ -625,6 +629,10 @@ #ifdef CONFIG_IPHASE5526 IPH5526_SCSI_FC, #endif +#ifdef CONFIG_BLK_DEV_3W_XXXX_RAID + TWXXXX, +#endif + /* "Removable host adapters" below this line (Parallel Port/USB/other) */ #ifdef CONFIG_SCSI_PPA PPA, @@ -868,7 +876,6 @@ printk ("scsi : %d host%s.\n", next_scsi_host, (next_scsi_host == 1) ? "" : "s"); - /* Now attach the high level drivers */ #ifdef CONFIG_BLK_DEV_SD diff -ur --new-file old/linux/drivers/scsi/hosts.h new/linux/drivers/scsi/hosts.h --- old/linux/drivers/scsi/hosts.h Fri Jan 21 01:07:11 2000 +++ new/linux/drivers/scsi/hosts.h Fri Jan 28 17:02:51 2000 @@ -334,7 +334,6 @@ unsigned int max_lun; unsigned int max_channel; - /* These parameters should be set by the detect routine */ unsigned long base; unsigned long io_port; @@ -434,6 +433,17 @@ unsigned int scsi_init(void); extern struct Scsi_Host * scsi_register(Scsi_Host_Template *, int j); extern void scsi_unregister(struct Scsi_Host * i); + +extern request_fn_proc * scsi_get_request_handler(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt); + +/* + * Prototypes for functions/data in scsi_scan.c + */ +extern void scan_scsis(struct Scsi_Host *shpnt, + unchar hardcoded, + unchar hchannel, + unchar hid, + unchar hlun); extern void scsi_mark_host_reset(struct Scsi_Host *Host); diff -ur --new-file old/linux/drivers/scsi/megaraid.c new/linux/drivers/scsi/megaraid.c --- old/linux/drivers/scsi/megaraid.c Thu Jan 20 19:44:46 2000 +++ new/linux/drivers/scsi/megaraid.c Tue Jan 25 20:41:20 2000 @@ -237,52 +237,17 @@ megaRaidProductInfo *productInfo ); +#include - -#if LINUX_VERSION_CODE > 0x020100 -# include -# include -# define cpuid smp_processor_id() -# if LINUX_VERSION_CODE < 0x020195 -# define DRIVER_LOCK_T unsigned long cpu_flags = 0; -# define DRIVER_LOCK_INIT(p) \ - spin_lock_init(&p->mega_lock); -# define DRIVER_LOCK(p) \ - if(!p->cpu_lock_count[cpuid]) { \ - spin_lock_irqsave(&p->mega_lock, cpu_flags); \ - p->cpu_lock_count[cpuid]++; \ - } else { \ - p->cpu_lock_count[cpuid]++; \ - } -# define DRIVER_UNLOCK(p) \ - if(--p->cpu_lock_count[cpuid] == 0) \ - spin_unlock_irqrestore(&p->mega_lock, cpu_flags); -# define IO_LOCK(p) spin_lock_irqsave(&io_request_lock,cpu_flags); -# define IO_UNLOCK(p) spin_unlock_irqrestore(&io_request_lock,cpu_flags); -# else -# define DRIVER_LOCK_T -# define DRIVER_LOCK_INIT(p) -# define DRIVER_LOCK(p) -# define DRIVER_UNLOCK(p) -# define IO_LOCK_T unsigned long io_flags = 0; -# define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags); -# define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags); -# endif -#else -# define cpuid 0 -# define DRIVER_LOCK_T long cpu_flags; -# define DRIVER_LOCK_INIT(p) -# define DRIVER_LOCK(p) \ - save_flags(cpu_flags); \ - cli(); -# define DRIVER_UNLOCK(p) \ - restore_flags(cpu_flags); -# define IO_LOCK(p) DRIVER_LOCK(p) -# define IO_UNLOCK(p) DRIVER_UNLOCK(p) -# define le32_to_cpu(x) (x) -# define cpu_to_le32(x) (x) -#endif +#define cpuid smp_processor_id() +#define DRIVER_LOCK_T +#define DRIVER_LOCK_INIT(p) +#define DRIVER_LOCK(p) +#define DRIVER_UNLOCK(p) +#define IO_LOCK_T unsigned long io_flags = 0; +#define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags); +#define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags); /* set SERDEBUG to 1 to enable serial debugging */ #define SERDEBUG 0 diff -ur --new-file old/linux/drivers/scsi/megaraid.h new/linux/drivers/scsi/megaraid.h --- old/linux/drivers/scsi/megaraid.h Fri Jan 21 01:07:26 2000 +++ new/linux/drivers/scsi/megaraid.h Fri Jan 28 17:03:07 2000 @@ -152,7 +152,7 @@ sg_tablesize: MAX_SGLIST, /* Scatter/Gather Table Size */\ cmd_per_lun: MAX_CMD_PER_LUN, /* SCSI Commands per LUN */\ present: 0, /* Present */\ - unchecked_isa_dma:1, /* Default Unchecked ISA DMA */\ + unchecked_isa_dma:0, /* Default Unchecked ISA DMA */\ use_clustering: ENABLE_CLUSTERING /* Enable Clustering */\ } #endif diff -ur --new-file old/linux/drivers/scsi/oktagon_esp.c new/linux/drivers/scsi/oktagon_esp.c --- old/linux/drivers/scsi/oktagon_esp.c Sun Aug 15 20:49:08 1999 +++ new/linux/drivers/scsi/oktagon_esp.c Wed Jan 26 21:45:20 2000 @@ -116,24 +116,25 @@ int oktagon_esp_detect(Scsi_Host_Template *tpnt) { struct NCR_ESP *esp; - const struct ConfigDev *esp_dev; - int key; + struct zorro_dev *z = NULL; unsigned long address; struct ESP_regs *eregs; - if((key = zorro_find(ZORRO_PROD_BSC_OKTAGON_2008, 0, 0))){ - esp_dev = zorro_get_board(key); - + while ((z = zorro_find_device(ZORRO_PROD_BSC_OKTAGON_2008, z))) { + unsigned long board = z->resource.start; + if (request_mem_region(board+OKTAGON_ESP_ADDR, + sizeof(struct ESP_regs), "NCR53C9x")) { + strcpy(z->name, "Oktagon 2008 SCSI Host Adapter"); /* * It is a SCSI controller. * Hardwire Host adapter to SCSI ID 7 */ - address = (unsigned long)ZTWO_VADDR(esp_dev->cd_BoardAddr); + address = (unsigned long)ZTWO_VADDR(board); eregs = (struct ESP_regs *)(address + OKTAGON_ESP_ADDR); /* This line was 5 lines lower */ - esp = esp_allocate(tpnt, (void *) esp_dev); + esp = esp_allocate(tpnt, (void *)board+OKTAGON_ESP_ADDR); /* we have to shift the registers only one bit for oktagon */ esp->shift = 1; @@ -197,7 +198,6 @@ esp->esp_command_dvma = (__u32) cmd_buffer; esp->irq = IRQ_AMIGA_PORTS; - esp->slot = key; request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ, "BSC Oktagon SCSI", esp_intr); @@ -209,7 +209,6 @@ esp_initialize(esp); - zorro_config_board(key, 0); printk("ESP_Oktagon Driver 1.1" #ifdef USE_BOTTOM_HALF " [BOTTOM_HALF]" @@ -222,6 +221,7 @@ current_esp = esp; register_reboot_notifier(&oktagon_notifier); return esps_in_use; + } } return 0; } @@ -585,11 +585,9 @@ int oktagon_esp_release(struct Scsi_Host *instance) { #ifdef MODULE - unsigned int key; - - key = ((struct NCR_ESP *)instance->hostdata)->slot; + unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev; esp_release(); - zorro_unconfig_board(key, 0); + release_mem_region(address, sizeof(struct ESP_regs)); free_irq(IRQ_AMIGA_PORTS, esp_intr); unregister_reboot_notifier(&oktagon_notifier); #endif diff -ur --new-file old/linux/drivers/scsi/pci2220i.h new/linux/drivers/scsi/pci2220i.h --- old/linux/drivers/scsi/pci2220i.h Fri Jan 21 01:07:30 2000 +++ new/linux/drivers/scsi/pci2220i.h Fri Jan 28 17:03:08 2000 @@ -248,7 +248,7 @@ USHORT SupportLBA :1; // 49 LBA supported USHORT SupportIORDYDisable :1; // 49 IORDY can be disabled USHORT SupportIORDY :1; // 49 IORDY supported - USHORT ReservedPsuedoDMA :1; // 49 reserved for pseudo DMA mode support + USHORT ReservedPseudoDMA :1; // 49 reserved for pseudo DMA mode support USHORT Reserved3 :3; // 49 USHORT Reserved4; // 50 USHORT Reserved5 :8; // 51 Transfer Cycle Timing - PIO diff -ur --new-file old/linux/drivers/scsi/qlogicfc.c new/linux/drivers/scsi/qlogicfc.c --- old/linux/drivers/scsi/qlogicfc.c Fri Nov 12 01:57:30 1999 +++ new/linux/drivers/scsi/qlogicfc.c Wed Jan 26 22:29:39 2000 @@ -77,7 +77,7 @@ /* Set the following to 1 to include fabric support, fabric support is * currently not as well tested as the other aspects of the driver */ -#define ISP2x00_FABRIC 0 +#define ISP2x00_FABRIC 1 /* Macros used for debugging */ /* @@ -649,11 +649,11 @@ /* this is here so the queues are nicely aligned */ long send_marker; /* do we need to send a marker? */ - char res[RES_QUEUE_LEN + 1][QUEUE_ENTRY_LEN]; - char req[QLOGICFC_REQ_QUEUE_LEN + 1][QUEUE_ENTRY_LEN]; + char * res; + char * req; struct init_cb control_block; int adapter_state; - unsigned long int tag_ages[126]; + unsigned long int tag_ages[QLOGICFC_MAX_ID + 1]; Scsi_Cmnd *handle_ptrs[QLOGICFC_REQ_QUEUE_LEN + 1]; unsigned long handle_serials[QLOGICFC_REQ_QUEUE_LEN + 1]; struct id_name_map port_db[QLOGICFC_MAX_ID + 1]; @@ -662,6 +662,7 @@ u_int port_id; u_char queued; u_char host_id; + struct timer_list explore_timer; }; @@ -676,7 +677,7 @@ static int isp2x00_init(struct Scsi_Host *); static int isp2x00_reset_hardware(struct Scsi_Host *); static int isp2x00_mbox_command(struct Scsi_Host *, u_short[]); -static int isp2x00_return_status(struct Status_Entry *); +static int isp2x00_return_status(Scsi_Cmnd *, struct Status_Entry *); static void isp2x00_intr_handler(int, void *, struct pt_regs *); static void do_isp2x00_intr_handler(int, void *, struct pt_regs *); static int isp2x00_make_portdb(struct Scsi_Host *); @@ -744,14 +745,27 @@ memset(hostdata, 0, sizeof(struct isp2x00_hostdata)); hostdata->pci_dev = pdev; + hostdata->res = (char *) kmalloc((RES_QUEUE_LEN + 1)*QUEUE_ENTRY_LEN, GFP_KERNEL); + if (!hostdata->res){ + printk("qlogicfc%d : could not allocate memory for response queue.\n", hostdata->host_id); + scsi_unregister(host); + continue; + } + hostdata->req = (char *) kmalloc((QLOGICFC_REQ_QUEUE_LEN + 1)*QUEUE_ENTRY_LEN, GFP_KERNEL); + if (!hostdata->req){ + printk("qlogicfc%d : could not allocate memory for request queue.\n", hostdata->host_id); + kfree(hostdata->res); + scsi_unregister(host); + continue; + } hostdata->queued = 0; /* set up the control block */ hostdata->control_block.version = 0x1; - hostdata->control_block.firm_opts = 0x0108; + hostdata->control_block.firm_opts = 0x000e; hostdata->control_block.max_frame_len = 2048; - hostdata->control_block.max_iocb = 256; - hostdata->control_block.exec_throttle = 8; + hostdata->control_block.max_iocb = QLOGICFC_REQ_QUEUE_LEN; + hostdata->control_block.exec_throttle = QLOGICFC_CMD_PER_LUN; hostdata->control_block.retry_delay = 5; hostdata->control_block.retry_cnt = 1; hostdata->control_block.node_name[0] = 0x0020; @@ -761,16 +775,18 @@ hostdata->control_block.hard_addr = 0x0003; hostdata->control_block.req_queue_len = QLOGICFC_REQ_QUEUE_LEN + 1; hostdata->control_block.res_queue_len = RES_QUEUE_LEN + 1; - hostdata->control_block.res_queue_addr_lo = virt_to_bus_low32(&hostdata->res); - hostdata->control_block.res_queue_addr_high = virt_to_bus_high32(&hostdata->res); - hostdata->control_block.req_queue_addr_lo = virt_to_bus_low32(&hostdata->req); - hostdata->control_block.req_queue_addr_high = virt_to_bus_high32(&hostdata->req); - + hostdata->control_block.res_queue_addr_lo = virt_to_bus_low32(hostdata->res); + hostdata->control_block.res_queue_addr_high = virt_to_bus_high32(hostdata->res); + hostdata->control_block.req_queue_addr_lo = virt_to_bus_low32(hostdata->req); + hostdata->control_block.req_queue_addr_high = virt_to_bus_high32(hostdata->req); hostdata->adapter_state = AS_LOOP_DOWN; + hostdata->explore_timer.data = 1; hostdata->host_id = hosts; - + if (isp2x00_init(host) || isp2x00_reset_hardware(host)) { + kfree(hostdata->res); + kfree(hostdata->req); scsi_unregister(host); continue; } @@ -779,6 +795,8 @@ if (request_irq(host->irq, do_isp2x00_intr_handler, SA_INTERRUPT | SA_SHIRQ, "qlogicfc", host)) { printk("qlogicfc%d : interrupt %d already in use\n", hostdata->host_id, host->irq); + kfree(hostdata->res); + kfree(hostdata->req); scsi_unregister(host); continue; } @@ -787,6 +805,8 @@ "in use\n", hostdata->host_id, host->io_port, host->io_port + 0xff); free_irq(host->irq, host); + kfree(hostdata->res); + kfree(hostdata->req); scsi_unregister(host); continue; } @@ -803,6 +823,7 @@ printk("qlogicfc%d : link is not up\n", hostdata->host_id); } hosts++; + hostdata->explore_timer.data = 0; } } @@ -1078,6 +1099,9 @@ release_region(host->io_port, 0xff); + kfree(hostdata->res); + kfree(hostdata->req); + LEAVE("isp2x00_release"); return 0; @@ -1133,7 +1157,12 @@ hostdata->adapter_state = AS_LOOP_GOOD; printk("qlogicfc%d : Port Database\n", hostdata->host_id); for (i = 0; hostdata->port_db[i].wwn != 0; i++) { - printk("wwn: %08x%08x scsi_id: %x loop_id: %x\n", (u_int) (hostdata->port_db[i].wwn >> 32), (u_int) hostdata->port_db[i].wwn, i, hostdata->port_db[i].loop_id); + printk("wwn: %08x%08x scsi_id: %x loop_id: ", (u_int) (hostdata->port_db[i].wwn >> 32), (u_int) hostdata->port_db[i].wwn, i); + if (hostdata->port_db[i].loop_id != hostdata->port_db[0].loop_id || i == 0) + printk("%x", hostdata->port_db[i].loop_id); + else + printk("Not Available"); + printk("\n"); } } if (hostdata->adapter_state == AS_FIRMWARE_DEAD) { @@ -1148,7 +1177,7 @@ DEBUG(printk("qlogicfc%d : request queue depth %d\n", hostdata->host_id, REQ_QUEUE_DEPTH(in_ptr, out_ptr))); - cmd = (struct Command_Entry *) &hostdata->req[in_ptr][0]; + cmd = (struct Command_Entry *) &hostdata->req[in_ptr*QUEUE_ENTRY_LEN]; in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN; if (in_ptr == out_ptr) { DEBUG(printk("qlogicfc%d : request queue overflow\n", hostdata->host_id)); @@ -1175,7 +1204,7 @@ DEBUG(printk("qlogicfc%d : request queue overflow\n", hostdata->host_id)); return 1; } - cmd = (struct Command_Entry *) &hostdata->req[in_ptr][0]; + cmd = (struct Command_Entry *) &hostdata->req[in_ptr*QUEUE_ENTRY_LEN]; in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN; } TRACE("queue command", in_ptr, Cmnd); @@ -1197,6 +1226,7 @@ printk("slot %d has %p\n", i, hostdata->handle_ptrs[i]); } } + return 1; } cmd->hdr.entry_type = ENTRY_COMMAND; @@ -1234,7 +1264,7 @@ while (sg_count > 0) { ++cmd->hdr.entry_cnt; cont = (struct Continuation_Entry *) - &hostdata->req[in_ptr][0]; + &hostdata->req[in_ptr*QUEUE_ENTRY_LEN]; memset(cont, 0, sizeof(struct Continuation_Entry)); in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN; if (in_ptr == out_ptr) { @@ -1280,8 +1310,9 @@ /* scsi.c expects sense info in a different buffer */ cmd->dataseg[0].d_base = virt_to_bus_low32(Cmnd->sense_buffer); #if BITS_PER_LONG > 32 - cmd->dataseg[0].d_base_hi = virt_to_bus_high32(Cmnd->request_buffer); + cmd->dataseg[0].d_base_hi = virt_to_bus_high32(Cmnd->sense_buffer); #endif + cmd->dataseg[0].d_count = sizeof(Cmnd->sense_buffer); cmd->segment_cnt = 1; cmd->control_flags = CFLAG_READ; break; @@ -1333,8 +1364,57 @@ } -#define ASYNC_EVENT_INTERRUPT 0x01 +/* we have received an event, such as a lip or an RSCN, which may mean that + * our port database is incorrect so the port database must be recreated. + */ +static void redo_port_db(unsigned long arg) +{ + + struct Scsi_Host * host = (struct Scsi_Host *) arg; + struct isp2x00_hostdata * hostdata; + unsigned long flags; + int i; + + hostdata = (struct isp2x00_hostdata *) host->hostdata; + hostdata->explore_timer.data = 0; + del_timer(&hostdata->explore_timer); + + spin_lock_irqsave(&io_request_lock, flags); + if (hostdata->adapter_state & AS_REDO_FABRIC_PORTDB || hostdata->adapter_state & AS_REDO_LOOP_PORTDB) { + isp2x00_make_portdb(host); + printk("qlogicfc%d : Port Database\n", hostdata->host_id); + for (i = 0; hostdata->port_db[i].wwn != 0; i++) { + printk("wwn: %08x%08x scsi_id: %x loop_id: ", (u_int) (hostdata->port_db[i].wwn >> 32), (u_int) hostdata->port_db[i].wwn, i); + if (hostdata->port_db[i].loop_id != hostdata->port_db[0].loop_id || i == 0) + printk("%x", hostdata->port_db[i].loop_id); + else + printk("Not Available"); + printk("\n"); + } + + for (i = 0; i < QLOGICFC_REQ_QUEUE_LEN; i++){ + if (hostdata->handle_ptrs[i] && (hostdata->port_db[hostdata->handle_ptrs[i]->target].loop_id > QLOGICFC_MAX_LOOP_ID || hostdata->adapter_state & AS_REDO_LOOP_PORTDB)){ + if (hostdata->port_db[hostdata->handle_ptrs[i]->target].loop_id != hostdata->port_db[0].loop_id){ + hostdata->handle_ptrs[i]->result = DID_SOFT_ERROR << 16; + if (hostdata->handle_ptrs[i]->scsi_done){ + (*hostdata->handle_ptrs[i]->scsi_done) (hostdata->handle_ptrs[i]); + } + else printk("qlogicfc%d : done is null?\n", hostdata->host_id); + hostdata->handle_ptrs[i] = NULL; + hostdata->handle_serials[i] = 0; + } + } + } + + hostdata->adapter_state = AS_LOOP_GOOD; + } + + spin_unlock_irqrestore(&io_request_lock, flags); + +} + +#define ASYNC_EVENT_INTERRUPT 0x01 void do_isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs) { @@ -1377,23 +1457,24 @@ switch (status) { case LOOP_UP: case POINT_TO_POINT_UP: - printk("qlogicfc%d : link is up\n", hostdata->host_id); + printk("qlogicfc%d : Link is Up\n", hostdata->host_id); hostdata->adapter_state = AS_REDO_FABRIC_PORTDB | AS_REDO_LOOP_PORTDB; break; case LOOP_DOWN: - printk("qlogicfc%d : link is down\n", hostdata->host_id); + printk("qlogicfc%d : Link is Down\n", hostdata->host_id); hostdata->adapter_state = AS_LOOP_DOWN; break; case CONNECTION_MODE: printk("received CONNECTION_MODE irq %x\n", inw(host->io_port + MBOX1)); break; case CHANGE_NOTIFICATION: + printk("qlogicfc%d : RSCN Received\n", hostdata->host_id); if (hostdata->adapter_state == AS_LOOP_GOOD) hostdata->adapter_state = AS_REDO_FABRIC_PORTDB; break; case LIP_OCCURED: - case PORT_DB_CHANGED: case LIP_RECEIVED: + printk("qlogicfc%d : Loop Reinitialized\n", hostdata->host_id); if (hostdata->adapter_state == AS_LOOP_GOOD) hostdata->adapter_state = AS_REDO_LOOP_PORTDB; break; @@ -1428,22 +1509,27 @@ default: printk("qlogicfc%d : got an unknown status? %x\n", hostdata->host_id, status); } + if ((hostdata->adapter_state & AS_REDO_LOOP_PORTDB || hostdata->adapter_state & AS_REDO_FABRIC_PORTDB) && hostdata->explore_timer.data == 0){ + hostdata->explore_timer.function = redo_port_db; + hostdata->explore_timer.data = (unsigned long)host; + hostdata->explore_timer.expires = jiffies + (HZ/4); + init_timer(&hostdata->explore_timer); + add_timer(&hostdata->explore_timer); + } outw(0x0, host->io_port + PCI_SEMAPHORE); } else { DEBUG_INTR(printk("qlogicfc%d : response queue update\n", hostdata->host_id)); DEBUG_INTR(printk("qlogicfc%d : response queue depth %d\n", hostdata->host_id, RES_QUEUE_DEPTH(in_ptr, out_ptr))); while (out_ptr != in_ptr) { - sts = (struct Status_Entry *) &hostdata->res[out_ptr][0]; + sts = (struct Status_Entry *) &hostdata->res[out_ptr*QUEUE_ENTRY_LEN]; out_ptr = (out_ptr + 1) & RES_QUEUE_LEN; TRACE("done", out_ptr, Cmnd); DEBUG_INTR(isp2x00_print_status_entry(sts)); if (sts->hdr.entry_type == ENTRY_STATUS && (Cmnd = hostdata->handle_ptrs[sts->handle])) { - Cmnd->result = isp2x00_return_status(sts); - hostdata->handle_ptrs[sts->handle] = NULL; + Cmnd->result = isp2x00_return_status(Cmnd, sts); hostdata->queued--; - /* * if any of the following are true we do not * call scsi_done. if the status is CS_ABORTED @@ -1453,6 +1539,7 @@ if (hostdata->handle_serials[sts->handle] != Cmnd->serial_number || sts->completion_status == CS_ABORTED){ hostdata->handle_serials[sts->handle] = 0; + hostdata->handle_ptrs[sts->handle] = NULL; outw(out_ptr, host->io_port + MBOX5); continue; } @@ -1473,6 +1560,8 @@ continue; } + hostdata->handle_ptrs[sts->handle] = NULL; + if (sts->completion_status == CS_RESET_OCCURRED || (sts->status_flags & STF_BUS_RESET)) hostdata->send_marker = 1; @@ -1514,7 +1603,7 @@ } -static int isp2x00_return_status(struct Status_Entry *sts) +static int isp2x00_return_status(Scsi_Cmnd *Cmnd, struct Status_Entry *sts) { int host_status = DID_ERROR; #if DEBUG_ISP2x00_INTR @@ -1558,7 +1647,10 @@ host_status = DID_ERROR; break; case CS_DATA_UNDERRUN: - host_status = DID_OK; + if (Cmnd->underflow <= (Cmnd->request_bufflen - sts->residual)) + host_status = DID_OK; + else + host_status = DID_ERROR; break; case CS_PORT_UNAVAILABLE: case CS_PORT_LOGGED_OUT: @@ -1848,7 +1940,7 @@ static int isp2x00_init(struct Scsi_Host *sh) { - u_int io_base; + u_long io_base; struct isp2x00_hostdata *hostdata; u_char revision; u_int irq; diff -ur --new-file old/linux/drivers/scsi/qlogicfc_asm.c new/linux/drivers/scsi/qlogicfc_asm.c --- old/linux/drivers/scsi/qlogicfc_asm.c Sat Oct 2 16:41:14 1999 +++ new/linux/drivers/scsi/qlogicfc_asm.c Wed Jan 26 22:29:39 2000 @@ -1,7464 +1,7804 @@ - +/************************************************************************ + * * + * --- ISP2100 Fabric Initiator/Target Firmware --- * + * with expanded LUN addressing. * + * * + ************************************************************************ + * Copyright (C) 1999 Qlogic, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted provided + * that the following conditions are met: + * 1. Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistribution 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR 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. + * * + ************************************************************************ + */ /* - * Firmware Version 1.15.37 (15:37 May 03, 1999) + * W W A RRRR N N IIIII N N GGG + * W W A A R R N N I N N G G + * W W A A R R NN N I NN N G + * W W W AAAAA RRR N N N I N N N G GG + * W W W A A R R N NN I N NN G G + * W W W W A A R R N N I N N G G + * W W A A R R N N IIIII N N GGGG + * + * This version of firmware is a release candidate, + * design verification testing (DVT) has not been completed. + */ +/* + * Firmware Version 1.17.30 (14:05 Sep 30, 1999) */ unsigned short risc_code_addr01 = 0x1000 ; -unsigned short risc_code_length2100 = 0x66e6; -unsigned short risc_code_length2200 = 0x81bd; +unsigned short risc_code_length2100 = 0x77a0; +unsigned short risc_code_length2200 = 0x7a68; -unsigned short risc_code2100[] = { - 0x0078, 0x1029, 0x0000, 0x66e6, 0x0000, 0x2043, 0x4f50, 0x5952, - 0x4947, 0x4854, 0x2031, 0x3939, 0x3620, 0x514c, 0x4f47, 0x4943, +unsigned short risc_code2100[] = { + 0x0078, 0x1029, 0x0000, 0x77a0, 0x0000, 0x2043, 0x4f50, 0x5952, + 0x4947, 0x4854, 0x2031, 0x3939, 0x3920, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3231, 0x3030, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056, - 0x6572, 0x7369, 0x6f6e, 0x2030, 0x312e, 0x3135, 0x2020, 0x2020, - 0x2400, 0x20c1, 0x0021, 0x20a1, 0x76e6, 0x2009, 0x0000, 0x20a9, - 0x071a, 0x41a4, 0x3400, 0x20c9, 0x7bff, 0x2091, 0x2000, 0x2059, - 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x209a, 0x2051, 0x7700, - 0x2a70, 0x705b, 0x9600, 0x705f, 0xffff, 0x7057, 0x95f9, 0x7063, - 0x0300, 0x1078, 0x127a, 0x20a1, 0x7e00, 0x715c, 0x810d, 0x810d, - 0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, 0x0007, 0xa112, 0xa00e, - 0x21a8, 0x41a4, 0x3400, 0x8211, 0x00c0, 0x1058, 0x715c, 0x3400, - 0xa102, 0x0040, 0x1068, 0x0048, 0x1068, 0x20a8, 0xa00e, 0x41a4, - 0x1078, 0x1241, 0x1078, 0x1366, 0x1078, 0x14eb, 0x1078, 0x19c0, - 0x1078, 0x362b, 0x1078, 0x5cac, 0x1078, 0x12f1, 0x1078, 0x2429, - 0x1078, 0x3d6e, 0x1078, 0x3b46, 0x1078, 0x45af, 0x1078, 0x1e55, - 0x1078, 0x47ef, 0x1078, 0x428f, 0x1078, 0x1d74, 0x1078, 0x1e34, - 0x2091, 0x3009, 0x7823, 0x0000, 0x0090, 0x109d, 0x7820, 0xa086, - 0x0002, 0x00c0, 0x109d, 0x7823, 0x4000, 0x0068, 0x1095, 0x781b, - 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, 0x7003, 0x0000, - 0x2001, 0x017f, 0x2003, 0x0000, 0x2a70, 0x7000, 0xa08e, 0x0003, - 0x00c0, 0x10bd, 0x1078, 0x2d9c, 0x1078, 0x2451, 0x1078, 0x3dbe, - 0x1078, 0x3c31, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048, - 0x10c1, 0x1078, 0x45c7, 0x0078, 0x10a4, 0x1079, 0x10c5, 0x0078, - 0x10aa, 0x1078, 0x597e, 0x0078, 0x10b9, 0x10cf, 0x10d0, 0x1143, - 0x10cd, 0x11be, 0x123e, 0x123f, 0x1240, 0x1078, 0x12cd, 0x007c, - 0x127e, 0x0f7e, 0x2091, 0x8000, 0x1078, 0x2ec1, 0x2079, 0x0100, - 0x7844, 0xa005, 0x00c0, 0x1134, 0x2011, 0x3558, 0x1078, 0x4689, - 0x780f, 0x00ff, 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011, 0x8010, - 0x73b8, 0x1078, 0x2d59, 0x1078, 0x57c9, 0x2011, 0x0004, 0x1078, - 0x6a6d, 0x1078, 0x3ae0, 0x70c7, 0x0000, 0x70c3, 0x0000, 0x1078, - 0x1137, 0x72bc, 0x2079, 0x7751, 0x7804, 0xd0ac, 0x0040, 0x1101, - 0xc295, 0x72be, 0xa296, 0x0004, 0x0040, 0x1122, 0x2011, 0x0001, - 0x1078, 0x6a6d, 0x708b, 0x0000, 0x708f, 0xffff, 0x7003, 0x0002, - 0x0f7f, 0x1078, 0x214a, 0x2011, 0x0005, 0x1078, 0x58d8, 0x1078, - 0x4d96, 0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f, 0x127f, - 0x0078, 0x1136, 0x708b, 0x0000, 0x708f, 0xffff, 0x7003, 0x0002, - 0x2011, 0x0005, 0x1078, 0x58d8, 0x1078, 0x4d96, 0x0c7e, 0x2061, - 0x0100, 0x60e3, 0x0008, 0x0c7f, 0x0f7f, 0x127f, 0x007c, 0x0c7e, - 0x20a9, 0x0082, 0x2009, 0x007e, 0x1078, 0x3834, 0x8108, 0x00f0, - 0x113c, 0x0c7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x708c, 0xa086, - 0xffff, 0x0040, 0x1151, 0x1078, 0x214a, 0x1078, 0x4d96, 0x0078, - 0x11bc, 0x70bc, 0xd09c, 0x0040, 0x1179, 0xd084, 0x0040, 0x1179, - 0x0f7e, 0x2079, 0x0100, 0x790c, 0xc1b5, 0x790e, 0x0f7f, 0xd08c, - 0x0040, 0x1179, 0x70c0, 0xa086, 0xffff, 0x0040, 0x1175, 0x1078, - 0x223f, 0x1078, 0x4d96, 0x2011, 0x0001, 0x2019, 0x0000, 0x1078, - 0x2277, 0x1078, 0x4d96, 0x0078, 0x11bc, 0x70c4, 0xa005, 0x00c0, - 0x11bc, 0x7088, 0xa005, 0x00c0, 0x11bc, 0x2001, 0x7752, 0x2004, - 0xd0ac, 0x0040, 0x119f, 0x157e, 0x0c7e, 0x20a9, 0x007f, 0x2009, - 0x0000, 0x017e, 0x1078, 0x384c, 0x00c0, 0x1192, 0x6000, 0xd0ec, - 0x00c0, 0x119a, 0x017f, 0x8108, 0x00f0, 0x1189, 0x0c7f, 0x157f, - 0x0078, 0x119f, 0x017f, 0x0c7f, 0x157f, 0x0078, 0x11bc, 0x7003, - 0x0003, 0x708f, 0xffff, 0x2001, 0x0000, 0x1078, 0x2025, 0x1078, - 0x2dd7, 0x2001, 0x7937, 0x2004, 0xa086, 0x0005, 0x00c0, 0x11b4, - 0x2011, 0x0000, 0x1078, 0x58d8, 0x2011, 0x0000, 0x1078, 0x58e2, - 0x1078, 0x4d96, 0x1078, 0x4e56, 0x127f, 0x007c, 0x017e, 0x0f7e, - 0x127e, 0x2091, 0x8000, 0x2079, 0x0100, 0x7940, 0xa18c, 0x0010, - 0x7942, 0x7924, 0xd1b4, 0x0040, 0x11cf, 0x7827, 0x0040, 0xd19c, - 0x0040, 0x11d4, 0x7827, 0x0008, 0x007e, 0x037e, 0x157e, 0x7900, - 0xa18a, 0x0003, 0x0050, 0x11fa, 0x7954, 0xd1ac, 0x00c0, 0x11fa, - 0x2009, 0x00f8, 0x1078, 0x35fa, 0x7843, 0x0090, 0x7843, 0x0010, - 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x00c0, 0x11f2, 0x7824, 0xd0ac, - 0x00c0, 0x122e, 0x00f0, 0x11ea, 0x2001, 0x0001, 0x1078, 0x2025, - 0x0078, 0x1237, 0x7853, 0x0000, 0x782f, 0x0020, 0x20a9, 0x0008, - 0x00e0, 0x1200, 0x2091, 0x6000, 0x00f0, 0x1200, 0x7853, 0x0400, - 0x782f, 0x0000, 0x2009, 0x00f8, 0x1078, 0x35fa, 0x20a9, 0x000e, - 0x0005, 0x00f0, 0x1210, 0x7853, 0x1400, 0x7843, 0x0090, 0x7843, - 0x0010, 0x2019, 0x61a8, 0x7854, 0x0005, 0x0005, 0xd08c, 0x0040, - 0x1225, 0x7824, 0xd0ac, 0x00c0, 0x122e, 0x8319, 0x00c0, 0x121b, - 0x2001, 0x0001, 0x1078, 0x2025, 0x0078, 0x1235, 0x7828, 0xc09d, - 0x782a, 0x7827, 0x0008, 0x7827, 0x0040, 0x7853, 0x0400, 0x157f, - 0x037f, 0x007f, 0x127f, 0x0f7f, 0x017f, 0x007c, 0x007c, 0x007c, - 0x007c, 0x2a70, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048, - 0x124d, 0x704f, 0xffff, 0x0078, 0x124f, 0x704f, 0x0000, 0x7053, - 0xffff, 0x7067, 0x0000, 0x706b, 0x0000, 0x2061, 0x7920, 0x6003, - 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013, - 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0, 0x2061, - 0x7928, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, 0x0000, 0x600f, - 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001, 0x601f, - 0x0000, 0x007c, 0x1078, 0x12a0, 0x2011, 0x0000, 0x81ff, 0x0040, - 0x129f, 0xa186, 0x0001, 0x00c0, 0x128f, 0x705f, 0x8fff, 0x7057, - 0x8601, 0x7063, 0x0100, 0x705b, 0x8600, 0x0078, 0x129d, 0xa186, - 0x0002, 0x00c0, 0x1297, 0x2011, 0x0000, 0x0078, 0x129d, 0xa186, - 0x0005, 0x00c0, 0x129d, 0x2011, 0x0001, 0x1078, 0x12c7, 0x007c, - 0x2009, 0x0000, 0x2011, 0x0000, 0x1078, 0x12c7, 0x2019, 0xaaaa, - 0x2061, 0xffff, 0x2362, 0x2c24, 0x2061, 0x7fff, 0x2c04, 0xa406, - 0x0040, 0x12b5, 0xc18d, 0x0078, 0x12c2, 0xc185, 0x2011, 0x0001, - 0x1078, 0x12c7, 0x2061, 0xffff, 0x2362, 0x2c04, 0xa306, 0x00c0, - 0x12c2, 0xc195, 0x2011, 0x0001, 0x1078, 0x12c7, 0x007c, 0x3800, - 0xa084, 0xfffc, 0xa205, 0x20c0, 0x007c, 0x2091, 0x8000, 0x0068, - 0x12cf, 0x007e, 0x017e, 0x2079, 0x0000, 0x7818, 0xa084, 0x0000, - 0x00c0, 0x12d5, 0x017f, 0x792e, 0x007f, 0x782a, 0x007f, 0x7826, - 0x3900, 0x783a, 0x7823, 0x8002, 0x781b, 0x0001, 0x2091, 0x5000, - 0x2091, 0x4080, 0x2079, 0x7700, 0x7803, 0x0005, 0x0078, 0x12ee, - 0x007c, 0x2071, 0x7700, 0x7158, 0x712e, 0x2021, 0x0001, 0xa190, - 0x002d, 0xa298, 0x002d, 0x0048, 0x1307, 0x705c, 0xa302, 0x00c8, - 0x1307, 0x220a, 0x2208, 0x2310, 0x8420, 0x0078, 0x12f9, 0x200b, - 0x0000, 0x749e, 0x74a2, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000, - 0x2071, 0x7700, 0x70a0, 0xa0ea, 0x0010, 0x00c8, 0x131a, 0xa06e, - 0x0078, 0x1324, 0x8001, 0x70a2, 0x702c, 0x2068, 0x2d04, 0x702e, - 0x206b, 0x0000, 0x6807, 0x0000, 0x127f, 0x0e7f, 0x007c, 0x0e7e, - 0x2071, 0x7700, 0x127e, 0x2091, 0x8000, 0x70a0, 0x8001, 0x00c8, - 0x1334, 0xa06e, 0x0078, 0x133d, 0x70a2, 0x702c, 0x2068, 0x2d04, - 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x127f, 0x0e7f, 0x007c, - 0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0x7700, 0x702c, 0x206a, - 0x2d00, 0x702e, 0x70a0, 0x8000, 0x70a2, 0x127f, 0x0e7f, 0x007c, - 0x8dff, 0x0040, 0x135c, 0x6804, 0x6807, 0x0000, 0x007e, 0x1078, - 0x1340, 0x0d7f, 0x0078, 0x1350, 0x007c, 0x0e7e, 0x2071, 0x7700, - 0x70a0, 0xa08a, 0x0010, 0xa00d, 0x0e7f, 0x007c, 0x0e7e, 0x2071, - 0x7959, 0x7007, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000, 0x2071, - 0x0000, 0x7010, 0xa085, 0x8004, 0x7012, 0x0e7f, 0x007c, 0x0e7e, - 0x2270, 0x700b, 0x0000, 0x2071, 0x7959, 0x7018, 0xa088, 0x7962, - 0x220a, 0x8000, 0xa084, 0x0007, 0x701a, 0x7004, 0xa005, 0x00c0, - 0x138f, 0x0f7e, 0x2079, 0x0010, 0x1078, 0x13a0, 0x0f7f, 0x0e7f, - 0x007c, 0x0e7e, 0x2071, 0x7959, 0x7004, 0xa005, 0x00c0, 0x139e, - 0x0f7e, 0x2079, 0x0010, 0x1078, 0x13a0, 0x0f7f, 0x0e7f, 0x007c, - 0x7000, 0x0079, 0x13a3, 0x13a7, 0x1411, 0x142e, 0x142e, 0x7018, - 0x711c, 0xa106, 0x00c0, 0x13af, 0x7007, 0x0000, 0x007c, 0x0d7e, - 0xa180, 0x7962, 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007, - 0x711e, 0x7803, 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c, - 0x783a, 0x6830, 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804, - 0x0d7f, 0xd084, 0x0040, 0x13d1, 0x7007, 0x0001, 0x1078, 0x13d6, - 0x007c, 0x7007, 0x0002, 0x1078, 0x13ec, 0x007c, 0x017e, 0x027e, - 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x13e1, 0x2110, - 0xa006, 0x700e, 0x7212, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803, - 0x0041, 0x027f, 0x017f, 0x007c, 0x017e, 0x027e, 0x137e, 0x147e, - 0x157e, 0x7014, 0x2098, 0x20a1, 0x0014, 0x7803, 0x0026, 0x710c, - 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x1400, 0x2110, 0xa006, - 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803, - 0x0001, 0x3300, 0x7016, 0x157f, 0x147f, 0x137f, 0x027f, 0x017f, - 0x007c, 0x137e, 0x147e, 0x157e, 0x2099, 0x77e5, 0x20a1, 0x0018, - 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000, - 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x700b, - 0x77e0, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x137e, 0x147e, - 0x157e, 0x2001, 0x7814, 0x209c, 0x20a1, 0x0014, 0x7803, 0x0026, - 0x2001, 0x7815, 0x20ac, 0x53a6, 0x2099, 0x7816, 0x20a1, 0x0018, - 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000, - 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c, 0x7002, 0x700b, - 0x7811, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x017e, 0x0e7e, - 0x2071, 0x7959, 0x0f7e, 0x2079, 0x0010, 0x7904, 0x7803, 0x0002, - 0xd1fc, 0x0040, 0x1471, 0xa18c, 0x0700, 0x0040, 0x146e, 0x7008, - 0xa080, 0x0002, 0x2003, 0x0200, 0x0078, 0x1471, 0x7004, 0x1079, - 0x1475, 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x13a0, 0x147d, 0x149f, - 0x14b9, 0x14e2, 0x147b, 0x0078, 0x147b, 0x137e, 0x147e, 0x157e, - 0x7014, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x7010, 0x20a8, - 0x53a5, 0x3400, 0x7016, 0x157f, 0x147f, 0x137f, 0x700c, 0xa005, - 0x0040, 0x14a6, 0x1078, 0x13d6, 0x007c, 0x7008, 0xa080, 0x0002, - 0x2003, 0x0100, 0x7007, 0x0000, 0x1078, 0x13a0, 0x007c, 0x700c, - 0xa005, 0x0040, 0x14a6, 0x1078, 0x13ec, 0x007c, 0x0d7e, 0x7008, - 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, 0x682e, 0x783c, - 0x6832, 0x680b, 0x0100, 0x0d7f, 0x7007, 0x0000, 0x1078, 0x13a0, - 0x007c, 0x137e, 0x147e, 0x157e, 0x2001, 0x77e3, 0x2004, 0xa080, + 0x6572, 0x7369, 0x6f6e, 0x2030, 0x312e, 0x3137, 0x2020, 0x2020, + 0x2400, 0x2091, 0x2000, 0x20c1, 0x0021, 0x2039, 0xffff, 0x2019, + 0xaaaa, 0x2760, 0x2069, 0x7fff, 0x20c1, 0x0020, 0x2c2c, 0x2d34, + 0x2762, 0x236a, 0x2c24, 0x2d04, 0x266a, 0x2562, 0xa406, 0x00c0, + 0x104e, 0x20c1, 0x0021, 0x2c2c, 0x2362, 0x2c04, 0x2562, 0xa306, + 0x0040, 0x104e, 0x20c1, 0x0020, 0x2039, 0x8fff, 0x20a1, 0x8f00, + 0x2708, 0x810d, 0x810d, 0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, + 0x0008, 0xa112, 0xa00e, 0x21a8, 0x41a4, 0x3400, 0x8211, 0x00c0, + 0x105b, 0x2708, 0x3400, 0xa102, 0x0040, 0x106b, 0x0048, 0x106b, + 0x20a8, 0xa00e, 0x41a4, 0x20a1, 0x87a0, 0x2009, 0x0000, 0x20a9, + 0x0760, 0x41a4, 0x3400, 0x20c9, 0x8cff, 0x2059, 0x0000, 0x2b78, + 0x7823, 0x0004, 0x2089, 0x226f, 0x2051, 0x8800, 0x2a70, 0x775e, + 0xa786, 0x8fff, 0x0040, 0x108e, 0x705b, 0xa700, 0x7057, 0xa6f5, + 0x7063, 0x0200, 0x7067, 0x0200, 0x0078, 0x1096, 0x7057, 0x9b01, + 0x7063, 0x0100, 0x7067, 0x0100, 0x705b, 0x9b00, 0x1078, 0x128f, + 0x1078, 0x136a, 0x1078, 0x1513, 0x1078, 0x1b00, 0x1078, 0x3d25, + 0x1078, 0x68a0, 0x1078, 0x12f5, 0x1078, 0x26b2, 0x1078, 0x4778, + 0x1078, 0x42aa, 0x1078, 0x5004, 0x1078, 0x1fc3, 0x1078, 0x5260, + 0x1078, 0x4cb7, 0x1078, 0x1ee5, 0x1078, 0x1fa0, 0x2091, 0x3009, + 0x7823, 0x0000, 0x0090, 0x10cb, 0x7820, 0xa086, 0x0002, 0x00c0, + 0x10cb, 0x7823, 0x4000, 0x0068, 0x10c3, 0x781b, 0x0001, 0x2091, + 0x5000, 0x2091, 0x4080, 0x2a70, 0x7003, 0x0000, 0x2001, 0x017f, + 0x2003, 0x0000, 0x2a70, 0x7000, 0xa08e, 0x0003, 0x00c0, 0x10eb, + 0x1078, 0x31bd, 0x1078, 0x26da, 0x1078, 0x47c8, 0x1078, 0x4469, + 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048, 0x10ef, 0x1078, + 0x5020, 0x0078, 0x10d2, 0x1079, 0x10f3, 0x0078, 0x10d8, 0x1078, + 0x6565, 0x0078, 0x10e7, 0x10fd, 0x10fe, 0x1189, 0x10fb, 0x1208, + 0x128c, 0x128d, 0x128e, 0x1078, 0x12d2, 0x007c, 0x127e, 0x0f7e, + 0x2091, 0x8000, 0x1078, 0x3541, 0x2079, 0x0100, 0x7844, 0xa005, + 0x00c0, 0x117a, 0x2011, 0x3c35, 0x1078, 0x50f2, 0x780f, 0x00ff, + 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011, 0x8010, 0x73bc, 0x1078, + 0x317a, 0x7238, 0xc284, 0x723a, 0x2001, 0x880c, 0x2014, 0xc2ac, + 0x2202, 0x1078, 0x6376, 0x2011, 0x0004, 0x1078, 0x7802, 0x1078, + 0x4236, 0x1078, 0x3d0d, 0x0040, 0x1135, 0x7083, 0x0001, 0x70b7, + 0x0000, 0x1078, 0x36ef, 0x0078, 0x117a, 0x70cb, 0x0000, 0x70c7, + 0x0000, 0x706b, 0x0000, 0x706f, 0x0000, 0x1078, 0x117d, 0x72c0, + 0x2079, 0x8851, 0x7804, 0xd0ac, 0x0040, 0x1147, 0xc295, 0x72c2, + 0xa296, 0x0004, 0x0040, 0x1168, 0x2011, 0x0001, 0x1078, 0x7802, + 0x708f, 0x0000, 0x7093, 0xffff, 0x7003, 0x0002, 0x0f7f, 0x1078, + 0x231f, 0x2011, 0x0005, 0x1078, 0x64ae, 0x1078, 0x5888, 0x0c7e, + 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f, 0x127f, 0x0078, 0x117c, + 0x708f, 0x0000, 0x7093, 0xffff, 0x7003, 0x0002, 0x2011, 0x0005, + 0x1078, 0x64ae, 0x1078, 0x5888, 0x0c7e, 0x2061, 0x0100, 0x60e3, + 0x0008, 0x0c7f, 0x0f7f, 0x127f, 0x007c, 0x0c7e, 0x20a9, 0x0082, + 0x2009, 0x007e, 0x1078, 0x3f76, 0x8108, 0x00f0, 0x1182, 0x0c7f, + 0x007c, 0x127e, 0x2091, 0x8000, 0x7090, 0xa086, 0xffff, 0x0040, + 0x1197, 0x1078, 0x231f, 0x1078, 0x5888, 0x0078, 0x1206, 0x70c0, + 0xd09c, 0x0040, 0x11c3, 0xd084, 0x0040, 0x11c3, 0x0f7e, 0x2079, + 0x0100, 0x790c, 0xc1b5, 0x790e, 0x0f7f, 0xd08c, 0x0040, 0x11c3, + 0x70c4, 0xa086, 0xffff, 0x0040, 0x11bf, 0x1078, 0x2449, 0x1078, + 0x5888, 0x70c0, 0xd094, 0x00c0, 0x1206, 0x2011, 0x0001, 0x2019, + 0x0000, 0x1078, 0x2481, 0x1078, 0x5888, 0x0078, 0x1206, 0x70c8, + 0xa005, 0x00c0, 0x1206, 0x708c, 0xa005, 0x00c0, 0x1206, 0x2001, + 0x8852, 0x2004, 0xd0ac, 0x0040, 0x11e9, 0x157e, 0x0c7e, 0x20a9, + 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x3f8e, 0x00c0, 0x11dc, + 0x6000, 0xd0ec, 0x00c0, 0x11e4, 0x017f, 0x8108, 0x00f0, 0x11d3, + 0x0c7f, 0x157f, 0x0078, 0x11e9, 0x017f, 0x0c7f, 0x157f, 0x0078, + 0x1206, 0x7003, 0x0003, 0x7093, 0xffff, 0x2001, 0x0000, 0x1078, + 0x21f3, 0x1078, 0x31f8, 0x2001, 0x8aa3, 0x2004, 0xa086, 0x0005, + 0x00c0, 0x11fe, 0x2011, 0x0000, 0x1078, 0x64ae, 0x2011, 0x0000, + 0x1078, 0x64b8, 0x1078, 0x5888, 0x1078, 0x5948, 0x127f, 0x007c, + 0x017e, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079, 0x0100, 0x2009, + 0x00f7, 0x1078, 0x3cdc, 0x7940, 0xa18c, 0x0010, 0x7942, 0x7924, + 0xd1b4, 0x0040, 0x121d, 0x7827, 0x0040, 0xd19c, 0x0040, 0x1222, + 0x7827, 0x0008, 0x007e, 0x037e, 0x157e, 0x7900, 0xa18a, 0x0003, + 0x0050, 0x1248, 0x7954, 0xd1ac, 0x00c0, 0x1248, 0x2009, 0x00f8, + 0x1078, 0x3cdc, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x09c4, + 0x7820, 0xd09c, 0x00c0, 0x1240, 0x7824, 0xd0ac, 0x00c0, 0x127c, + 0x00f0, 0x1238, 0x2001, 0x0001, 0x1078, 0x21f3, 0x0078, 0x1285, + 0x7853, 0x0000, 0x782f, 0x0020, 0x20a9, 0x0050, 0x00e0, 0x124e, + 0x2091, 0x6000, 0x00f0, 0x124e, 0x7853, 0x0400, 0x782f, 0x0000, + 0x2009, 0x00f8, 0x1078, 0x3cdc, 0x20a9, 0x000e, 0x0005, 0x00f0, + 0x125e, 0x7853, 0x1400, 0x7843, 0x0090, 0x7843, 0x0010, 0x2019, + 0x61a8, 0x7854, 0x0005, 0x0005, 0xd08c, 0x0040, 0x1273, 0x7824, + 0xd0ac, 0x00c0, 0x127c, 0x8319, 0x00c0, 0x1269, 0x2001, 0x0001, + 0x1078, 0x21f3, 0x0078, 0x1283, 0x7828, 0xc09d, 0x782a, 0x7827, + 0x0008, 0x7827, 0x0040, 0x7853, 0x0400, 0x157f, 0x037f, 0x007f, + 0x127f, 0x0f7f, 0x017f, 0x007c, 0x007c, 0x007c, 0x007c, 0x2a70, + 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048, 0x129b, 0x704f, + 0xffff, 0x0078, 0x129d, 0x704f, 0x0000, 0x7053, 0xffff, 0x706b, + 0x0000, 0x706f, 0x0000, 0x2061, 0x8a8c, 0x6003, 0x0909, 0x6007, + 0x0000, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, + 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0, 0x2061, 0x8a94, 0x6003, + 0x8000, 0x6007, 0x0000, 0x600b, 0x0000, 0x600f, 0x0200, 0x6013, + 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001, 0x601f, 0x0000, 0x2061, + 0x8a9c, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, + 0x2020, 0x007c, 0x2091, 0x8000, 0x0068, 0x12d4, 0x007e, 0x017e, + 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x12da, 0x017f, 0x792e, + 0x007f, 0x782a, 0x007f, 0x7826, 0x3900, 0x783a, 0x7823, 0x8002, + 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2079, 0x8800, + 0x7803, 0x0005, 0x0078, 0x12f2, 0x007c, 0x2071, 0x8800, 0x7158, + 0x712e, 0x2021, 0x0001, 0xa190, 0x002d, 0xa298, 0x002d, 0x0048, + 0x130b, 0x705c, 0xa302, 0x00c8, 0x130b, 0x220a, 0x2208, 0x2310, + 0x8420, 0x0078, 0x12fd, 0x200b, 0x0000, 0x74a2, 0x74a6, 0x007c, + 0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0x8800, 0x70a4, 0xa0ea, + 0x0010, 0x00c8, 0x131e, 0xa06e, 0x0078, 0x1328, 0x8001, 0x70a6, + 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, + 0x127f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0x8800, 0x127e, 0x2091, + 0x8000, 0x70a4, 0x8001, 0x00c8, 0x1338, 0xa06e, 0x0078, 0x1341, + 0x70a6, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, + 0x0000, 0x127f, 0x0e7f, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000, + 0x2071, 0x8800, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70a4, 0x8000, + 0x70a6, 0x127f, 0x0e7f, 0x007c, 0x8dff, 0x0040, 0x1360, 0x6804, + 0x6807, 0x0000, 0x007e, 0x1078, 0x1344, 0x0d7f, 0x0078, 0x1354, + 0x007c, 0x0e7e, 0x2071, 0x8800, 0x70a4, 0xa08a, 0x0010, 0xa00d, + 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0x8ac7, 0x7007, 0x0000, 0x701b, + 0x0000, 0x701f, 0x0000, 0x2071, 0x0000, 0x7010, 0xa085, 0x8004, + 0x7012, 0x0e7f, 0x007c, 0x0e7e, 0x2270, 0x700b, 0x0000, 0x2071, + 0x8ac7, 0x7018, 0xa088, 0x8ad0, 0x220a, 0x8000, 0xa084, 0x0007, + 0x701a, 0x7004, 0xa005, 0x00c0, 0x1393, 0x0f7e, 0x2079, 0x0010, + 0x1078, 0x13a4, 0x0f7f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0x8ac7, + 0x7004, 0xa005, 0x00c0, 0x13a2, 0x0f7e, 0x2079, 0x0010, 0x1078, + 0x13a4, 0x0f7f, 0x0e7f, 0x007c, 0x7000, 0x0079, 0x13a7, 0x13ab, + 0x1415, 0x1432, 0x1432, 0x7018, 0x711c, 0xa106, 0x00c0, 0x13b3, + 0x7007, 0x0000, 0x007c, 0x0d7e, 0xa180, 0x8ad0, 0x2004, 0x700a, + 0x2068, 0x8108, 0xa18c, 0x0007, 0x711e, 0x7803, 0x0026, 0x6824, + 0x7832, 0x6828, 0x7836, 0x682c, 0x783a, 0x6830, 0x783e, 0x6810, + 0x700e, 0x680c, 0x7016, 0x6804, 0x0d7f, 0xd084, 0x0040, 0x13d5, + 0x7007, 0x0001, 0x1078, 0x13da, 0x007c, 0x7007, 0x0002, 0x1078, + 0x13f0, 0x007c, 0x017e, 0x027e, 0x710c, 0x2011, 0x0040, 0xa182, + 0x0040, 0x00c8, 0x13e5, 0x2110, 0xa006, 0x700e, 0x7212, 0x8203, + 0x7822, 0x7803, 0x0020, 0x7803, 0x0041, 0x027f, 0x017f, 0x007c, + 0x017e, 0x027e, 0x137e, 0x147e, 0x157e, 0x7014, 0x2098, 0x20a1, + 0x0014, 0x7803, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, + 0x00c8, 0x1404, 0x2110, 0xa006, 0x700e, 0x22a8, 0x53a6, 0x8203, + 0x7822, 0x7803, 0x0020, 0x3300, 0x7016, 0x7803, 0x0001, 0x157f, + 0x147f, 0x137f, 0x027f, 0x017f, 0x007c, 0x137e, 0x147e, 0x157e, + 0x2099, 0x88f9, 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, + 0x0020, 0x127e, 0x2091, 0x8000, 0x7803, 0x0041, 0x7007, 0x0003, + 0x7000, 0xc084, 0x7002, 0x700b, 0x88f4, 0x127f, 0x157f, 0x147f, + 0x137f, 0x007c, 0x137e, 0x147e, 0x157e, 0x2001, 0x8928, 0x209c, + 0x20a1, 0x0014, 0x7803, 0x0026, 0x2001, 0x8929, 0x20ac, 0x53a6, + 0x2099, 0x892a, 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, + 0x0020, 0x127e, 0x2091, 0x8000, 0x7803, 0x0001, 0x7007, 0x0004, + 0x7000, 0xc08c, 0x7002, 0x700b, 0x8925, 0x127f, 0x157f, 0x147f, + 0x137f, 0x007c, 0x017e, 0x0e7e, 0x2071, 0x8ac7, 0x0f7e, 0x2079, + 0x0010, 0x7904, 0x7803, 0x0002, 0xd1fc, 0x0040, 0x146c, 0xa18c, + 0x0700, 0x7004, 0x1079, 0x1470, 0x0f7f, 0x0e7f, 0x017f, 0x007c, + 0x13a4, 0x1478, 0x14a5, 0x14cd, 0x1500, 0x1476, 0x0078, 0x1476, + 0xa18c, 0x0700, 0x00c0, 0x149e, 0x137e, 0x147e, 0x157e, 0x7014, + 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x7010, 0x20a8, 0x53a5, + 0x3400, 0x7016, 0x157f, 0x147f, 0x137f, 0x700c, 0xa005, 0x0040, + 0x14ba, 0x1078, 0x13da, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003, + 0x0100, 0x7007, 0x0000, 0x1078, 0x13a4, 0x007c, 0x7008, 0xa080, + 0x0002, 0x2003, 0x0200, 0x0078, 0x1499, 0xa18c, 0x0700, 0x00c0, + 0x14b0, 0x700c, 0xa005, 0x0040, 0x14ba, 0x1078, 0x13f0, 0x007c, + 0x7008, 0xa080, 0x0002, 0x2003, 0x0200, 0x7007, 0x0000, 0x1078, + 0x13a4, 0x007c, 0x0d7e, 0x7008, 0x2068, 0x7830, 0x6826, 0x7834, + 0x682a, 0x7838, 0x682e, 0x783c, 0x6832, 0x680b, 0x0100, 0x0d7f, + 0x7007, 0x0000, 0x1078, 0x13a4, 0x007c, 0xa18c, 0x0700, 0x00c0, + 0x14fa, 0x137e, 0x147e, 0x157e, 0x2001, 0x88f7, 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x20a9, 0x0020, - 0x53a5, 0x2001, 0x77e5, 0x2004, 0xd0bc, 0x0040, 0x14d8, 0x2001, - 0x77ee, 0x2004, 0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020, 0x53a5, - 0x157f, 0x147f, 0x137f, 0x7007, 0x0000, 0x1078, 0x3e67, 0x1078, - 0x13a0, 0x007c, 0x2001, 0x7813, 0x2003, 0x0100, 0x7007, 0x0000, - 0x1078, 0x13a0, 0x007c, 0x127e, 0x2091, 0x2100, 0x2079, 0x0030, - 0x2071, 0x796a, 0x7003, 0x0000, 0x700f, 0x7970, 0x7013, 0x7970, - 0x780f, 0x0070, 0x127f, 0x007c, 0x6934, 0xa184, 0x0007, 0x0079, - 0x1501, 0x1509, 0x154f, 0x1509, 0x1509, 0x1509, 0x1534, 0x1518, - 0x150d, 0xa085, 0x0001, 0x0078, 0x1569, 0x684c, 0xd0bc, 0x0040, - 0x1509, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, 0x0078, 0x1557, - 0xa18c, 0x00ff, 0xa186, 0x001e, 0x00c0, 0x1509, 0x684c, 0xd0bc, - 0x0040, 0x1509, 0x6860, 0x682e, 0x685c, 0x682a, 0x6804, 0x681a, - 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x1c7e, 0x2004, - 0x6832, 0x6858, 0x0078, 0x155f, 0xa18c, 0x00ff, 0xa186, 0x0015, - 0x00c0, 0x1509, 0x684c, 0xd0ac, 0x0040, 0x1509, 0x6804, 0x681a, - 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x1c7e, 0x2004, - 0x6832, 0xa006, 0x682e, 0x682a, 0x6858, 0x0078, 0x155f, 0x684c, - 0xd0ac, 0x0040, 0x1509, 0xa006, 0x682e, 0x682a, 0x6858, 0xa18c, - 0x000f, 0xa188, 0x1c7e, 0x210c, 0x6932, 0x2d08, 0x691a, 0x6826, - 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c, 0x6912, 0x6980, - 0x6916, 0x007c, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001, 0x020a, - 0x2004, 0x82ff, 0x0040, 0x1584, 0xa280, 0x0004, 0x0d7e, 0x206c, - 0x684c, 0xd0dc, 0x00c0, 0x1580, 0x1078, 0x14fc, 0x10c0, 0x12cd, - 0x6808, 0x8000, 0x680a, 0x0d7f, 0x127e, 0x047e, 0x037e, 0x027e, - 0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000, 0xa005, 0x00c0, - 0x1598, 0x7206, 0x2001, 0x15ac, 0x007e, 0x2260, 0x0078, 0x16c4, - 0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a, 0x8108, 0xa182, - 0x798b, 0x0048, 0x15a5, 0x2009, 0x7970, 0x710e, 0x7000, 0xa005, - 0x00c0, 0x15ac, 0x1078, 0x16ad, 0x127f, 0x007c, 0x127e, 0x027e, - 0x037e, 0x0c7e, 0x007e, 0x2091, 0x2100, 0x007f, 0x047f, 0x037f, - 0x027f, 0x0d7e, 0x0c7e, 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e, - 0xa005, 0x0040, 0x1600, 0x6808, 0xa005, 0x0040, 0x1666, 0x7000, - 0xa005, 0x00c0, 0x15cd, 0x0078, 0x15fa, 0x700c, 0x7110, 0xa106, - 0x00c0, 0x166a, 0x7004, 0xa406, 0x00c0, 0x15fa, 0x2001, 0x0005, - 0x2004, 0xd08c, 0x0040, 0x15e3, 0x047e, 0x1078, 0x1785, 0x047f, - 0x2460, 0x0078, 0x15c3, 0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0, - 0x15d6, 0x7804, 0xa084, 0x6000, 0x0040, 0x15f4, 0xa086, 0x6000, - 0x0040, 0x15f4, 0x0078, 0x15d6, 0x7803, 0x0004, 0x7003, 0x0000, - 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x5d41, 0x0078, 0x166a, - 0x6808, 0xa005, 0x0040, 0x1666, 0x7000, 0xa005, 0x00c0, 0x160a, - 0x0078, 0x1666, 0x700c, 0x7110, 0xa106, 0x00c0, 0x1613, 0x7004, - 0xa406, 0x00c0, 0x1666, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0040, - 0x1620, 0x047e, 0x1078, 0x1785, 0x047f, 0x2460, 0x0078, 0x1600, - 0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0, 0x1613, 0x2001, 0x0005, - 0x2004, 0xd08c, 0x00c0, 0x1619, 0x7804, 0xa084, 0x6000, 0x0040, - 0x1637, 0xa086, 0x6000, 0x0040, 0x1637, 0x0078, 0x1613, 0x7007, - 0x0000, 0xa016, 0x2218, 0x7000, 0xa08e, 0x0001, 0x0040, 0x1658, - 0xa08e, 0x0002, 0x00c0, 0x1666, 0x0c7e, 0x0e7e, 0x6818, 0x2060, - 0x1078, 0x1c53, 0x2804, 0xac70, 0x6034, 0xd09c, 0x00c0, 0x1654, - 0x7308, 0x720c, 0x0078, 0x1656, 0x7310, 0x7214, 0x0e7f, 0x0c7f, - 0x7820, 0xa318, 0x7824, 0xa211, 0x6810, 0xa300, 0x6812, 0x6814, - 0xa201, 0x6816, 0x7803, 0x0004, 0x7003, 0x0000, 0x2009, 0x0048, - 0x1078, 0x5d41, 0x0c7f, 0x0d7f, 0x127f, 0x007c, 0x0f7e, 0x0e7e, - 0x2071, 0x796a, 0x7000, 0xa086, 0x0000, 0x0040, 0x16aa, 0x7004, - 0xac06, 0x00c0, 0x169b, 0x2079, 0x0030, 0x7804, 0xd0fc, 0x00c0, - 0x1697, 0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0, 0x167d, 0x7803, - 0x0004, 0x7804, 0xd0ac, 0x00c0, 0x1689, 0x7803, 0x0002, 0x7803, - 0x0009, 0x7003, 0x0003, 0x7007, 0x0000, 0x0078, 0x169b, 0x1078, - 0x1785, 0x0078, 0x1672, 0x157e, 0x20a9, 0x0009, 0x2009, 0x7970, - 0x2104, 0xac06, 0x00c0, 0x16a5, 0x200a, 0xa188, 0x0003, 0x00f0, - 0x16a0, 0x157f, 0x0e7f, 0x0f7f, 0x007c, 0x700c, 0x7110, 0xa106, - 0x00c0, 0x16b5, 0x7003, 0x0000, 0x007c, 0x2104, 0x7006, 0x2060, - 0x8108, 0x211c, 0x8108, 0x2124, 0x8108, 0xa182, 0x798b, 0x0048, - 0x16c3, 0x2009, 0x7970, 0x7112, 0x8cff, 0x00c0, 0x16cb, 0x1078, - 0x1950, 0x0078, 0x16f2, 0x6010, 0x2068, 0x2d58, 0x6828, 0xa406, - 0x00c0, 0x16d6, 0x682c, 0xa306, 0x0040, 0x16da, 0x1078, 0x1c9e, - 0x00c0, 0x16c7, 0x684c, 0xd0f4, 0x00c0, 0x16c7, 0x6824, 0x2050, - 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009, - 0x0011, 0x1078, 0x16f3, 0x0040, 0x16f1, 0x2009, 0x0001, 0x1078, - 0x16f3, 0x2d58, 0x007c, 0x8aff, 0x0040, 0x1780, 0xa03e, 0x2730, - 0x6850, 0xd0fc, 0x00c0, 0x1712, 0x0d7e, 0x2804, 0xac68, 0x2900, - 0x0079, 0x1702, 0x1762, 0x1722, 0x1722, 0x1762, 0x1762, 0x175a, - 0x1762, 0x1722, 0x1762, 0x1728, 0x1728, 0x1762, 0x1762, 0x1762, - 0x1751, 0x1728, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, - 0x0d7e, 0xd99c, 0x0040, 0x1765, 0x2804, 0xac68, 0x6f08, 0x6e0c, - 0x0078, 0x1765, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0078, 0x1765, - 0x7b0c, 0xd3bc, 0x0040, 0x1749, 0x7004, 0x0e7e, 0x2070, 0x701c, - 0x0e7f, 0xa086, 0x0008, 0x00c0, 0x1749, 0x7b08, 0xa39c, 0x0fff, - 0x2d20, 0x0d7f, 0x0d7e, 0x6a14, 0x82ff, 0x00c0, 0x1744, 0x6810, - 0xa302, 0x0048, 0x1744, 0x6b10, 0x2011, 0x0000, 0x2468, 0x0078, - 0x174b, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0078, - 0x1765, 0x0d7f, 0x0d7e, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, - 0x00c0, 0x1762, 0x0d7f, 0x1078, 0x1c3a, 0x00c0, 0x16f3, 0xa00e, - 0x0078, 0x1780, 0x0d7f, 0x1078, 0x12cd, 0x7b22, 0x7a26, 0x7d32, - 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x0d7f, - 0x6828, 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x2300, 0x6b10, - 0xa302, 0x6812, 0x2200, 0x6a14, 0xa203, 0x6816, 0x1078, 0x1c3a, - 0x007c, 0x1078, 0x12cd, 0x1078, 0x12cd, 0x127e, 0x2091, 0x2100, - 0x007e, 0x017e, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, - 0xa184, 0x0700, 0x00c0, 0x1783, 0xa184, 0x0003, 0xa086, 0x0003, - 0x0040, 0x1783, 0x7000, 0x0079, 0x179d, 0x17a5, 0x17a7, 0x187f, - 0x18e7, 0x18fe, 0x17a5, 0x17a5, 0x17a5, 0x1078, 0x12cd, 0x8001, - 0x7002, 0xa184, 0x0880, 0x00c0, 0x17bc, 0x8aff, 0x0040, 0x181f, - 0x2009, 0x0001, 0x1078, 0x16f3, 0x0040, 0x1910, 0x2009, 0x0001, - 0x1078, 0x16f3, 0x0078, 0x1910, 0x7803, 0x0004, 0x7003, 0x0000, - 0xd1bc, 0x00c0, 0x1807, 0x027e, 0x037e, 0x6b28, 0x6a2c, 0x7820, - 0x686e, 0xa31a, 0x7824, 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x7820, - 0x6910, 0xa100, 0x6812, 0x7824, 0x6914, 0xa101, 0x6816, 0x037f, - 0x027f, 0x7830, 0x681e, 0x7834, 0x6822, 0x1078, 0x1c53, 0x2a00, - 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000, 0x6850, - 0xc0fd, 0x6852, 0x6808, 0x8001, 0x680a, 0x00c0, 0x17f9, 0x684c, - 0xd0e4, 0x0040, 0x17f9, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, - 0x5d41, 0x7808, 0xd0ec, 0x00c0, 0x1803, 0x7803, 0x0009, 0x7003, - 0x0004, 0x0078, 0x1910, 0x1078, 0x16ad, 0x0078, 0x1910, 0x057e, - 0x7d0c, 0xd5bc, 0x00c0, 0x180e, 0x1078, 0x7692, 0x057f, 0x1078, - 0x1914, 0x682b, 0xffff, 0x682f, 0xffff, 0x697c, 0x6912, 0x6980, - 0x6916, 0x7803, 0x0009, 0x7003, 0x0003, 0x0078, 0x1910, 0x684c, - 0xc0f5, 0x684e, 0x7814, 0xa005, 0x00c0, 0x1837, 0x7003, 0x0000, - 0x6808, 0x8001, 0x680a, 0x00c0, 0x1833, 0x7004, 0x2060, 0x2009, - 0x0048, 0x1078, 0x5d41, 0x1078, 0x16ad, 0x0078, 0x1910, 0x7814, - 0x6910, 0xa102, 0x6812, 0x6914, 0xa183, 0x0000, 0x6816, 0x7814, - 0x7908, 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214, 0x8214, - 0xa10a, 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b, 0x810b, - 0x1078, 0x197b, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803, 0x0001, - 0x7804, 0xd0fc, 0x0040, 0x1858, 0x7803, 0x0002, 0x7803, 0x0004, - 0x780f, 0x0070, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, 0x0048, - 0x1078, 0x5d41, 0x1078, 0x199e, 0x0040, 0x1833, 0x7908, 0xd1ec, - 0x00c0, 0x1876, 0x2009, 0x0009, 0x0078, 0x1878, 0x2009, 0x0019, - 0x7902, 0x7803, 0x0009, 0x7003, 0x0003, 0x0078, 0x1910, 0x8001, - 0x7002, 0xd194, 0x0040, 0x1891, 0x7804, 0xd0fc, 0x00c0, 0x178d, - 0x8aff, 0x0040, 0x1910, 0x2009, 0x0001, 0x1078, 0x16f3, 0x0078, - 0x1910, 0xa184, 0x0880, 0x00c0, 0x189e, 0x8aff, 0x0040, 0x1910, - 0x2009, 0x0001, 0x1078, 0x16f3, 0x0078, 0x1910, 0x7803, 0x0004, - 0x7003, 0x0000, 0xd1bc, 0x00c0, 0x18d2, 0x027e, 0x037e, 0x6b28, - 0x6a2c, 0x1078, 0x1c53, 0x0d7e, 0x0f7e, 0x2d78, 0x2804, 0xac68, - 0x6034, 0xd09c, 0x00c0, 0x18c2, 0x6808, 0x2008, 0xa31a, 0x680c, - 0xa213, 0x7810, 0xa100, 0x7812, 0x690c, 0x7814, 0xa101, 0x7816, - 0x0078, 0x18ce, 0x6810, 0x2008, 0xa31a, 0x6814, 0xa213, 0x7810, - 0xa100, 0x7812, 0x6914, 0x7814, 0xa101, 0x7816, 0x0f7f, 0x0d7f, - 0x0078, 0x17c7, 0x057e, 0x7d0c, 0x1078, 0x7692, 0x057f, 0x1078, - 0x1914, 0x682b, 0xffff, 0x682f, 0xffff, 0x697c, 0x6912, 0x6980, - 0x6916, 0x7803, 0x0009, 0x7003, 0x0003, 0x0078, 0x1910, 0x7803, - 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, 0x0040, 0x18fa, 0x6808, - 0x8001, 0x680a, 0x00c0, 0x18fa, 0x7004, 0x2060, 0x2009, 0x0048, - 0x1078, 0x5d41, 0x1078, 0x16ad, 0x0078, 0x1910, 0x7803, 0x0004, - 0x7003, 0x0000, 0x7004, 0x2060, 0x6010, 0xa005, 0x0040, 0x18fa, - 0x2068, 0x6808, 0x8000, 0x680a, 0x6c28, 0x6b2c, 0x1078, 0x16c4, - 0x017f, 0x007f, 0x127f, 0x007c, 0x1078, 0x1925, 0x20e1, 0x9028, - 0x700f, 0x7970, 0x7013, 0x7970, 0x2001, 0x015d, 0x200c, 0x810a, - 0x2102, 0x2001, 0x0138, 0x2202, 0x007c, 0x2001, 0x0138, 0x2014, + 0x53a5, 0x2001, 0x88f9, 0x2004, 0xd0bc, 0x0040, 0x14f0, 0x2001, + 0x8902, 0x2004, 0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020, 0x53a5, + 0x157f, 0x147f, 0x137f, 0x7007, 0x0000, 0x1078, 0x4871, 0x1078, + 0x13a4, 0x007c, 0x2011, 0x8003, 0x1078, 0x317a, 0x0078, 0x14fe, + 0xa18c, 0x0700, 0x00c0, 0x150d, 0x2001, 0x8927, 0x2003, 0x0100, + 0x7007, 0x0000, 0x1078, 0x13a4, 0x007c, 0x2011, 0x8004, 0x1078, + 0x317a, 0x0078, 0x1511, 0x127e, 0x2091, 0x2100, 0x2079, 0x0030, + 0x2071, 0x8ad8, 0x7803, 0x0004, 0x7003, 0x0000, 0x700f, 0x8ade, + 0x7013, 0x8ade, 0x780f, 0x0076, 0x127f, 0x007c, 0x6934, 0xa184, + 0x0007, 0x0079, 0x152b, 0x1533, 0x1579, 0x1533, 0x1533, 0x1533, + 0x155e, 0x1542, 0x1537, 0xa085, 0x0001, 0x0078, 0x1593, 0x684c, + 0xd0bc, 0x0040, 0x1533, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, + 0x0078, 0x1581, 0xa18c, 0x00ff, 0xa186, 0x001e, 0x00c0, 0x1533, + 0x684c, 0xd0bc, 0x0040, 0x1533, 0x6860, 0x682e, 0x685c, 0x682a, + 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, + 0x1def, 0x2004, 0x6832, 0x6858, 0x0078, 0x1589, 0xa18c, 0x00ff, + 0xa186, 0x0015, 0x00c0, 0x1533, 0x684c, 0xd0ac, 0x0040, 0x1533, + 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, + 0x1def, 0x2004, 0x6832, 0xa006, 0x682e, 0x682a, 0x6858, 0x0078, + 0x1589, 0x684c, 0xd0ac, 0x0040, 0x1533, 0xa006, 0x682e, 0x682a, + 0x6858, 0xa18c, 0x000f, 0xa188, 0x1def, 0x210c, 0x6932, 0x2d08, + 0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c, + 0x6912, 0x6980, 0x6916, 0x007c, 0x20e1, 0x0007, 0x20e1, 0x2000, + 0x2001, 0x020a, 0x2004, 0x82ff, 0x0040, 0x15ae, 0xa280, 0x0004, + 0x0d7e, 0x206c, 0x684c, 0xd0dc, 0x00c0, 0x15aa, 0x1078, 0x1526, + 0x10c0, 0x12d2, 0x6808, 0x8000, 0x680a, 0x0d7f, 0x127e, 0x047e, + 0x037e, 0x027e, 0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000, + 0xa005, 0x00c0, 0x15c2, 0x7206, 0x2001, 0x15e3, 0x007e, 0x2260, + 0x0078, 0x1724, 0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a, + 0x8108, 0xa182, 0x8af9, 0x0048, 0x15cf, 0x2009, 0x8ade, 0x710e, + 0x7010, 0xa102, 0xa082, 0x0009, 0x0040, 0x15da, 0xa080, 0x001b, + 0x00c0, 0x15dd, 0x2009, 0x0138, 0x200a, 0x7000, 0xa005, 0x00c0, + 0x15e3, 0x1078, 0x1705, 0x127f, 0x007c, 0x127e, 0x027e, 0x037e, + 0x0c7e, 0x007e, 0x2091, 0x2100, 0x007f, 0x047f, 0x037f, 0x027f, + 0x0d7e, 0x0c7e, 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e, 0xa005, + 0x0040, 0x163c, 0x6808, 0xa005, 0x0040, 0x16a2, 0x7000, 0xa005, + 0x00c0, 0x1604, 0x0078, 0x1631, 0x700c, 0x7110, 0xa106, 0x00c0, + 0x16ab, 0x7004, 0xa406, 0x00c0, 0x1631, 0x2001, 0x0005, 0x2004, + 0xd08c, 0x0040, 0x161a, 0x047e, 0x1078, 0x1816, 0x047f, 0x2460, + 0x0078, 0x15fa, 0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0, 0x160d, + 0x7804, 0xa084, 0x6000, 0x0040, 0x162b, 0xa086, 0x6000, 0x0040, + 0x162b, 0x0078, 0x160d, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, + 0x2060, 0x6100, 0xa18e, 0x0004, 0x00c0, 0x16ab, 0x2009, 0x0048, + 0x1078, 0x6939, 0x0078, 0x16ab, 0x6808, 0xa005, 0x0040, 0x16a2, + 0x7000, 0xa005, 0x00c0, 0x1646, 0x0078, 0x16a2, 0x700c, 0x7110, + 0xa106, 0x00c0, 0x164f, 0x7004, 0xa406, 0x00c0, 0x16a2, 0x2001, + 0x0005, 0x2004, 0xd08c, 0x0040, 0x165c, 0x047e, 0x1078, 0x1816, + 0x047f, 0x2460, 0x0078, 0x163c, 0x2001, 0x0207, 0x2004, 0xd09c, + 0x00c0, 0x164f, 0x2001, 0x0005, 0x2004, 0xd08c, 0x00c0, 0x1655, + 0x7804, 0xa084, 0x6000, 0x0040, 0x1673, 0xa086, 0x6000, 0x0040, + 0x1673, 0x0078, 0x164f, 0x7007, 0x0000, 0xa016, 0x2218, 0x7000, + 0xa08e, 0x0001, 0x0040, 0x1694, 0xa08e, 0x0002, 0x00c0, 0x16a2, + 0x0c7e, 0x0e7e, 0x6818, 0x2060, 0x1078, 0x1dc4, 0x2804, 0xac70, + 0x6034, 0xd09c, 0x00c0, 0x1690, 0x7308, 0x720c, 0x0078, 0x1692, + 0x7310, 0x7214, 0x0e7f, 0x0c7f, 0x7820, 0xa318, 0x7824, 0xa211, + 0x6810, 0xa300, 0x6812, 0x6814, 0xa201, 0x6816, 0x7803, 0x0004, + 0x7003, 0x0000, 0x6100, 0xa18e, 0x0004, 0x00c0, 0x16ab, 0x2009, + 0x0048, 0x1078, 0x6939, 0x0c7f, 0x0d7f, 0x127f, 0x007c, 0x0f7e, + 0x0e7e, 0x027e, 0x037e, 0x047e, 0x1078, 0x19e5, 0x027e, 0x2071, + 0x8ad8, 0x7000, 0xa086, 0x0000, 0x0040, 0x16f6, 0x7004, 0xac06, + 0x00c0, 0x16e7, 0x2079, 0x0030, 0x7000, 0xa086, 0x0003, 0x0040, + 0x16e7, 0x7804, 0xd0fc, 0x00c0, 0x16e3, 0x2001, 0x0207, 0x2004, + 0xd09c, 0x00c0, 0x16c9, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0, + 0x16d5, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003, 0x0003, 0x7007, + 0x0000, 0x0078, 0x16e7, 0x1078, 0x1816, 0x0078, 0x16b9, 0x157e, + 0x20a9, 0x0009, 0x2009, 0x8ade, 0x2104, 0xac06, 0x00c0, 0x16f1, + 0x200a, 0xa188, 0x0003, 0x00f0, 0x16ec, 0x157f, 0x027f, 0x2001, + 0x015d, 0x201c, 0x831a, 0x2302, 0x2001, 0x0138, 0x2202, 0x047f, + 0x037f, 0x027f, 0x0e7f, 0x0f7f, 0x007c, 0x700c, 0x7110, 0xa106, + 0x00c0, 0x170d, 0x7003, 0x0000, 0x007c, 0x2104, 0x7006, 0x2060, + 0x8108, 0x211c, 0x8108, 0x2124, 0x8108, 0xa182, 0x8af9, 0x0048, + 0x171b, 0x2009, 0x8ade, 0x7112, 0x700c, 0xa106, 0x00c0, 0x1724, + 0x2001, 0x0138, 0x2003, 0x0008, 0x8cff, 0x00c0, 0x172b, 0x1078, + 0x1a10, 0x0078, 0x1757, 0x6010, 0x2068, 0x2d58, 0x6828, 0xa406, + 0x00c0, 0x1736, 0x682c, 0xa306, 0x0040, 0x173f, 0x601c, 0xa086, + 0x0008, 0x0040, 0x173f, 0x1078, 0x1e0f, 0x00c0, 0x1727, 0x684c, + 0xd0f4, 0x00c0, 0x1727, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, + 0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009, 0x0011, 0x1078, 0x1758, + 0x0040, 0x1756, 0x2009, 0x0001, 0x1078, 0x1758, 0x2d58, 0x007c, + 0x8aff, 0x0040, 0x17ef, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x00c0, + 0x177a, 0xd0f4, 0x00c0, 0x178a, 0x0d7e, 0x2804, 0xac68, 0x2900, + 0x0079, 0x176a, 0x17d1, 0x1791, 0x1791, 0x17d1, 0x17d1, 0x17c9, + 0x17d1, 0x1791, 0x17d1, 0x1797, 0x1797, 0x17d1, 0x17d1, 0x17d1, + 0x17c0, 0x1797, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, + 0x0d7e, 0xd99c, 0x0040, 0x17d4, 0x2804, 0xac68, 0x6f08, 0x6e0c, + 0x0078, 0x17d4, 0xc0f4, 0x6852, 0x6b6c, 0x6a70, 0x0d7e, 0x0078, + 0x17db, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0078, 0x17d4, 0x7b0c, + 0xd3bc, 0x0040, 0x17b8, 0x7004, 0x0e7e, 0x2070, 0x701c, 0x0e7f, + 0xa086, 0x0008, 0x00c0, 0x17b8, 0x7b08, 0xa39c, 0x0fff, 0x2d20, + 0x0d7f, 0x0d7e, 0x6a14, 0x82ff, 0x00c0, 0x17b3, 0x6810, 0xa302, + 0x0048, 0x17b3, 0x6b10, 0x2011, 0x0000, 0x2468, 0x0078, 0x17ba, + 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0078, 0x17d4, + 0x0d7f, 0x0d7e, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, + 0x17d1, 0x0d7f, 0x1078, 0x1dab, 0x00c0, 0x1758, 0xa00e, 0x0078, + 0x17ef, 0x0d7f, 0x1078, 0x12d2, 0x7b22, 0x7a26, 0x7d32, 0x7c36, + 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x0d7f, 0x6828, + 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x2300, 0x6b10, 0xa302, + 0x6812, 0x2200, 0x6a14, 0xa203, 0x6816, 0x1078, 0x1dab, 0x007c, + 0x1078, 0x12d2, 0x7803, 0x0004, 0x7004, 0x2060, 0x0d7e, 0x6010, + 0x2068, 0x7003, 0x0000, 0x1078, 0x19b4, 0x1078, 0x77ed, 0x0040, + 0x180f, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, + 0x682b, 0xffff, 0x682f, 0xffff, 0x6850, 0xc0bd, 0x6852, 0x0d7f, + 0x1078, 0x759a, 0x0078, 0x19b0, 0x1078, 0x12d2, 0x127e, 0x2091, + 0x2100, 0x007e, 0x017e, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, + 0x0002, 0xa184, 0x0700, 0x00c0, 0x17f2, 0xa184, 0x0003, 0xa086, + 0x0003, 0x0040, 0x1814, 0x7000, 0x0079, 0x182e, 0x1836, 0x1838, + 0x1914, 0x1987, 0x199e, 0x1836, 0x1836, 0x1836, 0x1078, 0x12d2, + 0x8001, 0x7002, 0xa184, 0x0880, 0x00c0, 0x184d, 0x8aff, 0x0040, + 0x18b6, 0x2009, 0x0001, 0x1078, 0x1758, 0x0040, 0x19b0, 0x2009, + 0x0001, 0x1078, 0x1758, 0x0078, 0x19b0, 0x7803, 0x0004, 0x7003, + 0x0000, 0xd1bc, 0x00c0, 0x189f, 0x027e, 0x037e, 0x7808, 0xd0ec, + 0x00c0, 0x1860, 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1862, + 0x1078, 0x1a80, 0x6b28, 0x6a2c, 0x2400, 0x686e, 0xa31a, 0x2500, + 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x2400, 0x6910, 0xa100, 0x6812, + 0x2500, 0x6914, 0xa101, 0x6816, 0x037f, 0x027f, 0x2600, 0x681e, + 0x2700, 0x6822, 0x1078, 0x1dc4, 0x2a00, 0x6826, 0x2c00, 0x681a, + 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852, 0x6808, 0x8001, 0x680a, + 0x00c0, 0x1894, 0x684c, 0xd0e4, 0x0040, 0x1894, 0x7004, 0x2060, + 0x2009, 0x0048, 0x1078, 0x6939, 0x7000, 0xa086, 0x0004, 0x0040, + 0x19b0, 0x7003, 0x0000, 0x1078, 0x1705, 0x0078, 0x19b0, 0x057e, + 0x7d0c, 0xd5bc, 0x00c0, 0x18a6, 0x1078, 0x874c, 0x057f, 0x1078, + 0x19b4, 0x682b, 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, + 0x697c, 0x6912, 0x6980, 0x6916, 0x0078, 0x19b0, 0x684c, 0xc0f5, + 0x684e, 0x7814, 0xa005, 0x00c0, 0x18ce, 0x7003, 0x0000, 0x6808, + 0x8001, 0x680a, 0x00c0, 0x18ca, 0x7004, 0x2060, 0x2009, 0x0048, + 0x1078, 0x6939, 0x1078, 0x1705, 0x0078, 0x19b0, 0x7814, 0x6910, + 0xa102, 0x6812, 0x6914, 0xa183, 0x0000, 0x6816, 0x7814, 0x7908, + 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214, 0x8214, 0xa10a, + 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b, 0x810b, 0x1078, + 0x1a3b, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803, 0x0001, 0x7804, + 0xd0fc, 0x0040, 0x18ef, 0x7803, 0x0002, 0x7803, 0x0004, 0x780f, + 0x0076, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, 0x0048, 0x1078, + 0x6939, 0x1078, 0x1a5e, 0x0040, 0x18ca, 0x7908, 0xd1ec, 0x00c0, + 0x190d, 0x2009, 0x0009, 0x0078, 0x190f, 0x2009, 0x0019, 0x7902, + 0x7003, 0x0003, 0x0078, 0x19b0, 0x8001, 0x7002, 0xd194, 0x0040, + 0x1926, 0x7804, 0xd0fc, 0x00c0, 0x181e, 0x8aff, 0x0040, 0x19b0, + 0x2009, 0x0001, 0x1078, 0x1758, 0x0078, 0x19b0, 0xa184, 0x0880, + 0x00c0, 0x1933, 0x8aff, 0x0040, 0x19b0, 0x2009, 0x0001, 0x1078, + 0x1758, 0x0078, 0x19b0, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, + 0x00c0, 0x1973, 0x027e, 0x037e, 0x7808, 0xd0ec, 0x00c0, 0x1946, + 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1948, 0x1078, 0x1a80, + 0x6b28, 0x6a2c, 0x1078, 0x1dc4, 0x0d7e, 0x0f7e, 0x2d78, 0x2804, + 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1963, 0x6808, 0x2008, 0xa31a, + 0x680c, 0xa213, 0x7810, 0xa100, 0x7812, 0x690c, 0x7814, 0xa101, + 0x7816, 0x0078, 0x196f, 0x6810, 0x2008, 0xa31a, 0x6814, 0xa213, + 0x7810, 0xa100, 0x7812, 0x6914, 0x7814, 0xa101, 0x7816, 0x0f7f, + 0x0d7f, 0x0078, 0x1864, 0x057e, 0x7d0c, 0x1078, 0x874c, 0x057f, + 0x1078, 0x19b4, 0x682b, 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, + 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x0078, 0x19b0, 0x7803, + 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, 0x0040, 0x199a, 0x6808, + 0x8001, 0x680a, 0x00c0, 0x199a, 0x7004, 0x2060, 0x2009, 0x0048, + 0x1078, 0x6939, 0x1078, 0x1705, 0x0078, 0x19b0, 0x7803, 0x0004, + 0x7003, 0x0000, 0x7004, 0x2060, 0x6010, 0xa005, 0x0040, 0x199a, + 0x2068, 0x6808, 0x8000, 0x680a, 0x6c28, 0x6b2c, 0x1078, 0x1724, + 0x017f, 0x007f, 0x127f, 0x007c, 0x0c7e, 0x1078, 0x19e5, 0x20e1, + 0x9028, 0x700c, 0x7110, 0xa106, 0x0040, 0x19db, 0x2104, 0xa005, + 0x0040, 0x19c8, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001, 0x600a, + 0xa188, 0x0003, 0xa182, 0x8af9, 0x0048, 0x19d0, 0x2009, 0x8ade, + 0x7112, 0x700c, 0xa106, 0x00c0, 0x19b9, 0x2001, 0x0138, 0x2003, + 0x0008, 0x0078, 0x19b9, 0x2001, 0x015d, 0x200c, 0x810a, 0x2102, + 0x2001, 0x0138, 0x2202, 0x0c7f, 0x007c, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000, 0x2021, 0xb015, 0x2001, 0x0141, 0x201c, 0xd3dc, - 0x00c0, 0x1942, 0x2001, 0x0109, 0x201c, 0xa39c, 0x0048, 0x00c0, - 0x1942, 0x2001, 0x0111, 0x201c, 0x83ff, 0x00c0, 0x1942, 0x8421, - 0x00c0, 0x192c, 0x007c, 0x2011, 0x0201, 0x2009, 0x003c, 0x2204, - 0xa005, 0x00c0, 0x194f, 0x8109, 0x00c0, 0x1947, 0x007c, 0x007c, - 0x1078, 0x1943, 0x0040, 0x1978, 0x7908, 0xd1ec, 0x00c0, 0x1968, - 0x1078, 0x199e, 0x0040, 0x1968, 0x7803, 0x0009, 0x7904, 0xd1fc, - 0x0040, 0x195e, 0x7803, 0x0006, 0x1078, 0x1943, 0x0040, 0x1978, - 0x780c, 0xd0a4, 0x00c0, 0x1978, 0x7007, 0x0000, 0x1078, 0x199e, - 0x0040, 0x197a, 0x7803, 0x0019, 0x7003, 0x0003, 0x0078, 0x197a, - 0x1078, 0x1914, 0x007c, 0x3c00, 0x007e, 0x0e7e, 0x2071, 0x0200, - 0x7808, 0xa084, 0xf000, 0xa10d, 0x1078, 0x1925, 0x20e1, 0x7000, + 0x00c0, 0x1a02, 0x2001, 0x0109, 0x201c, 0xa39c, 0x0048, 0x00c0, + 0x1a02, 0x2001, 0x0111, 0x201c, 0x83ff, 0x00c0, 0x1a02, 0x8421, + 0x00c0, 0x19ec, 0x007c, 0x2011, 0x0201, 0x2009, 0x003c, 0x2204, + 0xa005, 0x00c0, 0x1a0f, 0x8109, 0x00c0, 0x1a07, 0x007c, 0x007c, + 0x1078, 0x1a03, 0x0040, 0x1a38, 0x7908, 0xd1ec, 0x00c0, 0x1a28, + 0x1078, 0x1a5e, 0x0040, 0x1a28, 0x7803, 0x0009, 0x7904, 0xd1fc, + 0x0040, 0x1a1e, 0x7803, 0x0006, 0x1078, 0x1a03, 0x0040, 0x1a38, + 0x780c, 0xd0a4, 0x00c0, 0x1a38, 0x7007, 0x0000, 0x1078, 0x1a5e, + 0x0040, 0x1a3a, 0x7803, 0x0019, 0x7003, 0x0003, 0x0078, 0x1a3a, + 0x1078, 0x19b4, 0x007c, 0x3c00, 0x007e, 0x0e7e, 0x2071, 0x0200, + 0x7808, 0xa084, 0xf000, 0xa10d, 0x1078, 0x19e5, 0x20e1, 0x7000, 0x7324, 0x7420, 0x7028, 0x7028, 0x7426, 0x7037, 0x0001, 0x810f, 0x712e, 0x702f, 0x0100, 0x7037, 0x0008, 0x7326, 0x7422, 0x2001, 0x0138, 0x2202, 0x0e7f, 0x007f, 0x20e0, 0x007c, 0x3c00, 0x007e, - 0x7908, 0xa18c, 0x0fff, 0xa182, 0x0009, 0x0048, 0x19ab, 0xa085, - 0x0001, 0x0078, 0x19bd, 0x2001, 0x020a, 0x81ff, 0x0040, 0x19b6, + 0x7908, 0xa18c, 0x0fff, 0xa182, 0x0009, 0x0048, 0x1a6b, 0xa085, + 0x0001, 0x0078, 0x1a7d, 0x2001, 0x020a, 0x81ff, 0x0040, 0x1a76, 0x20e1, 0x6000, 0x200c, 0x200c, 0x200c, 0x200c, 0x20e1, 0x7000, 0x200c, 0x200c, 0x7003, 0x0000, 0xa006, 0x007f, 0x20e0, 0x007c, - 0x0e7e, 0x2071, 0x798b, 0x7003, 0x0000, 0x0e7f, 0x007c, 0x0d7e, - 0xa280, 0x0004, 0x206c, 0x694c, 0xd1dc, 0x00c0, 0x1a42, 0x6934, - 0xa184, 0x0007, 0x0079, 0x19d4, 0x19dc, 0x1a2d, 0x19dc, 0x19dc, - 0x19dc, 0x1a12, 0x19ef, 0x19de, 0x1078, 0x12cd, 0x684c, 0xd0b4, - 0x0040, 0x1b46, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, - 0x687c, 0x680a, 0x6880, 0x680e, 0x6958, 0x0078, 0x1a35, 0x6834, - 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x19dc, 0x684c, 0xd0b4, - 0x0040, 0x1b46, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, + 0x7c20, 0x7d24, 0x7e30, 0x7f34, 0x700c, 0x7110, 0xa106, 0x0040, + 0x1aff, 0x7004, 0x017e, 0x210c, 0xa106, 0x017f, 0x0040, 0x1aff, + 0x0d7e, 0x0c7e, 0x216c, 0x2d00, 0xa005, 0x0040, 0x1afd, 0x6810, + 0x2068, 0x6850, 0xd0fc, 0x0040, 0x1ac9, 0x8108, 0x2104, 0x6b2c, + 0xa306, 0x00c0, 0x1afd, 0x8108, 0x2104, 0x6a28, 0xa206, 0x00c0, + 0x1afd, 0x6850, 0xc0fc, 0xc0f5, 0x6852, 0x686c, 0x7822, 0x6870, + 0x7826, 0x681c, 0x7832, 0x6820, 0x7836, 0x6818, 0x2060, 0x6034, + 0xd09c, 0x0040, 0x1ac4, 0x6830, 0x2004, 0xac68, 0x6808, 0x783a, + 0x680c, 0x783e, 0x0078, 0x1afb, 0xa006, 0x783a, 0x783e, 0x0078, + 0x1afb, 0x8108, 0x2104, 0xa005, 0x00c0, 0x1afd, 0x8108, 0x2104, + 0xa005, 0x00c0, 0x1afd, 0x6850, 0xc0f5, 0x6852, 0x6830, 0x2004, + 0x6918, 0xa160, 0x6834, 0xd09c, 0x00c0, 0x1aed, 0x6008, 0x7822, + 0x686e, 0x600c, 0x7826, 0x6872, 0x6000, 0x7832, 0x6004, 0x7836, + 0xa006, 0x783a, 0x783e, 0x0078, 0x1afb, 0x6010, 0x7822, 0x686e, + 0x6014, 0x7826, 0x6872, 0x6000, 0x7832, 0x6004, 0x7836, 0x6008, + 0x783a, 0x600c, 0x783e, 0x7803, 0x0011, 0x0c7f, 0x0d7f, 0x007c, + 0x0e7e, 0x2071, 0x8af9, 0x7003, 0x0000, 0x0e7f, 0x007c, 0x0d7e, + 0xa280, 0x0004, 0x206c, 0x694c, 0xd1dc, 0x00c0, 0x1b82, 0x6934, + 0xa184, 0x0007, 0x0079, 0x1b14, 0x1b1c, 0x1b6d, 0x1b1c, 0x1b1c, + 0x1b1c, 0x1b52, 0x1b2f, 0x1b1e, 0x1078, 0x12d2, 0x684c, 0xd0b4, + 0x0040, 0x1c90, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, + 0x687c, 0x680a, 0x6880, 0x680e, 0x6958, 0x0078, 0x1b75, 0x6834, + 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x1b1c, 0x684c, 0xd0b4, + 0x0040, 0x1c90, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880, 0x680e, 0x6804, 0x681a, 0xa080, 0x000d, - 0x2004, 0xa084, 0x000f, 0xa080, 0x1c7e, 0x2004, 0x6832, 0x6958, - 0x0078, 0x1a3e, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x00c0, 0x1a42, - 0x684c, 0xd0b4, 0x0040, 0x1b46, 0x6804, 0x681a, 0xa080, 0x000d, - 0x2004, 0xa084, 0x000f, 0xa080, 0x1c7e, 0x2004, 0x6832, 0x6958, - 0xa006, 0x682e, 0x682a, 0x0078, 0x1a3e, 0x684c, 0xd0b4, 0x0040, - 0x1781, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00, 0x681a, 0x6834, - 0xa084, 0x000f, 0xa080, 0x1c7e, 0x2004, 0x6832, 0x6926, 0x684c, + 0x2004, 0xa084, 0x000f, 0xa080, 0x1def, 0x2004, 0x6832, 0x6958, + 0x0078, 0x1b7e, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x00c0, 0x1b82, + 0x684c, 0xd0b4, 0x0040, 0x1c90, 0x6804, 0x681a, 0xa080, 0x000d, + 0x2004, 0xa084, 0x000f, 0xa080, 0x1def, 0x2004, 0x6832, 0x6958, + 0xa006, 0x682e, 0x682a, 0x0078, 0x1b7e, 0x684c, 0xd0b4, 0x0040, + 0x17f0, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00, 0x681a, 0x6834, + 0xa084, 0x000f, 0xa080, 0x1def, 0x2004, 0x6832, 0x6926, 0x684c, 0xc0dd, 0x684e, 0x0d7f, 0x007c, 0x0f7e, 0x2079, 0x0020, 0x7804, - 0xd0fc, 0x10c0, 0x1b4a, 0x0e7e, 0x0d7e, 0x2071, 0x798b, 0x7000, - 0xa005, 0x00c0, 0x1ac0, 0x0c7e, 0x7206, 0xa280, 0x0004, 0x205c, + 0xd0fc, 0x10c0, 0x1cb7, 0x0e7e, 0x0d7e, 0x2071, 0x8af9, 0x7000, + 0xa005, 0x00c0, 0x1c07, 0x0c7e, 0x7206, 0xa280, 0x0004, 0x205c, 0x7004, 0x2068, 0x7803, 0x0004, 0x6818, 0x0d7e, 0x2068, 0x686c, 0x7812, 0x6890, 0x0f7e, 0x20e1, 0x9040, 0x2079, 0x0200, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x0f7f, 0x0d7f, 0x2b68, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f, - 0x6908, 0xa184, 0x0007, 0x0040, 0x1a82, 0x017e, 0x2009, 0x0008, - 0xa102, 0x017f, 0xa108, 0x791a, 0x7116, 0x701e, 0x680c, 0xa081, - 0x0000, 0x781e, 0x701a, 0xa006, 0x700e, 0x7012, 0x7004, 0x692c, - 0x6814, 0xa106, 0x00c0, 0x1a99, 0x6928, 0x6810, 0xa106, 0x0040, - 0x1aa6, 0x037e, 0x047e, 0x6b14, 0x6c10, 0x1078, 0x1c9e, 0x047f, - 0x037f, 0x0040, 0x1aa6, 0x0c7f, 0x0078, 0x1ac0, 0x8aff, 0x00c0, - 0x1aae, 0x0c7f, 0xa085, 0x0001, 0x0078, 0x1ac0, 0x127e, 0x2091, - 0x8000, 0x2079, 0x0020, 0x2009, 0x0001, 0x1078, 0x1ac4, 0x0040, - 0x1abd, 0x2009, 0x0001, 0x1078, 0x1ac4, 0x127f, 0x0c7f, 0xa006, - 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x077e, 0x067e, 0x057e, 0x047e, - 0x037e, 0x027e, 0x8aff, 0x0040, 0x1b3f, 0x700c, 0x7214, 0xa202, - 0x7010, 0x7218, 0xa203, 0x0048, 0x1b3e, 0xa03e, 0x2730, 0x6850, - 0xd0fc, 0x00c0, 0x1af1, 0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079, - 0x1ae1, 0x1b20, 0x1b01, 0x1b01, 0x1b20, 0x1b20, 0x1b18, 0x1b20, - 0x1b01, 0x1b20, 0x1b07, 0x1b07, 0x1b20, 0x1b20, 0x1b20, 0x1b0f, - 0x1b07, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0xd99c, - 0x0040, 0x1b24, 0x0d7e, 0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078, - 0x1b23, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0078, 0x1b23, 0x6b10, - 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0078, 0x1b23, 0x0d7f, - 0x0d7e, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x1b20, - 0x0d7f, 0x1078, 0x1c3a, 0x00c0, 0x1aca, 0xa00e, 0x0078, 0x1b3f, - 0x0d7f, 0x1078, 0x12cd, 0x0d7f, 0x7b22, 0x7a26, 0x7d32, 0x7c36, - 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x6828, 0xa300, - 0x682a, 0x682c, 0xa201, 0x682e, 0x700c, 0xa300, 0x700e, 0x7010, - 0xa201, 0x7012, 0x1078, 0x1c3a, 0x0078, 0x1b3f, 0xa006, 0x027f, - 0x037f, 0x047f, 0x057f, 0x067f, 0x077f, 0x007c, 0x1078, 0x12cd, - 0x1078, 0x12cd, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x0f7e, - 0x0e7e, 0x0d7e, 0x0c7e, 0x2079, 0x0020, 0x2071, 0x798b, 0x2b68, - 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x00c0, - 0x1b48, 0x7000, 0x0079, 0x1b64, 0x1c0b, 0x1b68, 0x1bd8, 0x1c09, - 0x8001, 0x7002, 0xd19c, 0x00c0, 0x1b7c, 0x8aff, 0x0040, 0x1b9b, - 0x2009, 0x0001, 0x1078, 0x1ac4, 0x0040, 0x1c0b, 0x2009, 0x0001, - 0x1078, 0x1ac4, 0x0078, 0x1c0b, 0x7803, 0x0004, 0xd194, 0x0040, - 0x1b8c, 0x6850, 0xc0fc, 0x6852, 0x8aff, 0x00c0, 0x1b91, 0x684c, - 0xc0f5, 0x684e, 0x0078, 0x1b91, 0x1078, 0x1c53, 0x6850, 0xc0fd, - 0x6852, 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, - 0x0000, 0x0078, 0x1c0b, 0x711c, 0x81ff, 0x0040, 0x1bb1, 0x7918, - 0x7922, 0x7827, 0x0000, 0x7803, 0x0001, 0x7000, 0x8000, 0x7002, - 0x700c, 0xa100, 0x700e, 0x7010, 0xa081, 0x0000, 0x7012, 0x0078, - 0x1c0b, 0x0f7e, 0x027e, 0x781c, 0x007e, 0x7818, 0x007e, 0x2079, - 0x0100, 0x7a14, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, 0x7820, - 0xd0bc, 0x00c0, 0x1bbf, 0x79c8, 0x007f, 0xa102, 0x78ca, 0x79c4, - 0x007f, 0xa102, 0x78c6, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, - 0x027f, 0x0f7f, 0x7803, 0x0008, 0x7003, 0x0000, 0x0078, 0x1c0b, - 0x8001, 0x7002, 0xd194, 0x0040, 0x1bed, 0x7804, 0xd0fc, 0x00c0, - 0x1b5a, 0xd19c, 0x00c0, 0x1c07, 0x8aff, 0x0040, 0x1c0b, 0x2009, - 0x0001, 0x1078, 0x1ac4, 0x0078, 0x1c0b, 0x027e, 0x037e, 0x6b28, - 0x6a2c, 0x1078, 0x1c53, 0x0d7e, 0x2804, 0xac68, 0x6034, 0xd09c, - 0x00c0, 0x1c00, 0x6808, 0xa31a, 0x680c, 0xa213, 0x0078, 0x1c04, - 0x6810, 0xa31a, 0x6814, 0xa213, 0x0d7f, 0x0078, 0x1b8c, 0x0078, - 0x1b8c, 0x1078, 0x12cd, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x017f, - 0x007f, 0x127f, 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0x798b, 0x7000, - 0xa086, 0x0000, 0x0040, 0x1c37, 0x2079, 0x0020, 0x20e1, 0x9040, - 0x7804, 0xd0fc, 0x0040, 0x1c1e, 0x1078, 0x1b4a, 0x7000, 0xa086, - 0x0000, 0x00c0, 0x1c1e, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0, - 0x1c2d, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x0e7f, - 0x0f7f, 0x007c, 0x8840, 0x2804, 0xa005, 0x00c0, 0x1c4e, 0x6004, - 0xa005, 0x0040, 0x1c50, 0x681a, 0x2060, 0x6034, 0xa084, 0x000f, - 0xa080, 0x1c7e, 0x2044, 0x88ff, 0x1040, 0x12cd, 0x8a51, 0x007c, - 0x2051, 0x0000, 0x007c, 0x8a50, 0x8841, 0x2804, 0xa005, 0x00c0, - 0x1c6d, 0x2c00, 0xad06, 0x0040, 0x1c62, 0x6000, 0xa005, 0x00c0, - 0x1c62, 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080, - 0x1c8e, 0x2044, 0x88ff, 0x1040, 0x12cd, 0x007c, 0x0000, 0x0011, - 0x0015, 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f, - 0x0015, 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x1c73, - 0x1c6f, 0x0000, 0x0000, 0x1c7d, 0x0000, 0x1c73, 0x0000, 0x1c7a, - 0x1c77, 0x0000, 0x0000, 0x0000, 0x1c7d, 0x1c7a, 0x0000, 0x1c75, - 0x1c75, 0x0000, 0x0000, 0x1c7d, 0x0000, 0x1c75, 0x0000, 0x1c7b, - 0x1c7b, 0x0000, 0x0000, 0x0000, 0x1c7d, 0x1c7b, 0x0a7e, 0x097e, - 0x087e, 0x6858, 0xa055, 0x0040, 0x1d3f, 0x2d60, 0x6034, 0xa0cc, - 0x000f, 0xa9c0, 0x1c7e, 0xa986, 0x0007, 0x0040, 0x1cb7, 0xa986, - 0x000e, 0x0040, 0x1cb7, 0xa986, 0x000f, 0x00c0, 0x1cbb, 0x605c, - 0xa422, 0x6060, 0xa31a, 0x2804, 0xa045, 0x00c0, 0x1cc9, 0x0050, - 0x1cc3, 0x0078, 0x1d3f, 0x6004, 0xa065, 0x0040, 0x1d3f, 0x0078, - 0x1ca6, 0x2804, 0xa005, 0x0040, 0x1ce7, 0xac68, 0xd99c, 0x00c0, - 0x1cd7, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0078, 0x1cdb, 0x6810, - 0xa422, 0x6814, 0xa31b, 0x0048, 0x1d06, 0x2300, 0xa405, 0x0040, - 0x1ced, 0x8a51, 0x0040, 0x1d3f, 0x8840, 0x0078, 0x1cc9, 0x6004, - 0xa065, 0x0040, 0x1d3f, 0x0078, 0x1ca6, 0x8a51, 0x0040, 0x1d3f, - 0x8840, 0x2804, 0xa005, 0x00c0, 0x1d00, 0x6004, 0xa065, 0x0040, - 0x1d3f, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x1c7e, 0x2804, 0x2040, - 0x2b68, 0x6850, 0xc0fc, 0x6852, 0x0078, 0x1d33, 0x8422, 0x8420, - 0x831a, 0xa399, 0x0000, 0x0d7e, 0x2b68, 0x6c6e, 0x6b72, 0x0d7f, - 0xd99c, 0x00c0, 0x1d21, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, - 0xa11b, 0x1048, 0x12cd, 0x6800, 0xa420, 0x6804, 0xa319, 0x0078, - 0x1d2d, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, 0x1048, - 0x12cd, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, 0x6b22, - 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832, 0x2a00, - 0x6826, 0x007f, 0x007f, 0x007f, 0xa006, 0x0078, 0x1d44, 0x087f, - 0x097f, 0x0a7f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0005, 0x2004, - 0xa084, 0x0007, 0x0079, 0x1d4c, 0x1d54, 0x1d55, 0x1d58, 0x1d5b, - 0x1d60, 0x1d63, 0x1d68, 0x1d6d, 0x007c, 0x1078, 0x1b4a, 0x007c, - 0x1078, 0x1785, 0x007c, 0x1078, 0x1785, 0x1078, 0x1b4a, 0x007c, - 0x1078, 0x1456, 0x007c, 0x1078, 0x1b4a, 0x1078, 0x1456, 0x007c, - 0x1078, 0x1785, 0x1078, 0x1456, 0x007c, 0x1078, 0x1785, 0x1078, - 0x1b4a, 0x1078, 0x1456, 0x007c, 0x127e, 0x2091, 0x2300, 0x2079, - 0x0200, 0x2071, 0x7c80, 0x2069, 0x7700, 0x2009, 0x0004, 0x7912, - 0x7817, 0x0004, 0x1078, 0x2052, 0x781b, 0x0002, 0x20e1, 0x8700, - 0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x781c, 0xa084, 0x0007, - 0x0079, 0x1d92, 0x1db6, 0x1d9a, 0x1d9e, 0x1da2, 0x1da8, 0x1dac, - 0x1db0, 0x1db4, 0x1078, 0x4298, 0x0078, 0x1db6, 0x1078, 0x42c7, - 0x0078, 0x1db6, 0x1078, 0x4298, 0x1078, 0x42c7, 0x0078, 0x1db6, - 0x1078, 0x1db8, 0x0078, 0x1db6, 0x1078, 0x1db8, 0x0078, 0x1db6, - 0x1078, 0x1db8, 0x0078, 0x1db6, 0x1078, 0x1db8, 0x127f, 0x007c, - 0x007e, 0x017e, 0x027e, 0x7930, 0xa184, 0x0003, 0x0040, 0x1dc2, - 0x1078, 0x12cd, 0xa184, 0x0030, 0x0040, 0x1dd3, 0x6a00, 0xa286, - 0x0003, 0x00c0, 0x1dcd, 0x1078, 0x12cd, 0x1078, 0x3591, 0x20e1, - 0x9010, 0x0078, 0x1ddf, 0xa184, 0x00c0, 0x0040, 0x1dd9, 0x1078, - 0x12cd, 0xa184, 0x0300, 0x0040, 0x1ddf, 0x20e1, 0x9020, 0x7932, - 0x027f, 0x017f, 0x007f, 0x007c, 0x017e, 0x0e7e, 0x0f7e, 0x2071, - 0x7700, 0x7128, 0x2001, 0x7923, 0x2102, 0x2001, 0x792b, 0x2102, - 0xa182, 0x0211, 0x00c8, 0x1df8, 0x2009, 0x0008, 0x0078, 0x1e22, - 0xa182, 0x0259, 0x00c8, 0x1e00, 0x2009, 0x0007, 0x0078, 0x1e22, - 0xa182, 0x02c1, 0x00c8, 0x1e08, 0x2009, 0x0006, 0x0078, 0x1e22, - 0xa182, 0x0349, 0x00c8, 0x1e10, 0x2009, 0x0005, 0x0078, 0x1e22, - 0xa182, 0x0421, 0x00c8, 0x1e18, 0x2009, 0x0004, 0x0078, 0x1e22, - 0xa182, 0x0581, 0x00c8, 0x1e20, 0x2009, 0x0003, 0x0078, 0x1e22, - 0x2009, 0x0002, 0x2079, 0x0200, 0x7912, 0xa182, 0x0005, 0x00c8, - 0x1e2c, 0x7916, 0x0078, 0x1e2e, 0x7817, 0x0004, 0x1078, 0x2052, - 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x127e, 0x2091, 0x2200, 0x2061, - 0x0100, 0x2071, 0x7700, 0x6024, 0x6026, 0x6033, 0x00ef, 0x60e7, - 0x0000, 0x60eb, 0x00ef, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, - 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x0caf, 0x600f, - 0x00ff, 0x602b, 0x002f, 0x127f, 0x007c, 0x2001, 0x772d, 0x2003, - 0x0000, 0x2001, 0x772c, 0x2003, 0x0001, 0x007c, 0x127e, 0x2091, - 0x2200, 0x007e, 0x017e, 0x027e, 0x6124, 0xa184, 0x002c, 0x00c0, - 0x1e6d, 0xa184, 0x0007, 0x0079, 0x1e73, 0xa195, 0x0004, 0xa284, - 0x0007, 0x0079, 0x1e73, 0x1e9f, 0x1e7b, 0x1e7f, 0x1e83, 0x1e89, - 0x1e8d, 0x1e93, 0x1e99, 0x1078, 0x4802, 0x0078, 0x1e9f, 0x1078, - 0x48f1, 0x0078, 0x1e9f, 0x1078, 0x48f1, 0x1078, 0x4802, 0x0078, - 0x1e9f, 0x1078, 0x1ea4, 0x0078, 0x1e9f, 0x1078, 0x4802, 0x1078, - 0x1ea4, 0x0078, 0x1e9f, 0x1078, 0x48f1, 0x1078, 0x1ea4, 0x0078, - 0x1e9f, 0x1078, 0x48f1, 0x1078, 0x4802, 0x1078, 0x1ea4, 0x027f, - 0x017f, 0x007f, 0x127f, 0x007c, 0xd1ac, 0x0040, 0x1f58, 0x017e, - 0x047e, 0x0c7e, 0x644c, 0x74ba, 0xa48c, 0xff00, 0xa196, 0xff00, - 0x0040, 0x1ed3, 0x6030, 0xa084, 0x00ff, 0x810f, 0xa116, 0x0040, - 0x1ed3, 0x7130, 0xd18c, 0x00c0, 0x1ed3, 0x2011, 0x7752, 0x2214, - 0xd2ec, 0x0040, 0x1ec7, 0xc18d, 0x7132, 0x0078, 0x1ed3, 0x6240, - 0xa294, 0x0010, 0x0040, 0x1f15, 0x6248, 0xa294, 0xff00, 0xa296, - 0xff00, 0x00c0, 0x1f15, 0x037e, 0x73b8, 0x2011, 0x8013, 0x1078, - 0x2d59, 0x037f, 0x7130, 0xc185, 0x7132, 0x2011, 0x7752, 0x220c, - 0xd1a4, 0x0040, 0x1efd, 0x017e, 0x2009, 0x0001, 0x2011, 0x0100, - 0x1078, 0x47d0, 0x2019, 0x000e, 0x1078, 0x75d9, 0xa484, 0x00ff, - 0xa080, 0x2329, 0x200c, 0xa18c, 0xff00, 0x810f, 0x8127, 0xa006, - 0x2009, 0x000e, 0x1078, 0x7641, 0x017f, 0xd1ac, 0x00c0, 0x1f06, - 0x2019, 0x0004, 0x1078, 0x2293, 0x0078, 0x1f15, 0x157e, 0x20a9, - 0x007f, 0x2009, 0x0000, 0x1078, 0x384c, 0x00c0, 0x1f11, 0x1078, - 0x3637, 0x8108, 0x00f0, 0x1f0b, 0x157f, 0x0c7f, 0x047f, 0x6043, - 0x0000, 0x2009, 0x00f7, 0x1078, 0x35fa, 0x0f7e, 0x2079, 0x7949, - 0x783c, 0xa086, 0x0000, 0x0040, 0x1f2d, 0x6027, 0x0004, 0x783f, - 0x0000, 0x2079, 0x0140, 0x7803, 0x0000, 0x0f7f, 0x2011, 0x0003, - 0x1078, 0x58d8, 0x2011, 0x0002, 0x1078, 0x58e2, 0x1078, 0x57ee, - 0x1078, 0x4706, 0x037e, 0x2019, 0x0000, 0x1078, 0x5880, 0x037f, - 0x60e3, 0x0000, 0x017f, 0x2001, 0x7700, 0x2014, 0xa296, 0x0004, - 0x00c0, 0x1f50, 0xd19c, 0x00c0, 0x1f50, 0x6228, 0xc29d, 0x622a, - 0x2003, 0x0001, 0x2001, 0x7720, 0x2003, 0x0000, 0x6027, 0x0020, - 0xd194, 0x0040, 0x1ff9, 0x0f7e, 0x2079, 0x7949, 0x783c, 0xa086, - 0x0001, 0x00c0, 0x1f7c, 0x017e, 0x6027, 0x0004, 0x783f, 0x0000, - 0x2079, 0x0140, 0x7803, 0x1000, 0x7803, 0x0000, 0x2079, 0x7936, - 0x7807, 0x0000, 0x7833, 0x0000, 0x1078, 0x4d96, 0x1078, 0x4e56, - 0x017f, 0x0f7f, 0x0078, 0x1ff9, 0x0f7f, 0x017e, 0x6220, 0xd2b4, - 0x0040, 0x1fb1, 0x1078, 0x4706, 0x1078, 0x569c, 0x6027, 0x0004, - 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0040, 0x1f94, - 0x6803, 0x1000, 0x6803, 0x0000, 0x0d7f, 0x0c7e, 0x2061, 0x7936, - 0x6028, 0xa09a, 0x0002, 0x00c8, 0x1fa4, 0x8000, 0x602a, 0x0c7f, - 0x1078, 0x568e, 0x0078, 0x1ff8, 0x2019, 0x793f, 0x2304, 0xa065, - 0x0040, 0x1fae, 0x2009, 0x0027, 0x1078, 0x5d41, 0x0c7f, 0x0078, - 0x1ff8, 0xd2bc, 0x0040, 0x1ff8, 0x1078, 0x4714, 0x6017, 0x0010, - 0x6027, 0x0004, 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, - 0x0040, 0x1fc6, 0x6803, 0x1000, 0x6803, 0x0000, 0x0d7f, 0x0c7e, - 0x2061, 0x7936, 0x6044, 0xa09a, 0x0002, 0x00c8, 0x1fe7, 0x8000, - 0x6046, 0x603c, 0x0c7f, 0xa005, 0x0040, 0x1ff8, 0x1078, 0x470b, - 0xa080, 0x0007, 0x2004, 0xa086, 0x0006, 0x00c0, 0x1fe3, 0x6017, - 0x0012, 0x0078, 0x1ff8, 0x6017, 0x0016, 0x0078, 0x1ff8, 0x037e, - 0x2019, 0x0001, 0x1078, 0x5880, 0x037f, 0x2019, 0x7945, 0x2304, - 0xa065, 0x0040, 0x1ff7, 0x2009, 0x004f, 0x1078, 0x5d41, 0x0c7f, - 0x017f, 0xd19c, 0x0040, 0x2021, 0x017e, 0x6028, 0xc09c, 0x602a, - 0x2011, 0x0003, 0x1078, 0x58d8, 0x2011, 0x0002, 0x1078, 0x58e2, - 0x1078, 0x57ee, 0x1078, 0x4706, 0x037e, 0x2019, 0x0000, 0x1078, - 0x5880, 0x037f, 0x60e3, 0x0000, 0x1078, 0x76b0, 0x1078, 0x76ce, - 0x2001, 0x7700, 0x2003, 0x0004, 0x6027, 0x0008, 0x1078, 0x11be, - 0x017f, 0xa18c, 0xffd0, 0x6126, 0x007c, 0x007e, 0x017e, 0x027e, - 0x0e7e, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2071, 0x7700, 0x71b0, - 0x70b2, 0xa116, 0x0040, 0x204b, 0x81ff, 0x0040, 0x203d, 0x2011, - 0x8011, 0x1078, 0x2d59, 0x0078, 0x204b, 0x2011, 0x8012, 0x1078, - 0x2d59, 0x037e, 0x0c7e, 0x2061, 0x0100, 0x2019, 0x0028, 0x1078, - 0x2293, 0x0c7f, 0x037f, 0x127f, 0x0f7f, 0x0e7f, 0x027f, 0x017f, - 0x007f, 0x007c, 0x0c7e, 0x0f7e, 0x007e, 0x027e, 0x2061, 0x0100, - 0xa190, 0x206d, 0x2204, 0x60f2, 0xa192, 0x0005, 0x00c8, 0x2064, - 0xa190, 0x2076, 0x0078, 0x2066, 0x2011, 0x207a, 0x2204, 0x60ee, - 0x027f, 0x007f, 0x0f7f, 0x0c7f, 0x007c, 0x0840, 0x0840, 0x0840, - 0x0580, 0x0420, 0x0348, 0x02c0, 0x0258, 0x0210, 0x01a8, 0x01a8, - 0x01a8, 0x01a8, 0x0140, 0x00f8, 0x00d0, 0x00b0, 0x00a0, 0x2028, - 0x2130, 0xa094, 0xff00, 0x00c0, 0x2088, 0x81ff, 0x0040, 0x208c, - 0x1078, 0x444b, 0x0078, 0x2093, 0xa080, 0x2329, 0x200c, 0xa18c, - 0xff00, 0x810f, 0xa006, 0x007c, 0xa080, 0x2329, 0x200c, 0xa18c, - 0x00ff, 0x007c, 0x20ba, 0x20be, 0x20c2, 0x20c8, 0x20ce, 0x20d4, - 0x20da, 0x20e2, 0x20ea, 0x20f0, 0x20f6, 0x20fe, 0x2106, 0x210e, - 0x2116, 0x2120, 0x212a, 0x212a, 0x212a, 0x212a, 0x212a, 0x212a, - 0x212a, 0x212a, 0x212a, 0x212a, 0x212a, 0x212a, 0x212a, 0x212a, - 0x212a, 0x212a, 0x107e, 0x007e, 0x0078, 0x2143, 0x107e, 0x007e, - 0x0078, 0x2143, 0x107e, 0x007e, 0x1078, 0x1e5e, 0x0078, 0x2143, - 0x107e, 0x007e, 0x1078, 0x1e5e, 0x0078, 0x2143, 0x107e, 0x007e, - 0x1078, 0x1d45, 0x0078, 0x2143, 0x107e, 0x007e, 0x1078, 0x1d45, - 0x0078, 0x2143, 0x107e, 0x007e, 0x1078, 0x1e5e, 0x1078, 0x1d45, - 0x0078, 0x2143, 0x107e, 0x007e, 0x1078, 0x1e5e, 0x1078, 0x1d45, - 0x0078, 0x2143, 0x107e, 0x007e, 0x1078, 0x1d8a, 0x0078, 0x2143, - 0x107e, 0x007e, 0x1078, 0x1d8a, 0x0078, 0x2143, 0x107e, 0x007e, - 0x1078, 0x1e5e, 0x1078, 0x1d8a, 0x0078, 0x2143, 0x107e, 0x007e, - 0x1078, 0x1e5e, 0x1078, 0x1d8a, 0x0078, 0x2143, 0x107e, 0x007e, - 0x1078, 0x1d45, 0x1078, 0x1d8a, 0x0078, 0x2143, 0x107e, 0x007e, - 0x1078, 0x1d45, 0x1078, 0x1d8a, 0x0078, 0x2143, 0x107e, 0x007e, - 0x1078, 0x1e5e, 0x1078, 0x1d45, 0x1078, 0x1d8a, 0x0078, 0x2143, - 0x107e, 0x007e, 0x1078, 0x1e5e, 0x1078, 0x1d45, 0x1078, 0x1d8a, - 0x0078, 0x2143, 0x0005, 0x0078, 0x212a, 0xb084, 0x003c, 0x8004, - 0x8004, 0x0079, 0x2133, 0x2143, 0x20c0, 0x20c4, 0x20ca, 0x20d0, - 0x20d6, 0x20dc, 0x20e4, 0x20ec, 0x20f2, 0x20f8, 0x2100, 0x2108, - 0x2110, 0x2118, 0x2122, 0x0008, 0x212d, 0x007f, 0x107f, 0x2091, - 0x8001, 0x007c, 0x0c7e, 0x027e, 0x2041, 0x007e, 0x70bc, 0xd09c, - 0x0040, 0x2154, 0x2041, 0x007f, 0x2001, 0x010c, 0x203c, 0x727c, - 0x82ff, 0x0040, 0x219f, 0x037e, 0x738c, 0xa38e, 0xffff, 0x00c0, - 0x2163, 0x2019, 0x0001, 0x8314, 0xa2e0, 0x7dc0, 0x2c04, 0xa38c, - 0x0001, 0x0040, 0x2170, 0xa084, 0xff00, 0x8007, 0x0078, 0x2172, - 0xa084, 0x00ff, 0xa70e, 0x0040, 0x2194, 0xa08e, 0x00ff, 0x0040, - 0x219a, 0x2009, 0x0000, 0x1078, 0x207f, 0x1078, 0x3811, 0x00c0, - 0x2197, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x218e, - 0x1078, 0x21f1, 0x0040, 0x2197, 0x0078, 0x2194, 0x1078, 0x22f5, - 0x1078, 0x2218, 0x0040, 0x2197, 0x8318, 0x0078, 0x2163, 0x738e, - 0x0078, 0x219c, 0x708f, 0xffff, 0x037f, 0x0078, 0x21ee, 0xa780, - 0x2329, 0x203c, 0xa7bc, 0xff00, 0x873f, 0x708c, 0xa096, 0xffff, - 0x0040, 0x21b1, 0xa812, 0x00c8, 0x21c1, 0x708f, 0xffff, 0x0078, - 0x21eb, 0x2009, 0x0000, 0x70bc, 0xd09c, 0x0040, 0x21bc, 0xd094, - 0x0040, 0x21bc, 0x2009, 0x007e, 0x2100, 0xa802, 0x20a8, 0x0078, - 0x21c5, 0x2008, 0x2810, 0xa202, 0x20a8, 0x2700, 0x157e, 0x017e, - 0xa106, 0x0040, 0x21e2, 0x1078, 0x3811, 0x00c0, 0x21eb, 0x6004, - 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x21dc, 0x1078, 0x21f1, - 0x0040, 0x21eb, 0x0078, 0x21e2, 0x1078, 0x22f5, 0x1078, 0x2218, - 0x0040, 0x21eb, 0x017f, 0x8108, 0x157f, 0x00f0, 0x21c5, 0x708f, - 0xffff, 0x0078, 0x21ee, 0x017f, 0x157f, 0x718e, 0x027f, 0x0c7f, - 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x1078, 0x5cb4, - 0x0040, 0x2213, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, - 0x1078, 0x37e0, 0x2001, 0x0000, 0x1078, 0x37f4, 0x127e, 0x2091, - 0x8000, 0x7088, 0x8000, 0x708a, 0x127f, 0x2009, 0x0004, 0x1078, - 0x5d41, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, 0x007c, - 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x1078, 0x5cb4, 0x0040, - 0x223a, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, - 0x37e0, 0x2001, 0x0002, 0x1078, 0x37f4, 0x127e, 0x2091, 0x8000, - 0x7088, 0x8000, 0x708a, 0x127f, 0x2009, 0x0002, 0x1078, 0x5d41, - 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, 0x007c, 0x0c7e, - 0x027e, 0x2009, 0x0080, 0x1078, 0x3811, 0x00c0, 0x224d, 0x1078, - 0x2250, 0x0040, 0x224d, 0x70c3, 0xffff, 0x027f, 0x0c7f, 0x007c, - 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x1078, 0x5cb4, 0x0040, - 0x2272, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, - 0x37e0, 0x2001, 0x0002, 0x1078, 0x37f4, 0x127e, 0x2091, 0x8000, - 0x70c4, 0x8000, 0x70c6, 0x127f, 0x2009, 0x0002, 0x1078, 0x5d41, - 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, 0x007c, 0x0c7e, - 0x0d7e, 0x2009, 0x007f, 0x1078, 0x3811, 0x00c0, 0x2290, 0x2c68, - 0x1078, 0x5cb4, 0x0040, 0x2290, 0x2d00, 0x601a, 0x6312, 0x601f, - 0x0001, 0x620a, 0x2009, 0x0022, 0x1078, 0x5d41, 0xa085, 0x0001, - 0x0d7f, 0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x067e, 0x037e, 0x027e, - 0x1078, 0x4a85, 0x1078, 0x4a35, 0x1078, 0x6219, 0x20a9, 0x007f, - 0x2009, 0x0000, 0x017e, 0x1078, 0x384c, 0x00c0, 0x22ab, 0x1078, - 0x3a36, 0x1078, 0x3637, 0x017f, 0x8108, 0x00f0, 0x22a2, 0x027f, - 0x037f, 0x067f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e, 0x037e, - 0x027e, 0x017e, 0x6218, 0x2270, 0x72a0, 0x027e, 0x2019, 0x0029, - 0x1078, 0x4a7e, 0x1078, 0x49c1, 0x2c08, 0x1078, 0x747b, 0x017f, - 0x2e60, 0x1078, 0x3a36, 0x6210, 0x6314, 0x1078, 0x3637, 0x6212, - 0x6316, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, - 0x007e, 0x6018, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x00c0, 0x22eb, - 0x2071, 0x7700, 0x7088, 0xa005, 0x0040, 0x22e8, 0x8001, 0x708a, - 0x007f, 0x0e7f, 0x007c, 0x2071, 0x7700, 0x70c4, 0xa005, 0x0040, - 0x22e8, 0x8001, 0x70c6, 0x0078, 0x22e8, 0x6000, 0xc08c, 0x6002, - 0x007c, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x157e, 0x81ff, - 0x00c0, 0x2306, 0x20a9, 0x0001, 0x0078, 0x230a, 0x20a9, 0x007f, - 0x2011, 0x0000, 0x027e, 0xa2e0, 0x7820, 0x2c64, 0x8cff, 0x0040, - 0x231c, 0x2019, 0x0029, 0x1078, 0x4a7e, 0x1078, 0x49c1, 0x2c08, - 0x1078, 0x747b, 0x1078, 0x3a36, 0x027f, 0x8210, 0x00f0, 0x230a, - 0x027e, 0x027f, 0x157f, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f, - 0x007c, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, - 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, - 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, - 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, - 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, - 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, - 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, - 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, - 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, - 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, - 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, - 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, - 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, - 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, - 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, - 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, - 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, - 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, - 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, - 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, - 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, - 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, - 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, - 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, - 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, - 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, - 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, - 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x6908, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0007, 0x0040, 0x1bc9, + 0xa184, 0x0007, 0x0040, 0x1bc9, 0x017e, 0x2009, 0x0008, 0xa102, + 0x017f, 0xa108, 0x791a, 0x7116, 0x701e, 0x680c, 0xa081, 0x0000, + 0x781e, 0x701a, 0xa006, 0x700e, 0x7012, 0x7004, 0x692c, 0x6814, + 0xa106, 0x00c0, 0x1be0, 0x6928, 0x6810, 0xa106, 0x0040, 0x1bed, + 0x037e, 0x047e, 0x6b14, 0x6c10, 0x1078, 0x1e0f, 0x047f, 0x037f, + 0x0040, 0x1bed, 0x0c7f, 0x0078, 0x1c07, 0x8aff, 0x00c0, 0x1bf5, + 0x0c7f, 0xa085, 0x0001, 0x0078, 0x1c07, 0x127e, 0x2091, 0x8000, + 0x2079, 0x0020, 0x2009, 0x0001, 0x1078, 0x1c0b, 0x0040, 0x1c04, + 0x2009, 0x0001, 0x1078, 0x1c0b, 0x127f, 0x0c7f, 0xa006, 0x0d7f, + 0x0e7f, 0x0f7f, 0x007c, 0x077e, 0x067e, 0x057e, 0x047e, 0x037e, + 0x027e, 0x8aff, 0x0040, 0x1c89, 0x700c, 0x7214, 0xa23a, 0x7010, + 0x7218, 0xa203, 0x0048, 0x1c88, 0xa705, 0x0040, 0x1c88, 0xa03e, + 0x2730, 0x6850, 0xd0fc, 0x00c0, 0x1c3b, 0x0d7e, 0x2804, 0xac68, + 0x2900, 0x0079, 0x1c2b, 0x1c6a, 0x1c4b, 0x1c4b, 0x1c6a, 0x1c6a, + 0x1c62, 0x1c6a, 0x1c4b, 0x1c6a, 0x1c51, 0x1c51, 0x1c6a, 0x1c6a, + 0x1c6a, 0x1c59, 0x1c51, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, + 0x6c20, 0xd99c, 0x0040, 0x1c6e, 0x0d7e, 0x2804, 0xac68, 0x6f08, + 0x6e0c, 0x0078, 0x1c6d, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0078, + 0x1c6d, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0078, + 0x1c6d, 0x0d7f, 0x0d7e, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, + 0x00c0, 0x1c6a, 0x0d7f, 0x1078, 0x1dab, 0x00c0, 0x1c11, 0xa00e, + 0x0078, 0x1c89, 0x0d7f, 0x1078, 0x12d2, 0x0d7f, 0x7b22, 0x7a26, + 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, + 0x6828, 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x700c, 0xa300, + 0x700e, 0x7010, 0xa201, 0x7012, 0x1078, 0x1dab, 0x0078, 0x1c89, + 0xa006, 0x027f, 0x037f, 0x047f, 0x057f, 0x067f, 0x077f, 0x007c, + 0x1078, 0x12d2, 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, + 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x0d7e, 0x6010, + 0x2068, 0x1078, 0x77ed, 0x0040, 0x1ca8, 0x6850, 0xc0bd, 0x6852, + 0x0d7f, 0x1078, 0x759a, 0x20e1, 0x9040, 0x1078, 0x6753, 0x2011, + 0x0000, 0x1078, 0x64b8, 0x1078, 0x5948, 0x0078, 0x1d7c, 0x127e, + 0x2091, 0x2200, 0x007e, 0x017e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, + 0x2079, 0x0020, 0x2071, 0x8af9, 0x2b68, 0x6818, 0x2060, 0x7904, + 0x7803, 0x0002, 0xa184, 0x0700, 0x00c0, 0x1c92, 0x7000, 0x0079, + 0x1cd1, 0x1d7c, 0x1cd5, 0x1d49, 0x1d7a, 0x8001, 0x7002, 0xd19c, + 0x00c0, 0x1ce9, 0x8aff, 0x0040, 0x1d08, 0x2009, 0x0001, 0x1078, + 0x1c0b, 0x0040, 0x1d7c, 0x2009, 0x0001, 0x1078, 0x1c0b, 0x0078, + 0x1d7c, 0x7803, 0x0004, 0xd194, 0x0040, 0x1cf9, 0x6850, 0xc0fc, + 0x6852, 0x8aff, 0x00c0, 0x1cfe, 0x684c, 0xc0f5, 0x684e, 0x0078, + 0x1cfe, 0x1078, 0x1dc4, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826, + 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000, 0x0078, 0x1d7c, + 0x711c, 0x81ff, 0x0040, 0x1d1e, 0x7918, 0x7922, 0x7827, 0x0000, + 0x7803, 0x0001, 0x7000, 0x8000, 0x7002, 0x700c, 0xa100, 0x700e, + 0x7010, 0xa081, 0x0000, 0x7012, 0x0078, 0x1d7c, 0x0f7e, 0x027e, + 0x781c, 0x007e, 0x7818, 0x007e, 0x2079, 0x0100, 0x7a14, 0xa284, + 0x0004, 0xa085, 0x0012, 0x7816, 0x7820, 0xd0bc, 0x00c0, 0x1d2c, + 0x79c8, 0x007f, 0xa102, 0x017f, 0x007e, 0x017e, 0x79c4, 0x007f, + 0xa102, 0x78c6, 0x007f, 0x78ca, 0xa284, 0x0004, 0xa085, 0x0012, + 0x7816, 0x027f, 0x0f7f, 0x7803, 0x0008, 0x7003, 0x0000, 0x0078, + 0x1d7c, 0x8001, 0x7002, 0xd194, 0x0040, 0x1d5e, 0x7804, 0xd0fc, + 0x00c0, 0x1cc7, 0xd19c, 0x00c0, 0x1d78, 0x8aff, 0x0040, 0x1d7c, + 0x2009, 0x0001, 0x1078, 0x1c0b, 0x0078, 0x1d7c, 0x027e, 0x037e, + 0x6b28, 0x6a2c, 0x1078, 0x1dc4, 0x0d7e, 0x2804, 0xac68, 0x6034, + 0xd09c, 0x00c0, 0x1d71, 0x6808, 0xa31a, 0x680c, 0xa213, 0x0078, + 0x1d75, 0x6810, 0xa31a, 0x6814, 0xa213, 0x0d7f, 0x0078, 0x1cf9, + 0x0078, 0x1cf9, 0x1078, 0x12d2, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, + 0x017f, 0x007f, 0x127f, 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0x8af9, + 0x7000, 0xa086, 0x0000, 0x0040, 0x1da8, 0x2079, 0x0020, 0x20e1, + 0x9040, 0x7804, 0xd0fc, 0x0040, 0x1d8f, 0x1078, 0x1cb7, 0x7000, + 0xa086, 0x0000, 0x00c0, 0x1d8f, 0x7803, 0x0004, 0x7804, 0xd0ac, + 0x00c0, 0x1d9e, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, + 0x0e7f, 0x0f7f, 0x007c, 0x8840, 0x2804, 0xa005, 0x00c0, 0x1dbf, + 0x6004, 0xa005, 0x0040, 0x1dc1, 0x681a, 0x2060, 0x6034, 0xa084, + 0x000f, 0xa080, 0x1def, 0x2044, 0x88ff, 0x1040, 0x12d2, 0x8a51, + 0x007c, 0x2051, 0x0000, 0x007c, 0x8a50, 0x8841, 0x2804, 0xa005, + 0x00c0, 0x1dde, 0x2c00, 0xad06, 0x0040, 0x1dd3, 0x6000, 0xa005, + 0x00c0, 0x1dd3, 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, + 0xa080, 0x1dff, 0x2044, 0x88ff, 0x1040, 0x12d2, 0x007c, 0x0000, + 0x0011, 0x0015, 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, + 0x000f, 0x0015, 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, + 0x1de4, 0x1de0, 0x0000, 0x0000, 0x1dee, 0x0000, 0x1de4, 0x0000, + 0x1deb, 0x1de8, 0x0000, 0x0000, 0x0000, 0x1dee, 0x1deb, 0x0000, + 0x1de6, 0x1de6, 0x0000, 0x0000, 0x1dee, 0x0000, 0x1de6, 0x0000, + 0x1dec, 0x1dec, 0x0000, 0x0000, 0x0000, 0x1dee, 0x1dec, 0x0a7e, + 0x097e, 0x087e, 0x6858, 0xa055, 0x0040, 0x1eb0, 0x2d60, 0x6034, + 0xa0cc, 0x000f, 0xa9c0, 0x1def, 0xa986, 0x0007, 0x0040, 0x1e28, + 0xa986, 0x000e, 0x0040, 0x1e28, 0xa986, 0x000f, 0x00c0, 0x1e2c, + 0x605c, 0xa422, 0x6060, 0xa31a, 0x2804, 0xa045, 0x00c0, 0x1e3a, + 0x0050, 0x1e34, 0x0078, 0x1eb0, 0x6004, 0xa065, 0x0040, 0x1eb0, + 0x0078, 0x1e17, 0x2804, 0xa005, 0x0040, 0x1e58, 0xac68, 0xd99c, + 0x00c0, 0x1e48, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0078, 0x1e4c, + 0x6810, 0xa422, 0x6814, 0xa31b, 0x0048, 0x1e77, 0x2300, 0xa405, + 0x0040, 0x1e5e, 0x8a51, 0x0040, 0x1eb0, 0x8840, 0x0078, 0x1e3a, + 0x6004, 0xa065, 0x0040, 0x1eb0, 0x0078, 0x1e17, 0x8a51, 0x0040, + 0x1eb0, 0x8840, 0x2804, 0xa005, 0x00c0, 0x1e71, 0x6004, 0xa065, + 0x0040, 0x1eb0, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x1def, 0x2804, + 0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852, 0x0078, 0x1ea4, 0x8422, + 0x8420, 0x831a, 0xa399, 0x0000, 0x0d7e, 0x2b68, 0x6c6e, 0x6b72, + 0x0d7f, 0xd99c, 0x00c0, 0x1e92, 0x6908, 0x2400, 0xa122, 0x690c, + 0x2300, 0xa11b, 0x1048, 0x12d2, 0x6800, 0xa420, 0x6804, 0xa319, + 0x0078, 0x1e9e, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, + 0x1048, 0x12d2, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, + 0x6b22, 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832, + 0x2a00, 0x6826, 0x007f, 0x007f, 0x007f, 0xa006, 0x0078, 0x1eb5, + 0x087f, 0x097f, 0x0a7f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0005, + 0x2004, 0xa084, 0x0007, 0x0079, 0x1ebd, 0x1ec5, 0x1ec6, 0x1ec9, + 0x1ecc, 0x1ed1, 0x1ed4, 0x1ed9, 0x1ede, 0x007c, 0x1078, 0x1cb7, + 0x007c, 0x1078, 0x1816, 0x007c, 0x1078, 0x1816, 0x1078, 0x1cb7, + 0x007c, 0x1078, 0x145a, 0x007c, 0x1078, 0x1cb7, 0x1078, 0x145a, + 0x007c, 0x1078, 0x1816, 0x1078, 0x145a, 0x007c, 0x1078, 0x1816, + 0x1078, 0x1cb7, 0x1078, 0x145a, 0x007c, 0x127e, 0x2091, 0x2300, + 0x2079, 0x0200, 0x2071, 0x8d80, 0x2069, 0x8800, 0x2009, 0x0004, + 0x7912, 0x7817, 0x0004, 0x1078, 0x2220, 0x781b, 0x0002, 0x20e1, + 0x8700, 0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x781c, 0xa084, + 0x0007, 0x0079, 0x1f03, 0x1f27, 0x1f0b, 0x1f0f, 0x1f13, 0x1f19, + 0x1f1d, 0x1f21, 0x1f25, 0x1078, 0x4cc0, 0x0078, 0x1f27, 0x1078, + 0x4cef, 0x0078, 0x1f27, 0x1078, 0x4cc0, 0x1078, 0x4cef, 0x0078, + 0x1f27, 0x1078, 0x1f29, 0x0078, 0x1f27, 0x1078, 0x1f29, 0x0078, + 0x1f27, 0x1078, 0x1f29, 0x0078, 0x1f27, 0x1078, 0x1f29, 0x127f, + 0x007c, 0x007e, 0x017e, 0x027e, 0x7930, 0xa184, 0x0003, 0x0040, + 0x1f35, 0x20e1, 0x9040, 0x0078, 0x1f52, 0xa184, 0x0030, 0x0040, + 0x1f46, 0x6a00, 0xa286, 0x0003, 0x00c0, 0x1f40, 0x0078, 0x1f42, + 0x1078, 0x3c73, 0x20e1, 0x9010, 0x0078, 0x1f52, 0xa184, 0x00c0, + 0x0040, 0x1f4c, 0x1078, 0x12d2, 0xa184, 0x0300, 0x0040, 0x1f52, + 0x20e1, 0x9020, 0x7932, 0x027f, 0x017f, 0x007f, 0x007c, 0x017e, + 0x0e7e, 0x0f7e, 0x2071, 0x8800, 0x7128, 0x2001, 0x8a8f, 0x2102, + 0x2001, 0x8a97, 0x2102, 0xa182, 0x0211, 0x00c8, 0x1f6b, 0x2009, + 0x0008, 0x0078, 0x1f95, 0xa182, 0x0259, 0x00c8, 0x1f73, 0x2009, + 0x0007, 0x0078, 0x1f95, 0xa182, 0x02c1, 0x00c8, 0x1f7b, 0x2009, + 0x0006, 0x0078, 0x1f95, 0xa182, 0x0349, 0x00c8, 0x1f83, 0x2009, + 0x0005, 0x0078, 0x1f95, 0xa182, 0x0421, 0x00c8, 0x1f8b, 0x2009, + 0x0004, 0x0078, 0x1f95, 0xa182, 0x0581, 0x00c8, 0x1f93, 0x2009, + 0x0003, 0x0078, 0x1f95, 0x2009, 0x0002, 0x2079, 0x0200, 0x7912, + 0x7817, 0x0004, 0x1078, 0x2220, 0x0f7f, 0x0e7f, 0x017f, 0x007c, + 0x127e, 0x2091, 0x2200, 0x2061, 0x0100, 0x2071, 0x8800, 0x6024, + 0x6026, 0x6053, 0x0030, 0x6033, 0x00ef, 0x60e7, 0x0000, 0x60eb, + 0x00ef, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, + 0x0080, 0x602f, 0x0000, 0x6007, 0x0eaf, 0x600f, 0x00ff, 0x602b, + 0x002f, 0x127f, 0x007c, 0x2001, 0x882e, 0x2003, 0x0000, 0x2001, + 0x882d, 0x2003, 0x0001, 0x007c, 0x127e, 0x2091, 0x2200, 0x007e, + 0x017e, 0x027e, 0x6124, 0xa184, 0x002c, 0x00c0, 0x1fdb, 0xa184, + 0x0007, 0x0079, 0x1fe1, 0xa195, 0x0004, 0xa284, 0x0007, 0x0079, + 0x1fe1, 0x200d, 0x1fe9, 0x1fed, 0x1ff1, 0x1ff7, 0x1ffb, 0x2001, + 0x2007, 0x1078, 0x5273, 0x0078, 0x200d, 0x1078, 0x5362, 0x0078, + 0x200d, 0x1078, 0x5362, 0x1078, 0x5273, 0x0078, 0x200d, 0x1078, + 0x2012, 0x0078, 0x200d, 0x1078, 0x5273, 0x1078, 0x2012, 0x0078, + 0x200d, 0x1078, 0x5362, 0x1078, 0x2012, 0x0078, 0x200d, 0x1078, + 0x5362, 0x1078, 0x5273, 0x1078, 0x2012, 0x027f, 0x017f, 0x007f, + 0x127f, 0x007c, 0xd1ac, 0x0040, 0x20ec, 0x017e, 0x047e, 0x0c7e, + 0x644c, 0xa486, 0xf0f0, 0x00c0, 0x2024, 0x2061, 0x0100, 0x644a, + 0x6043, 0x0090, 0x6043, 0x0010, 0x74be, 0xa48c, 0xff00, 0x7034, + 0xd084, 0x0040, 0x203c, 0xa186, 0xf800, 0x00c0, 0x203c, 0x7038, + 0xd084, 0x00c0, 0x203c, 0xc085, 0x703a, 0x037e, 0x2418, 0x2011, + 0x8016, 0x1078, 0x317a, 0x037f, 0xa196, 0xff00, 0x0040, 0x2061, + 0x6030, 0xa084, 0x00ff, 0x810f, 0xa116, 0x0040, 0x2061, 0x7130, + 0xd18c, 0x00c0, 0x2061, 0x2011, 0x8852, 0x2214, 0xd2ec, 0x0040, + 0x2055, 0xc18d, 0x7132, 0x0078, 0x2061, 0x6240, 0xa294, 0x0010, + 0x0040, 0x20af, 0x6248, 0xa294, 0xff00, 0xa296, 0xff00, 0x00c0, + 0x20af, 0x7034, 0xd08c, 0x00c0, 0x206d, 0x2001, 0x880c, 0x200c, + 0xd1ac, 0x00c0, 0x20af, 0xc1ad, 0x2102, 0x037e, 0x73bc, 0x2011, + 0x8013, 0x1078, 0x317a, 0x037f, 0x7130, 0xc185, 0x7132, 0x2011, + 0x8852, 0x220c, 0xd1a4, 0x0040, 0x2097, 0x017e, 0x2009, 0x0001, + 0x2011, 0x0100, 0x1078, 0x5243, 0x2019, 0x000e, 0x1078, 0x8683, + 0xa484, 0x00ff, 0xa080, 0x25b2, 0x200c, 0xa18c, 0xff00, 0x810f, + 0x8127, 0xa006, 0x2009, 0x000e, 0x1078, 0x86f5, 0x017f, 0xd1ac, + 0x00c0, 0x20a0, 0x2019, 0x0004, 0x1078, 0x249d, 0x0078, 0x20af, + 0x157e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x1078, 0x3f8e, 0x00c0, + 0x20ab, 0x1078, 0x3d31, 0x8108, 0x00f0, 0x20a5, 0x157f, 0x0c7f, + 0x047f, 0x0f7e, 0x2079, 0x8ab5, 0x783c, 0xa086, 0x0000, 0x0040, + 0x20c1, 0x6027, 0x0004, 0x783f, 0x0000, 0x2079, 0x0140, 0x7803, + 0x0000, 0x0f7f, 0x2011, 0x0003, 0x1078, 0x64ae, 0x2011, 0x0002, + 0x1078, 0x64b8, 0x1078, 0x639b, 0x1078, 0x516f, 0x037e, 0x2019, + 0x0000, 0x1078, 0x642d, 0x037f, 0x60e3, 0x0000, 0x017f, 0x2001, + 0x8800, 0x2014, 0xa296, 0x0004, 0x00c0, 0x20e4, 0xd19c, 0x00c0, + 0x20e4, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0x8821, + 0x2003, 0x0000, 0x6027, 0x0020, 0xd194, 0x0040, 0x21c7, 0x0f7e, + 0x2079, 0x8ab5, 0x783c, 0xa086, 0x0001, 0x00c0, 0x2110, 0x017e, + 0x6027, 0x0004, 0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x1000, + 0x7803, 0x0000, 0x2079, 0x8aa2, 0x7807, 0x0000, 0x7833, 0x0000, + 0x1078, 0x5888, 0x1078, 0x5948, 0x017f, 0x0f7f, 0x0078, 0x21c7, + 0x0f7f, 0x017e, 0x6220, 0xd2b4, 0x0040, 0x217d, 0x1078, 0x516f, + 0x1078, 0x6232, 0x6027, 0x0004, 0x0f7e, 0x2019, 0x8aab, 0x2304, + 0xa07d, 0x0040, 0x2153, 0x7804, 0xa086, 0x0032, 0x00c0, 0x2153, + 0x0d7e, 0x0c7e, 0x0e7e, 0x2069, 0x0140, 0x618c, 0x6288, 0x7818, + 0x608e, 0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, + 0x00c0, 0x2137, 0x6043, 0x0000, 0x6803, 0x1000, 0x6803, 0x0000, + 0x618e, 0x628a, 0x1078, 0x578f, 0x1078, 0x5888, 0x7810, 0x2070, + 0x7037, 0x0103, 0x2f60, 0x1078, 0x690e, 0x0e7f, 0x0c7f, 0x0d7f, + 0x0f7f, 0x017f, 0x007c, 0x0f7f, 0x0d7e, 0x2069, 0x0140, 0x6804, + 0xa084, 0x4000, 0x0040, 0x2160, 0x6803, 0x1000, 0x6803, 0x0000, + 0x0d7f, 0x0c7e, 0x2061, 0x8aa2, 0x6028, 0xa09a, 0x0002, 0x00c8, + 0x2170, 0x8000, 0x602a, 0x0c7f, 0x1078, 0x6224, 0x0078, 0x21c6, + 0x2019, 0x8aab, 0x2304, 0xa065, 0x0040, 0x217a, 0x2009, 0x0027, + 0x1078, 0x6939, 0x0c7f, 0x0078, 0x21c6, 0xd2bc, 0x0040, 0x21c6, + 0x1078, 0x517c, 0x6017, 0x0010, 0x6027, 0x0004, 0x0d7e, 0x2069, + 0x0140, 0x6804, 0xa084, 0x4000, 0x0040, 0x2192, 0x6803, 0x1000, + 0x6803, 0x0000, 0x0d7f, 0x0c7e, 0x2061, 0x8aa2, 0x6044, 0xa09a, + 0x0002, 0x00c8, 0x21b5, 0x8000, 0x6046, 0x603c, 0x0c7f, 0xa005, + 0x0040, 0x21c6, 0x2009, 0x07d0, 0x1078, 0x5174, 0xa080, 0x0007, + 0x2004, 0xa086, 0x0006, 0x00c0, 0x21b1, 0x6017, 0x0012, 0x0078, + 0x21c6, 0x6017, 0x0016, 0x0078, 0x21c6, 0x037e, 0x2019, 0x0001, + 0x1078, 0x642d, 0x037f, 0x2019, 0x8ab1, 0x2304, 0xa065, 0x0040, + 0x21c5, 0x2009, 0x004f, 0x1078, 0x6939, 0x0c7f, 0x017f, 0xd19c, + 0x0040, 0x21ef, 0x017e, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, + 0x1078, 0x64ae, 0x2011, 0x0002, 0x1078, 0x64b8, 0x1078, 0x639b, + 0x1078, 0x516f, 0x037e, 0x2019, 0x0000, 0x1078, 0x642d, 0x037f, + 0x60e3, 0x0000, 0x1078, 0x876a, 0x1078, 0x8788, 0x2001, 0x8800, + 0x2003, 0x0004, 0x6027, 0x0008, 0x1078, 0x1208, 0x017f, 0xa18c, + 0xffd0, 0x6126, 0x007c, 0x007e, 0x017e, 0x027e, 0x0e7e, 0x0f7e, + 0x127e, 0x2091, 0x8000, 0x2071, 0x8800, 0x71b4, 0x70b6, 0xa116, + 0x0040, 0x2219, 0x81ff, 0x0040, 0x220b, 0x2011, 0x8011, 0x1078, + 0x317a, 0x0078, 0x2219, 0x2011, 0x8012, 0x1078, 0x317a, 0x037e, + 0x0c7e, 0x2061, 0x0100, 0x2019, 0x0028, 0x1078, 0x249d, 0x0c7f, + 0x037f, 0x127f, 0x0f7f, 0x0e7f, 0x027f, 0x017f, 0x007f, 0x007c, + 0x0c7e, 0x0f7e, 0x007e, 0x027e, 0x2061, 0x0100, 0xa190, 0x2233, + 0x2204, 0x60f2, 0x2011, 0x2240, 0x2204, 0x60ee, 0x027f, 0x007f, + 0x0f7f, 0x0c7f, 0x007c, 0x0840, 0x0840, 0x0840, 0x0580, 0x0420, + 0x0348, 0x02c0, 0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8, + 0x0140, 0x00f8, 0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c, 0x00ff, + 0x2130, 0xa094, 0xff00, 0x00c0, 0x2250, 0x81ff, 0x0040, 0x2254, + 0x1078, 0x4e98, 0x0078, 0x225b, 0xa080, 0x25b2, 0x200c, 0xa18c, + 0xff00, 0x810f, 0xa006, 0x007c, 0xa080, 0x25b2, 0x200c, 0xa18c, + 0x00ff, 0x007c, 0x0c7e, 0x2061, 0x8800, 0x6030, 0x0040, 0x226b, + 0xc09d, 0x0078, 0x226c, 0xc09c, 0x6032, 0x0c7f, 0x007c, 0x228f, + 0x2293, 0x2297, 0x229d, 0x22a3, 0x22a9, 0x22af, 0x22b7, 0x22bf, + 0x22c5, 0x22cb, 0x22d3, 0x22db, 0x22e3, 0x22eb, 0x22f5, 0x22ff, + 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x22ff, + 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x107e, + 0x007e, 0x0078, 0x2318, 0x107e, 0x007e, 0x0078, 0x2318, 0x107e, + 0x007e, 0x1078, 0x1fcc, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078, + 0x1fcc, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078, 0x1eb6, 0x0078, + 0x2318, 0x107e, 0x007e, 0x1078, 0x1eb6, 0x0078, 0x2318, 0x107e, + 0x007e, 0x1078, 0x1fcc, 0x1078, 0x1eb6, 0x0078, 0x2318, 0x107e, + 0x007e, 0x1078, 0x1fcc, 0x1078, 0x1eb6, 0x0078, 0x2318, 0x107e, + 0x007e, 0x1078, 0x1efb, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078, + 0x1efb, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078, 0x1fcc, 0x1078, + 0x1efb, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078, 0x1fcc, 0x1078, + 0x1efb, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078, 0x1eb6, 0x1078, + 0x1efb, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078, 0x1eb6, 0x1078, + 0x1efb, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078, 0x1fcc, 0x1078, + 0x1eb6, 0x1078, 0x1efb, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078, + 0x1fcc, 0x1078, 0x1eb6, 0x1078, 0x1efb, 0x0078, 0x2318, 0x0005, + 0x0078, 0x22ff, 0xb084, 0x003c, 0x8004, 0x8004, 0x0079, 0x2308, + 0x2318, 0x2295, 0x2299, 0x229f, 0x22a5, 0x22ab, 0x22b1, 0x22b9, + 0x22c1, 0x22c7, 0x22cd, 0x22d5, 0x22dd, 0x22e5, 0x22ed, 0x22f7, + 0x0008, 0x2302, 0x007f, 0x107f, 0x2091, 0x8001, 0x007c, 0x0c7e, + 0x027e, 0x2041, 0x007e, 0x70c0, 0xd09c, 0x0040, 0x2329, 0x2041, + 0x007f, 0xd094, 0x2001, 0x010c, 0x203c, 0x00c0, 0x2388, 0x7280, + 0xd284, 0x0040, 0x2388, 0xd28c, 0x00c0, 0x2388, 0x037e, 0x7390, + 0xa38e, 0xffff, 0x00c0, 0x233e, 0x2019, 0x0001, 0x8314, 0xa2e0, + 0x8ec0, 0x2c04, 0xa38c, 0x0001, 0x0040, 0x234b, 0xa084, 0xff00, + 0x8007, 0x0078, 0x234d, 0xa084, 0x00ff, 0xa70e, 0x0040, 0x237d, + 0xa08e, 0x00ff, 0x00c0, 0x2362, 0x2011, 0x8852, 0x2214, 0xd2ec, + 0x00c0, 0x2383, 0x7280, 0xc28d, 0x7282, 0x7093, 0xffff, 0x037f, + 0x0078, 0x2388, 0x2009, 0x0000, 0x1078, 0x2245, 0x1078, 0x3f53, + 0x00c0, 0x2380, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, + 0x2377, 0x1078, 0x23ef, 0x0040, 0x2380, 0x0078, 0x237d, 0x1078, + 0x2503, 0x1078, 0x241c, 0x0040, 0x2380, 0x8318, 0x0078, 0x233e, + 0x7392, 0x0078, 0x2385, 0x7093, 0xffff, 0x037f, 0x0078, 0x23ec, + 0xa780, 0x25b2, 0x203c, 0xa7bc, 0xff00, 0x873f, 0x7090, 0xa096, + 0xffff, 0x0040, 0x239a, 0xa812, 0x00c8, 0x23aa, 0x7093, 0xffff, + 0x0078, 0x23e9, 0x2009, 0x0000, 0x70c0, 0xd09c, 0x0040, 0x23a5, + 0xd094, 0x0040, 0x23a5, 0x2009, 0x007e, 0x2100, 0xa802, 0x20a8, + 0x0078, 0x23ae, 0x2008, 0x2810, 0xa202, 0x20a8, 0x2700, 0x157e, + 0x017e, 0xa106, 0x0040, 0x23e0, 0x1078, 0x3f53, 0x00c0, 0x23e9, + 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x23c5, 0x1078, + 0x257d, 0x0040, 0x23e0, 0x0078, 0x23d4, 0x7280, 0xd28c, 0x0040, + 0x23da, 0x6004, 0xa084, 0x00ff, 0xa082, 0x0006, 0x0048, 0x23e0, + 0x1078, 0x3f76, 0x0078, 0x23e0, 0x1078, 0x23ef, 0x0040, 0x23e9, + 0x0078, 0x23e0, 0x1078, 0x2503, 0x1078, 0x241c, 0x0040, 0x23e9, + 0x017f, 0x8108, 0x157f, 0x00f0, 0x23ae, 0x7093, 0xffff, 0x0078, + 0x23ec, 0x017f, 0x157f, 0x7192, 0x027f, 0x0c7f, 0x007c, 0x017e, + 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x2001, 0x8856, 0x2004, 0xa084, + 0x00ff, 0x6842, 0x1078, 0x68a8, 0x0040, 0x2417, 0x2d00, 0x601a, + 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x3ef1, 0x2001, 0x0000, + 0x1078, 0x3f05, 0x127e, 0x2091, 0x8000, 0x708c, 0x8000, 0x708e, + 0x127f, 0x2009, 0x0004, 0x1078, 0x6939, 0xa085, 0x0001, 0x0c7f, + 0x0d7f, 0x077f, 0x017f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, + 0x2c68, 0x2001, 0x8856, 0x2004, 0xa084, 0x00ff, 0x6842, 0x1078, + 0x68a8, 0x0040, 0x2444, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, + 0x0000, 0x1078, 0x3ef1, 0x2001, 0x0002, 0x1078, 0x3f05, 0x127e, + 0x2091, 0x8000, 0x708c, 0x8000, 0x708e, 0x127f, 0x2009, 0x0002, + 0x1078, 0x6939, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, + 0x007c, 0x0c7e, 0x027e, 0x2009, 0x0080, 0x1078, 0x3f53, 0x00c0, + 0x2457, 0x1078, 0x245a, 0x0040, 0x2457, 0x70c7, 0xffff, 0x027f, + 0x0c7f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x1078, + 0x68a8, 0x0040, 0x247c, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, + 0x0000, 0x1078, 0x3ef1, 0x2001, 0x0002, 0x1078, 0x3f05, 0x127e, + 0x2091, 0x8000, 0x70c8, 0x8000, 0x70ca, 0x127f, 0x2009, 0x0002, + 0x1078, 0x6939, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, + 0x007c, 0x0c7e, 0x0d7e, 0x2009, 0x007f, 0x1078, 0x3f53, 0x00c0, + 0x249a, 0x2c68, 0x1078, 0x68a8, 0x0040, 0x249a, 0x2d00, 0x601a, + 0x6312, 0x601f, 0x0001, 0x620a, 0x2009, 0x0022, 0x1078, 0x6939, + 0xa085, 0x0001, 0x0d7f, 0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x067e, + 0x037e, 0x027e, 0x1078, 0x54fd, 0x1078, 0x549f, 0x1078, 0x6ea5, + 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x3f8e, 0x00c0, + 0x24b5, 0x1078, 0x418b, 0x1078, 0x3d31, 0x017f, 0x8108, 0x00f0, + 0x24ac, 0x027f, 0x037f, 0x067f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, + 0x0c7e, 0x037e, 0x027e, 0x017e, 0x6218, 0x2270, 0x72a0, 0x027e, + 0x2019, 0x0029, 0x1078, 0x54f0, 0x087e, 0x2041, 0x0000, 0x1078, + 0x5419, 0x2c08, 0x1078, 0x84d2, 0x087f, 0x017f, 0x2e60, 0x1078, + 0x418b, 0x6210, 0x6314, 0x1078, 0x3d31, 0x6212, 0x6316, 0x017f, + 0x027f, 0x037f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x007e, 0x6018, + 0xa080, 0x0028, 0x2004, 0xd0bc, 0x00c0, 0x24f9, 0x2071, 0x8800, + 0x708c, 0xa005, 0x0040, 0x24f6, 0x8001, 0x708e, 0x007f, 0x0e7f, + 0x007c, 0x2071, 0x8800, 0x70c8, 0xa005, 0x0040, 0x24f6, 0x8001, + 0x70ca, 0x0078, 0x24f6, 0x6000, 0xc08c, 0x6002, 0x007c, 0x0f7e, + 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x157e, 0x2178, 0x81ff, + 0x00c0, 0x2516, 0x20a9, 0x0001, 0x0078, 0x2531, 0x2001, 0x8852, + 0x2004, 0xd0c4, 0x0040, 0x252d, 0xd0a4, 0x0040, 0x252d, 0x047e, + 0x6018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0xa006, + 0x2009, 0x002d, 0x1078, 0x86f5, 0x047f, 0x20a9, 0x00ff, 0x2011, + 0x0000, 0x027e, 0xa288, 0x8934, 0x210c, 0x81ff, 0x0040, 0x255a, + 0x8fff, 0x1040, 0x2566, 0x2019, 0x0029, 0x1078, 0x54f0, 0x087e, + 0x2041, 0x0000, 0x1078, 0x5419, 0x0c7e, 0x027e, 0x2160, 0x6204, + 0xa294, 0x00ff, 0x2001, 0x0004, 0x8007, 0xa215, 0x6206, 0x027f, + 0x0c7f, 0x017e, 0x2c08, 0x1078, 0x84d2, 0x017f, 0x087f, 0x2160, + 0x1078, 0x418b, 0x027f, 0x8210, 0x00f0, 0x2531, 0x157f, 0x017f, + 0x027f, 0x037f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x047e, 0x027e, + 0x017e, 0x2001, 0x8852, 0x2004, 0xd0c4, 0x0040, 0x2579, 0xd0a4, + 0x0040, 0x2579, 0xa006, 0x2220, 0x8427, 0x2009, 0x0029, 0x1078, + 0x86f5, 0x017f, 0x027f, 0x047f, 0x007c, 0x017e, 0x027e, 0x037e, + 0x0c7e, 0x7280, 0x82ff, 0x0040, 0x25ab, 0xa290, 0x8852, 0x2214, + 0xd2ac, 0x00c0, 0x25ab, 0x2100, 0x1078, 0x225c, 0x81ff, 0x0040, + 0x25ad, 0x2019, 0x0001, 0x8314, 0xa2e0, 0x8ec0, 0x2c04, 0xd384, + 0x0040, 0x259f, 0xa084, 0xff00, 0x8007, 0x0078, 0x25a1, 0xa084, + 0x00ff, 0xa116, 0x0040, 0x25ad, 0xa096, 0x00ff, 0x0040, 0x25ab, + 0x8318, 0x0078, 0x2593, 0xa085, 0x0001, 0x0c7f, 0x037f, 0x027f, + 0x017f, 0x007c, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, + 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, + 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, + 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, + 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, + 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, + 0x689d, 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, + 0x6282, 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, + 0x8074, 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, + 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, + 0x5559, 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, + 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, + 0x8043, 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, + 0x4932, 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, + 0x4227, 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, + 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, + 0x8000, 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, + 0x8000, 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, + 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, + 0x2900, 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, + 0x2200, 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, + 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, + 0x1600, 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, + 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, + 0x0900, 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, + 0x8000, 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, + 0x8000, 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x8000, 0x2071, 0x776d, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, - 0x703a, 0x703e, 0x7033, 0x777d, 0x7037, 0x777d, 0x7007, 0x0001, - 0x2061, 0x77bd, 0x6003, 0x0002, 0x007c, 0x0090, 0x2450, 0x0068, - 0x2450, 0x2071, 0x776d, 0x2b78, 0x7818, 0xd084, 0x00c0, 0x2450, - 0x2a60, 0x7820, 0xa08e, 0x0069, 0x00c0, 0x2537, 0x0079, 0x24d4, - 0x007c, 0x2071, 0x776d, 0x7004, 0x0079, 0x2456, 0x245a, 0x245b, - 0x2465, 0x2477, 0x007c, 0x0090, 0x2464, 0x0068, 0x2464, 0x2b78, - 0x7818, 0xd084, 0x0040, 0x2483, 0x007c, 0x2b78, 0x2061, 0x77bd, - 0x6008, 0xa08e, 0x0100, 0x0040, 0x2472, 0xa086, 0x0200, 0x0040, - 0x252f, 0x007c, 0x7014, 0x2068, 0x2a60, 0x7018, 0x007a, 0x7010, - 0x2068, 0x6834, 0xa086, 0x0103, 0x0040, 0x247f, 0x007c, 0x2a60, - 0x2b78, 0x7018, 0x007a, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x00c8, - 0x248c, 0x61b0, 0x0079, 0x2494, 0x2100, 0xa08a, 0x0036, 0x00c8, - 0x252b, 0x61b0, 0x0079, 0x24d4, 0x250d, 0x253f, 0x2547, 0x254b, - 0x2553, 0x2559, 0x255d, 0x2566, 0x256a, 0x2572, 0x2576, 0x252b, - 0x252b, 0x252b, 0x257a, 0x252b, 0x258a, 0x25a1, 0x25b8, 0x2634, - 0x2639, 0x2666, 0x26c0, 0x26d1, 0x26ef, 0x2722, 0x272c, 0x2739, - 0x274c, 0x2766, 0x276f, 0x27ac, 0x27b2, 0x252b, 0x27c2, 0x252b, - 0x252b, 0x252b, 0x252b, 0x252b, 0x27c6, 0x27cc, 0x252b, 0x252b, - 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x27d4, 0x252b, - 0x252b, 0x252b, 0x252b, 0x252b, 0x27e1, 0x27e7, 0x252b, 0x252b, - 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, - 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, - 0x252b, 0x252b, 0x252b, 0x252b, 0x2572, 0x2576, 0x252b, 0x252b, - 0x27f9, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, - 0x252b, 0x252b, 0x252b, 0x252b, 0x2846, 0x2913, 0x2927, 0x292e, - 0x2991, 0x29e2, 0x29ed, 0x2a2c, 0x2a3b, 0x2a4a, 0x2a4d, 0x27fd, - 0x2a76, 0x2abd, 0x2aca, 0x2bc5, 0x2cb3, 0x2cda, 0x2de4, 0x2df2, - 0x2dff, 0x2e39, 0x713c, 0x0078, 0x250d, 0x2021, 0x4000, 0x1078, - 0x2d33, 0x127e, 0x2091, 0x8000, 0x0068, 0x251a, 0x7818, 0xd084, - 0x0040, 0x251d, 0x127f, 0x0078, 0x2511, 0x781b, 0x0001, 0x7c22, - 0x7926, 0x7a2a, 0x7b2e, 0x2091, 0x4080, 0x7007, 0x0001, 0x2091, - 0x5000, 0x127f, 0x007c, 0x2021, 0x4001, 0x0078, 0x250f, 0x2021, - 0x4002, 0x0078, 0x250f, 0x2021, 0x4003, 0x0078, 0x250f, 0x2021, - 0x4005, 0x0078, 0x250f, 0x2021, 0x4006, 0x0078, 0x250f, 0xa02e, - 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0078, 0x2d42, 0x7823, - 0x0004, 0x7824, 0x007a, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, - 0x7930, 0x0078, 0x2d46, 0x7924, 0x7828, 0x2114, 0x200a, 0x0078, - 0x250d, 0x7924, 0x2114, 0x0078, 0x250d, 0x2099, 0x0009, 0x20a1, - 0x0009, 0x20a9, 0x0007, 0x53a3, 0x0078, 0x250d, 0x7824, 0x2060, - 0x0078, 0x257c, 0x2009, 0x0001, 0x2011, 0x000f, 0x2019, 0x0025, - 0x0078, 0x250d, 0x7d38, 0x7c3c, 0x0078, 0x2541, 0x7d38, 0x7c3c, - 0x0078, 0x254d, 0x2061, 0x1000, 0x610c, 0xa006, 0x2c14, 0xa200, - 0x8c60, 0x8109, 0x00c0, 0x257e, 0x2010, 0xa005, 0x0040, 0x250d, - 0x0078, 0x2533, 0x2061, 0x7751, 0x7824, 0x7930, 0xa11a, 0x00c8, - 0x253b, 0x8019, 0x0040, 0x253b, 0x604a, 0x6142, 0x782c, 0x6052, - 0x7828, 0x6056, 0xa006, 0x605a, 0x605e, 0x1078, 0x3d89, 0x0078, - 0x250d, 0x2061, 0x7751, 0x7824, 0x7930, 0xa11a, 0x00c8, 0x253b, - 0x8019, 0x0040, 0x253b, 0x604e, 0x6146, 0x782c, 0x6062, 0x7828, - 0x6066, 0xa006, 0x606a, 0x606e, 0x1078, 0x3b5f, 0x0078, 0x250d, - 0xa02e, 0x2520, 0x81ff, 0x00c0, 0x2537, 0x7924, 0x7b28, 0x7a2c, - 0x20a9, 0x0005, 0x20a1, 0x7774, 0x41a1, 0x1078, 0x2cf8, 0x0040, - 0x2537, 0x2009, 0x0020, 0x1078, 0x2d42, 0x701b, 0x25d0, 0x007c, - 0x6834, 0x2008, 0xa084, 0x00ff, 0xa096, 0x0011, 0x0040, 0x25dc, - 0xa096, 0x0019, 0x00c0, 0x2537, 0x810f, 0xa18c, 0x00ff, 0x0040, - 0x2537, 0x710e, 0x700c, 0x8001, 0x0040, 0x260d, 0x700e, 0x1078, - 0x2cf8, 0x0040, 0x2537, 0x2009, 0x0020, 0x2061, 0x77bd, 0x6224, - 0x6328, 0x642c, 0x6530, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, - 0x0000, 0xa5a9, 0x0000, 0x1078, 0x2d42, 0x701b, 0x2600, 0x007c, - 0x6834, 0xa084, 0x00ff, 0xa096, 0x0002, 0x0040, 0x260b, 0xa096, - 0x000a, 0x00c0, 0x2537, 0x0078, 0x25e2, 0x7010, 0x2068, 0x6838, - 0xc0fd, 0x683a, 0x1078, 0x3744, 0x00c0, 0x261b, 0x7007, 0x0003, - 0x701b, 0x261d, 0x007c, 0x1078, 0x3c22, 0x127e, 0x2091, 0x8000, - 0x20a9, 0x0005, 0x2099, 0x7774, 0x530a, 0x2100, 0xa210, 0xa399, - 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0xad80, 0x000d, 0x2009, - 0x0020, 0x127f, 0x0078, 0x2d46, 0x6198, 0x7824, 0x609a, 0x0078, - 0x250d, 0x2091, 0x8000, 0x7823, 0x4000, 0x7827, 0x4953, 0x782b, - 0x5020, 0x782f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7832, 0x3f00, - 0x7836, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, - 0xa205, 0x783a, 0x2009, 0x04fd, 0x2104, 0x783e, 0x781b, 0x0001, - 0x2091, 0x5000, 0x2091, 0x4080, 0x2071, 0x0010, 0x20c1, 0x00f0, - 0xa08a, 0x0003, 0x00c8, 0x0427, 0x0078, 0x0423, 0x81ff, 0x00c0, - 0x2537, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x384c, 0x00c0, - 0x253b, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048, 0x267a, - 0x0078, 0x253b, 0x7c28, 0x7d2c, 0x1078, 0x39fd, 0xd28c, 0x00c0, - 0x2685, 0x1078, 0x3991, 0x0078, 0x2687, 0x1078, 0x39cb, 0x00c0, - 0x26b1, 0x2061, 0x7e00, 0x127e, 0x2091, 0x8000, 0x6000, 0xa086, - 0x0000, 0x0040, 0x269f, 0x6010, 0xa06d, 0x0040, 0x269f, 0x683c, - 0xa406, 0x00c0, 0x269f, 0x6840, 0xa506, 0x0040, 0x26aa, 0x127f, - 0xace0, 0x0008, 0x2001, 0x7715, 0x2004, 0xac02, 0x00c8, 0x2537, - 0x0078, 0x268b, 0x1078, 0x6852, 0x127f, 0x0040, 0x2537, 0x0078, - 0x250d, 0xa00e, 0x2001, 0x0005, 0x1078, 0x3c22, 0x127e, 0x2091, - 0x8000, 0x1078, 0x6c5c, 0x1078, 0x3b92, 0x127f, 0x0078, 0x250d, - 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2d10, 0x0040, 0x253b, 0x1078, - 0x38d5, 0x0040, 0x2537, 0x1078, 0x3a0a, 0x0040, 0x2537, 0x0078, - 0x250d, 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2d22, 0x0040, 0x253b, - 0x1078, 0x3a71, 0x0040, 0x2537, 0x2019, 0x0005, 0x1078, 0x3a2b, - 0x0040, 0x2537, 0x7828, 0xa08a, 0x1000, 0x00c8, 0x253b, 0x8003, - 0x800b, 0x810b, 0xa108, 0x1078, 0x4696, 0x0078, 0x250d, 0x127e, - 0x2091, 0x8000, 0x81ff, 0x00c0, 0x271c, 0x2029, 0x00ff, 0x644c, - 0x2400, 0xa506, 0x0040, 0x2716, 0x2508, 0x1078, 0x384c, 0x00c0, - 0x2716, 0x1078, 0x3a71, 0x0040, 0x271c, 0x2019, 0x0004, 0x1078, - 0x3a2b, 0x0040, 0x271c, 0x7824, 0xa08a, 0x1000, 0x00c8, 0x271f, - 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x4696, 0x8529, 0x00c8, - 0x26f8, 0x127f, 0x0078, 0x250d, 0x127f, 0x0078, 0x2537, 0x127f, - 0x0078, 0x253b, 0x1078, 0x2d10, 0x0040, 0x253b, 0x1078, 0x3942, - 0x1078, 0x39fd, 0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, 0x1078, - 0x2d10, 0x0040, 0x253b, 0x1078, 0x3931, 0x1078, 0x39fd, 0x0078, - 0x250d, 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2d10, 0x0040, 0x253b, - 0x1078, 0x39ce, 0x0040, 0x2537, 0x1078, 0x378d, 0x1078, 0x398a, - 0x1078, 0x39fd, 0x0078, 0x250d, 0x1078, 0x2d10, 0x0040, 0x253b, - 0x1078, 0x38d5, 0x0040, 0x2537, 0x62a0, 0x2019, 0x0005, 0x0c7e, - 0x1078, 0x3a36, 0x0c7f, 0x1078, 0x4a7e, 0x1078, 0x49c1, 0x2c08, - 0x1078, 0x747b, 0x1078, 0x39fd, 0x0078, 0x250d, 0x1078, 0x2d10, - 0x0040, 0x253b, 0x1078, 0x39fd, 0x2208, 0x0078, 0x250d, 0x157e, - 0x0d7e, 0x0e7e, 0x2069, 0x77ff, 0x6810, 0x6914, 0xa10a, 0x00c8, - 0x277b, 0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019, 0x0000, - 0x20a9, 0x007e, 0x2069, 0x7820, 0x2d04, 0xa075, 0x0040, 0x2790, - 0x704c, 0x1078, 0x279a, 0xa210, 0x7080, 0x1078, 0x279a, 0xa318, - 0x8d68, 0x00f0, 0x2784, 0x2300, 0xa218, 0x0e7f, 0x0d7f, 0x157f, - 0x0078, 0x250d, 0x0f7e, 0x017e, 0xa07d, 0x0040, 0x27a9, 0x2001, - 0x0000, 0x8000, 0x2f0c, 0x81ff, 0x0040, 0x27a9, 0x2178, 0x0078, - 0x27a1, 0x017f, 0x0f7f, 0x007c, 0x2069, 0x77ff, 0x6910, 0x629c, - 0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, 0x614c, 0xa190, 0x2329, - 0x2214, 0xa294, 0x00ff, 0x6068, 0xa084, 0xff00, 0xa215, 0x6364, - 0x0078, 0x250d, 0x613c, 0x6240, 0x0078, 0x250d, 0x1078, 0x2d22, - 0x0040, 0x253b, 0x0078, 0x250d, 0x1078, 0x2d22, 0x0040, 0x253b, - 0x6244, 0x6338, 0x0078, 0x250d, 0x613c, 0x6240, 0x7824, 0x603e, - 0x7b28, 0x6342, 0x2069, 0x7751, 0x831f, 0xa305, 0x6816, 0x0078, - 0x250d, 0x1078, 0x2d22, 0x0040, 0x253b, 0x0078, 0x250d, 0x1078, - 0x2d22, 0x0040, 0x253b, 0x7828, 0xa00d, 0x0040, 0x253b, 0x782c, - 0xa005, 0x0040, 0x253b, 0x6244, 0x6146, 0x6338, 0x603a, 0x0078, - 0x250d, 0x7d38, 0x7c3c, 0x0078, 0x25ba, 0x7824, 0xa09c, 0x00ff, - 0xa39a, 0x0003, 0x00c8, 0x2537, 0x624c, 0xa084, 0xff00, 0x8007, - 0xa206, 0x00c0, 0x2815, 0x2001, 0x7740, 0x2009, 0x000c, 0x7a2c, - 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x2d46, 0x81ff, 0x00c0, 0x2537, - 0x1078, 0x2d22, 0x0040, 0x253b, 0x6004, 0xa084, 0x00ff, 0xa086, - 0x0006, 0x00c0, 0x2537, 0x0c7e, 0x1078, 0x2cf8, 0x0c7f, 0x0040, - 0x2537, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x6b56, - 0x0040, 0x2537, 0x7007, 0x0003, 0x701b, 0x2837, 0x007c, 0x6830, - 0xa086, 0x0100, 0x0040, 0x2537, 0xad80, 0x000e, 0x2009, 0x000c, - 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x2d46, 0x1078, 0x2cf8, - 0x0040, 0x2537, 0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, - 0x1078, 0x2d42, 0x701b, 0x2855, 0x007c, 0xade8, 0x000d, 0x6800, - 0xa005, 0x0040, 0x253b, 0x6804, 0xd0ac, 0x0040, 0x2862, 0xd0a4, - 0x0040, 0x253b, 0xd094, 0x0040, 0x286d, 0x0c7e, 0x2061, 0x0100, - 0x6104, 0xa18c, 0xffdf, 0x6106, 0x0c7f, 0xd08c, 0x0040, 0x2878, - 0x0c7e, 0x2061, 0x0100, 0x6104, 0xa18d, 0x0010, 0x6106, 0x0c7f, - 0x2009, 0x0100, 0x210c, 0xa18a, 0x0002, 0x0048, 0x288d, 0xd084, - 0x0040, 0x288d, 0x6a28, 0xa28a, 0x007f, 0x00c8, 0x253b, 0xa288, - 0x2329, 0x210c, 0xa18c, 0x00ff, 0x6152, 0xd0dc, 0x0040, 0x2896, - 0x6828, 0xa08a, 0x007f, 0x00c8, 0x253b, 0x604e, 0x6808, 0xa08a, - 0x0100, 0x0048, 0x253b, 0xa08a, 0x0841, 0x00c8, 0x253b, 0xa084, - 0x0007, 0x00c0, 0x253b, 0x680c, 0xa005, 0x0040, 0x253b, 0x6810, - 0xa005, 0x0040, 0x253b, 0x6848, 0x6940, 0xa10a, 0x00c8, 0x253b, - 0x8001, 0x0040, 0x253b, 0x684c, 0x6944, 0xa10a, 0x00c8, 0x253b, - 0x8001, 0x0040, 0x253b, 0x20a9, 0x001c, 0x2d98, 0x2069, 0x7751, - 0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084, - 0x00ff, 0x6042, 0x1078, 0x3d89, 0x1078, 0x3b5f, 0x6000, 0xa086, - 0x0000, 0x00c0, 0x2911, 0x6808, 0x602a, 0x1078, 0x1de4, 0x6818, - 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, - 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0040, 0x28f1, 0x6830, - 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0078, - 0x28f3, 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x1078, - 0x4722, 0x0c7e, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, - 0x0c7f, 0x60b4, 0xa005, 0x0040, 0x290d, 0x6003, 0x0001, 0x2091, - 0x301d, 0x1078, 0x3591, 0x0078, 0x2911, 0x6003, 0x0004, 0x2091, - 0x301d, 0x0078, 0x250d, 0x6000, 0xa086, 0x0000, 0x0040, 0x2537, - 0x2069, 0x7751, 0x7830, 0x6842, 0x7834, 0x6846, 0x2d00, 0x2009, - 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x2d46, 0x81ff, - 0x00c0, 0x2537, 0x1078, 0x3591, 0x0078, 0x250d, 0x81ff, 0x00c0, - 0x2537, 0x617c, 0x81ff, 0x0040, 0x2948, 0x703f, 0x0000, 0x2001, - 0x7dc0, 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x127e, - 0x2091, 0x8000, 0x1078, 0x2d46, 0x701b, 0x250a, 0x127f, 0x007c, - 0x703f, 0x0001, 0x0d7e, 0x2069, 0x7dc0, 0x20a9, 0x0040, 0x20a1, - 0x7dc0, 0x2019, 0xffff, 0x43a4, 0x654c, 0xa588, 0x2329, 0x210c, - 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100, 0xa506, - 0x0040, 0x297a, 0x1078, 0x384c, 0x00c0, 0x297a, 0x6014, 0x821c, - 0x0048, 0x2972, 0xa398, 0x7dc0, 0xa085, 0xff00, 0x8007, 0x201a, - 0x0078, 0x2979, 0xa398, 0x7dc0, 0x2324, 0xa4a4, 0xff00, 0xa405, - 0x201a, 0x8210, 0x8108, 0xa182, 0x0080, 0x00c8, 0x2981, 0x0078, - 0x295e, 0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a, 0x0d7f, 0x20a9, - 0x0040, 0x20a1, 0x7dc0, 0x2099, 0x7dc0, 0x1078, 0x35da, 0x0078, - 0x2937, 0x1078, 0x2d22, 0x0040, 0x253b, 0x0c7e, 0x1078, 0x2cf8, - 0x0c7f, 0x0040, 0x2537, 0x2001, 0x7752, 0x2004, 0xd0b4, 0x0040, - 0x29be, 0x6000, 0xd08c, 0x00c0, 0x29be, 0x6004, 0xa084, 0x00ff, - 0xa086, 0x0006, 0x00c0, 0x29be, 0x6837, 0x0000, 0x6838, 0xc0fd, - 0x683a, 0x1078, 0x6b8e, 0x0040, 0x2537, 0x7007, 0x0003, 0x701b, - 0x29ba, 0x007c, 0x1078, 0x2d22, 0x0040, 0x253b, 0x20a9, 0x002b, - 0x2c98, 0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, - 0x0006, 0x2098, 0xad80, 0x0006, 0x20a0, 0x1078, 0x35da, 0x20a9, - 0x0004, 0xac80, 0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, 0x1078, - 0x35da, 0x2d00, 0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, - 0x0078, 0x2d46, 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2d10, 0x0040, - 0x253b, 0x1078, 0x3a15, 0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, - 0x7828, 0xa08a, 0x1000, 0x00c8, 0x253b, 0x1078, 0x2d22, 0x0040, - 0x253b, 0x1078, 0x3a71, 0x0040, 0x2537, 0x2019, 0x0004, 0x1078, - 0x3a2b, 0x7924, 0x810f, 0x7a28, 0x1078, 0x2a08, 0x0078, 0x250d, - 0xa186, 0x00ff, 0x0040, 0x2a10, 0x1078, 0x2a20, 0x0078, 0x2a1f, - 0x2029, 0x007e, 0x2061, 0x7700, 0x644c, 0x2400, 0xa506, 0x0040, - 0x2a1c, 0x2508, 0x1078, 0x2a20, 0x8529, 0x00c8, 0x2a15, 0x007c, - 0x1078, 0x384c, 0x00c0, 0x2a2b, 0x2200, 0x8003, 0x800b, 0x810b, - 0xa108, 0x1078, 0x4696, 0x007c, 0x81ff, 0x00c0, 0x2537, 0x1078, - 0x2d10, 0x0040, 0x253b, 0x1078, 0x38d5, 0x0040, 0x2537, 0x1078, - 0x3a20, 0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2d10, - 0x0040, 0x253b, 0x1078, 0x38d5, 0x0040, 0x2537, 0x1078, 0x3a0a, - 0x0078, 0x250d, 0x6100, 0x0078, 0x250d, 0x1078, 0x2d22, 0x0040, - 0x253b, 0x6004, 0xa086, 0x0707, 0x0040, 0x253b, 0x2001, 0x7700, - 0x2004, 0xa086, 0x0003, 0x00c0, 0x2537, 0x0d7e, 0xace8, 0x000a, - 0x7924, 0xd184, 0x0040, 0x2a66, 0xace8, 0x0006, 0x680c, 0x8007, - 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f, 0x6a00, 0x8217, - 0x0d7f, 0x6100, 0xa18c, 0x0200, 0x0078, 0x250d, 0x7824, 0xa084, - 0x00ff, 0xa086, 0x00ff, 0x0040, 0x2a80, 0x81ff, 0x00c0, 0x2537, - 0x7828, 0xa08a, 0x1000, 0x00c8, 0x253b, 0x7924, 0xa18c, 0xff00, - 0x810f, 0xa186, 0x00ff, 0x0040, 0x2a94, 0xa182, 0x007f, 0x00c8, - 0x253b, 0x2100, 0x1078, 0x2094, 0x027e, 0x0c7e, 0x127e, 0x2091, - 0x8000, 0x2061, 0x7949, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, + 0x8000, 0x8000, 0x2071, 0x8881, 0x7003, 0x0002, 0xa006, 0x7012, + 0x7016, 0x703a, 0x703e, 0x7033, 0x8891, 0x7037, 0x8891, 0x7007, + 0x0001, 0x2061, 0x88d1, 0x6003, 0x0002, 0x007c, 0x0090, 0x26d9, + 0x0068, 0x26d9, 0x2071, 0x8881, 0x2b78, 0x7818, 0xd084, 0x00c0, + 0x26d9, 0x2a60, 0x7820, 0xa08e, 0x0069, 0x00c0, 0x27c9, 0x0079, + 0x275d, 0x007c, 0x2071, 0x8881, 0x7004, 0x0079, 0x26df, 0x26e3, + 0x26e4, 0x26ee, 0x2700, 0x007c, 0x0090, 0x26ed, 0x0068, 0x26ed, + 0x2b78, 0x7818, 0xd084, 0x0040, 0x270c, 0x007c, 0x2b78, 0x2061, + 0x88d1, 0x6008, 0xa08e, 0x0100, 0x0040, 0x26fb, 0xa086, 0x0200, + 0x0040, 0x27c1, 0x007c, 0x7014, 0x2068, 0x2a60, 0x7018, 0x007a, + 0x7010, 0x2068, 0x6834, 0xa086, 0x0103, 0x0040, 0x2708, 0x007c, + 0x2a60, 0x2b78, 0x7018, 0x007a, 0x2a60, 0x7820, 0xa08a, 0x0040, + 0x00c8, 0x2715, 0x61b4, 0x0079, 0x271d, 0x2100, 0xa08a, 0x003f, + 0x00c8, 0x27bd, 0x61b4, 0x0079, 0x275d, 0x279f, 0x27d1, 0x27d9, + 0x27dd, 0x27e5, 0x27eb, 0x27ef, 0x27f8, 0x27fc, 0x2804, 0x2808, + 0x27bd, 0x27bd, 0x27bd, 0x280c, 0x27bd, 0x281c, 0x2833, 0x284a, + 0x28c6, 0x28cb, 0x28f8, 0x2952, 0x2963, 0x2981, 0x29c2, 0x29cc, + 0x29d9, 0x29ec, 0x2a0a, 0x2a13, 0x2a50, 0x2a56, 0x27bd, 0x2a66, + 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x2a6a, 0x2a74, 0x27bd, + 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x2a7c, + 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x2a89, 0x2a91, 0x27bd, + 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x2aa3, 0x2af4, 0x2b45, + 0x2b56, 0x27bd, 0x27bd, 0x27bd, 0x34bd, 0x27bd, 0x27bd, 0x27bd, + 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x2804, 0x2808, 0x27bd, + 0x27bd, 0x2b6d, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, + 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x2bba, 0x2ce1, 0x2cf5, + 0x2d01, 0x2d64, 0x2dbd, 0x2dc8, 0x2e07, 0x2e16, 0x2e25, 0x2e28, + 0x2b71, 0x2e51, 0x2e9d, 0x2eaa, 0x2fb9, 0x30d1, 0x30f8, 0x3205, + 0x3214, 0x3221, 0x325b, 0x32f8, 0x27bd, 0x27bd, 0x27bd, 0x27bd, + 0x3360, 0x337c, 0x33f6, 0x34ae, 0x713c, 0x0078, 0x279f, 0x2021, + 0x4000, 0x1078, 0x3154, 0x127e, 0x2091, 0x8000, 0x0068, 0x27ac, + 0x7818, 0xd084, 0x0040, 0x27af, 0x127f, 0x0078, 0x27a3, 0x7c22, + 0x7926, 0x7a2a, 0x7b2e, 0x781b, 0x0001, 0x2091, 0x4080, 0x7007, + 0x0001, 0x2091, 0x5000, 0x127f, 0x007c, 0x2021, 0x4001, 0x0078, + 0x27a1, 0x2021, 0x4002, 0x0078, 0x27a1, 0x2021, 0x4003, 0x0078, + 0x27a1, 0x2021, 0x4005, 0x0078, 0x27a1, 0x2021, 0x4006, 0x0078, + 0x27a1, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0078, + 0x3163, 0x7823, 0x0004, 0x7824, 0x007a, 0xa02e, 0x2520, 0x7b28, + 0x7a2c, 0x7824, 0x7930, 0x0078, 0x3167, 0x7924, 0x7828, 0x2114, + 0x200a, 0x0078, 0x279f, 0x7924, 0x2114, 0x0078, 0x279f, 0x2099, + 0x0009, 0x20a1, 0x0009, 0x20a9, 0x0007, 0x53a3, 0x0078, 0x279f, + 0x7824, 0x2060, 0x0078, 0x280e, 0x2009, 0x0001, 0x2011, 0x0011, + 0x2019, 0x001e, 0x0078, 0x279f, 0x7d38, 0x7c3c, 0x0078, 0x27d3, + 0x7d38, 0x7c3c, 0x0078, 0x27df, 0x2061, 0x1000, 0x610c, 0xa006, + 0x2c14, 0xa200, 0x8c60, 0x8109, 0x00c0, 0x2810, 0x2010, 0xa005, + 0x0040, 0x279f, 0x0078, 0x27c5, 0x2069, 0x8851, 0x7824, 0x7930, + 0xa11a, 0x00c8, 0x27cd, 0x8019, 0x0040, 0x27cd, 0x684a, 0x6942, + 0x782c, 0x6852, 0x7828, 0x6856, 0xa006, 0x685a, 0x685e, 0x1078, + 0x4793, 0x0078, 0x279f, 0x2069, 0x8851, 0x7824, 0x7934, 0xa11a, + 0x00c8, 0x27cd, 0x8019, 0x0040, 0x27cd, 0x684e, 0x6946, 0x782c, + 0x6862, 0x7828, 0x6866, 0xa006, 0x686a, 0x686e, 0x1078, 0x4343, + 0x0078, 0x279f, 0xa02e, 0x2520, 0x81ff, 0x00c0, 0x27c9, 0x7924, + 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1, 0x8888, 0x41a1, 0x1078, + 0x3119, 0x0040, 0x27c9, 0x2009, 0x0020, 0x1078, 0x3163, 0x701b, + 0x2862, 0x007c, 0x6834, 0x2008, 0xa084, 0x00ff, 0xa096, 0x0011, + 0x0040, 0x286e, 0xa096, 0x0019, 0x00c0, 0x27c9, 0x810f, 0xa18c, + 0x00ff, 0x0040, 0x27c9, 0x710e, 0x700c, 0x8001, 0x0040, 0x289f, + 0x700e, 0x1078, 0x3119, 0x0040, 0x27c9, 0x2009, 0x0020, 0x2061, + 0x88d1, 0x6224, 0x6328, 0x642c, 0x6530, 0xa290, 0x0040, 0xa399, + 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x1078, 0x3163, 0x701b, + 0x2892, 0x007c, 0x6834, 0xa084, 0x00ff, 0xa096, 0x0002, 0x0040, + 0x289d, 0xa096, 0x000a, 0x00c0, 0x27c9, 0x0078, 0x2874, 0x7010, + 0x2068, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x3e3e, 0x00c0, 0x28ad, + 0x7007, 0x0003, 0x701b, 0x28af, 0x007c, 0x1078, 0x4454, 0x127e, + 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0x8888, 0x530a, 0x2100, + 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0xad80, + 0x000d, 0x2009, 0x0020, 0x127f, 0x0078, 0x3167, 0x619c, 0x7824, + 0x609e, 0x0078, 0x279f, 0x2091, 0x8000, 0x7823, 0x4000, 0x7827, + 0x4953, 0x782b, 0x5020, 0x782f, 0x2020, 0x2009, 0x017f, 0x2104, + 0x7832, 0x3f00, 0x7836, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, + 0x603c, 0x8007, 0xa205, 0x783a, 0x2009, 0x04fd, 0x2104, 0x783e, + 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2071, 0x0010, + 0x20c1, 0x00f0, 0xa08a, 0x0003, 0x00c8, 0x0427, 0x0078, 0x0423, + 0x81ff, 0x00c0, 0x27c9, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, + 0x3f8e, 0x00c0, 0x27cd, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000, + 0x0048, 0x290c, 0x0078, 0x27cd, 0x7c28, 0x7d2c, 0x1078, 0x4146, + 0xd28c, 0x00c0, 0x2917, 0x1078, 0x40da, 0x0078, 0x2919, 0x1078, + 0x4114, 0x00c0, 0x2943, 0x2061, 0x8f00, 0x127e, 0x2091, 0x8000, + 0x6000, 0xa086, 0x0000, 0x0040, 0x2931, 0x6010, 0xa06d, 0x0040, + 0x2931, 0x683c, 0xa406, 0x00c0, 0x2931, 0x6840, 0xa506, 0x0040, + 0x293c, 0x127f, 0xace0, 0x000c, 0x2001, 0x8815, 0x2004, 0xac02, + 0x00c8, 0x27c9, 0x0078, 0x291d, 0x1078, 0x759a, 0x127f, 0x0040, + 0x27c9, 0x0078, 0x279f, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4454, + 0x127e, 0x2091, 0x8000, 0x1078, 0x7a4e, 0x1078, 0x4376, 0x127f, + 0x0078, 0x279f, 0x81ff, 0x00c0, 0x27c9, 0x1078, 0x3131, 0x0040, + 0x27cd, 0x1078, 0x4017, 0x0040, 0x27c9, 0x1078, 0x4154, 0x0040, + 0x27c9, 0x0078, 0x279f, 0x81ff, 0x00c0, 0x27c9, 0x1078, 0x3143, + 0x0040, 0x27cd, 0x1078, 0x41c7, 0x0040, 0x27c9, 0x2019, 0x0005, + 0x1078, 0x4175, 0x0040, 0x27c9, 0x7828, 0xa08a, 0x1000, 0x00c8, + 0x27cd, 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x50ff, 0x0078, + 0x279f, 0x127e, 0x2091, 0x8000, 0x81ff, 0x0040, 0x298b, 0x2009, + 0x0001, 0x0078, 0x29bc, 0x2029, 0x00ff, 0x644c, 0x2400, 0xa506, + 0x0040, 0x29b6, 0x2508, 0x1078, 0x3f8e, 0x00c0, 0x29b6, 0x1078, + 0x41c7, 0x00c0, 0x29a1, 0x2009, 0x0002, 0x62a4, 0x2518, 0x0078, + 0x29bc, 0x2019, 0x0004, 0x1078, 0x4175, 0x00c0, 0x29ab, 0x2009, + 0x0006, 0x0078, 0x29bc, 0x7824, 0xa08a, 0x1000, 0x00c8, 0x29bf, + 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x50ff, 0x8529, 0x00c8, + 0x298e, 0x127f, 0x0078, 0x279f, 0x127f, 0x0078, 0x27c9, 0x127f, + 0x0078, 0x27cd, 0x1078, 0x3131, 0x0040, 0x27cd, 0x1078, 0x408b, + 0x1078, 0x4146, 0x0078, 0x279f, 0x81ff, 0x00c0, 0x27c9, 0x1078, + 0x3131, 0x0040, 0x27cd, 0x1078, 0x407a, 0x1078, 0x4146, 0x0078, + 0x279f, 0x81ff, 0x00c0, 0x27c9, 0x1078, 0x3131, 0x0040, 0x27cd, + 0x1078, 0x4117, 0x0040, 0x27c9, 0x1078, 0x3e87, 0x1078, 0x40d3, + 0x1078, 0x4146, 0x0078, 0x279f, 0x1078, 0x3131, 0x0040, 0x27cd, + 0x1078, 0x4017, 0x0040, 0x27c9, 0x62a0, 0x2019, 0x0005, 0x0c7e, + 0x1078, 0x418b, 0x0c7f, 0x1078, 0x54f0, 0x087e, 0x2041, 0x0000, + 0x1078, 0x5419, 0x2c08, 0x1078, 0x84d2, 0x087f, 0x1078, 0x4146, + 0x0078, 0x279f, 0x1078, 0x3131, 0x0040, 0x27cd, 0x1078, 0x4146, + 0x2208, 0x0078, 0x279f, 0x157e, 0x0d7e, 0x0e7e, 0x2069, 0x8913, + 0x6810, 0x6914, 0xa10a, 0x00c8, 0x2a1f, 0x2009, 0x0000, 0x6816, + 0x2011, 0x0000, 0x2019, 0x0000, 0x20a9, 0x00ff, 0x2069, 0x8934, + 0x2d04, 0xa075, 0x0040, 0x2a34, 0x704c, 0x1078, 0x2a3e, 0xa210, + 0x7080, 0x1078, 0x2a3e, 0xa318, 0x8d68, 0x00f0, 0x2a28, 0x2300, + 0xa218, 0x0e7f, 0x0d7f, 0x157f, 0x0078, 0x279f, 0x0f7e, 0x017e, + 0xa07d, 0x0040, 0x2a4d, 0x2001, 0x0000, 0x8000, 0x2f0c, 0x81ff, + 0x0040, 0x2a4d, 0x2178, 0x0078, 0x2a45, 0x017f, 0x0f7f, 0x007c, + 0x2069, 0x8913, 0x6910, 0x62a0, 0x0078, 0x279f, 0x81ff, 0x00c0, + 0x27c9, 0x614c, 0xa190, 0x25b2, 0x2214, 0xa294, 0x00ff, 0x606c, + 0xa084, 0xff00, 0xa215, 0x6368, 0x0078, 0x279f, 0x613c, 0x6240, + 0x0078, 0x279f, 0x127e, 0x2091, 0x8000, 0x6134, 0xa006, 0x2010, + 0x2018, 0x127f, 0x0078, 0x279f, 0x1078, 0x3143, 0x0040, 0x27cd, + 0x6244, 0x6338, 0x0078, 0x279f, 0x613c, 0x6240, 0x7824, 0x603e, + 0x7b28, 0x6342, 0x2069, 0x8851, 0x831f, 0xa305, 0x6816, 0x0078, + 0x279f, 0x127e, 0x2091, 0x8000, 0x7824, 0x6036, 0x127f, 0x0078, + 0x279f, 0x1078, 0x3143, 0x0040, 0x27cd, 0x7828, 0xa00d, 0x0040, + 0x27cd, 0x782c, 0xa005, 0x0040, 0x27cd, 0x6244, 0x6146, 0x6338, + 0x603a, 0x0078, 0x279f, 0x2001, 0x8800, 0x2004, 0xa086, 0x0003, + 0x00c0, 0x27c9, 0x0c7e, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, + 0x00ff, 0xa196, 0x00ff, 0x00c0, 0x2aba, 0x6030, 0xa085, 0xff00, + 0x0078, 0x2ac9, 0xa182, 0x007f, 0x00c8, 0x2aed, 0xa188, 0x25b2, + 0x210c, 0xa18c, 0x00ff, 0x6030, 0xa116, 0x0040, 0x2aed, 0x810f, + 0xa105, 0x127e, 0x2091, 0x8000, 0x007e, 0x1078, 0x68a8, 0x007f, + 0x0040, 0x2aea, 0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, 0x1078, + 0x3119, 0x0040, 0x2af0, 0x6837, 0x0000, 0x7007, 0x0003, 0x701b, + 0x279f, 0x2d00, 0x6012, 0x2009, 0x0032, 0x1078, 0x6939, 0x127f, + 0x0c7f, 0x007c, 0x0c7f, 0x0078, 0x27c9, 0x0c7f, 0x0078, 0x27cd, + 0x1078, 0x690e, 0x0078, 0x2aea, 0x2001, 0x8800, 0x2004, 0xa086, + 0x0003, 0x00c0, 0x27c9, 0x0c7e, 0x2061, 0x0100, 0x7924, 0x810f, + 0xa18c, 0x00ff, 0xa196, 0x00ff, 0x00c0, 0x2b0b, 0x6030, 0xa085, + 0xff00, 0x0078, 0x2b1a, 0xa182, 0x007f, 0x00c8, 0x2b3e, 0xa188, + 0x25b2, 0x210c, 0xa18c, 0x00ff, 0x6030, 0xa116, 0x0040, 0x2b3e, + 0x810f, 0xa105, 0x127e, 0x2091, 0x8000, 0x007e, 0x1078, 0x68a8, + 0x007f, 0x0040, 0x2b3b, 0x601a, 0x600b, 0xbc05, 0x601f, 0x0001, + 0x1078, 0x3119, 0x0040, 0x2b41, 0x6837, 0x0000, 0x7007, 0x0003, + 0x701b, 0x279f, 0x2d00, 0x6012, 0x2009, 0x0032, 0x1078, 0x6939, + 0x127f, 0x0c7f, 0x007c, 0x0c7f, 0x0078, 0x27c9, 0x0c7f, 0x0078, + 0x27cd, 0x1078, 0x690e, 0x0078, 0x2b3b, 0x2061, 0x8b24, 0x127e, + 0x2091, 0x8000, 0x6000, 0xd084, 0x0040, 0x2b53, 0x6104, 0x6208, + 0x127f, 0x0078, 0x279f, 0x127f, 0x0078, 0x27cd, 0x81ff, 0x00c0, + 0x27c9, 0x127e, 0x2091, 0x8000, 0x6244, 0x6060, 0xa202, 0x0048, + 0x2b6a, 0xa085, 0x0001, 0x1078, 0x2262, 0x1078, 0x36ef, 0x127f, + 0x0078, 0x279f, 0x127f, 0x0078, 0x27cd, 0x7d38, 0x7c3c, 0x0078, + 0x284c, 0x7824, 0xa09c, 0x00ff, 0xa39a, 0x0003, 0x00c8, 0x27c9, + 0x624c, 0xa084, 0xff00, 0x8007, 0xa206, 0x00c0, 0x2b89, 0x2001, + 0x8840, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, + 0x3167, 0x81ff, 0x00c0, 0x27c9, 0x1078, 0x3143, 0x0040, 0x27cd, + 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x27c9, 0x0c7e, + 0x1078, 0x3119, 0x0c7f, 0x0040, 0x27c9, 0x6837, 0x0000, 0x6838, + 0xc0fd, 0x683a, 0x1078, 0x792c, 0x0040, 0x27c9, 0x7007, 0x0003, + 0x701b, 0x2bab, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x27c9, + 0xad80, 0x000e, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, + 0x0078, 0x3167, 0x1078, 0x3119, 0x0040, 0x27c9, 0x1078, 0x3d16, + 0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3163, + 0x701b, 0x2bcb, 0x007c, 0xade8, 0x000d, 0x6800, 0xa005, 0x0040, + 0x27cd, 0x6804, 0xd0ac, 0x0040, 0x2bd8, 0xd0a4, 0x0040, 0x27cd, + 0xd094, 0x0040, 0x2be3, 0x0c7e, 0x2061, 0x0100, 0x6104, 0xa18c, + 0xffdf, 0x6106, 0x0c7f, 0xd08c, 0x0040, 0x2bee, 0x0c7e, 0x2061, + 0x0100, 0x6104, 0xa18d, 0x0010, 0x6106, 0x0c7f, 0x2009, 0x0100, + 0x210c, 0xa18a, 0x0002, 0x0048, 0x2c03, 0xd084, 0x0040, 0x2c03, + 0x6a28, 0xa28a, 0x007f, 0x00c8, 0x27cd, 0xa288, 0x25b2, 0x210c, + 0xa18c, 0x00ff, 0x6152, 0xd0dc, 0x0040, 0x2c0c, 0x6828, 0xa08a, + 0x007f, 0x00c8, 0x27cd, 0x604e, 0x6808, 0xa08a, 0x0100, 0x0048, + 0x27cd, 0xa08a, 0x0841, 0x00c8, 0x27cd, 0xa084, 0x0007, 0x00c0, + 0x27cd, 0x680c, 0xa005, 0x0040, 0x27cd, 0x6810, 0xa005, 0x0040, + 0x27cd, 0x6848, 0x6940, 0xa10a, 0x00c8, 0x27cd, 0x8001, 0x0040, + 0x27cd, 0x684c, 0x6944, 0xa10a, 0x00c8, 0x27cd, 0x8001, 0x0040, + 0x27cd, 0x6804, 0xd0fc, 0x0040, 0x2c54, 0x1078, 0x3119, 0x0040, + 0x27c9, 0x2009, 0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0xa290, + 0x0038, 0xa399, 0x0000, 0x1078, 0x3163, 0x701b, 0x2c48, 0x007c, + 0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069, 0x886d, 0x2da0, + 0x53a3, 0x7010, 0xa0e8, 0x000d, 0x20a9, 0x001c, 0x2d98, 0x2069, + 0x8851, 0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e, 0x8007, + 0xa084, 0x00ff, 0x6042, 0x1078, 0x4793, 0x1078, 0x42d3, 0x1078, + 0x4343, 0x6000, 0xa086, 0x0000, 0x00c0, 0x2cdf, 0x6808, 0x602a, + 0x1078, 0x1f57, 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, + 0x8217, 0x831f, 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, + 0x0040, 0x2c8c, 0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, + 0x8217, 0x831f, 0x0078, 0x2c8e, 0xa084, 0xf0ff, 0x6006, 0x610a, + 0x620e, 0x6312, 0x1078, 0x518a, 0x6904, 0xd1fc, 0x0040, 0x2cc1, + 0x0c7e, 0x2009, 0x0000, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x0040, + 0x2cbe, 0x0078, 0x2ca8, 0x839d, 0x00c8, 0x2cbe, 0x3508, 0x8109, + 0x1078, 0x4cb2, 0x6878, 0x6016, 0x6874, 0x2008, 0xa084, 0xff00, + 0x8007, 0x600a, 0xa184, 0x00ff, 0x6006, 0x8108, 0x00c0, 0x2cbc, + 0x6003, 0x0003, 0x0078, 0x2cbe, 0x6003, 0x0001, 0x00f0, 0x2ca3, + 0x0c7f, 0x0c7e, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, + 0x0c7f, 0x1078, 0x3352, 0x0040, 0x2ccf, 0x1078, 0x2262, 0x60b8, + 0xa005, 0x0040, 0x2cdb, 0x6003, 0x0001, 0x2091, 0x301d, 0x1078, + 0x3c73, 0x0078, 0x2cdf, 0x6003, 0x0004, 0x2091, 0x301d, 0x0078, + 0x279f, 0x6000, 0xa086, 0x0000, 0x0040, 0x27c9, 0x2069, 0x8851, + 0x7830, 0x6842, 0x7834, 0x6846, 0x2d00, 0x2009, 0x001c, 0x7a2c, + 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x3167, 0x81ff, 0x00c0, 0x27c9, + 0xa006, 0x1078, 0x2262, 0x1078, 0x3d16, 0x1078, 0x3c73, 0x0078, + 0x279f, 0x81ff, 0x00c0, 0x27c9, 0x6180, 0x81ff, 0x0040, 0x2d1b, + 0x703f, 0x0000, 0x2001, 0x8ec0, 0x2009, 0x0040, 0x7a2c, 0x7b28, + 0x7c3c, 0x7d38, 0x127e, 0x2091, 0x8000, 0x1078, 0x3167, 0x701b, + 0x279c, 0x127f, 0x007c, 0x703f, 0x0001, 0x0d7e, 0x2069, 0x8ec0, + 0x20a9, 0x0040, 0x20a1, 0x8ec0, 0x2019, 0xffff, 0x43a4, 0x654c, + 0xa588, 0x25b2, 0x210c, 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, + 0x0002, 0x2100, 0xa506, 0x0040, 0x2d4d, 0x1078, 0x3f8e, 0x00c0, + 0x2d4d, 0x6014, 0x821c, 0x0048, 0x2d45, 0xa398, 0x8ec0, 0xa085, + 0xff00, 0x8007, 0x201a, 0x0078, 0x2d4c, 0xa398, 0x8ec0, 0x2324, + 0xa4a4, 0xff00, 0xa405, 0x201a, 0x8210, 0x8108, 0xa182, 0x0080, + 0x00c8, 0x2d54, 0x0078, 0x2d31, 0x8201, 0x8007, 0x2d0c, 0xa105, + 0x206a, 0x0d7f, 0x20a9, 0x0040, 0x20a1, 0x8ec0, 0x2099, 0x8ec0, + 0x1078, 0x3cbc, 0x0078, 0x2d0a, 0x1078, 0x3143, 0x0040, 0x27cd, + 0x0c7e, 0x1078, 0x3119, 0x0c7f, 0x00c0, 0x2d72, 0x2009, 0x0002, + 0x0078, 0x27c9, 0x2001, 0x8852, 0x2004, 0xd0b4, 0x0040, 0x2d99, + 0x6000, 0xd08c, 0x00c0, 0x2d99, 0x6004, 0xa084, 0x00ff, 0xa086, + 0x0006, 0x00c0, 0x2d99, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, + 0x1078, 0x7980, 0x00c0, 0x2d90, 0x2009, 0x0003, 0x0078, 0x27c9, + 0x7007, 0x0003, 0x701b, 0x2d95, 0x007c, 0x1078, 0x3143, 0x0040, + 0x27cd, 0x20a9, 0x002b, 0x2c98, 0xade8, 0x0002, 0x2da0, 0x53a3, + 0x20a9, 0x0004, 0xac80, 0x0006, 0x2098, 0xad80, 0x0006, 0x20a0, + 0x1078, 0x3cbc, 0x20a9, 0x0004, 0xac80, 0x000a, 0x2098, 0xad80, + 0x000a, 0x20a0, 0x1078, 0x3cbc, 0x2d00, 0x2009, 0x002b, 0x7a2c, + 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x3167, 0x81ff, 0x00c0, 0x27c9, + 0x1078, 0x3131, 0x0040, 0x27cd, 0x1078, 0x415f, 0x0078, 0x279f, + 0x81ff, 0x00c0, 0x27c9, 0x7828, 0xa08a, 0x1000, 0x00c8, 0x27cd, + 0x1078, 0x3143, 0x0040, 0x27cd, 0x1078, 0x41c7, 0x0040, 0x27c9, + 0x2019, 0x0004, 0x1078, 0x4175, 0x7924, 0x810f, 0x7a28, 0x1078, + 0x2de3, 0x0078, 0x279f, 0xa186, 0x00ff, 0x0040, 0x2deb, 0x1078, + 0x2dfb, 0x0078, 0x2dfa, 0x2029, 0x007e, 0x2061, 0x8800, 0x644c, + 0x2400, 0xa506, 0x0040, 0x2df7, 0x2508, 0x1078, 0x2dfb, 0x8529, + 0x00c8, 0x2df0, 0x007c, 0x1078, 0x3f8e, 0x00c0, 0x2e06, 0x2200, + 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x50ff, 0x007c, 0x81ff, + 0x00c0, 0x27c9, 0x1078, 0x3131, 0x0040, 0x27cd, 0x1078, 0x4017, + 0x0040, 0x27c9, 0x1078, 0x416a, 0x0078, 0x279f, 0x81ff, 0x00c0, + 0x27c9, 0x1078, 0x3131, 0x0040, 0x27cd, 0x1078, 0x4017, 0x0040, + 0x27c9, 0x1078, 0x4154, 0x0078, 0x279f, 0x6100, 0x0078, 0x279f, + 0x1078, 0x3143, 0x0040, 0x27cd, 0x6004, 0xa086, 0x0707, 0x0040, + 0x27cd, 0x2001, 0x8800, 0x2004, 0xa086, 0x0003, 0x00c0, 0x27c9, + 0x0d7e, 0xace8, 0x000a, 0x7924, 0xd184, 0x0040, 0x2e41, 0xace8, + 0x0006, 0x680c, 0x8007, 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, + 0x831f, 0x6a00, 0x8217, 0x0d7f, 0x6100, 0xa18c, 0x0200, 0x0078, + 0x279f, 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff, 0x0040, 0x2e5b, + 0x81ff, 0x00c0, 0x27c9, 0xa006, 0x1078, 0x2262, 0x1078, 0x3d16, + 0x7828, 0xa08a, 0x1000, 0x00c8, 0x27cd, 0x7924, 0xa18c, 0xff00, + 0x810f, 0xa186, 0x00ff, 0x0040, 0x2e74, 0xa182, 0x007f, 0x00c8, + 0x27cd, 0x2100, 0x1078, 0x225c, 0x027e, 0x0c7e, 0x127e, 0x2091, + 0x8000, 0x2061, 0x8ab5, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0x0100, 0x6030, 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, 0x6043, - 0x0090, 0x6043, 0x0010, 0x2009, 0x001e, 0x2011, 0x35b6, 0x1078, - 0x4719, 0x7924, 0xa18c, 0xff00, 0x810f, 0x7a28, 0x1078, 0x2a08, - 0x127f, 0x0c7f, 0x027f, 0x0078, 0x250d, 0x7924, 0xa18c, 0xff00, - 0x810f, 0x0c7e, 0x1078, 0x3811, 0x2c08, 0x0c7f, 0x00c0, 0x253b, - 0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, 0x60bc, 0xd09c, 0x0040, - 0x2537, 0x1078, 0x2cf8, 0x0040, 0x2537, 0x6823, 0x0000, 0x7924, - 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x2d42, 0x701b, 0x2ae1, - 0x007c, 0x2009, 0x0080, 0x1078, 0x384c, 0x00c0, 0x2aee, 0x6004, - 0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, 0x2af2, 0x2021, 0x400a, - 0x0078, 0x250f, 0x0d7e, 0xade8, 0x000d, 0x6900, 0x6a08, 0x6b0c, - 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0040, 0x2b65, - 0xa0be, 0x0112, 0x0040, 0x2b65, 0xa0be, 0x0113, 0x0040, 0x2b65, - 0xa0be, 0x0114, 0x0040, 0x2b65, 0xa0be, 0x0117, 0x0040, 0x2b65, - 0xa0be, 0x011a, 0x0040, 0x2b65, 0xa0be, 0x0121, 0x0040, 0x2b5b, - 0xa0be, 0x0131, 0x0040, 0x2b5b, 0xa0be, 0x0171, 0x0040, 0x2b65, - 0xa0be, 0x0173, 0x0040, 0x2b65, 0xa0be, 0x01a1, 0x00c0, 0x2b2d, - 0x6830, 0x8007, 0x6832, 0x0078, 0x2b6b, 0xa0be, 0x0212, 0x0040, - 0x2b61, 0xa0be, 0x0213, 0x0040, 0x2b61, 0xa0be, 0x0214, 0x0040, - 0x2b53, 0xa0be, 0x0217, 0x0040, 0x2b4d, 0xa0be, 0x021a, 0x00c0, - 0x2b46, 0x6838, 0x8007, 0x683a, 0x0078, 0x2b65, 0xa0be, 0x0300, - 0x0040, 0x2b65, 0x0d7f, 0x0078, 0x253b, 0xad80, 0x0010, 0x20a9, - 0x0007, 0x1078, 0x2ba1, 0xad80, 0x000e, 0x20a9, 0x0001, 0x1078, - 0x2ba1, 0x0078, 0x2b65, 0xad80, 0x000c, 0x1078, 0x2baf, 0x0078, - 0x2b6b, 0xad80, 0x000e, 0x1078, 0x2baf, 0xad80, 0x000c, 0x20a9, - 0x0001, 0x1078, 0x2ba1, 0x0c7e, 0x1078, 0x2cf8, 0x0040, 0x2b96, - 0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119, 0x684f, 0x0020, 0x685b, - 0x0001, 0x810b, 0x697e, 0x6883, 0x0000, 0x6a86, 0x6b8a, 0x6c8e, - 0x6d92, 0x6996, 0x689b, 0x0000, 0x0c7f, 0x0d7f, 0x6837, 0x0000, - 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x1078, 0x6b72, 0x0040, - 0x2537, 0x7007, 0x0003, 0x701b, 0x2b9a, 0x007c, 0x0c7f, 0x0d7f, - 0x0078, 0x2537, 0x6820, 0xa086, 0x8001, 0x0040, 0x2537, 0x0078, - 0x250d, 0x017e, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x290a, - 0x8108, 0x280a, 0x8108, 0x00f0, 0x2ba3, 0x017f, 0x007c, 0x017e, - 0x0a7e, 0x0b7e, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x2054, - 0x8000, 0x205c, 0x2b0a, 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108, - 0x280a, 0x0b7f, 0x0a7f, 0x017f, 0x007c, 0x81ff, 0x00c0, 0x2537, + 0x0090, 0x6043, 0x0010, 0x2009, 0x001e, 0x2011, 0x3c98, 0x1078, + 0x5181, 0x7924, 0xa18c, 0xff00, 0x810f, 0x7a28, 0x1078, 0x2de3, + 0x127f, 0x0c7f, 0x027f, 0x0078, 0x279f, 0x7924, 0xa18c, 0xff00, + 0x810f, 0x0c7e, 0x1078, 0x3f53, 0x2c08, 0x0c7f, 0x00c0, 0x27cd, + 0x0078, 0x279f, 0x81ff, 0x0040, 0x2eb1, 0x2009, 0x0001, 0x0078, + 0x27c9, 0x60c0, 0xd09c, 0x00c0, 0x2eb9, 0x2009, 0x0005, 0x0078, + 0x27c9, 0x1078, 0x3119, 0x00c0, 0x2ec1, 0x2009, 0x0002, 0x0078, + 0x27c9, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3163, + 0x701b, 0x2ecb, 0x007c, 0x2009, 0x0080, 0x1078, 0x3f8e, 0x00c0, + 0x2ed8, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, 0x2edc, + 0x2021, 0x400a, 0x0078, 0x27a1, 0x0d7e, 0xade8, 0x000d, 0x6900, + 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, + 0x0040, 0x2f4f, 0xa0be, 0x0112, 0x0040, 0x2f4f, 0xa0be, 0x0113, + 0x0040, 0x2f4f, 0xa0be, 0x0114, 0x0040, 0x2f4f, 0xa0be, 0x0117, + 0x0040, 0x2f4f, 0xa0be, 0x011a, 0x0040, 0x2f4f, 0xa0be, 0x0121, + 0x0040, 0x2f45, 0xa0be, 0x0131, 0x0040, 0x2f45, 0xa0be, 0x0171, + 0x0040, 0x2f4f, 0xa0be, 0x0173, 0x0040, 0x2f4f, 0xa0be, 0x01a1, + 0x00c0, 0x2f17, 0x6830, 0x8007, 0x6832, 0x0078, 0x2f55, 0xa0be, + 0x0212, 0x0040, 0x2f4b, 0xa0be, 0x0213, 0x0040, 0x2f4b, 0xa0be, + 0x0214, 0x0040, 0x2f3d, 0xa0be, 0x0217, 0x0040, 0x2f37, 0xa0be, + 0x021a, 0x00c0, 0x2f30, 0x6838, 0x8007, 0x683a, 0x0078, 0x2f4f, + 0xa0be, 0x0300, 0x0040, 0x2f4f, 0x0d7f, 0x0078, 0x27cd, 0xad80, + 0x0010, 0x20a9, 0x0007, 0x1078, 0x2f95, 0xad80, 0x000e, 0x20a9, + 0x0001, 0x1078, 0x2f95, 0x0078, 0x2f4f, 0xad80, 0x000c, 0x1078, + 0x2fa3, 0x0078, 0x2f55, 0xad80, 0x000e, 0x1078, 0x2fa3, 0xad80, + 0x000c, 0x20a9, 0x0001, 0x1078, 0x2f95, 0x0c7e, 0x1078, 0x3119, + 0x0040, 0x2f86, 0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119, 0x6853, + 0x0000, 0x684f, 0x0020, 0x685b, 0x0001, 0x810b, 0x697e, 0x6883, + 0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996, 0x689b, 0x0000, + 0x0c7f, 0x0d7f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, + 0x0000, 0x1078, 0x7948, 0x00c0, 0x2f81, 0x2009, 0x0003, 0x0078, + 0x27c9, 0x7007, 0x0003, 0x701b, 0x2f8c, 0x007c, 0x0c7f, 0x0d7f, + 0x2009, 0x0002, 0x0078, 0x27c9, 0x6820, 0xa086, 0x8001, 0x00c0, + 0x279f, 0x2009, 0x0004, 0x0078, 0x27c9, 0x017e, 0x2008, 0x2044, + 0x8000, 0x204c, 0x8000, 0x290a, 0x8108, 0x280a, 0x8108, 0x00f0, + 0x2f97, 0x017f, 0x007c, 0x017e, 0x0a7e, 0x0b7e, 0x2008, 0x2044, + 0x8000, 0x204c, 0x8000, 0x2054, 0x8000, 0x205c, 0x2b0a, 0x8108, + 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a, 0x0b7f, 0x0a7f, 0x017f, + 0x007c, 0x81ff, 0x0040, 0x2fc0, 0x2009, 0x0001, 0x0078, 0x27c9, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0080, 0x0048, - 0x253b, 0xa182, 0x00ff, 0x00c8, 0x253b, 0x7a2c, 0x7b28, 0x6064, - 0xa306, 0x00c0, 0x2be3, 0x6068, 0xa24e, 0x0040, 0x253b, 0xa9cc, - 0xff00, 0x0040, 0x253b, 0x0c7e, 0x1078, 0x2c57, 0x2c68, 0x0c7f, - 0x0040, 0x2c0a, 0xa0c6, 0x4000, 0x00c0, 0x2bf0, 0x0078, 0x2c07, - 0xa0c6, 0x4007, 0x00c0, 0x2bf7, 0x2408, 0x0078, 0x2c07, 0xa0c6, - 0x4008, 0x00c0, 0x2bff, 0x2708, 0x2610, 0x0078, 0x2c07, 0xa0c6, - 0x4009, 0x00c0, 0x2c05, 0x0078, 0x2c07, 0x2001, 0x4006, 0x2020, - 0x0078, 0x250f, 0x017e, 0x0b7e, 0x0c7e, 0x0e7e, 0x2c70, 0x1078, - 0x5cb4, 0x0040, 0x2c45, 0x2d00, 0x601a, 0x2e58, 0x0e7f, 0x0e7e, - 0x0c7e, 0x1078, 0x2cf8, 0x0c7f, 0x2b70, 0x0040, 0x2537, 0x6837, - 0x0000, 0x2d00, 0x6012, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, - 0x127e, 0x2091, 0x8000, 0x1078, 0x22b5, 0x127f, 0x601f, 0x0001, - 0x2001, 0x0000, 0x1078, 0x37e0, 0x2001, 0x0002, 0x1078, 0x37f4, - 0x127e, 0x2091, 0x8000, 0x7088, 0x8000, 0x708a, 0x127f, 0x2009, - 0x0002, 0x1078, 0x5d41, 0xa085, 0x0001, 0x0e7f, 0x0c7f, 0x0b7f, - 0x017f, 0x0040, 0x2537, 0x7007, 0x0003, 0x701b, 0x2c50, 0x007c, - 0x6830, 0xa086, 0x0100, 0x00c0, 0x250d, 0x0078, 0x2537, 0x0e7e, - 0x0d7e, 0x2029, 0x0000, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, - 0x78a0, 0x2e04, 0xa005, 0x00c0, 0x2c6b, 0x2100, 0xa406, 0x0040, - 0x2ca8, 0x0078, 0x2c9c, 0x2068, 0x6f10, 0x2700, 0xa306, 0x00c0, - 0x2c8d, 0x6e14, 0x2600, 0xa206, 0x00c0, 0x2c8d, 0x2400, 0xa106, - 0x00c0, 0x2c89, 0x2d60, 0xd884, 0x0040, 0x2cae, 0x6004, 0xa084, - 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2cae, 0x2001, 0x4000, 0x0078, - 0x2caf, 0x2001, 0x4007, 0x0078, 0x2caf, 0x2400, 0xa106, 0x00c0, - 0x2c9c, 0x6e14, 0x87ff, 0x00c0, 0x2c98, 0x86ff, 0x0040, 0x2ca8, - 0x2001, 0x4008, 0x0078, 0x2caf, 0x8420, 0x8e70, 0x00f0, 0x2c61, - 0x2001, 0x4009, 0x0078, 0x2caf, 0x2001, 0x0001, 0x0078, 0x2caf, - 0x1078, 0x3811, 0x00c0, 0x2ca4, 0x6312, 0x6216, 0xa006, 0xa005, - 0x0d7f, 0x0e7f, 0x007c, 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2cf8, - 0x0040, 0x2537, 0x6837, 0x0000, 0x7824, 0xa005, 0x0040, 0x253b, - 0xa096, 0x00ff, 0x0040, 0x2cc8, 0xa092, 0x0004, 0x00c8, 0x253b, - 0x2010, 0x2d18, 0x1078, 0x2277, 0x0040, 0x2537, 0x7007, 0x0003, - 0x701b, 0x2cd3, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2537, - 0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, 0x7924, 0xa18c, 0xff00, - 0x810f, 0xa182, 0x0080, 0x0048, 0x253b, 0xa182, 0x00ff, 0x00c8, - 0x253b, 0x127e, 0x2091, 0x8000, 0x1078, 0x6a99, 0x00c0, 0x2cf5, - 0x1078, 0x3834, 0x127f, 0x0078, 0x250d, 0x127f, 0x0078, 0x2537, - 0x1078, 0x1327, 0x0040, 0x2d0f, 0xa006, 0x6802, 0x7010, 0xa005, - 0x00c0, 0x2d07, 0x2d00, 0x7012, 0x7016, 0x0078, 0x2d0d, 0x7014, - 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80, 0x000d, 0x007c, - 0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x384c, 0x00c0, 0x2d1f, - 0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048, 0x2d20, 0xa066, - 0x8cff, 0x007c, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x1078, 0x384c, - 0x00c0, 0x2d30, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0048, 0x2d31, - 0xa066, 0x8cff, 0x007c, 0x017e, 0x7110, 0x81ff, 0x0040, 0x2d3e, - 0x2168, 0x6904, 0x1078, 0x1340, 0x0078, 0x2d35, 0x7112, 0x7116, - 0x017f, 0x007c, 0x2031, 0x0001, 0x0078, 0x2d48, 0x2031, 0x0000, - 0x2061, 0x77bd, 0x6606, 0x6112, 0x600e, 0x6226, 0x632a, 0x642e, - 0x6532, 0x2c10, 0x1078, 0x1377, 0x7007, 0x0002, 0x701b, 0x250d, - 0x007c, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, - 0x777b, 0x2004, 0xa005, 0x00c0, 0x2d74, 0x0068, 0x2d74, 0x7818, - 0xd084, 0x00c0, 0x2d74, 0x781b, 0x0001, 0x7a22, 0x7b26, 0x7c2a, - 0x2091, 0x4080, 0x0078, 0x2d99, 0x017e, 0x0c7e, 0x0e7e, 0x2071, - 0x776d, 0x7138, 0xa182, 0x0008, 0x0048, 0x2d82, 0x7030, 0x2060, - 0x0078, 0x2d93, 0x7030, 0xa0e0, 0x0008, 0xac82, 0x77bd, 0x0048, - 0x2d8b, 0x2061, 0x777d, 0x2c00, 0x7032, 0x81ff, 0x00c0, 0x2d91, - 0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, 0x0e7f, 0x0c7f, - 0x017f, 0x127f, 0x0f7f, 0x007c, 0x0e7e, 0x2071, 0x776d, 0x7038, - 0xa005, 0x0040, 0x2dd5, 0x127e, 0x2091, 0x8000, 0x0068, 0x2dd4, - 0x0f7e, 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x2dd3, 0x0c7e, - 0x781b, 0x0001, 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826, - 0x6008, 0x782a, 0x2091, 0x4080, 0x7038, 0x8001, 0x703a, 0xa005, - 0x00c0, 0x2dc9, 0x7033, 0x777d, 0x7037, 0x777d, 0x0c7f, 0x0078, - 0x2dd3, 0xac80, 0x0008, 0xa0fa, 0x77bd, 0x0048, 0x2dd1, 0x2001, - 0x777d, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f, 0x007c, 0x027e, - 0x2001, 0x7752, 0x2004, 0xd0c4, 0x0040, 0x2de2, 0x2011, 0x8014, - 0x1078, 0x2d59, 0x027f, 0x007c, 0x81ff, 0x00c0, 0x2537, 0x127e, - 0x2091, 0x8000, 0x6030, 0xc08d, 0x6032, 0x1078, 0x3591, 0x127f, - 0x0078, 0x250d, 0x7824, 0x2008, 0xa18c, 0xfffd, 0x00c0, 0x2dfd, - 0x61c8, 0xa10d, 0x61ca, 0x0078, 0x250d, 0x0078, 0x253b, 0x81ff, - 0x00c0, 0x2537, 0x6000, 0xa086, 0x0003, 0x00c0, 0x2537, 0x2001, - 0x7752, 0x2004, 0xd0a4, 0x00c0, 0x2537, 0x1078, 0x2d22, 0x0040, - 0x253b, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2e1c, - 0x7828, 0xa005, 0x0040, 0x250d, 0x0c7e, 0x1078, 0x2cf8, 0x0c7f, - 0x0040, 0x2537, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, - 0x683a, 0x1078, 0x6bfb, 0x0040, 0x2537, 0x7007, 0x0003, 0x701b, - 0x2e32, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2537, 0x0078, - 0x250d, 0x2001, 0x7700, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2537, - 0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x2cf8, 0x0040, - 0x2537, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f, - 0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x1078, 0x384c, 0x00c0, - 0x2e7f, 0x6004, 0xa0c6, 0x0707, 0x0040, 0x2e7f, 0xa084, 0x00ff, - 0xa0c6, 0x0006, 0x00c0, 0x2e7f, 0x87ff, 0x0040, 0x2e72, 0xac80, - 0x0006, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x1078, 0x2baf, - 0x0078, 0x2e7b, 0xac80, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, - 0x53a3, 0x1078, 0x2baf, 0x21a2, 0x94a0, 0xa6b0, 0x0005, 0x8108, - 0xa186, 0x007e, 0x0040, 0x2e8a, 0xa686, 0x0028, 0x0040, 0x2e93, - 0x0078, 0x2e55, 0x86ff, 0x00c0, 0x2e91, 0x7120, 0x810b, 0x0078, - 0x250d, 0x702f, 0x0001, 0x711e, 0x7020, 0xa600, 0x7022, 0x772a, - 0x2061, 0x77bd, 0x6007, 0x0000, 0x6612, 0x7024, 0x600e, 0x6226, - 0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x1377, 0x7007, 0x0002, - 0x701b, 0x2eab, 0x007c, 0x702c, 0xa005, 0x00c0, 0x2ebd, 0x711c, - 0x7024, 0x20a0, 0x7728, 0x2031, 0x0000, 0x2061, 0x77bd, 0x6224, - 0x6328, 0x642c, 0x6530, 0x0078, 0x2e55, 0x7120, 0x810b, 0x0078, - 0x250d, 0x127e, 0x0c7e, 0x0e7e, 0x2061, 0x0100, 0x2071, 0x7700, - 0x6044, 0xd0a4, 0x00c0, 0x2eea, 0xd084, 0x0040, 0x2ed3, 0x1078, - 0x3015, 0x0078, 0x2ee6, 0xd08c, 0x0040, 0x2eda, 0x1078, 0x2f2c, - 0x0078, 0x2ee6, 0xd094, 0x0040, 0x2ee1, 0x1078, 0x2f0f, 0x0078, - 0x2ee6, 0xd09c, 0x0040, 0x2ee6, 0x1078, 0x2ef4, 0x0e7f, 0x0c7f, - 0x127f, 0x007c, 0x017e, 0x6128, 0xd19c, 0x00c0, 0x2ef1, 0xc19d, - 0x612a, 0x017f, 0x0078, 0x2ee6, 0x6043, 0x0040, 0x6043, 0x0000, - 0x706f, 0x0000, 0x7087, 0x0001, 0x70a7, 0x0000, 0x70bf, 0x0000, - 0x2009, 0x7dc0, 0x200b, 0x0000, 0x707f, 0x0000, 0x7073, 0x000f, - 0x2009, 0x000f, 0x2011, 0x3551, 0x1078, 0x4719, 0x007c, 0x7070, - 0xa005, 0x00c0, 0x2f2b, 0x2011, 0x3551, 0x1078, 0x4689, 0x6043, - 0x0020, 0x6043, 0x0000, 0x6044, 0xd08c, 0x00c0, 0x2f27, 0x7083, - 0x0000, 0x6043, 0x0090, 0x6043, 0x0010, 0x0078, 0x2f2b, 0x7077, - 0x0000, 0x0078, 0x2f2b, 0x007c, 0x7074, 0xa08a, 0x0003, 0x00c8, - 0x2f35, 0x1079, 0x2f38, 0x0078, 0x2f37, 0x1078, 0x12cd, 0x007c, - 0x2f3b, 0x2f8a, 0x3014, 0x0f7e, 0x7077, 0x0001, 0x20e1, 0xa000, - 0x20e1, 0x8700, 0x1078, 0x1de4, 0x20e1, 0x9080, 0x20e1, 0x4000, - 0x2079, 0x7c00, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, 0x0000, - 0x780f, 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b, 0x0000, - 0x781f, 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b, 0x0000, - 0x782f, 0x0000, 0x2079, 0x7c0c, 0x207b, 0x1101, 0x7807, 0x0000, - 0x2099, 0x7705, 0x20a1, 0x7c0e, 0x20a9, 0x0004, 0x53a3, 0x2079, - 0x7c12, 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0x7c00, 0x20a1, - 0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000, - 0x1078, 0x3578, 0x0f7f, 0x707b, 0x0000, 0x6043, 0x0008, 0x6043, - 0x0000, 0x007c, 0x0d7e, 0x7078, 0x707b, 0x0000, 0xa025, 0x0040, - 0x2ffe, 0x6020, 0xd0b4, 0x00c0, 0x2ffc, 0x7184, 0x81ff, 0x0040, - 0x2fe5, 0xa486, 0x000c, 0x00c0, 0x2ff0, 0xa480, 0x0018, 0x8004, - 0x20a8, 0x2011, 0x7c80, 0x2019, 0x7c00, 0x220c, 0x2304, 0xa106, - 0x00c0, 0x2fbc, 0x8210, 0x8318, 0x00f0, 0x2fa5, 0x6043, 0x0004, - 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x7077, 0x0002, - 0x7083, 0x0002, 0x0078, 0x2ffc, 0x2069, 0x7c80, 0x6930, 0xa18e, - 0x1101, 0x00c0, 0x2ff0, 0x6834, 0xa005, 0x00c0, 0x2ff0, 0x6900, - 0xa18c, 0x00ff, 0x00c0, 0x2fd0, 0x6804, 0xa005, 0x0040, 0x2fe5, - 0x2011, 0x7c8e, 0x2019, 0x7705, 0x20a9, 0x0004, 0x220c, 0x2304, - 0xa102, 0x0048, 0x2fe3, 0x00c0, 0x2ff0, 0x8210, 0x8318, 0x00f0, - 0x2fd6, 0x0078, 0x2ff0, 0x7087, 0x0000, 0x20e1, 0x9080, 0x20e1, - 0x4000, 0x2099, 0x7c80, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, - 0x6043, 0x0008, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x2ffc, - 0x60c3, 0x000c, 0x1078, 0x3578, 0x0d7f, 0x007c, 0x6020, 0xd0b4, - 0x00c0, 0x2ffc, 0x60c3, 0x000c, 0x2011, 0x7940, 0x2013, 0x0000, - 0x707b, 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, - 0x1078, 0x5693, 0x0078, 0x2ffc, 0x007c, 0x7080, 0xa08a, 0x001d, - 0x00c8, 0x301e, 0x1079, 0x3021, 0x0078, 0x3020, 0x1078, 0x12cd, - 0x007c, 0x3045, 0x3054, 0x3085, 0x309a, 0x30ca, 0x30f2, 0x3122, - 0x314c, 0x317c, 0x31a2, 0x31eb, 0x320d, 0x3231, 0x3247, 0x326f, - 0x3282, 0x328b, 0x32a4, 0x32d2, 0x32fa, 0x3328, 0x3352, 0x339a, - 0x33cb, 0x33ed, 0x342b, 0x3451, 0x346a, 0x3477, 0x7003, 0x0007, - 0x6004, 0xa084, 0xfff9, 0x6006, 0x007c, 0x608b, 0xbc94, 0x608f, - 0xf0f0, 0x6043, 0x0002, 0x7083, 0x0001, 0x2009, 0x07d0, 0x2011, - 0x3558, 0x1078, 0x467c, 0x007c, 0x0f7e, 0x7078, 0xa086, 0x0014, - 0x00c0, 0x3083, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x3083, - 0x2079, 0x7c80, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x3081, 0x7834, - 0xa005, 0x00c0, 0x3081, 0x7a38, 0xd2fc, 0x0040, 0x3077, 0x70a4, - 0xa005, 0x00c0, 0x3077, 0x1078, 0x3611, 0x70a7, 0x0001, 0x2011, - 0x3558, 0x1078, 0x4689, 0x7083, 0x0010, 0x1078, 0x328b, 0x0078, - 0x3083, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0003, 0x6043, - 0x0004, 0x1078, 0x35e2, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9, - 0x000a, 0x20a3, 0x0000, 0x00f0, 0x3091, 0x60c3, 0x0014, 0x1078, - 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x30c8, 0x2011, - 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, 0x30c4, 0x2079, - 0x7c80, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x30c4, 0x7834, 0xa005, - 0x00c0, 0x30c4, 0x7a38, 0xd2fc, 0x0040, 0x30be, 0x70a4, 0xa005, - 0x00c0, 0x30be, 0x1078, 0x3611, 0x70a7, 0x0001, 0x7083, 0x0004, - 0x1078, 0x30ca, 0x0078, 0x30c8, 0x7083, 0x0002, 0x707b, 0x0000, - 0x0f7f, 0x007c, 0x7083, 0x0005, 0x1078, 0x35e2, 0x20a3, 0x1103, - 0x20a3, 0x0000, 0x3430, 0x2011, 0x7c8e, 0x706c, 0xa005, 0x00c0, - 0x30e4, 0x714c, 0xa186, 0xffff, 0x0040, 0x30e4, 0x1078, 0x351c, - 0x0040, 0x30e4, 0x1078, 0x3611, 0x20a9, 0x0008, 0x2298, 0x26a0, - 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, - 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x3120, 0x2011, - 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, 0x311c, 0x2079, - 0x7c80, 0x7a30, 0xa296, 0x1103, 0x00c0, 0x311c, 0x7834, 0xa005, - 0x00c0, 0x311c, 0x7a38, 0xd2fc, 0x0040, 0x3116, 0x70a4, 0xa005, - 0x00c0, 0x3116, 0x1078, 0x3611, 0x70a7, 0x0001, 0x7083, 0x0006, - 0x1078, 0x3122, 0x0078, 0x3120, 0x7083, 0x0002, 0x707b, 0x0000, - 0x0f7f, 0x007c, 0x7083, 0x0007, 0x1078, 0x35e2, 0x20a3, 0x1104, - 0x20a3, 0x0000, 0x3430, 0x2011, 0x7c8e, 0x706c, 0xa005, 0x00c0, - 0x313e, 0x7150, 0xa186, 0xffff, 0x0040, 0x313e, 0xa180, 0x2329, - 0x200c, 0xa18c, 0xff00, 0x810f, 0x1078, 0x351c, 0x20a9, 0x0008, - 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, - 0x0014, 0x1078, 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, - 0x317a, 0x2011, 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, - 0x3176, 0x2079, 0x7c80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3176, - 0x7834, 0xa005, 0x00c0, 0x3176, 0x7a38, 0xd2fc, 0x0040, 0x3170, - 0x70a4, 0xa005, 0x00c0, 0x3170, 0x1078, 0x3611, 0x70a7, 0x0001, - 0x7083, 0x0008, 0x1078, 0x317c, 0x0078, 0x317a, 0x7083, 0x0002, - 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0009, 0x1078, 0x35e2, - 0x20a3, 0x1105, 0x20a3, 0x0100, 0x3430, 0x706c, 0xa005, 0x00c0, - 0x318f, 0x1078, 0x3486, 0x0040, 0x319f, 0x0078, 0x3199, 0x20a9, - 0x0008, 0x2099, 0x7c8e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, - 0x0000, 0x60c3, 0x0014, 0x1078, 0x3578, 0x0078, 0x31a1, 0x1078, - 0x303e, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x31e9, 0x2011, - 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, 0x31e5, 0x2079, - 0x7c80, 0x7a30, 0xa296, 0x1105, 0x00c0, 0x31e5, 0x7834, 0x2011, - 0x0100, 0xa21e, 0x00c0, 0x31ce, 0x7a38, 0xd2fc, 0x0040, 0x31c8, - 0x70a4, 0xa005, 0x00c0, 0x31c8, 0x1078, 0x3611, 0x70a7, 0x0001, - 0x7083, 0x000a, 0x1078, 0x31eb, 0x0078, 0x31e9, 0xa005, 0x00c0, - 0x31e5, 0x7a38, 0xd2fc, 0x0040, 0x31dd, 0x70a4, 0xa005, 0x00c0, - 0x31dd, 0x1078, 0x3611, 0x70a7, 0x0001, 0x707f, 0x0000, 0x7083, - 0x000e, 0x1078, 0x326f, 0x0078, 0x31e9, 0x7083, 0x0002, 0x707b, - 0x0000, 0x0f7f, 0x007c, 0x7083, 0x000b, 0x2011, 0x7c0e, 0x22a0, - 0x20a9, 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, 0x2009, - 0x0000, 0x41a4, 0x1078, 0x35e2, 0x20a3, 0x1106, 0x20a3, 0x0000, - 0x6030, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6, - 0x60c3, 0x0084, 0x1078, 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, - 0x0040, 0x322f, 0x2011, 0x3558, 0x1078, 0x4689, 0xa086, 0x0084, - 0x00c0, 0x322b, 0x2079, 0x7c80, 0x7a30, 0xa296, 0x1106, 0x00c0, - 0x322b, 0x7834, 0xa005, 0x00c0, 0x322b, 0x7083, 0x000c, 0x1078, - 0x3231, 0x0078, 0x322f, 0x7083, 0x0002, 0x707b, 0x0000, 0x0f7f, - 0x007c, 0x7083, 0x000d, 0x1078, 0x35e2, 0x20a3, 0x1107, 0x20a3, - 0x0000, 0x2099, 0x7c8e, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, - 0x20a3, 0x0000, 0x60c3, 0x0084, 0x1078, 0x3578, 0x007c, 0x0f7e, - 0x7078, 0xa005, 0x0040, 0x326d, 0x2011, 0x3558, 0x1078, 0x4689, - 0xa086, 0x0084, 0x00c0, 0x3269, 0x2079, 0x7c80, 0x7a30, 0xa296, - 0x1107, 0x00c0, 0x3269, 0x7834, 0xa005, 0x00c0, 0x3269, 0x707f, - 0x0001, 0x1078, 0x35d4, 0x7083, 0x000e, 0x1078, 0x326f, 0x0078, - 0x326d, 0x7083, 0x0002, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, - 0x000f, 0x707b, 0x0000, 0x608b, 0xbc85, 0x608f, 0xb5b5, 0x6043, - 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x3558, 0x1078, - 0x467c, 0x007c, 0x7078, 0xa005, 0x0040, 0x328a, 0x2011, 0x3558, - 0x1078, 0x4689, 0x007c, 0x7083, 0x0011, 0x20e1, 0x9080, 0x20e1, - 0x4000, 0x2099, 0x7c80, 0x20a1, 0x020b, 0x7478, 0xa480, 0x0018, - 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, - 0x0014, 0x1078, 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, - 0x32d0, 0x2011, 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, - 0x32ce, 0x2079, 0x7c80, 0x7a30, 0xa296, 0x1103, 0x00c0, 0x32ce, - 0x7834, 0xa005, 0x00c0, 0x32ce, 0x7a38, 0xd2fc, 0x0040, 0x32c8, - 0x70a4, 0xa005, 0x00c0, 0x32c8, 0x1078, 0x3611, 0x70a7, 0x0001, - 0x7083, 0x0012, 0x1078, 0x32d2, 0x0078, 0x32d0, 0x707b, 0x0000, - 0x0f7f, 0x007c, 0x7083, 0x0013, 0x1078, 0x35ee, 0x20a3, 0x1103, - 0x20a3, 0x0000, 0x3430, 0x2011, 0x7c8e, 0x706c, 0xa005, 0x00c0, - 0x32ec, 0x714c, 0xa186, 0xffff, 0x0040, 0x32ec, 0x1078, 0x351c, - 0x0040, 0x32ec, 0x1078, 0x3611, 0x20a9, 0x0008, 0x2298, 0x26a0, - 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, - 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x3326, 0x2011, - 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, 0x3324, 0x2079, - 0x7c80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3324, 0x7834, 0xa005, - 0x00c0, 0x3324, 0x7a38, 0xd2fc, 0x0040, 0x331e, 0x70a4, 0xa005, - 0x00c0, 0x331e, 0x1078, 0x3611, 0x70a7, 0x0001, 0x7083, 0x0014, - 0x1078, 0x3328, 0x0078, 0x3326, 0x707b, 0x0000, 0x0f7f, 0x007c, - 0x7083, 0x0015, 0x1078, 0x35ee, 0x20a3, 0x1104, 0x20a3, 0x0000, - 0x3430, 0x2011, 0x7c8e, 0x706c, 0xa006, 0x00c0, 0x3344, 0x7150, - 0xa186, 0xffff, 0x0040, 0x3344, 0xa180, 0x2329, 0x200c, 0xa18c, - 0xff00, 0x810f, 0x1078, 0x351c, 0x20a9, 0x0008, 0x2298, 0x26a0, + 0x27cd, 0xa182, 0x00ff, 0x00c8, 0x27cd, 0x7a2c, 0x7b28, 0x6068, + 0xa306, 0x00c0, 0x2fdb, 0x606c, 0xa24e, 0x0040, 0x27cd, 0xa9cc, + 0xff00, 0x0040, 0x27cd, 0x0c7e, 0x1078, 0x3071, 0x2c68, 0x0c7f, + 0x0040, 0x3002, 0xa0c6, 0x4000, 0x00c0, 0x2fe8, 0x0078, 0x2fff, + 0xa0c6, 0x4007, 0x00c0, 0x2fef, 0x2408, 0x0078, 0x2fff, 0xa0c6, + 0x4008, 0x00c0, 0x2ff7, 0x2708, 0x2610, 0x0078, 0x2fff, 0xa0c6, + 0x4009, 0x00c0, 0x2ffd, 0x0078, 0x2fff, 0x2001, 0x4006, 0x2020, + 0x0078, 0x27a1, 0x2d00, 0x7022, 0x017e, 0x0b7e, 0x0c7e, 0x0e7e, + 0x2c70, 0x1078, 0x68a8, 0x0040, 0x304f, 0x2d00, 0x601a, 0x2001, + 0x8856, 0x2004, 0xa084, 0x00ff, 0x6842, 0x2e58, 0x0e7f, 0x0e7e, + 0x0c7e, 0x1078, 0x3119, 0x0c7f, 0x2b70, 0x00c0, 0x3029, 0x1078, + 0x690e, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f, 0x2009, 0x0002, 0x0078, + 0x27c9, 0x6837, 0x0000, 0x2d00, 0x6012, 0x6833, 0x0000, 0x6838, + 0xc0fd, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x24bf, 0x127f, + 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x3ef1, 0x2001, 0x0002, + 0x1078, 0x3f05, 0x127e, 0x2091, 0x8000, 0x708c, 0x8000, 0x708e, + 0x127f, 0x2009, 0x0002, 0x1078, 0x6939, 0xa085, 0x0001, 0x0e7f, + 0x0c7f, 0x0b7f, 0x017f, 0x00c0, 0x3059, 0x2009, 0x0003, 0x0078, + 0x27c9, 0x7007, 0x0003, 0x701b, 0x305e, 0x007c, 0x6830, 0xa086, + 0x0100, 0x2009, 0x0004, 0x0040, 0x27c9, 0x7020, 0x2060, 0x2009, + 0x0000, 0x1078, 0x4233, 0x00c0, 0x306f, 0x2009, 0x0001, 0x0078, + 0x279f, 0x0e7e, 0x0d7e, 0x2029, 0x0000, 0x2021, 0x0080, 0x20a9, + 0x007f, 0x2071, 0x89b4, 0x2e04, 0xa005, 0x00c0, 0x3086, 0x2100, + 0xa406, 0x00c0, 0x30b7, 0x2428, 0x0078, 0x30b7, 0x2068, 0x6f10, + 0x2700, 0xa306, 0x00c0, 0x30a8, 0x6e14, 0x2600, 0xa206, 0x00c0, + 0x30a8, 0x2400, 0xa106, 0x00c0, 0x30a4, 0x2d60, 0xd884, 0x0040, + 0x30cc, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x30cc, + 0x2001, 0x4000, 0x0078, 0x30cd, 0x2001, 0x4007, 0x0078, 0x30cd, + 0x2400, 0xa106, 0x00c0, 0x30b7, 0x6e14, 0x87ff, 0x00c0, 0x30b3, + 0x86ff, 0x0040, 0x3083, 0x2001, 0x4008, 0x0078, 0x30cd, 0x8420, + 0x8e70, 0x00f0, 0x307b, 0x85ff, 0x00c0, 0x30c6, 0x2001, 0x4009, + 0x0078, 0x30cd, 0x2001, 0x0001, 0x0078, 0x30cd, 0x1078, 0x3f53, + 0x00c0, 0x30c2, 0x6312, 0x6216, 0xa006, 0xa005, 0x0d7f, 0x0e7f, + 0x007c, 0x81ff, 0x00c0, 0x27c9, 0x1078, 0x3119, 0x0040, 0x27c9, + 0x6837, 0x0000, 0x7824, 0xa005, 0x0040, 0x27cd, 0xa096, 0x00ff, + 0x0040, 0x30e6, 0xa092, 0x0004, 0x00c8, 0x27cd, 0x2010, 0x2d18, + 0x1078, 0x2481, 0x0040, 0x27c9, 0x7007, 0x0003, 0x701b, 0x30f1, + 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x27c9, 0x0078, 0x279f, + 0x7924, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0080, 0x0048, 0x27cd, + 0xa182, 0x00ff, 0x00c8, 0x27cd, 0x127e, 0x2091, 0x8000, 0x1078, + 0x782e, 0x00c0, 0x3116, 0xa190, 0x8934, 0x2204, 0xa065, 0x0040, + 0x3116, 0x1078, 0x3d31, 0x127f, 0x0078, 0x279f, 0x127f, 0x0078, + 0x27c9, 0x1078, 0x132b, 0x0040, 0x3130, 0xa006, 0x6802, 0x7010, + 0xa005, 0x00c0, 0x3128, 0x2d00, 0x7012, 0x7016, 0x0078, 0x312e, + 0x7014, 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80, 0x000d, + 0x007c, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x3f8e, 0x00c0, + 0x3140, 0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048, 0x3141, + 0xa066, 0x8cff, 0x007c, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x1078, + 0x3f8e, 0x00c0, 0x3151, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0048, + 0x3152, 0xa066, 0x8cff, 0x007c, 0x017e, 0x7110, 0x81ff, 0x0040, + 0x315f, 0x2168, 0x6904, 0x1078, 0x1344, 0x0078, 0x3156, 0x7112, + 0x7116, 0x017f, 0x007c, 0x2031, 0x0001, 0x0078, 0x3169, 0x2031, + 0x0000, 0x2061, 0x88d1, 0x6606, 0x6112, 0x600e, 0x6226, 0x632a, + 0x642e, 0x6532, 0x2c10, 0x1078, 0x137b, 0x7007, 0x0002, 0x701b, + 0x279f, 0x007c, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079, 0x0000, + 0x2001, 0x888f, 0x2004, 0xa005, 0x00c0, 0x3195, 0x0068, 0x3195, + 0x7818, 0xd084, 0x00c0, 0x3195, 0x7a22, 0x7b26, 0x7c2a, 0x781b, + 0x0001, 0x2091, 0x4080, 0x0078, 0x31ba, 0x017e, 0x0c7e, 0x0e7e, + 0x2071, 0x8881, 0x7138, 0xa182, 0x0008, 0x0048, 0x31a3, 0x7030, + 0x2060, 0x0078, 0x31b4, 0x7030, 0xa0e0, 0x0008, 0xac82, 0x88d1, + 0x0048, 0x31ac, 0x2061, 0x8891, 0x2c00, 0x7032, 0x81ff, 0x00c0, + 0x31b2, 0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, 0x0e7f, + 0x0c7f, 0x017f, 0x127f, 0x0f7f, 0x007c, 0x0e7e, 0x2071, 0x8881, + 0x7038, 0xa005, 0x0040, 0x31f6, 0x127e, 0x2091, 0x8000, 0x0068, + 0x31f5, 0x0f7e, 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x31f4, + 0x0c7e, 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826, 0x6008, + 0x782a, 0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001, 0x703a, + 0xa005, 0x00c0, 0x31ea, 0x7033, 0x8891, 0x7037, 0x8891, 0x0c7f, + 0x0078, 0x31f4, 0xac80, 0x0008, 0xa0fa, 0x88d1, 0x0048, 0x31f2, + 0x2001, 0x8891, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f, 0x007c, + 0x027e, 0x2001, 0x8852, 0x2004, 0xd0c4, 0x0040, 0x3203, 0x2011, + 0x8014, 0x1078, 0x317a, 0x027f, 0x007c, 0x81ff, 0x00c0, 0x27c9, + 0x127e, 0x2091, 0x8000, 0x6030, 0xc08d, 0xc0ac, 0x6032, 0x1078, + 0x3c73, 0x127f, 0x0078, 0x279f, 0x7824, 0x2008, 0xa18c, 0xfffd, + 0x00c0, 0x321f, 0x61cc, 0xa10d, 0x61ce, 0x0078, 0x279f, 0x0078, + 0x27cd, 0x81ff, 0x00c0, 0x27c9, 0x6000, 0xa086, 0x0003, 0x00c0, + 0x27c9, 0x2001, 0x8852, 0x2004, 0xd0a4, 0x00c0, 0x27c9, 0x1078, + 0x3143, 0x0040, 0x27cd, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, + 0x00c0, 0x323e, 0x7828, 0xa005, 0x0040, 0x279f, 0x0c7e, 0x1078, + 0x3119, 0x0c7f, 0x0040, 0x27c9, 0x6837, 0x0000, 0x6833, 0x0000, + 0x6838, 0xc0fd, 0x683a, 0x1078, 0x79ed, 0x0040, 0x27c9, 0x7007, + 0x0003, 0x701b, 0x3254, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, + 0x27c9, 0x0078, 0x279f, 0x2001, 0x8800, 0x2004, 0xa086, 0x0003, + 0x00c0, 0x27c9, 0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, + 0x3119, 0x0040, 0x27c9, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023, + 0x0000, 0x702f, 0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x1078, + 0x3f8e, 0x00c0, 0x32ad, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, + 0x0040, 0x3288, 0xa0c4, 0xff00, 0xa8c6, 0x0600, 0x00c0, 0x32ad, + 0x2001, 0x8852, 0x2004, 0xd0ac, 0x00c0, 0x3292, 0x1078, 0x4233, + 0x0040, 0x32ad, 0xd784, 0x0040, 0x32a0, 0xac80, 0x0006, 0x2098, + 0x3400, 0x20a9, 0x0004, 0x53a3, 0x1078, 0x2fa3, 0x0078, 0x32a9, + 0xac80, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x1078, + 0x2fa3, 0x21a2, 0x94a0, 0xa6b0, 0x0005, 0x8108, 0xd78c, 0x0040, + 0x32b7, 0xa186, 0x0100, 0x0040, 0x32c1, 0x0078, 0x32bb, 0xa186, + 0x007e, 0x0040, 0x32c1, 0xa686, 0x0028, 0x0040, 0x32ca, 0x0078, + 0x3277, 0x86ff, 0x00c0, 0x32c8, 0x7120, 0x810b, 0x0078, 0x279f, + 0x702f, 0x0001, 0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, + 0x88d1, 0x6007, 0x0000, 0x6612, 0x7024, 0x600e, 0x6226, 0x632a, + 0x642e, 0x6532, 0x2c10, 0x1078, 0x137b, 0x7007, 0x0002, 0x701b, + 0x32e2, 0x007c, 0x702c, 0xa005, 0x00c0, 0x32f4, 0x711c, 0x7024, + 0x20a0, 0x7728, 0x2031, 0x0000, 0x2061, 0x88d1, 0x6224, 0x6328, + 0x642c, 0x6530, 0x0078, 0x3277, 0x7120, 0x810b, 0x0078, 0x279f, + 0x2029, 0x007e, 0x7924, 0x7a28, 0x7b2c, 0x7c38, 0xa184, 0xff00, + 0x8007, 0xa0e2, 0x0020, 0x0048, 0x27cd, 0xa502, 0x0048, 0x27cd, + 0xa184, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x27cd, 0xa502, 0x0048, + 0x27cd, 0xa284, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x27cd, + 0xa502, 0x0048, 0x27cd, 0xa284, 0x00ff, 0xa0e2, 0x0020, 0x0048, + 0x27cd, 0xa502, 0x0048, 0x27cd, 0xa384, 0xff00, 0x8007, 0xa0e2, + 0x0020, 0x0048, 0x27cd, 0xa502, 0x0048, 0x27cd, 0xa384, 0x00ff, + 0xa0e2, 0x0020, 0x0048, 0x27cd, 0xa502, 0x0048, 0x27cd, 0xa484, + 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x27cd, 0xa502, 0x0048, + 0x27cd, 0xa484, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x27cd, 0xa502, + 0x0048, 0x27cd, 0x2061, 0x8a9c, 0x6102, 0x6206, 0x630a, 0x640e, + 0x0078, 0x279f, 0x007e, 0x2001, 0x8852, 0x2004, 0xd0cc, 0x007f, + 0x007c, 0x007e, 0x2001, 0x8871, 0x2004, 0xd0bc, 0x007f, 0x007c, + 0x6160, 0x7a24, 0x6300, 0x82ff, 0x00c0, 0x3369, 0x7926, 0x0078, + 0x279f, 0x83ff, 0x00c0, 0x27cd, 0x2001, 0xfff0, 0xa200, 0x00c8, + 0x27cd, 0x2019, 0xffff, 0x6064, 0xa302, 0xa200, 0x0048, 0x27cd, + 0x7926, 0x6262, 0x0078, 0x279f, 0x2001, 0x8800, 0x2004, 0xa086, + 0x0003, 0x00c0, 0x27c9, 0x7c28, 0x7d24, 0x7e38, 0x7f2c, 0x1078, + 0x3119, 0x0040, 0x27c9, 0x2009, 0x0000, 0x2019, 0x0000, 0x7023, + 0x0000, 0x702f, 0x0000, 0xad80, 0x0003, 0x7026, 0x20a0, 0xa1e0, + 0x8934, 0x2c64, 0x8cff, 0x0040, 0x33b6, 0x6004, 0xa084, 0x00ff, + 0xa086, 0x0006, 0x0040, 0x33ab, 0x6004, 0xa084, 0xff00, 0xa086, + 0x0600, 0x00c0, 0x33b6, 0x6014, 0x20a2, 0x94a0, 0x6010, 0x8007, + 0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, 0x8108, 0xa182, + 0x00ff, 0x0040, 0x33c1, 0xa386, 0x002a, 0x0040, 0x33ca, 0x0078, + 0x3397, 0x83ff, 0x00c0, 0x33c8, 0x7120, 0x810c, 0x0078, 0x279f, + 0x702f, 0x0001, 0x711e, 0x7020, 0xa300, 0x7022, 0x2061, 0x88d1, + 0x6007, 0x0000, 0x6312, 0x7024, 0x600e, 0x6426, 0x652a, 0x662e, + 0x6732, 0x2c10, 0x1078, 0x137b, 0x7007, 0x0002, 0x701b, 0x33e1, + 0x007c, 0x702c, 0xa005, 0x00c0, 0x33f2, 0x711c, 0x7024, 0x20a0, + 0x2019, 0x0000, 0x2061, 0x88d1, 0x6424, 0x6528, 0x662c, 0x6730, + 0x0078, 0x3397, 0x7120, 0x810c, 0x0078, 0x279f, 0x81ff, 0x00c0, + 0x27c9, 0x60c0, 0xd09c, 0x0040, 0x27c9, 0x1078, 0x3119, 0x0040, + 0x27c9, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3163, + 0x701b, 0x340b, 0x007c, 0x0d7e, 0xade8, 0x000d, 0x6828, 0xa0be, + 0x7000, 0x0040, 0x341e, 0xa0be, 0x7100, 0x0040, 0x341e, 0xa0be, + 0x7200, 0x0040, 0x341e, 0x0d7f, 0x0078, 0x27cd, 0x6820, 0x6924, + 0x1078, 0x2245, 0x00c0, 0x3447, 0x1078, 0x3f53, 0x00c0, 0x3447, + 0x7122, 0x6612, 0x6516, 0x6e18, 0x0c7e, 0x1078, 0x3119, 0x0040, + 0x3447, 0x1078, 0x3119, 0x0040, 0x3447, 0x0c7f, 0x0d7f, 0x6837, + 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x1078, 0x7964, + 0x0040, 0x27c9, 0x7007, 0x0003, 0x701b, 0x344a, 0x007c, 0x0d7f, + 0x0078, 0x27c9, 0x7120, 0x1078, 0x3f76, 0x6820, 0xa086, 0x8001, + 0x0040, 0x27c9, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002, 0x007e, + 0x20a9, 0x002a, 0x2098, 0x20a0, 0x1078, 0x3cbc, 0x007f, 0xade8, + 0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0x88d1, 0x6007, + 0x0000, 0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x00c0, 0x3471, 0x0078, + 0x3475, 0xa7c6, 0x7100, 0x00c0, 0x347d, 0xa6c2, 0x0004, 0x0048, + 0x27cd, 0x2009, 0x0004, 0x0078, 0x3167, 0xa7c6, 0x7200, 0x00c0, + 0x27cd, 0xa6c2, 0x0054, 0x0048, 0x27cd, 0x600e, 0x6013, 0x002a, + 0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x137b, 0x7007, + 0x0002, 0x701b, 0x3494, 0x007c, 0x701c, 0x2068, 0x6804, 0xa080, + 0x0001, 0x2004, 0xa080, 0x0002, 0x007e, 0x20a9, 0x002a, 0x2098, + 0x20a0, 0x1078, 0x3cbc, 0x007f, 0x2009, 0x002a, 0x2061, 0x88d1, + 0x6224, 0x6328, 0x642c, 0x6530, 0x0078, 0x3167, 0x81ff, 0x00c0, + 0x27c9, 0x1078, 0x3131, 0x0040, 0x27cd, 0x1078, 0x4017, 0x0040, + 0x27c9, 0x1078, 0x4180, 0x0078, 0x279f, 0x7824, 0xd084, 0x0040, + 0x2d64, 0x1078, 0x3143, 0x0040, 0x27cd, 0x0c7e, 0x1078, 0x3119, + 0x0c7f, 0x00c0, 0x34cf, 0x2009, 0x0002, 0x0078, 0x27c9, 0x6004, + 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x34f8, 0x2001, 0x8852, + 0x2004, 0xd0b4, 0x0040, 0x2d99, 0x6000, 0xd08c, 0x00c0, 0x2d99, + 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x7980, 0x00c0, + 0x34ed, 0x2009, 0x0003, 0x0078, 0x27c9, 0x7007, 0x0003, 0x701b, + 0x34f2, 0x007c, 0x1078, 0x3143, 0x0040, 0x27cd, 0x0078, 0x2d99, + 0x2009, 0x882d, 0x210c, 0x81ff, 0x0040, 0x3502, 0x2009, 0x0001, + 0x0078, 0x27c9, 0x2001, 0x8800, 0x2004, 0xa086, 0x0003, 0x0040, + 0x350d, 0x2009, 0x0007, 0x0078, 0x27c9, 0x2001, 0x8852, 0x2004, + 0xd0ac, 0x0040, 0x3517, 0x2009, 0x0008, 0x0078, 0x27c9, 0x609c, + 0xd0a4, 0x00c0, 0x351e, 0xd0ac, 0x00c0, 0x2d99, 0x6837, 0x0000, + 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x79ed, 0x00c0, + 0x352d, 0x2009, 0x0003, 0x0078, 0x27c9, 0x7007, 0x0003, 0x701b, + 0x3532, 0x007c, 0x6830, 0xa086, 0x0100, 0x00c0, 0x353b, 0x2009, + 0x0004, 0x0078, 0x27c9, 0x1078, 0x3143, 0x0040, 0x27cd, 0x0078, + 0x34d6, 0x127e, 0x0c7e, 0x0e7e, 0x2061, 0x0100, 0x2071, 0x8800, + 0x6044, 0xd0a4, 0x00c0, 0x356a, 0xd084, 0x0040, 0x3553, 0x1078, + 0x36c6, 0x0078, 0x3566, 0xd08c, 0x0040, 0x355a, 0x1078, 0x35dd, + 0x0078, 0x3566, 0xd094, 0x0040, 0x3561, 0x1078, 0x35b1, 0x0078, + 0x3566, 0xd09c, 0x0040, 0x3566, 0x1078, 0x3574, 0x0e7f, 0x0c7f, + 0x127f, 0x007c, 0x017e, 0x6128, 0xd19c, 0x00c0, 0x3571, 0xc19d, + 0x612a, 0x017f, 0x0078, 0x3566, 0x624c, 0xa286, 0xf0f0, 0x00c0, + 0x3585, 0x6048, 0xa086, 0xf0f0, 0x0040, 0x3585, 0x624a, 0x6043, + 0x0090, 0x6043, 0x0010, 0x0078, 0x35b0, 0xa294, 0xff00, 0xa296, + 0xf700, 0x0040, 0x3596, 0x6240, 0xa294, 0x0010, 0x0040, 0x3596, + 0x2009, 0x00f7, 0x1078, 0x3cdc, 0x0078, 0x35b0, 0x6043, 0x0040, + 0x6043, 0x0000, 0x7073, 0x0000, 0x708b, 0x0001, 0x70ab, 0x0000, + 0x70c3, 0x0000, 0x2009, 0x8ec0, 0x200b, 0x0000, 0x7083, 0x0000, + 0x7077, 0x000f, 0x2009, 0x000f, 0x2011, 0x3c2e, 0x1078, 0x5181, + 0x007c, 0x157e, 0x7074, 0xa005, 0x00c0, 0x35db, 0x2011, 0x3c2e, + 0x1078, 0x50f2, 0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, + 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x00c0, 0x35d4, 0x00f0, 0x35c2, + 0x6242, 0x7087, 0x0000, 0x6040, 0xa094, 0x0010, 0xa285, 0x0080, + 0x6042, 0x6242, 0x0078, 0x35db, 0x6242, 0x7087, 0x0000, 0x707b, + 0x0000, 0x0078, 0x35db, 0x157f, 0x007c, 0x7078, 0xa08a, 0x0003, + 0x00c8, 0x35e6, 0x1079, 0x35e9, 0x0078, 0x35e8, 0x1078, 0x12d2, + 0x007c, 0x35ec, 0x363b, 0x36c5, 0x0f7e, 0x707b, 0x0001, 0x20e1, + 0xa000, 0x20e1, 0x8700, 0x1078, 0x1f57, 0x20e1, 0x9080, 0x20e1, + 0x4000, 0x2079, 0x8d00, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, + 0x0000, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b, + 0x0000, 0x781f, 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b, + 0x0000, 0x782f, 0x0000, 0x2079, 0x8d0c, 0x207b, 0x1101, 0x7807, + 0x0000, 0x2099, 0x8805, 0x20a1, 0x8d0e, 0x20a9, 0x0004, 0x53a3, + 0x2079, 0x8d12, 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0x8d00, + 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, + 0x0000, 0x1078, 0x3c5a, 0x0f7f, 0x707f, 0x0000, 0x6043, 0x0008, + 0x6043, 0x0000, 0x007c, 0x0d7e, 0x707c, 0x707f, 0x0000, 0xa025, + 0x0040, 0x36af, 0x6020, 0xd0b4, 0x00c0, 0x36ad, 0x7188, 0x81ff, + 0x0040, 0x3696, 0xa486, 0x000c, 0x00c0, 0x36a1, 0xa480, 0x0018, + 0x8004, 0x20a8, 0x2011, 0x8d80, 0x2019, 0x8d00, 0x220c, 0x2304, + 0xa106, 0x00c0, 0x366d, 0x8210, 0x8318, 0x00f0, 0x3656, 0x6043, + 0x0004, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x707b, + 0x0002, 0x7087, 0x0002, 0x0078, 0x36ad, 0x2069, 0x8d80, 0x6930, + 0xa18e, 0x1101, 0x00c0, 0x36a1, 0x6834, 0xa005, 0x00c0, 0x36a1, + 0x6900, 0xa18c, 0x00ff, 0x00c0, 0x3681, 0x6804, 0xa005, 0x0040, + 0x3696, 0x2011, 0x8d8e, 0x2019, 0x8805, 0x20a9, 0x0004, 0x220c, + 0x2304, 0xa102, 0x0048, 0x3694, 0x00c0, 0x36a1, 0x8210, 0x8318, + 0x00f0, 0x3687, 0x0078, 0x36a1, 0x708b, 0x0000, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x2099, 0x8d80, 0x20a1, 0x020b, 0x20a9, 0x0014, + 0x53a6, 0x6043, 0x0008, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, + 0x36ad, 0x60c3, 0x000c, 0x1078, 0x3c5a, 0x0d7f, 0x007c, 0x6020, + 0xd0b4, 0x00c0, 0x36ad, 0x60c3, 0x000c, 0x2011, 0x8aac, 0x2013, + 0x0000, 0x707f, 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, + 0x9575, 0x1078, 0x6229, 0x0078, 0x36ad, 0x007c, 0x7084, 0xa08a, + 0x001d, 0x00c8, 0x36cf, 0x1079, 0x36d2, 0x0078, 0x36d1, 0x1078, + 0x12d2, 0x007c, 0x36fc, 0x370b, 0x373c, 0x3751, 0x3781, 0x37ad, + 0x37dd, 0x3813, 0x3843, 0x386b, 0x38b4, 0x38de, 0x3902, 0x3918, + 0x3940, 0x3953, 0x395c, 0x3988, 0x39b6, 0x39e2, 0x3a10, 0x3a46, + 0x3a8f, 0x3abe, 0x3ae0, 0x3b22, 0x3b48, 0x3b61, 0x3b62, 0x0c7e, + 0x2061, 0x8800, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, + 0xfff9, 0x6006, 0x0c7f, 0x007c, 0x608b, 0xbc94, 0x608f, 0xf0f0, + 0x6043, 0x0002, 0x7087, 0x0001, 0x2009, 0x07d0, 0x2011, 0x3c35, + 0x1078, 0x50e5, 0x007c, 0x0f7e, 0x707c, 0xa086, 0x0014, 0x00c0, + 0x373a, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x373a, 0x2079, + 0x8d80, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x3738, 0x7834, 0xa005, + 0x00c0, 0x3738, 0x7a38, 0xd2fc, 0x0040, 0x372e, 0x70a8, 0xa005, + 0x00c0, 0x372e, 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x2011, 0x3c35, + 0x1078, 0x50f2, 0x7087, 0x0010, 0x1078, 0x395c, 0x0078, 0x373a, + 0x707f, 0x0000, 0x0f7f, 0x007c, 0x7087, 0x0003, 0x6043, 0x0004, + 0x1078, 0x3cc4, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9, 0x000a, + 0x20a3, 0x0000, 0x00f0, 0x3748, 0x60c3, 0x0014, 0x1078, 0x3c5a, + 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x377f, 0x2011, 0x3c35, + 0x1078, 0x50f2, 0xa086, 0x0014, 0x00c0, 0x377b, 0x2079, 0x8d80, + 0x7a30, 0xa296, 0x1102, 0x00c0, 0x377b, 0x7834, 0xa005, 0x00c0, + 0x377b, 0x7a38, 0xd2fc, 0x0040, 0x3775, 0x70a8, 0xa005, 0x00c0, + 0x3775, 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x7087, 0x0004, 0x1078, + 0x3781, 0x0078, 0x377f, 0x7087, 0x0002, 0x707f, 0x0000, 0x0f7f, + 0x007c, 0x7087, 0x0005, 0x1078, 0x3cc4, 0x20a3, 0x1103, 0x20a3, + 0x0000, 0x3430, 0x2011, 0x8d8e, 0x1078, 0x3d0d, 0x00c0, 0x379f, + 0x7070, 0xa005, 0x00c0, 0x379f, 0x714c, 0xa186, 0xffff, 0x0040, + 0x379f, 0x1078, 0x3bf9, 0x0040, 0x379f, 0x1078, 0x3cf3, 0x20a9, + 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0014, 0x1078, 0x3c5a, 0x007c, 0x0f7e, 0x707c, 0xa005, + 0x0040, 0x37db, 0x2011, 0x3c35, 0x1078, 0x50f2, 0xa086, 0x0014, + 0x00c0, 0x37d7, 0x2079, 0x8d80, 0x7a30, 0xa296, 0x1103, 0x00c0, + 0x37d7, 0x7834, 0xa005, 0x00c0, 0x37d7, 0x7a38, 0xd2fc, 0x0040, + 0x37d1, 0x70a8, 0xa005, 0x00c0, 0x37d1, 0x1078, 0x3cf3, 0x70ab, + 0x0001, 0x7087, 0x0006, 0x1078, 0x37dd, 0x0078, 0x37db, 0x7087, + 0x0002, 0x707f, 0x0000, 0x0f7f, 0x007c, 0x7087, 0x0007, 0x1078, + 0x3cc4, 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0x8d8e, + 0x1078, 0x3d0d, 0x00c0, 0x3805, 0x7070, 0xa005, 0x00c0, 0x3805, + 0x7150, 0xa186, 0xffff, 0x0040, 0x3805, 0xa180, 0x25b2, 0x200c, + 0xa18c, 0xff00, 0x810f, 0x1078, 0x3bf9, 0x0040, 0x3805, 0x1078, + 0x3359, 0x0040, 0x3805, 0x1078, 0x2262, 0x20a9, 0x0008, 0x2298, + 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, + 0x1078, 0x3c5a, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3841, + 0x2011, 0x3c35, 0x1078, 0x50f2, 0xa086, 0x0014, 0x00c0, 0x383d, + 0x2079, 0x8d80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x383d, 0x7834, + 0xa005, 0x00c0, 0x383d, 0x7a38, 0xd2fc, 0x0040, 0x3837, 0x70a8, + 0xa005, 0x00c0, 0x3837, 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x7087, + 0x0008, 0x1078, 0x3843, 0x0078, 0x3841, 0x7087, 0x0002, 0x707f, + 0x0000, 0x0f7f, 0x007c, 0x7087, 0x0009, 0x1078, 0x3cc4, 0x20a3, + 0x1105, 0x20a3, 0x0100, 0x3430, 0x1078, 0x3d0d, 0x00c0, 0x385c, + 0x7070, 0xa005, 0x00c0, 0x385c, 0x1078, 0x3b63, 0x00c0, 0x3866, + 0xa085, 0x0001, 0x1078, 0x2262, 0x20a9, 0x0008, 0x2099, 0x8d8e, + 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, + 0x1078, 0x3c5a, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x38b2, + 0x2011, 0x3c35, 0x1078, 0x50f2, 0xa086, 0x0014, 0x00c0, 0x38ae, + 0x2079, 0x8d80, 0x7a30, 0xa296, 0x1105, 0x00c0, 0x38ae, 0x7834, + 0x2011, 0x0100, 0xa21e, 0x00c0, 0x3897, 0x7a38, 0xd2fc, 0x0040, + 0x3891, 0x70a8, 0xa005, 0x00c0, 0x3891, 0x1078, 0x3cf3, 0x70ab, + 0x0001, 0x7087, 0x000a, 0x1078, 0x38b4, 0x0078, 0x38b2, 0xa005, + 0x00c0, 0x38ae, 0x7a38, 0xd2fc, 0x0040, 0x38a6, 0x70a8, 0xa005, + 0x00c0, 0x38a6, 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x7083, 0x0000, + 0x7087, 0x000e, 0x1078, 0x3940, 0x0078, 0x38b2, 0x7087, 0x0002, + 0x707f, 0x0000, 0x0f7f, 0x007c, 0x7087, 0x000b, 0x2011, 0x8d0e, + 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, + 0x2009, 0x0000, 0x41a4, 0x1078, 0x3cc4, 0x20a3, 0x1106, 0x20a3, + 0x0000, 0x1078, 0x3d0d, 0x0040, 0x38d1, 0x2013, 0x0000, 0x0078, + 0x38d5, 0x6030, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, + 0x53a6, 0x60c3, 0x0084, 0x1078, 0x3c5a, 0x007c, 0x0f7e, 0x707c, + 0xa005, 0x0040, 0x3900, 0x2011, 0x3c35, 0x1078, 0x50f2, 0xa086, + 0x0084, 0x00c0, 0x38fc, 0x2079, 0x8d80, 0x7a30, 0xa296, 0x1106, + 0x00c0, 0x38fc, 0x7834, 0xa005, 0x00c0, 0x38fc, 0x7087, 0x000c, + 0x1078, 0x3902, 0x0078, 0x3900, 0x7087, 0x0002, 0x707f, 0x0000, + 0x0f7f, 0x007c, 0x7087, 0x000d, 0x1078, 0x3cc4, 0x20a3, 0x1107, + 0x20a3, 0x0000, 0x2099, 0x8d8e, 0x20a9, 0x0040, 0x53a6, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x1078, 0x3c5a, 0x007c, + 0x0f7e, 0x707c, 0xa005, 0x0040, 0x393e, 0x2011, 0x3c35, 0x1078, + 0x50f2, 0xa086, 0x0084, 0x00c0, 0x393a, 0x2079, 0x8d80, 0x7a30, + 0xa296, 0x1107, 0x00c0, 0x393a, 0x7834, 0xa005, 0x00c0, 0x393a, + 0x7083, 0x0001, 0x1078, 0x3cb6, 0x7087, 0x000e, 0x1078, 0x3940, + 0x0078, 0x393e, 0x7087, 0x0002, 0x707f, 0x0000, 0x0f7f, 0x007c, + 0x7087, 0x000f, 0x707f, 0x0000, 0x608b, 0xbc85, 0x608f, 0xb5b5, + 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x3c35, + 0x1078, 0x50e5, 0x007c, 0x707c, 0xa005, 0x0040, 0x395b, 0x2011, + 0x3c35, 0x1078, 0x50f2, 0x007c, 0x7087, 0x0011, 0x7168, 0x81ff, + 0x0040, 0x3971, 0x2009, 0x0000, 0x706c, 0xa084, 0x00ff, 0x1078, + 0x2245, 0xa186, 0x0080, 0x0040, 0x3971, 0x2011, 0x8d8e, 0x1078, + 0x3bf9, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x8d80, 0x20a1, + 0x020b, 0x747c, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, + 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014, 0x1078, 0x3c5a, 0x007c, + 0x0f7e, 0x707c, 0xa005, 0x0040, 0x39b4, 0x2011, 0x3c35, 0x1078, + 0x50f2, 0xa086, 0x0014, 0x00c0, 0x39b2, 0x2079, 0x8d80, 0x7a30, + 0xa296, 0x1103, 0x00c0, 0x39b2, 0x7834, 0xa005, 0x00c0, 0x39b2, + 0x7a38, 0xd2fc, 0x0040, 0x39ac, 0x70a8, 0xa005, 0x00c0, 0x39ac, + 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x7087, 0x0012, 0x1078, 0x39b6, + 0x0078, 0x39b4, 0x707f, 0x0000, 0x0f7f, 0x007c, 0x7087, 0x0013, + 0x1078, 0x3cd0, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, + 0x8d8e, 0x1078, 0x3d0d, 0x00c0, 0x39d4, 0x7070, 0xa005, 0x00c0, + 0x39d4, 0x714c, 0xa186, 0xffff, 0x0040, 0x39d4, 0x1078, 0x3bf9, + 0x0040, 0x39d4, 0x1078, 0x3cf3, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, - 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x3398, 0x2011, - 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, 0x3396, 0x2079, - 0x7c80, 0x7a30, 0xa296, 0x1105, 0x00c0, 0x3396, 0x7834, 0x2011, - 0x0100, 0xa21e, 0x00c0, 0x337f, 0x7a38, 0xd2f4, 0x0040, 0x3372, - 0x70bf, 0x0008, 0xd2fc, 0x0040, 0x337d, 0x70a4, 0xa005, 0x00c0, - 0x337d, 0x1078, 0x3611, 0x70a7, 0x0001, 0x0078, 0x3390, 0xa005, - 0x00c0, 0x3396, 0x7a38, 0xd2fc, 0x0040, 0x338e, 0x70a4, 0xa005, - 0x00c0, 0x338e, 0x1078, 0x3611, 0x70a7, 0x0001, 0x707f, 0x0000, - 0x7083, 0x0016, 0x1078, 0x339a, 0x0078, 0x3398, 0x707b, 0x0000, - 0x0f7f, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x7c80, - 0x20a1, 0x020b, 0x20a9, 0x000e, 0x53a6, 0x3430, 0x2011, 0x7c8e, - 0x7083, 0x0017, 0x0078, 0x33ae, 0x7083, 0x001b, 0x706c, 0xa005, - 0x00c0, 0x33b8, 0x1078, 0x3486, 0x0040, 0x33c8, 0x0078, 0x33c2, - 0x20a9, 0x0008, 0x2099, 0x7c8e, 0x26a0, 0x53a6, 0x20a3, 0x0000, - 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x3578, 0x0078, 0x33ca, - 0x1078, 0x303e, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x33eb, - 0x2011, 0x3558, 0x1078, 0x4689, 0xa086, 0x0084, 0x00c0, 0x33e9, - 0x2079, 0x7c80, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x33e9, 0x7834, - 0xa005, 0x00c0, 0x33e9, 0x7083, 0x0018, 0x1078, 0x33ed, 0x0078, - 0x33eb, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0019, 0x1078, - 0x35ee, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x3430, 0x2099, 0x7c8e, - 0x2039, 0x7c0e, 0x27a0, 0x20a9, 0x0040, 0x53a3, 0x2728, 0x2514, - 0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007, - 0xa205, 0x202a, 0x6030, 0x2310, 0x8214, 0xa2a0, 0x7c0e, 0x2414, - 0xa38c, 0x0001, 0x0040, 0x3418, 0xa294, 0xff00, 0x0078, 0x341b, - 0xa294, 0x00ff, 0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, - 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, - 0x1078, 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x344f, - 0x2011, 0x3558, 0x1078, 0x4689, 0xa086, 0x0084, 0x00c0, 0x344d, - 0x2079, 0x7c80, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x344d, 0x7834, - 0xa005, 0x00c0, 0x344d, 0x707f, 0x0001, 0x1078, 0x35d4, 0x7083, - 0x001a, 0x1078, 0x3451, 0x0078, 0x344f, 0x707b, 0x0000, 0x0f7f, - 0x007c, 0x7083, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, - 0x7c80, 0x20a1, 0x020b, 0x7478, 0xa480, 0x0018, 0xa080, 0x0007, - 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x1078, - 0x3578, 0x007c, 0x7078, 0xa005, 0x0040, 0x3476, 0x2011, 0x3558, - 0x1078, 0x4689, 0x7083, 0x001c, 0x1078, 0x3477, 0x007c, 0x707b, - 0x0000, 0x608b, 0xbc85, 0x608f, 0xb5b5, 0x6043, 0x0001, 0x2009, - 0x07d0, 0x2011, 0x3558, 0x1078, 0x467c, 0x007c, 0x087e, 0x097e, - 0x2029, 0x7752, 0x252c, 0x20a9, 0x0008, 0x2041, 0x7c0e, 0x28a0, - 0x2099, 0x7c8e, 0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, - 0x0040, 0x349c, 0x2011, 0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, - 0xffff, 0x00c0, 0x34ae, 0xd5d4, 0x0040, 0x34a9, 0x8210, 0x0078, - 0x34aa, 0x8211, 0x00f0, 0x349c, 0x0078, 0x3513, 0x82ff, 0x00c0, - 0x34c0, 0xd5d4, 0x0040, 0x34ba, 0xa1a6, 0x3fff, 0x0040, 0x34a6, - 0x0078, 0x34be, 0xa1a6, 0x3fff, 0x0040, 0x3513, 0xa18d, 0xc000, - 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0040, 0x34c9, 0x2019, - 0x0010, 0x2120, 0xd5d4, 0x0040, 0x34d0, 0x8423, 0x0078, 0x34d1, - 0x8424, 0x00c8, 0x34de, 0xd5d4, 0x0040, 0x34d9, 0x8319, 0x0078, - 0x34da, 0x8318, 0x00f0, 0x34ca, 0x0078, 0x3513, 0x23a8, 0x2021, - 0x0001, 0x8426, 0x8425, 0x00f0, 0x34e2, 0x2328, 0x8529, 0xa2be, - 0x0007, 0x0040, 0x34f6, 0x007e, 0x2039, 0x0007, 0x2200, 0xa73a, - 0x007f, 0x27a8, 0xa5a8, 0x0010, 0x00f0, 0x34f2, 0x754e, 0xa5c8, - 0x2329, 0x292c, 0xa5ac, 0x00ff, 0x6532, 0x60e7, 0x0000, 0x65ea, - 0x2018, 0x2304, 0xa405, 0x201a, 0x706f, 0x0001, 0x26a0, 0x2898, - 0x20a9, 0x0008, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, - 0x0001, 0x0078, 0x3519, 0xa006, 0x0078, 0x3519, 0xa006, 0x1078, - 0x12cd, 0x097f, 0x087f, 0x007c, 0x2118, 0x2021, 0x0000, 0x2001, - 0x0007, 0xa39a, 0x0010, 0x0048, 0x3529, 0x8420, 0x8001, 0x0078, - 0x3521, 0x2118, 0x84ff, 0x0040, 0x3532, 0xa39a, 0x0010, 0x8421, - 0x00c0, 0x352d, 0x2021, 0x0001, 0x83ff, 0x0040, 0x353b, 0x8423, - 0x8319, 0x00c0, 0x3537, 0xa238, 0x2704, 0xa42c, 0x00c0, 0x3550, - 0xa405, 0x203a, 0x714e, 0xa1a0, 0x2329, 0x242c, 0xa5ac, 0x00ff, - 0x6532, 0x60e7, 0x0000, 0x65ea, 0x706f, 0x0001, 0xa084, 0x0000, - 0x007c, 0x0e7e, 0x2071, 0x7700, 0x7073, 0x0000, 0x0e7f, 0x007c, - 0x0e7e, 0x0f7e, 0x2079, 0x0100, 0x2071, 0x0140, 0x1078, 0x569c, - 0x7004, 0xa084, 0x4000, 0x0040, 0x3569, 0x7003, 0x1000, 0x7003, - 0x0000, 0x127e, 0x2091, 0x8000, 0x2071, 0x7720, 0x2073, 0x0000, - 0x7843, 0x0090, 0x7843, 0x0010, 0x127f, 0x0f7f, 0x0e7f, 0x007c, - 0x127e, 0x2091, 0x8000, 0x2011, 0x7940, 0x2013, 0x0000, 0x707b, - 0x0000, 0x127f, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, - 0x1078, 0x5693, 0x2009, 0x07d0, 0x2011, 0x3558, 0x1078, 0x4719, - 0x007c, 0x017e, 0x027e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x2009, - 0x00f7, 0x1078, 0x35fa, 0x2061, 0x7949, 0x601b, 0x0000, 0x601f, - 0x0000, 0x2061, 0x7700, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, - 0x0090, 0x6043, 0x0010, 0x2009, 0x001e, 0x2011, 0x35b6, 0x1078, - 0x467c, 0x127f, 0x0c7f, 0x027f, 0x017f, 0x007c, 0x0e7e, 0x007e, - 0x127e, 0x2091, 0x8000, 0x2071, 0x0100, 0x1078, 0x569c, 0x2071, - 0x0140, 0x7004, 0xa084, 0x4000, 0x0040, 0x35ca, 0x7003, 0x1000, - 0x7003, 0x0000, 0x2001, 0x0001, 0x1078, 0x2025, 0x1078, 0x3591, - 0x127f, 0x007f, 0x0e7f, 0x007c, 0x20a9, 0x0040, 0x20a1, 0x7dc0, - 0x2099, 0x7c8e, 0x3304, 0x8007, 0x20a2, 0x9398, 0x94a0, 0x00f0, - 0x35da, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x7c00, - 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x007c, 0x20e1, 0x9080, - 0x20e1, 0x4000, 0x2099, 0x7c80, 0x20a1, 0x020b, 0x20a9, 0x000c, - 0x53a6, 0x007c, 0x0c7e, 0x007e, 0x2061, 0x0100, 0x810f, 0x2001, - 0x772c, 0x2004, 0xa005, 0x00c0, 0x360b, 0x6030, 0xa084, 0x00ff, - 0xa105, 0x0078, 0x360d, 0xa185, 0x00f7, 0x604a, 0x007f, 0x0c7f, - 0x007c, 0x017e, 0x047e, 0x2001, 0x7752, 0x2004, 0xd0a4, 0x0040, - 0x3624, 0xa006, 0x2020, 0x2009, 0x002a, 0x1078, 0x7641, 0x2001, - 0x770c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x1078, 0x2293, - 0x047f, 0x017f, 0x007c, 0x157e, 0x20a9, 0x00ff, 0x2009, 0x7820, - 0xa006, 0x200a, 0x8108, 0x00f0, 0x3631, 0x157f, 0x007c, 0x0d7e, - 0x037e, 0x157e, 0x137e, 0x147e, 0x2069, 0x7751, 0xa006, 0x6002, - 0x6007, 0x0707, 0x600a, 0x600e, 0x6012, 0xa198, 0x2329, 0x231c, - 0xa39c, 0x00ff, 0x6316, 0x20a9, 0x0004, 0xac98, 0x0006, 0x23a0, - 0x40a4, 0x20a9, 0x0004, 0xac98, 0x000a, 0x23a0, 0x40a4, 0x603e, - 0x6042, 0x604e, 0x6052, 0x6056, 0x605a, 0x605e, 0x6062, 0x6066, - 0x606a, 0x606e, 0x6072, 0x6076, 0x607a, 0x607e, 0x6082, 0x6086, - 0x608a, 0x608e, 0x6092, 0x6096, 0x609a, 0x609e, 0x61a2, 0x0d7e, - 0x60a4, 0xa06d, 0x0040, 0x3676, 0x1078, 0x1340, 0x60a7, 0x0000, - 0x60a8, 0xa06d, 0x0040, 0x367e, 0x1078, 0x1340, 0x60ab, 0x0000, - 0x0d7f, 0xa006, 0x604a, 0x6810, 0x603a, 0x680c, 0x6046, 0x6814, - 0xa084, 0x00ff, 0x6042, 0x147f, 0x137f, 0x157f, 0x037f, 0x0d7f, - 0x007c, 0x127e, 0x2091, 0x8000, 0x6944, 0x6e48, 0xa684, 0x3fff, - 0xa082, 0x4000, 0x00c8, 0x3737, 0xa18c, 0xff00, 0x810f, 0xa182, - 0x00ff, 0x00c8, 0x373d, 0x2001, 0x770c, 0x2004, 0xa084, 0x0003, - 0x00c0, 0x3720, 0xa188, 0x7820, 0x2104, 0xa065, 0x0040, 0x370e, - 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x3714, 0x60a4, - 0xa00d, 0x0040, 0x36bf, 0x1078, 0x3a5c, 0x0040, 0x3708, 0x60a8, - 0xa00d, 0x0040, 0x36d9, 0x1078, 0x3aac, 0x00c0, 0x36d9, 0x694c, - 0xd1fc, 0x00c0, 0x36cf, 0x1078, 0x37d1, 0x0078, 0x3703, 0x1078, - 0x37a2, 0x694c, 0xd1ec, 0x00c0, 0x3703, 0x1078, 0x3931, 0x0078, - 0x3703, 0x694c, 0xa184, 0xa000, 0x0040, 0x36f3, 0xd1ec, 0x0040, - 0x36ec, 0xd1fc, 0x0040, 0x36e8, 0x1078, 0x3942, 0x0078, 0x36ef, - 0x1078, 0x3942, 0x0078, 0x36f3, 0xd1fc, 0x0040, 0x36f3, 0x1078, - 0x37a2, 0x0078, 0x3703, 0x6050, 0xa00d, 0x0040, 0x36fe, 0x2d00, - 0x200a, 0x6803, 0x0000, 0x6052, 0x0078, 0x3703, 0x2d00, 0x6052, - 0x604e, 0x6803, 0x0000, 0x1078, 0x4960, 0xa006, 0x127f, 0x007c, - 0x2001, 0x0005, 0x2009, 0x0000, 0x0078, 0x3741, 0x2001, 0x0028, - 0x2009, 0x0000, 0x0078, 0x3741, 0xa082, 0x0006, 0x00c8, 0x3720, - 0x60a0, 0xd0bc, 0x0040, 0x36b7, 0x2001, 0x0028, 0x0078, 0x3733, - 0x2009, 0x770c, 0x210c, 0xd18c, 0x0040, 0x372a, 0x2001, 0x0004, - 0x0078, 0x3733, 0xd184, 0x0040, 0x3731, 0x2001, 0x0004, 0x0078, - 0x3733, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x3741, 0x2001, - 0x0029, 0x2009, 0x0000, 0x0078, 0x3741, 0x2001, 0x0029, 0x2009, - 0x0000, 0xa005, 0x127f, 0x007c, 0x6944, 0x6e48, 0xa684, 0x3fff, - 0xa082, 0x4000, 0x00c8, 0x3787, 0xa18c, 0xff00, 0x810f, 0xa182, - 0x00ff, 0x00c8, 0x3777, 0xa188, 0x7820, 0x2104, 0xa065, 0x0040, - 0x3777, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x377d, - 0x684c, 0xd0ec, 0x0040, 0x376a, 0x1078, 0x3942, 0x1078, 0x37a2, - 0x0078, 0x3772, 0x1078, 0x37a2, 0x684c, 0xd0fc, 0x0040, 0x3772, - 0x1078, 0x3931, 0x1078, 0x398a, 0xa006, 0x0078, 0x378b, 0x2001, - 0x0028, 0x2009, 0x0000, 0x0078, 0x378b, 0xa082, 0x0006, 0x0048, - 0x3760, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x378b, 0x2001, - 0x0029, 0x2009, 0x0000, 0xa005, 0x007c, 0x127e, 0x2091, 0x8000, - 0x6050, 0xa00d, 0x0040, 0x379b, 0x2d00, 0x200a, 0x6803, 0x0000, - 0x6052, 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, - 0x0078, 0x3799, 0x127e, 0x2091, 0x8000, 0x604c, 0xa005, 0x0040, - 0x37ae, 0x6802, 0x2d00, 0x604e, 0x127f, 0x007c, 0x2d00, 0x6052, - 0x604e, 0x6803, 0x0000, 0x0078, 0x37ac, 0x127e, 0x2091, 0x8000, - 0x604c, 0xa06d, 0x0040, 0x37c3, 0x6800, 0xa005, 0x00c0, 0x37c1, - 0x6052, 0x604e, 0xad05, 0x127f, 0x007c, 0x604c, 0xa06d, 0x0040, - 0x37d0, 0x6800, 0xa005, 0x00c0, 0x37ce, 0x6052, 0x604e, 0xad05, - 0x007c, 0x6803, 0x0000, 0x6084, 0xa00d, 0x0040, 0x37db, 0x2d00, - 0x200a, 0x6086, 0x007c, 0x2d00, 0x6086, 0x6082, 0x0078, 0x37da, - 0x127e, 0x0c7e, 0x027e, 0x2091, 0x8000, 0x6218, 0x2260, 0x6200, - 0xa005, 0x0040, 0x37ee, 0xc285, 0x0078, 0x37ef, 0xc284, 0x6202, - 0x027f, 0x0c7f, 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, - 0x6218, 0x2260, 0x6204, 0xa294, 0xff00, 0xa215, 0x6206, 0x0c7f, - 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260, - 0x6204, 0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x0c7f, 0x127f, - 0x007c, 0x027e, 0xa182, 0x00ff, 0x0048, 0x381a, 0xa085, 0x0001, - 0x0078, 0x3832, 0xa190, 0x7820, 0x2204, 0xa065, 0x00c0, 0x3831, - 0x017e, 0x0d7e, 0x1078, 0x130c, 0x2d60, 0x0d7f, 0x017f, 0x0040, - 0x3816, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab, 0x0000, 0x1078, - 0x3637, 0xa006, 0x027f, 0x007c, 0x027e, 0xa182, 0x00ff, 0x0048, - 0x383d, 0xa085, 0x0001, 0x0078, 0x384a, 0x0d7e, 0xa190, 0x7820, - 0x2204, 0xa06d, 0x0040, 0x3848, 0x2013, 0x0000, 0x1078, 0x1340, - 0x0d7f, 0xa006, 0x027f, 0x007c, 0x017e, 0xa182, 0x00ff, 0x0048, - 0x3855, 0xa085, 0x0001, 0x0078, 0x385c, 0xa188, 0x7820, 0x2104, - 0xa065, 0x0040, 0x3851, 0xa006, 0x017f, 0x007c, 0x0d7e, 0x157e, - 0x137e, 0x147e, 0x600b, 0x0000, 0x600f, 0x0000, 0x6000, 0xc08c, - 0x6002, 0x2069, 0x7c8e, 0x6808, 0x605e, 0x6810, 0x6062, 0x6138, - 0xa10a, 0x0048, 0x3874, 0x603a, 0x6814, 0x6066, 0x2099, 0x7c96, - 0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099, 0x7c9a, - 0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069, 0x7cae, - 0x6808, 0x606a, 0x690c, 0x616e, 0x6810, 0x6072, 0x6818, 0x6076, - 0xa182, 0x0211, 0x00c8, 0x3898, 0x2009, 0x0008, 0x0078, 0x38c2, - 0xa182, 0x0259, 0x00c8, 0x38a0, 0x2009, 0x0007, 0x0078, 0x38c2, - 0xa182, 0x02c1, 0x00c8, 0x38a8, 0x2009, 0x0006, 0x0078, 0x38c2, - 0xa182, 0x0349, 0x00c8, 0x38b0, 0x2009, 0x0005, 0x0078, 0x38c2, - 0xa182, 0x0421, 0x00c8, 0x38b8, 0x2009, 0x0004, 0x0078, 0x38c2, - 0xa182, 0x0581, 0x00c8, 0x38c0, 0x2009, 0x0003, 0x0078, 0x38c2, - 0x2009, 0x0002, 0x6192, 0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c, - 0x0e7e, 0x2071, 0x7c8d, 0x2e04, 0x6896, 0x2071, 0x7c8e, 0x7004, - 0x689a, 0x701c, 0x689e, 0x0e7f, 0x007c, 0x0d7e, 0x127e, 0x2091, - 0x8000, 0x60a4, 0xa06d, 0x0040, 0x38f9, 0x6900, 0x81ff, 0x00c0, - 0x390d, 0x6a04, 0xa282, 0x0010, 0x00c8, 0x3912, 0xad88, 0x0004, - 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0040, 0x38f4, 0x8108, - 0x00f0, 0x38ea, 0x1078, 0x12cd, 0x260a, 0x8210, 0x6a06, 0x0078, - 0x390d, 0x1078, 0x130c, 0x0040, 0x3912, 0x2d00, 0x60a6, 0x6803, + 0x3c5a, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3a0e, 0x2011, + 0x3c35, 0x1078, 0x50f2, 0xa086, 0x0014, 0x00c0, 0x3a0c, 0x2079, + 0x8d80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3a0c, 0x7834, 0xa005, + 0x00c0, 0x3a0c, 0x7a38, 0xd2fc, 0x0040, 0x3a06, 0x70a8, 0xa005, + 0x00c0, 0x3a06, 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x7087, 0x0014, + 0x1078, 0x3a10, 0x0078, 0x3a0e, 0x707f, 0x0000, 0x0f7f, 0x007c, + 0x7087, 0x0015, 0x1078, 0x3cd0, 0x20a3, 0x1104, 0x20a3, 0x0000, + 0x3430, 0x2011, 0x8d8e, 0x1078, 0x3d0d, 0x00c0, 0x3a38, 0x7070, + 0xa005, 0x00c0, 0x3a38, 0x7150, 0xa186, 0xffff, 0x0040, 0x3a38, + 0xa180, 0x25b2, 0x200c, 0xa18c, 0xff00, 0x810f, 0x1078, 0x3bf9, + 0x0040, 0x3a38, 0x1078, 0x3359, 0x0040, 0x3a38, 0x1078, 0x2262, + 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x60c3, 0x0014, 0x1078, 0x3c5a, 0x007c, 0x0f7e, 0x707c, + 0xa005, 0x0040, 0x3a8d, 0x2011, 0x3c35, 0x1078, 0x50f2, 0xa086, + 0x0014, 0x00c0, 0x3a8b, 0x2079, 0x8d80, 0x7a30, 0xa296, 0x1105, + 0x00c0, 0x3a8b, 0x7834, 0x2011, 0x0100, 0xa21e, 0x00c0, 0x3a6e, + 0x7a38, 0xd2fc, 0x0040, 0x3a6c, 0x70a8, 0xa005, 0x00c0, 0x3a6c, + 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x0078, 0x3a7f, 0xa005, 0x00c0, + 0x3a8b, 0x7a38, 0xd2fc, 0x0040, 0x3a7d, 0x70a8, 0xa005, 0x00c0, + 0x3a7d, 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x7083, 0x0000, 0x7a38, + 0xd2f4, 0x0040, 0x3a85, 0x70c3, 0x0008, 0x7087, 0x0016, 0x1078, + 0x3a8f, 0x0078, 0x3a8d, 0x707f, 0x0000, 0x0f7f, 0x007c, 0x20e1, + 0x9080, 0x20e1, 0x4000, 0x2099, 0x8d80, 0x20a1, 0x020b, 0x20a9, + 0x000e, 0x53a6, 0x3430, 0x2011, 0x8d8e, 0x7087, 0x0017, 0x1078, + 0x3d0d, 0x00c0, 0x3aaf, 0x7070, 0xa005, 0x00c0, 0x3aaf, 0x1078, + 0x3b63, 0x00c0, 0x3ab9, 0xa085, 0x0001, 0x1078, 0x2262, 0x20a9, + 0x0008, 0x2099, 0x8d8e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x60c3, 0x0014, 0x1078, 0x3c5a, 0x007c, 0x0f7e, 0x707c, + 0xa005, 0x0040, 0x3ade, 0x2011, 0x3c35, 0x1078, 0x50f2, 0xa086, + 0x0084, 0x00c0, 0x3adc, 0x2079, 0x8d80, 0x7a30, 0xa296, 0x1106, + 0x00c0, 0x3adc, 0x7834, 0xa005, 0x00c0, 0x3adc, 0x7087, 0x0018, + 0x1078, 0x3ae0, 0x0078, 0x3ade, 0x707f, 0x0000, 0x0f7f, 0x007c, + 0x7087, 0x0019, 0x1078, 0x3cd0, 0x20a3, 0x1106, 0x20a3, 0x0000, + 0x3430, 0x2099, 0x8d8e, 0x2039, 0x8d0e, 0x27a0, 0x20a9, 0x0040, + 0x53a3, 0x1078, 0x3d0d, 0x00c0, 0x3b14, 0x2728, 0x2514, 0x8207, + 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007, 0xa205, + 0x202a, 0x6030, 0x2310, 0x8214, 0xa2a0, 0x8d0e, 0x2414, 0xa38c, + 0x0001, 0x0040, 0x3b0f, 0xa294, 0xff00, 0x0078, 0x3b12, 0xa294, + 0x00ff, 0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040, + 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x1078, + 0x3c5a, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3b46, 0x2011, + 0x3c35, 0x1078, 0x50f2, 0xa086, 0x0084, 0x00c0, 0x3b44, 0x2079, + 0x8d80, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x3b44, 0x7834, 0xa005, + 0x00c0, 0x3b44, 0x7083, 0x0001, 0x1078, 0x3cb6, 0x7087, 0x001a, + 0x1078, 0x3b48, 0x0078, 0x3b46, 0x707f, 0x0000, 0x0f7f, 0x007c, + 0x7087, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x8d80, + 0x20a1, 0x020b, 0x747c, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, + 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x1078, 0x3c5a, + 0x007c, 0x007c, 0x007c, 0x087e, 0x097e, 0x2029, 0x8852, 0x252c, + 0x20a9, 0x0008, 0x2041, 0x8d0e, 0x28a0, 0x2099, 0x8d8e, 0x53a3, + 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0040, 0x3b79, 0x2011, + 0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, 0xffff, 0x00c0, 0x3b8b, + 0xd5d4, 0x0040, 0x3b86, 0x8210, 0x0078, 0x3b87, 0x8211, 0x00f0, + 0x3b79, 0x0078, 0x3bf0, 0x82ff, 0x00c0, 0x3b9d, 0xd5d4, 0x0040, + 0x3b97, 0xa1a6, 0x3fff, 0x0040, 0x3b83, 0x0078, 0x3b9b, 0xa1a6, + 0x3fff, 0x0040, 0x3bf0, 0xa18d, 0xc000, 0x20a9, 0x0010, 0x2019, + 0x0001, 0xd5d4, 0x0040, 0x3ba6, 0x2019, 0x0010, 0x2120, 0xd5d4, + 0x0040, 0x3bad, 0x8423, 0x0078, 0x3bae, 0x8424, 0x00c8, 0x3bbb, + 0xd5d4, 0x0040, 0x3bb6, 0x8319, 0x0078, 0x3bb7, 0x8318, 0x00f0, + 0x3ba7, 0x0078, 0x3bf0, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, + 0x00f0, 0x3bbf, 0x2328, 0x8529, 0xa2be, 0x0007, 0x0040, 0x3bd3, + 0x007e, 0x2039, 0x0007, 0x2200, 0xa73a, 0x007f, 0x27a8, 0xa5a8, + 0x0010, 0x00f0, 0x3bcf, 0x754e, 0xa5c8, 0x25b2, 0x292c, 0xa5ac, + 0x00ff, 0x6532, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0xa405, + 0x201a, 0x7073, 0x0001, 0x26a0, 0x2898, 0x20a9, 0x0008, 0x53a6, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, 0x0001, 0x0078, 0x3bf6, + 0xa006, 0x0078, 0x3bf6, 0xa006, 0x1078, 0x12d2, 0x097f, 0x087f, + 0x007c, 0x2118, 0x2021, 0x0000, 0x2001, 0x0007, 0xa39a, 0x0010, + 0x0048, 0x3c06, 0x8420, 0x8001, 0x0078, 0x3bfe, 0x2118, 0x84ff, + 0x0040, 0x3c0f, 0xa39a, 0x0010, 0x8421, 0x00c0, 0x3c0a, 0x2021, + 0x0001, 0x83ff, 0x0040, 0x3c18, 0x8423, 0x8319, 0x00c0, 0x3c14, + 0xa238, 0x2704, 0xa42c, 0x00c0, 0x3c2d, 0xa405, 0x203a, 0x714e, + 0xa1a0, 0x25b2, 0x242c, 0xa5ac, 0x00ff, 0x6532, 0x60e7, 0x0000, + 0x65ea, 0x7073, 0x0001, 0xa084, 0x0000, 0x007c, 0x0e7e, 0x2071, + 0x8800, 0x7077, 0x0000, 0x0e7f, 0x007c, 0x0e7e, 0x0f7e, 0x2079, + 0x0100, 0x2071, 0x0140, 0x1078, 0x6232, 0x7004, 0xa084, 0x4000, + 0x0040, 0x3c46, 0x7003, 0x1000, 0x7003, 0x0000, 0x127e, 0x2091, + 0x8000, 0x2071, 0x8821, 0x2073, 0x0000, 0x7840, 0x027e, 0xa094, + 0x0010, 0xa285, 0x0080, 0x7842, 0x7a42, 0x027f, 0x127f, 0x0f7f, + 0x0e7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x2011, 0x8aac, 0x2013, + 0x0000, 0x707f, 0x0000, 0x127f, 0x20e1, 0x9080, 0x60a3, 0x0056, + 0x60a7, 0x9575, 0x1078, 0x6229, 0x2009, 0x07d0, 0x2011, 0x3c35, + 0x1078, 0x5181, 0x007c, 0x017e, 0x027e, 0x0c7e, 0x127e, 0x2091, + 0x8000, 0x2009, 0x00f7, 0x1078, 0x3cdc, 0x2061, 0x8ab5, 0x601b, + 0x0000, 0x601f, 0x0000, 0x2061, 0x8800, 0x6003, 0x0001, 0x2061, + 0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x001e, 0x2011, + 0x3c98, 0x1078, 0x50e5, 0x127f, 0x0c7f, 0x027f, 0x017f, 0x007c, + 0x0e7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0x0100, 0x1078, + 0x6232, 0x2071, 0x0140, 0x7004, 0xa084, 0x4000, 0x0040, 0x3cac, + 0x7003, 0x1000, 0x7003, 0x0000, 0x2001, 0x0001, 0x1078, 0x21f3, + 0x1078, 0x3c73, 0x127f, 0x007f, 0x0e7f, 0x007c, 0x20a9, 0x0040, + 0x20a1, 0x8ec0, 0x2099, 0x8d8e, 0x3304, 0x8007, 0x20a2, 0x9398, + 0x94a0, 0x00f0, 0x3cbc, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, + 0x2099, 0x8d00, 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x007c, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x8d80, 0x20a1, 0x020b, + 0x20a9, 0x000c, 0x53a6, 0x007c, 0x0c7e, 0x007e, 0x2061, 0x0100, + 0x810f, 0x2001, 0x882d, 0x2004, 0xa005, 0x00c0, 0x3ced, 0x6030, + 0xa084, 0x00ff, 0xa105, 0x0078, 0x3cef, 0xa185, 0x00f7, 0x604a, + 0x007f, 0x0c7f, 0x007c, 0x017e, 0x047e, 0x2001, 0x8852, 0x2004, + 0xd0a4, 0x0040, 0x3d06, 0xa006, 0x2020, 0x2009, 0x002a, 0x1078, + 0x86f5, 0x2001, 0x880c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, + 0x1078, 0x249d, 0x047f, 0x017f, 0x007c, 0x007e, 0x2001, 0x880c, + 0x2004, 0xd09c, 0x0040, 0x3d14, 0x007f, 0x007c, 0x007e, 0x017e, + 0x127e, 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0xa18d, 0x0006, + 0x2102, 0x127f, 0x017f, 0x007f, 0x007c, 0x157e, 0x20a9, 0x00ff, + 0x2009, 0x8934, 0xa006, 0x200a, 0x8108, 0x00f0, 0x3d2b, 0x157f, + 0x007c, 0x0d7e, 0x037e, 0x157e, 0x137e, 0x147e, 0x2069, 0x8851, + 0xa006, 0x6002, 0x6007, 0x0707, 0x600a, 0x600e, 0x6012, 0xa198, + 0x25b2, 0x231c, 0xa39c, 0x00ff, 0x6316, 0x20a9, 0x0004, 0xac98, + 0x0006, 0x23a0, 0x40a4, 0x20a9, 0x0004, 0xac98, 0x000a, 0x23a0, + 0x40a4, 0x603e, 0x6042, 0x604e, 0x6052, 0x6056, 0x605a, 0x605e, + 0x6062, 0x6066, 0x606a, 0x606e, 0x6072, 0x6076, 0x607a, 0x607e, + 0x6082, 0x6086, 0x608a, 0x608e, 0x6092, 0x6096, 0x609a, 0x609e, + 0x61a2, 0x0d7e, 0x60a4, 0xa06d, 0x0040, 0x3d70, 0x1078, 0x1344, + 0x60a7, 0x0000, 0x60a8, 0xa06d, 0x0040, 0x3d78, 0x1078, 0x1344, + 0x60ab, 0x0000, 0x0d7f, 0xa006, 0x604a, 0x6810, 0x603a, 0x680c, + 0x6046, 0x6814, 0xa084, 0x00ff, 0x6042, 0x147f, 0x137f, 0x157f, + 0x037f, 0x0d7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x6944, 0x6e48, + 0xa684, 0x3fff, 0xa082, 0x4000, 0x00c8, 0x3e31, 0xa18c, 0xff00, + 0x810f, 0xa182, 0x00ff, 0x00c8, 0x3e37, 0x2001, 0x880c, 0x2004, + 0xa084, 0x0003, 0x00c0, 0x3e1a, 0xa188, 0x8934, 0x2104, 0xa065, + 0x0040, 0x3e08, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, + 0x3e0e, 0x60a4, 0xa00d, 0x0040, 0x3db9, 0x1078, 0x41b1, 0x0040, + 0x3e02, 0x60a8, 0xa00d, 0x0040, 0x3dd3, 0x1078, 0x4202, 0x00c0, + 0x3dd3, 0x694c, 0xd1fc, 0x00c0, 0x3dc9, 0x1078, 0x3ee2, 0x0078, + 0x3dfd, 0x1078, 0x3e9c, 0x694c, 0xd1ec, 0x00c0, 0x3dfd, 0x1078, + 0x407a, 0x0078, 0x3dfd, 0x694c, 0xa184, 0xa000, 0x0040, 0x3ded, + 0xd1ec, 0x0040, 0x3de6, 0xd1fc, 0x0040, 0x3de2, 0x1078, 0x408b, + 0x0078, 0x3de9, 0x1078, 0x408b, 0x0078, 0x3ded, 0xd1fc, 0x0040, + 0x3ded, 0x1078, 0x3e9c, 0x0078, 0x3dfd, 0x6050, 0xa00d, 0x0040, + 0x3df8, 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x0078, 0x3dfd, + 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x1078, 0x53b8, 0xa006, + 0x127f, 0x007c, 0x2001, 0x0005, 0x2009, 0x0000, 0x0078, 0x3e3b, + 0x2001, 0x0028, 0x2009, 0x0000, 0x0078, 0x3e3b, 0xa082, 0x0006, + 0x00c8, 0x3e1a, 0x60a0, 0xd0bc, 0x0040, 0x3db1, 0x2001, 0x0028, + 0x0078, 0x3e2d, 0x2009, 0x880c, 0x210c, 0xd18c, 0x0040, 0x3e24, + 0x2001, 0x0004, 0x0078, 0x3e2d, 0xd184, 0x0040, 0x3e2b, 0x2001, + 0x0004, 0x0078, 0x3e2d, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, + 0x3e3b, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x3e3b, 0x2001, + 0x0029, 0x2009, 0x0000, 0xa005, 0x127f, 0x007c, 0x6944, 0x6e48, + 0xa684, 0x3fff, 0xa082, 0x4000, 0x00c8, 0x3e81, 0xa18c, 0xff00, + 0x810f, 0xa182, 0x00ff, 0x00c8, 0x3e71, 0xa188, 0x8934, 0x2104, + 0xa065, 0x0040, 0x3e71, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, + 0x00c0, 0x3e77, 0x684c, 0xd0ec, 0x0040, 0x3e64, 0x1078, 0x408b, + 0x1078, 0x3e9c, 0x0078, 0x3e6c, 0x1078, 0x3e9c, 0x684c, 0xd0fc, + 0x0040, 0x3e6c, 0x1078, 0x407a, 0x1078, 0x40d3, 0xa006, 0x0078, + 0x3e85, 0x2001, 0x0028, 0x2009, 0x0000, 0x0078, 0x3e85, 0xa082, + 0x0006, 0x0048, 0x3e5a, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, + 0x3e85, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, 0x007c, 0x127e, + 0x2091, 0x8000, 0x6050, 0xa00d, 0x0040, 0x3e95, 0x2d00, 0x200a, + 0x6803, 0x0000, 0x6052, 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, + 0x6803, 0x0000, 0x0078, 0x3e93, 0x127e, 0x2091, 0x8000, 0x604c, + 0xa005, 0x0040, 0x3eb2, 0x0e7e, 0x2071, 0x8aa2, 0x7004, 0xa086, + 0x0002, 0x0040, 0x3eb9, 0x0e7f, 0x604c, 0x6802, 0x2d00, 0x604e, + 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x0078, + 0x3eb0, 0x701c, 0xac06, 0x00c0, 0x3eab, 0x604c, 0x2070, 0x7000, + 0x6802, 0x2d00, 0x7002, 0x0e7f, 0x127f, 0x007c, 0x127e, 0x2091, + 0x8000, 0x604c, 0xa06d, 0x0040, 0x3ed4, 0x6800, 0xa005, 0x00c0, + 0x3ed2, 0x6052, 0x604e, 0xad05, 0x127f, 0x007c, 0x604c, 0xa06d, + 0x0040, 0x3ee1, 0x6800, 0xa005, 0x00c0, 0x3edf, 0x6052, 0x604e, + 0xad05, 0x007c, 0x6803, 0x0000, 0x6084, 0xa00d, 0x0040, 0x3eec, + 0x2d00, 0x200a, 0x6086, 0x007c, 0x2d00, 0x6086, 0x6082, 0x0078, + 0x3eeb, 0x127e, 0x0c7e, 0x027e, 0x2091, 0x8000, 0x6218, 0x2260, + 0x6200, 0xa005, 0x0040, 0x3eff, 0xc285, 0x0078, 0x3f00, 0xc284, + 0x6202, 0x027f, 0x0c7f, 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, + 0x8000, 0x6218, 0x2260, 0x6204, 0x007e, 0xa086, 0x0006, 0x00c0, + 0x3f24, 0x609c, 0xd0ac, 0x0040, 0x3f24, 0x2001, 0x8852, 0x2004, + 0xd0a4, 0x0040, 0x3f24, 0xa284, 0xff00, 0x8007, 0xa086, 0x0007, + 0x00c0, 0x3f24, 0x6007, 0x0600, 0x007f, 0xa294, 0xff00, 0xa215, + 0x6206, 0x0c7f, 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, + 0x6218, 0x2260, 0x6204, 0x007e, 0xa086, 0x0006, 0x00c0, 0x3f4a, + 0x609c, 0xd0a4, 0x0040, 0x3f4a, 0x2001, 0x8852, 0x2004, 0xd0ac, + 0x00c0, 0x3f4a, 0xa284, 0x00ff, 0xa086, 0x0007, 0x00c0, 0x3f4a, + 0x6007, 0x0006, 0x007f, 0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, + 0x0c7f, 0x127f, 0x007c, 0x027e, 0xa182, 0x00ff, 0x0048, 0x3f5c, + 0xa085, 0x0001, 0x0078, 0x3f74, 0xa190, 0x8934, 0x2204, 0xa065, + 0x00c0, 0x3f73, 0x017e, 0x0d7e, 0x1078, 0x1310, 0x2d60, 0x0d7f, + 0x017f, 0x0040, 0x3f58, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab, + 0x0000, 0x1078, 0x3d31, 0xa006, 0x027f, 0x007c, 0x027e, 0xa182, + 0x00ff, 0x0048, 0x3f7f, 0xa085, 0x0001, 0x0078, 0x3f8c, 0x0d7e, + 0xa190, 0x8934, 0x2204, 0xa06d, 0x0040, 0x3f8a, 0x2013, 0x0000, + 0x1078, 0x1344, 0x0d7f, 0xa006, 0x027f, 0x007c, 0x017e, 0xa182, + 0x00ff, 0x0048, 0x3f97, 0xa085, 0x0001, 0x0078, 0x3f9e, 0xa188, + 0x8934, 0x2104, 0xa065, 0x0040, 0x3f93, 0xa006, 0x017f, 0x007c, + 0x0d7e, 0x157e, 0x137e, 0x147e, 0x600b, 0x0000, 0x600f, 0x0000, + 0x6000, 0xc08c, 0x6002, 0x2069, 0x8d8e, 0x6808, 0x605e, 0x6810, + 0x6062, 0x6138, 0xa10a, 0x0048, 0x3fb6, 0x603a, 0x6814, 0x6066, + 0x2099, 0x8d96, 0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x53a3, + 0x2099, 0x8d9a, 0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x53a3, + 0x2069, 0x8dae, 0x6808, 0x606a, 0x690c, 0x616e, 0x6810, 0x6072, + 0x6818, 0x6076, 0xa182, 0x0211, 0x00c8, 0x3fda, 0x2009, 0x0008, + 0x0078, 0x4004, 0xa182, 0x0259, 0x00c8, 0x3fe2, 0x2009, 0x0007, + 0x0078, 0x4004, 0xa182, 0x02c1, 0x00c8, 0x3fea, 0x2009, 0x0006, + 0x0078, 0x4004, 0xa182, 0x0349, 0x00c8, 0x3ff2, 0x2009, 0x0005, + 0x0078, 0x4004, 0xa182, 0x0421, 0x00c8, 0x3ffa, 0x2009, 0x0004, + 0x0078, 0x4004, 0xa182, 0x0581, 0x00c8, 0x4002, 0x2009, 0x0003, + 0x0078, 0x4004, 0x2009, 0x0002, 0x6192, 0x147f, 0x137f, 0x157f, + 0x0d7f, 0x007c, 0x0e7e, 0x2071, 0x8d8d, 0x2e04, 0x6896, 0x2071, + 0x8d8e, 0x7004, 0x689a, 0x701c, 0x689e, 0x0e7f, 0x007c, 0x0d7e, + 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x0040, 0x403b, 0x6900, + 0x81ff, 0x00c0, 0x404f, 0x6a04, 0xa282, 0x0010, 0x00c8, 0x4054, + 0xad88, 0x0004, 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0040, + 0x4036, 0x8108, 0x00f0, 0x402c, 0x1078, 0x12d2, 0x260a, 0x8210, + 0x6a06, 0x0078, 0x404f, 0x1078, 0x132b, 0x0040, 0x4054, 0x2d00, + 0x60a6, 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, + 0xffff, 0x8108, 0x00f0, 0x4047, 0x6807, 0x0001, 0x6e12, 0xa085, + 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006, 0x0078, 0x4051, 0x127e, + 0x2091, 0x8000, 0x0d7e, 0x60a4, 0xa00d, 0x0040, 0x4077, 0x2168, + 0x6800, 0xa005, 0x00c0, 0x4073, 0x1078, 0x41b1, 0x00c0, 0x4077, + 0x200b, 0xffff, 0x6804, 0xa08a, 0x0002, 0x0048, 0x4073, 0x8001, + 0x6806, 0x0078, 0x4077, 0x1078, 0x1344, 0x60a7, 0x0000, 0x0d7f, + 0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x4217, 0x0078, + 0x4083, 0x1078, 0x3e87, 0x1078, 0x4117, 0x00c0, 0x4081, 0x1078, + 0x40d3, 0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a8, + 0xa06d, 0x0040, 0x40af, 0x6950, 0x81ff, 0x00c0, 0x40c3, 0x6a54, + 0xa282, 0x0010, 0x00c8, 0x40d0, 0xad88, 0x0018, 0x20a9, 0x0010, + 0x2104, 0xa086, 0xffff, 0x0040, 0x40aa, 0x8108, 0x00f0, 0x40a0, + 0x1078, 0x12d2, 0x260a, 0x8210, 0x6a56, 0x0078, 0x40c3, 0x1078, + 0x132b, 0x0040, 0x40d0, 0x2d00, 0x60aa, 0x6853, 0x0000, 0xad88, + 0x0018, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x00f0, 0x40bb, + 0x6857, 0x0001, 0x6e62, 0x0078, 0x40c7, 0x1078, 0x3ee2, 0x1078, + 0x40dd, 0x00c0, 0x40c5, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, + 0xa006, 0x0078, 0x40cd, 0x127e, 0x2091, 0x8000, 0x1078, 0x53b8, + 0x127f, 0x007c, 0xa01e, 0x0078, 0x40df, 0x2019, 0x0001, 0xa00e, + 0x127e, 0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x00c0, + 0x40fd, 0x8dff, 0x0040, 0x4112, 0x83ff, 0x0040, 0x40f5, 0x6848, + 0xa606, 0x0040, 0x4102, 0x0078, 0x40fd, 0x683c, 0xa406, 0x00c0, + 0x40fd, 0x6840, 0xa506, 0x0040, 0x4102, 0x2d08, 0x6800, 0x2068, + 0x0078, 0x40e9, 0x6a00, 0x604c, 0xad06, 0x00c0, 0x410a, 0x624e, + 0x0078, 0x410d, 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0, 0x4112, + 0x6152, 0x8dff, 0x127f, 0x007c, 0xa01e, 0x0078, 0x4119, 0x2019, + 0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x0040, 0x4145, 0x83ff, + 0x0040, 0x4128, 0x6848, 0xa606, 0x0040, 0x4135, 0x0078, 0x4130, + 0x683c, 0xa406, 0x00c0, 0x4130, 0x6840, 0xa506, 0x0040, 0x4135, + 0x2d08, 0x6800, 0x2068, 0x0078, 0x411c, 0x6a00, 0x6080, 0xad06, + 0x00c0, 0x413d, 0x6282, 0x0078, 0x4140, 0xa180, 0x0000, 0x2202, + 0x82ff, 0x00c0, 0x4145, 0x6186, 0x8dff, 0x007c, 0xa016, 0x1078, + 0x41aa, 0x00c0, 0x414d, 0x2011, 0x0001, 0x1078, 0x41fb, 0x00c0, + 0x4153, 0xa295, 0x0002, 0x007c, 0x1078, 0x4233, 0x0040, 0x415c, + 0x1078, 0x78b9, 0x0078, 0x415e, 0xa085, 0x0001, 0x007c, 0x1078, + 0x4233, 0x0040, 0x4167, 0x1078, 0x784f, 0x0078, 0x4169, 0xa085, + 0x0001, 0x007c, 0x1078, 0x4233, 0x0040, 0x4172, 0x1078, 0x7899, + 0x0078, 0x4174, 0xa085, 0x0001, 0x007c, 0x1078, 0x4233, 0x0040, + 0x417d, 0x1078, 0x786b, 0x0078, 0x417f, 0xa085, 0x0001, 0x007c, + 0x1078, 0x4233, 0x0040, 0x4188, 0x1078, 0x78d9, 0x0078, 0x418a, + 0xa085, 0x0001, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x8000, + 0x6080, 0xa06d, 0x0040, 0x41a2, 0x6800, 0x007e, 0x6837, 0x0103, + 0x6b4a, 0x6847, 0x0000, 0x1078, 0x7a46, 0x1078, 0x4376, 0x007f, + 0x0078, 0x4191, 0x6083, 0x0000, 0x6087, 0x0000, 0x0d7f, 0x007f, + 0x127f, 0x007c, 0x60a4, 0xa00d, 0x00c0, 0x41b1, 0xa085, 0x0001, + 0x007c, 0x0e7e, 0x2170, 0x7000, 0xa005, 0x00c0, 0x41c4, 0x20a9, + 0x0010, 0xae88, 0x0004, 0x2104, 0xa606, 0x0040, 0x41c4, 0x8108, + 0x00f0, 0x41bb, 0xa085, 0x0001, 0xa006, 0x0e7f, 0x007c, 0x0d7e, + 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x00c0, 0x41d5, 0x1078, + 0x132b, 0x0040, 0x41e7, 0x2d00, 0x60a6, 0x6803, 0x0001, 0x6807, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, - 0x00f0, 0x3905, 0x6807, 0x0001, 0x6e12, 0xa085, 0x0001, 0x127f, - 0x0d7f, 0x007c, 0xa006, 0x0078, 0x390f, 0x127e, 0x2091, 0x8000, - 0x1078, 0x3a55, 0x00c0, 0x392f, 0x200b, 0xffff, 0x0d7e, 0x60a4, - 0x2068, 0x6804, 0xa08a, 0x0002, 0x0048, 0x392a, 0x8001, 0x6806, - 0x0078, 0x392e, 0x1078, 0x1340, 0x60a7, 0x0000, 0x0d7f, 0x127f, - 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x3ac1, 0x0078, 0x393a, - 0x1078, 0x378d, 0x1078, 0x39ce, 0x00c0, 0x3938, 0x1078, 0x398a, - 0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a8, 0xa06d, - 0x0040, 0x3966, 0x6950, 0x81ff, 0x00c0, 0x397a, 0x6a54, 0xa282, - 0x0010, 0x00c8, 0x3987, 0xad88, 0x0018, 0x20a9, 0x0010, 0x2104, - 0xa086, 0xffff, 0x0040, 0x3961, 0x8108, 0x00f0, 0x3957, 0x1078, - 0x12cd, 0x260a, 0x8210, 0x6a56, 0x0078, 0x397a, 0x1078, 0x130c, - 0x0040, 0x3987, 0x2d00, 0x60aa, 0x6853, 0x0000, 0xad88, 0x0018, - 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x00f0, 0x3972, 0x6857, - 0x0001, 0x6e62, 0x0078, 0x397e, 0x1078, 0x37d1, 0x1078, 0x3994, - 0x00c0, 0x397c, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006, - 0x0078, 0x3984, 0x127e, 0x2091, 0x8000, 0x1078, 0x4960, 0x127f, - 0x007c, 0xa01e, 0x0078, 0x3996, 0x2019, 0x0001, 0xa00e, 0x127e, - 0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x00c0, 0x39b4, - 0x8dff, 0x0040, 0x39c9, 0x83ff, 0x0040, 0x39ac, 0x6848, 0xa606, - 0x0040, 0x39b9, 0x0078, 0x39b4, 0x683c, 0xa406, 0x00c0, 0x39b4, - 0x6840, 0xa506, 0x0040, 0x39b9, 0x2d08, 0x6800, 0x2068, 0x0078, - 0x39a0, 0x6a00, 0x604c, 0xad06, 0x00c0, 0x39c1, 0x624e, 0x0078, - 0x39c4, 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0, 0x39c9, 0x6152, - 0x8dff, 0x127f, 0x007c, 0xa01e, 0x0078, 0x39d0, 0x2019, 0x0001, - 0xa00e, 0x6080, 0x2068, 0x8dff, 0x0040, 0x39fc, 0x83ff, 0x0040, - 0x39df, 0x6848, 0xa606, 0x0040, 0x39ec, 0x0078, 0x39e7, 0x683c, - 0xa406, 0x00c0, 0x39e7, 0x6840, 0xa506, 0x0040, 0x39ec, 0x2d08, - 0x6800, 0x2068, 0x0078, 0x39d3, 0x6a00, 0x6080, 0xad06, 0x00c0, - 0x39f4, 0x6282, 0x0078, 0x39f7, 0xa180, 0x0000, 0x2202, 0x82ff, - 0x00c0, 0x39fc, 0x6186, 0x8dff, 0x007c, 0x1078, 0x3a55, 0x00c0, - 0x3a03, 0x2011, 0x0001, 0x1078, 0x3aa5, 0x00c0, 0x3a09, 0xa295, - 0x0002, 0x007c, 0x1078, 0x3add, 0x0040, 0x3a12, 0x1078, 0x6b2b, - 0x0078, 0x3a14, 0xa085, 0x0001, 0x007c, 0x1078, 0x3add, 0x0040, - 0x3a1d, 0x1078, 0x6aba, 0x0078, 0x3a1f, 0xa085, 0x0001, 0x007c, - 0x1078, 0x3add, 0x0040, 0x3a28, 0x1078, 0x6b00, 0x0078, 0x3a2a, - 0xa085, 0x0001, 0x007c, 0x1078, 0x3add, 0x0040, 0x3a33, 0x1078, - 0x6ad6, 0x0078, 0x3a35, 0xa085, 0x0001, 0x007c, 0x127e, 0x007e, - 0x0d7e, 0x2091, 0x8000, 0x6080, 0xa06d, 0x0040, 0x3a4d, 0x6800, - 0x007e, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x6c54, - 0x1078, 0x3b92, 0x007f, 0x0078, 0x3a3c, 0x6083, 0x0000, 0x6087, - 0x0000, 0x0d7f, 0x007f, 0x127f, 0x007c, 0x60a4, 0xa00d, 0x00c0, - 0x3a5c, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x2170, 0x7000, 0xa005, - 0x00c0, 0x3a6f, 0x20a9, 0x0010, 0xae88, 0x0004, 0x2104, 0xa606, - 0x0040, 0x3a6f, 0x8108, 0x00f0, 0x3a66, 0xa085, 0x0001, 0x0e7f, - 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x00c0, - 0x3a7f, 0x1078, 0x130c, 0x0040, 0x3a91, 0x2d00, 0x60a6, 0x6803, - 0x0001, 0x6807, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, - 0xffff, 0x8108, 0x00f0, 0x3a87, 0xa085, 0x0001, 0x127f, 0x0d7f, - 0x007c, 0xa006, 0x0078, 0x3a8e, 0x0d7e, 0x127e, 0x2091, 0x8000, - 0x60a4, 0xa06d, 0x0040, 0x3aa2, 0x60a7, 0x0000, 0x1078, 0x1340, - 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, 0x60a8, 0xa00d, 0x00c0, - 0x3aac, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x2170, 0x7050, 0xa005, - 0x00c0, 0x3abf, 0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, - 0x0040, 0x3abf, 0x8108, 0x00f0, 0x3ab6, 0xa085, 0x0001, 0x0e7f, - 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x3aa5, 0x00c0, 0x3adb, - 0x200b, 0xffff, 0x0d7e, 0x60a8, 0x2068, 0x6854, 0xa08a, 0x0002, - 0x0048, 0x3ad6, 0x8001, 0x6856, 0x0078, 0x3ada, 0x1078, 0x1340, - 0x60ab, 0x0000, 0x0d7f, 0x127f, 0x007c, 0x609c, 0xd0a4, 0x007c, - 0x0f7e, 0x2079, 0x7751, 0x7804, 0xd0a4, 0x0040, 0x3b09, 0x157e, - 0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x384c, - 0x00c0, 0x3afd, 0x6004, 0xa084, 0xff00, 0x8007, 0xa086, 0x0006, - 0x00c0, 0x3afd, 0x6000, 0xc0ed, 0x6002, 0x017f, 0x8108, 0x00f0, - 0x3aed, 0x0c7f, 0x157f, 0x2009, 0x07d0, 0x2011, 0x3b0b, 0x1078, - 0x4719, 0x0f7f, 0x007c, 0x2011, 0x3b0b, 0x1078, 0x4689, 0x157e, - 0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x384c, - 0x00c0, 0x3b37, 0x6000, 0xd0ec, 0x0040, 0x3b37, 0x047e, 0x62a0, - 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x1078, 0x7641, - 0x6000, 0xc0e5, 0xc0ec, 0x6002, 0x2019, 0x0029, 0x1078, 0x4a7e, - 0x1078, 0x49c1, 0x2009, 0x0000, 0x1078, 0x747b, 0x047f, 0x017f, - 0x8108, 0x00f0, 0x3b15, 0x0c7f, 0x157f, 0x007c, 0x0c7e, 0x6018, - 0x2060, 0x6000, 0xc0ec, 0x6002, 0x0c7f, 0x007c, 0x2071, 0x77ff, - 0x7003, 0x0001, 0x7007, 0x0000, 0x7013, 0x0000, 0x7017, 0x0000, - 0x701b, 0x0000, 0x701f, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000, - 0x705b, 0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x007c, 0x0e7e, - 0x2071, 0x77ff, 0x684c, 0xa005, 0x00c0, 0x3b6d, 0x7028, 0xc085, - 0x702a, 0xa085, 0x0001, 0x0078, 0x3b90, 0x6a60, 0x7236, 0x6b64, - 0x733a, 0x6868, 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c, - 0x702e, 0x6844, 0x7032, 0x2009, 0x000d, 0x200a, 0x8007, 0x8006, - 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, - 0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0xa006, - 0x0e7f, 0x007c, 0x0e7e, 0x6838, 0xd0fc, 0x00c0, 0x3be3, 0x6804, - 0xa00d, 0x0040, 0x3bb1, 0x0d7e, 0x0e7e, 0x2071, 0x7700, 0x027e, - 0xa016, 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, - 0x00c0, 0x3ba2, 0x702e, 0x70a0, 0xa200, 0x70a2, 0x027f, 0x0e7f, - 0x0d7f, 0x2071, 0x77ff, 0x701c, 0xa005, 0x00c0, 0x3bf4, 0x0068, - 0x3bf2, 0x2071, 0x7751, 0x7004, 0xd09c, 0x0040, 0x3bf2, 0x6934, - 0xa186, 0x0103, 0x00c0, 0x3c05, 0x6948, 0x6844, 0xa105, 0x00c0, - 0x3be5, 0x2009, 0x8020, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, - 0x3bf2, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, - 0x2091, 0x4080, 0x2071, 0x7700, 0x702c, 0x206a, 0x2d00, 0x702e, - 0x70a0, 0x8000, 0x70a2, 0x0e7f, 0x007c, 0x6844, 0xa086, 0x0100, - 0x00c0, 0x3bf2, 0x6868, 0xa005, 0x00c0, 0x3bf2, 0x2009, 0x8020, - 0x0078, 0x3bcb, 0x2071, 0x77ff, 0x2d08, 0x206b, 0x0000, 0x7010, - 0x8000, 0x7012, 0x7018, 0xa06d, 0x711a, 0x0040, 0x3c02, 0x6902, - 0x0078, 0x3c03, 0x711e, 0x0078, 0x3be3, 0xa18c, 0x00ff, 0xa186, - 0x0017, 0x0040, 0x3c13, 0xa186, 0x001e, 0x0040, 0x3c13, 0xa18e, - 0x001f, 0x00c0, 0x3bf2, 0x684c, 0xd0cc, 0x0040, 0x3bf2, 0x6850, - 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0, 0x3bf2, 0x2009, 0x8021, - 0x0078, 0x3bcb, 0x007e, 0x6837, 0x0103, 0x20a9, 0x001c, 0xad80, - 0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x007f, 0x684a, 0x6952, - 0x007c, 0x2071, 0x77ff, 0x7004, 0x0079, 0x3c36, 0x3c3e, 0x3c4d, - 0x3cdd, 0x3cde, 0x3cee, 0x3cf4, 0x3c3f, 0x3ccb, 0x007c, 0x127e, - 0x2091, 0x8000, 0x0068, 0x3c4c, 0x2009, 0x000d, 0x7030, 0x200a, - 0x2091, 0x4080, 0x7007, 0x0001, 0x127f, 0x701c, 0xa06d, 0x0040, - 0x3cca, 0x0e7e, 0x2071, 0x7751, 0x7004, 0xd09c, 0x0040, 0x3cac, - 0x6934, 0xa186, 0x0103, 0x00c0, 0x3c82, 0x6948, 0x6844, 0xa105, - 0x00c0, 0x3c9f, 0x2009, 0x8020, 0x127e, 0x2091, 0x8000, 0x0068, - 0x3c7e, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x3c7e, 0x7122, - 0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, - 0x127f, 0x0e7f, 0x1078, 0x3d27, 0x0078, 0x3cca, 0x127f, 0x0e7f, - 0x0078, 0x3cca, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0040, 0x3c90, - 0xa186, 0x001e, 0x0040, 0x3c90, 0xa18e, 0x001f, 0x00c0, 0x3cac, - 0x684c, 0xd0cc, 0x0040, 0x3cac, 0x6850, 0xa084, 0x00ff, 0xa086, - 0x0001, 0x00c0, 0x3cac, 0x2009, 0x8021, 0x0078, 0x3c64, 0x6844, - 0xa086, 0x0100, 0x00c0, 0x3cac, 0x6868, 0xa005, 0x00c0, 0x3cac, - 0x2009, 0x8020, 0x0078, 0x3c64, 0x0e7f, 0x1078, 0x3d3b, 0x0040, - 0x3cca, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003, - 0x00c0, 0x3cc1, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0040, 0x3cc1, - 0x710e, 0x7007, 0x0003, 0x1078, 0x3d5b, 0x7050, 0xa086, 0x0100, - 0x0040, 0x3cde, 0x007c, 0x701c, 0xa06d, 0x0040, 0x3cdc, 0x1078, - 0x3d3b, 0x0040, 0x3cdc, 0x7007, 0x0003, 0x1078, 0x3d5b, 0x7050, - 0xa086, 0x0100, 0x0040, 0x3cde, 0x007c, 0x007c, 0x7050, 0xa09e, - 0x0100, 0x00c0, 0x3ce7, 0x7007, 0x0004, 0x0078, 0x3cee, 0xa086, - 0x0200, 0x00c0, 0x3ced, 0x7007, 0x0005, 0x007c, 0x1078, 0x3cf5, - 0x7006, 0x1078, 0x3d27, 0x007c, 0x007c, 0x702c, 0x7130, 0x8108, - 0xa102, 0x0048, 0x3d02, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, - 0x0078, 0x3d0c, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x3d0c, - 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x700c, 0x8001, 0x700e, - 0x00c0, 0x3d20, 0x127e, 0x2091, 0x8000, 0x0068, 0x3d23, 0x2001, - 0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x127f, 0x007c, - 0x2001, 0x0007, 0x007c, 0x2001, 0x0006, 0x127f, 0x007c, 0x701c, - 0xa06d, 0x0040, 0x3d3a, 0x127e, 0x2091, 0x8000, 0x7010, 0x8001, - 0x7012, 0x2d04, 0x701e, 0xa005, 0x00c0, 0x3d37, 0x701a, 0x127f, - 0x1078, 0x1340, 0x007c, 0x2019, 0x000d, 0x2304, 0x230c, 0xa10e, - 0x0040, 0x3d4a, 0x2304, 0x230c, 0xa10e, 0x0040, 0x3d4a, 0xa006, - 0x0078, 0x3d5a, 0x732c, 0x8319, 0x7130, 0xa102, 0x00c0, 0x3d54, - 0x2300, 0xa005, 0x0078, 0x3d5a, 0x0048, 0x3d59, 0xa302, 0x0078, - 0x3d5a, 0x8002, 0x007c, 0x2d00, 0x7026, 0xa080, 0x000d, 0x7056, - 0x7053, 0x0000, 0x127e, 0x2091, 0x8000, 0x2009, 0x7959, 0x2104, - 0xc08d, 0x200a, 0x127f, 0x1078, 0x1391, 0x007c, 0x2071, 0x77cd, - 0x7003, 0x0000, 0x7007, 0x0000, 0x700f, 0x0000, 0x702b, 0x0001, - 0x704f, 0x0000, 0x7053, 0x0001, 0x705f, 0x0020, 0x7063, 0x0040, - 0x7083, 0x0000, 0x708b, 0x0000, 0x708f, 0x0001, 0x70bf, 0x0000, - 0x007c, 0x0e7e, 0x2071, 0x77cd, 0x6848, 0xa005, 0x00c0, 0x3d97, - 0x7028, 0xc085, 0x702a, 0xa085, 0x0001, 0x0078, 0x3dbc, 0x6a50, - 0x7236, 0x6b54, 0x733a, 0x6858, 0x703e, 0x707a, 0x685c, 0x7042, - 0x707e, 0x6848, 0x702e, 0x6840, 0x7032, 0x2009, 0x000c, 0x200a, - 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, - 0x2100, 0xa319, 0x7272, 0x7376, 0x7028, 0xc084, 0x702a, 0x7007, - 0x0001, 0x700f, 0x0000, 0xa006, 0x0e7f, 0x007c, 0x2b78, 0x2071, - 0x77cd, 0x7004, 0x1079, 0x3e1c, 0x700c, 0x0079, 0x3dc7, 0x3dcc, - 0x3dc1, 0x3dc1, 0x3dc1, 0x3dc1, 0x007c, 0x700c, 0x0079, 0x3dd0, - 0x3dd5, 0x3e1a, 0x3e1a, 0x3e1b, 0x3e1b, 0x7830, 0x7930, 0xa106, - 0x0040, 0x3ddf, 0x7830, 0x7930, 0xa106, 0x00c0, 0x3e05, 0x7030, - 0xa10a, 0x0040, 0x3e05, 0x00c8, 0x3de7, 0x712c, 0xa10a, 0xa18a, - 0x0002, 0x00c8, 0x3e06, 0x1078, 0x130c, 0x0040, 0x3e05, 0x2d00, - 0x705a, 0x7063, 0x0040, 0x2001, 0x0003, 0x7057, 0x0000, 0x127e, - 0x007e, 0x2091, 0x8000, 0x2009, 0x7959, 0x2104, 0xc085, 0x200a, - 0x007f, 0x700e, 0x127f, 0x1078, 0x1391, 0x007c, 0x1078, 0x130c, - 0x0040, 0x3e05, 0x2d00, 0x705a, 0x1078, 0x130c, 0x00c0, 0x3e12, - 0x0078, 0x3df1, 0x2d00, 0x7086, 0x7063, 0x0080, 0x2001, 0x0004, - 0x0078, 0x3df5, 0x007c, 0x007c, 0x3e2d, 0x3e2e, 0x3e65, 0x3e66, - 0x3e1a, 0x3e9c, 0x3ea1, 0x3ed8, 0x3ed9, 0x3ef4, 0x3ef5, 0x3ef6, - 0x3ef7, 0x3ef8, 0x3ef9, 0x3f62, 0x3f8c, 0x007c, 0x700c, 0x0079, - 0x3e31, 0x3e36, 0x3e39, 0x3e49, 0x3e64, 0x3e64, 0x1078, 0x3dcd, - 0x007c, 0x127e, 0x8001, 0x700e, 0x7058, 0x007e, 0x1078, 0x426e, - 0x0040, 0x3e46, 0x2091, 0x8000, 0x1078, 0x3dcd, 0x0d7f, 0x0078, - 0x3e52, 0x127e, 0x8001, 0x700e, 0x1078, 0x426e, 0x7058, 0x2068, - 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, - 0x00ff, 0xa08a, 0x0020, 0x00c8, 0x3e61, 0x1079, 0x3e7c, 0x127f, - 0x007c, 0x127f, 0x1078, 0x3efa, 0x007c, 0x007c, 0x007c, 0x0e7e, - 0x2071, 0x77cd, 0x700c, 0x0079, 0x3e6d, 0x3e72, 0x3e72, 0x3e72, - 0x3e74, 0x3e78, 0x0e7f, 0x007c, 0x700f, 0x0001, 0x0078, 0x3e7a, - 0x700f, 0x0002, 0x0e7f, 0x007c, 0x3efa, 0x3efa, 0x3f16, 0x3efa, - 0x4001, 0x3efa, 0x3efa, 0x3efa, 0x3efa, 0x3efa, 0x3f16, 0x4040, - 0x408a, 0x40e3, 0x40f7, 0x3efa, 0x3efa, 0x3f32, 0x3f16, 0x3efa, - 0x3efa, 0x3f48, 0x4182, 0x41a0, 0x3efa, 0x3f32, 0x3efa, 0x3efa, - 0x3efa, 0x3efa, 0x3f48, 0x41a0, 0x7020, 0x2068, 0x1078, 0x1340, - 0x007c, 0x700c, 0x0079, 0x3ea4, 0x3ea9, 0x3eac, 0x3ebc, 0x3ed7, - 0x3ed7, 0x1078, 0x3dcd, 0x007c, 0x127e, 0x8001, 0x700e, 0x7058, - 0x007e, 0x1078, 0x426e, 0x0040, 0x3eb9, 0x2091, 0x8000, 0x1078, - 0x3dcd, 0x0d7f, 0x0078, 0x3ec5, 0x127e, 0x8001, 0x700e, 0x1078, - 0x426e, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, - 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x001a, 0x00c8, 0x3ed4, - 0x1079, 0x3eda, 0x127f, 0x007c, 0x127f, 0x1078, 0x3efa, 0x007c, - 0x007c, 0x007c, 0x3efa, 0x3f16, 0x3feb, 0x3efa, 0x3f16, 0x3efa, - 0x3f16, 0x3f16, 0x3efa, 0x3f16, 0x3feb, 0x3f16, 0x3f16, 0x3f16, - 0x3f16, 0x3f16, 0x3efa, 0x3f16, 0x3feb, 0x3efa, 0x3efa, 0x3f16, - 0x3efa, 0x3efa, 0x3efa, 0x3f16, 0x007c, 0x007c, 0x007c, 0x007c, - 0x007c, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0d5, - 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x3b92, 0x127f, 0x007c, - 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0e5, 0x683a, 0x127e, - 0x2091, 0x8000, 0x1078, 0x3b92, 0x127f, 0x007c, 0x7007, 0x0001, - 0x6838, 0xa084, 0x00ff, 0xc0ed, 0x683a, 0x127e, 0x2091, 0x8000, - 0x1078, 0x3b92, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, - 0x00ff, 0xc0dd, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x3b92, - 0x127f, 0x007c, 0x6834, 0x8007, 0xa084, 0x00ff, 0x0040, 0x3f08, - 0x8001, 0x00c0, 0x3f3f, 0x7007, 0x0001, 0x0078, 0x3fc8, 0x7007, - 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x3fc8, 0x007c, - 0x2d00, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, - 0x20a1, 0x77f8, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x00c8, - 0x3f24, 0x6884, 0xa08a, 0x0003, 0x00c8, 0x3f24, 0xa080, 0x3fb9, - 0x2004, 0x70c6, 0x7010, 0xa015, 0x0040, 0x3fac, 0x1078, 0x130c, - 0x00c0, 0x3f6d, 0x7007, 0x000f, 0x007c, 0x2d00, 0x7022, 0x70c4, - 0x2060, 0x6000, 0x6836, 0x6004, 0xad00, 0x7096, 0x6008, 0xa20a, - 0x00c8, 0x3f7c, 0xa00e, 0x2200, 0x7112, 0x620c, 0x8003, 0x800b, - 0xa296, 0x0004, 0x0040, 0x3f85, 0xa108, 0x719a, 0x810b, 0x719e, - 0xae90, 0x0022, 0x1078, 0x1377, 0x7090, 0xa08e, 0x0100, 0x0040, - 0x3fa0, 0xa086, 0x0200, 0x0040, 0x3f98, 0x7007, 0x0010, 0x007c, - 0x7020, 0x2068, 0x1078, 0x1340, 0x7014, 0x2068, 0x0078, 0x3f24, - 0x7020, 0x2068, 0x7018, 0x6802, 0x6807, 0x0000, 0x2d08, 0x2068, - 0x6906, 0x711a, 0x0078, 0x3f62, 0x7014, 0x2068, 0x7007, 0x0001, - 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x0040, 0x41bd, 0x0078, - 0x3fc8, 0x3fbc, 0x3fc0, 0x3fc4, 0x0002, 0x0011, 0x0007, 0x0004, - 0x000a, 0x000f, 0x0005, 0x0006, 0x0012, 0x000f, 0x0005, 0x0006, - 0x2009, 0x772c, 0x210c, 0x81ff, 0x00c0, 0x3fe5, 0x6838, 0xa084, - 0x00ff, 0x683a, 0x6853, 0x0000, 0x1078, 0x3691, 0x00c0, 0x3fd9, - 0x007c, 0x1078, 0x3c22, 0x127e, 0x2091, 0x8000, 0x1078, 0x6c54, - 0x1078, 0x3b92, 0x127f, 0x0078, 0x3fd8, 0x2001, 0x0028, 0x2009, - 0x0000, 0x0078, 0x3fd9, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906, - 0x711a, 0x7010, 0x8001, 0x7012, 0x0040, 0x3ffa, 0x7007, 0x0006, - 0x0078, 0x4000, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x107a, - 0x007c, 0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848, - 0xa084, 0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x0040, 0x402a, - 0x2009, 0x0000, 0x20a9, 0x007e, 0xa096, 0x0002, 0x0040, 0x402a, - 0xa005, 0x00c0, 0x403d, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x1078, - 0x384c, 0x00c0, 0x403d, 0x067e, 0x6e50, 0x1078, 0x3915, 0x067f, - 0x0078, 0x403d, 0x047e, 0x2011, 0x770c, 0x2224, 0xc484, 0xc48c, - 0x2412, 0x047f, 0x0c7e, 0x1078, 0x384c, 0x00c0, 0x4039, 0x1078, - 0x3a94, 0x8108, 0x00f0, 0x4033, 0x0c7f, 0x1078, 0x1340, 0x007c, - 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0x7752, 0x2004, - 0xd0a4, 0x0040, 0x4081, 0x2009, 0x0000, 0x1078, 0x428a, 0x6100, - 0xd184, 0x0040, 0x4066, 0x6858, 0xa084, 0x00ff, 0x00c0, 0x4084, - 0x6000, 0xd084, 0x0040, 0x4081, 0x6004, 0xa005, 0x00c0, 0x4087, - 0x6003, 0x0000, 0x600b, 0x0000, 0x0078, 0x407e, 0x2011, 0x0001, - 0x6860, 0xa005, 0x00c0, 0x406e, 0x2001, 0x001e, 0x8000, 0x6016, - 0x6858, 0xa084, 0x00ff, 0x0040, 0x4081, 0x6006, 0x6858, 0x8007, - 0xa084, 0x00ff, 0x0040, 0x4081, 0x600a, 0x6202, 0x127f, 0x0078, - 0x425d, 0x127f, 0x0078, 0x4255, 0x127f, 0x0078, 0x424d, 0x127f, - 0x0078, 0x4251, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, - 0x7752, 0x2004, 0xd0a4, 0x0040, 0x40e0, 0x2009, 0x0000, 0x1078, - 0x428a, 0x6000, 0xa084, 0x0001, 0x0040, 0x40e0, 0x6204, 0x6308, - 0x6c48, 0xa484, 0x0003, 0x0040, 0x40b8, 0x6958, 0xa18c, 0x00ff, - 0x8001, 0x00c0, 0x40b1, 0x2100, 0xa210, 0x0048, 0x40dd, 0x0078, - 0x40b8, 0x8001, 0x00c0, 0x40dd, 0x2100, 0xa212, 0x0048, 0x40dd, - 0xa484, 0x000c, 0x0040, 0x40d2, 0x6958, 0x810f, 0xa18c, 0x00ff, - 0xa082, 0x0004, 0x00c0, 0x40ca, 0x2100, 0xa318, 0x0048, 0x40dd, - 0x0078, 0x40d2, 0xa082, 0x0004, 0x00c0, 0x40dd, 0x2100, 0xa31a, - 0x0048, 0x40dd, 0x6860, 0xa005, 0x0040, 0x40d8, 0x8000, 0x6016, - 0x6206, 0x630a, 0x127f, 0x0078, 0x425d, 0x127f, 0x0078, 0x4259, - 0x127f, 0x0078, 0x4255, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, - 0x2009, 0x0000, 0x1078, 0x428a, 0x6308, 0x8318, 0x0048, 0x40f4, - 0x630a, 0x127f, 0x0078, 0x426b, 0x127f, 0x0078, 0x4259, 0x127e, - 0x0c7e, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0040, - 0x410d, 0x2009, 0x0000, 0x0c7e, 0x1078, 0x4727, 0x6000, 0x2001, - 0xfcff, 0x6002, 0x0c7f, 0x0078, 0x4144, 0x6858, 0xa005, 0x0040, - 0x4159, 0x685c, 0xa065, 0x0040, 0x4155, 0x2001, 0x772c, 0x2004, - 0xa005, 0x0040, 0x411f, 0x1078, 0x6bb6, 0x0078, 0x4125, 0x6013, - 0x0400, 0x2009, 0x0041, 0x1078, 0x5d41, 0x6958, 0xa18c, 0xe600, - 0xa186, 0x2000, 0x0040, 0x413c, 0xa186, 0x0400, 0x0040, 0x413c, - 0x2009, 0x0000, 0x0c7e, 0x1078, 0x4727, 0x6000, 0xa084, 0xfdff, - 0x6002, 0x0c7f, 0x0078, 0x4144, 0x027e, 0x2009, 0x0000, 0x2011, - 0xfdff, 0x1078, 0x47d0, 0x027f, 0x684c, 0xd0c4, 0x0040, 0x4151, - 0x2009, 0x0000, 0x1078, 0x4727, 0x6008, 0x8000, 0x0048, 0x4151, - 0x600a, 0x0c7f, 0x127f, 0x0078, 0x425d, 0x0c7f, 0x127f, 0x0078, - 0x4255, 0x6954, 0xa186, 0x002a, 0x00c0, 0x4165, 0x2001, 0x770c, - 0x200c, 0xc194, 0x2102, 0x0078, 0x4144, 0xa186, 0x0020, 0x0040, - 0x417a, 0xa186, 0x0029, 0x00c0, 0x4155, 0x6944, 0xa18c, 0xff00, - 0x810f, 0x1078, 0x384c, 0x00c0, 0x4144, 0x6000, 0xc0e4, 0x6002, - 0x0078, 0x4144, 0x685c, 0xa065, 0x0040, 0x4155, 0x6017, 0x0014, - 0x0078, 0x4144, 0x2009, 0x0000, 0x1078, 0x428a, 0x6000, 0xa084, - 0x0001, 0x0040, 0x419c, 0x2091, 0x8000, 0x6204, 0x8210, 0x0048, - 0x4196, 0x6206, 0x2091, 0x8001, 0x0078, 0x426b, 0x2091, 0x8001, - 0x6853, 0x0016, 0x0078, 0x4264, 0x6853, 0x0007, 0x0078, 0x4264, - 0x6834, 0x8007, 0xa084, 0x00ff, 0x00c0, 0x41aa, 0x1078, 0x3f08, - 0x0078, 0x41bc, 0x2030, 0x8001, 0x00c0, 0x41b4, 0x7007, 0x0001, - 0x1078, 0x41bd, 0x0078, 0x41bc, 0x7007, 0x0006, 0x7012, 0x2d00, - 0x7016, 0x701a, 0x704b, 0x41bd, 0x007c, 0x0e7e, 0x2009, 0x772c, - 0x210c, 0x81ff, 0x00c0, 0x423f, 0x2009, 0x770c, 0x210c, 0xd194, - 0x00c0, 0x4249, 0x6848, 0x2070, 0xae82, 0x7e00, 0x0048, 0x422e, - 0x2001, 0x7715, 0x2004, 0xae02, 0x00c8, 0x422e, 0x2009, 0x0000, - 0x1078, 0x428a, 0x6100, 0xa184, 0x0001, 0x0040, 0x4214, 0xa184, - 0x0100, 0x00c0, 0x4232, 0xa184, 0x0200, 0x00c0, 0x4236, 0x601c, - 0xa005, 0x00c0, 0x423a, 0x711c, 0xa186, 0x0006, 0x00c0, 0x4219, - 0x6853, 0x0000, 0x6803, 0x0000, 0x2d08, 0x127e, 0x2091, 0x8000, - 0x7010, 0xa005, 0x00c0, 0x420b, 0x7112, 0x7018, 0xa065, 0x0040, - 0x423e, 0x6000, 0xd0e4, 0x00c0, 0x4243, 0x2e60, 0x1078, 0x4730, - 0x127f, 0x0e7f, 0x007c, 0x2068, 0x6800, 0xa005, 0x00c0, 0x420b, - 0x6902, 0x127f, 0x0e7f, 0x007c, 0x0e7f, 0x6853, 0x0006, 0x0078, - 0x4264, 0x6944, 0xa18c, 0xff00, 0x810f, 0x1078, 0x384c, 0x00c0, - 0x4244, 0x6000, 0xd0e4, 0x00c0, 0x4244, 0x711c, 0xa186, 0x0007, - 0x00c0, 0x422e, 0x6853, 0x0002, 0x0078, 0x4246, 0x6853, 0x0008, - 0x0078, 0x4246, 0x6853, 0x000e, 0x0078, 0x4246, 0x6853, 0x0017, - 0x0078, 0x4246, 0x6853, 0x0035, 0x0078, 0x4246, 0x127f, 0x6853, - 0x0028, 0x0078, 0x4246, 0x127f, 0x6853, 0x0029, 0x0e7f, 0x0078, - 0x4264, 0x6853, 0x002a, 0x0078, 0x4246, 0x2009, 0x003e, 0x0078, - 0x425f, 0x2009, 0x0004, 0x0078, 0x425f, 0x2009, 0x0006, 0x0078, - 0x425f, 0x2009, 0x0016, 0x0078, 0x425f, 0x2009, 0x0001, 0x6854, - 0xa084, 0xff00, 0xa105, 0x6856, 0x2091, 0x8000, 0x1078, 0x3b92, - 0x2091, 0x8001, 0x007c, 0x1078, 0x1340, 0x007c, 0x702c, 0x7130, - 0x8108, 0xa102, 0x0048, 0x427b, 0xa00e, 0x7034, 0x7072, 0x7038, - 0x7076, 0x0078, 0x4287, 0x7070, 0xa080, 0x0040, 0x7072, 0x00c8, - 0x4287, 0x7074, 0xa081, 0x0000, 0x7076, 0xa085, 0x0001, 0x7932, - 0x7132, 0x007c, 0x0d7e, 0x1078, 0x4727, 0x0d7f, 0x007c, 0x0d7e, + 0x00f0, 0x41dd, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006, + 0x0078, 0x41e4, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, + 0x0040, 0x41f8, 0x60a7, 0x0000, 0x1078, 0x1344, 0xa085, 0x0001, + 0x127f, 0x0d7f, 0x007c, 0x60a8, 0xa00d, 0x00c0, 0x4202, 0xa085, + 0x0001, 0x007c, 0x0e7e, 0x2170, 0x7050, 0xa005, 0x00c0, 0x4215, + 0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0040, 0x4215, + 0x8108, 0x00f0, 0x420c, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x127e, + 0x2091, 0x8000, 0x1078, 0x41fb, 0x00c0, 0x4231, 0x200b, 0xffff, + 0x0d7e, 0x60a8, 0x2068, 0x6854, 0xa08a, 0x0002, 0x0048, 0x422c, + 0x8001, 0x6856, 0x0078, 0x4230, 0x1078, 0x1344, 0x60ab, 0x0000, + 0x0d7f, 0x127f, 0x007c, 0x609c, 0xd0a4, 0x007c, 0x0f7e, 0x2079, + 0x8851, 0x7804, 0xd0a4, 0x0040, 0x4263, 0x157e, 0x0c7e, 0x20a9, + 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x3f8e, 0x00c0, 0x4257, + 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004, 0x0040, 0x4254, + 0xa086, 0x0006, 0x00c0, 0x4257, 0x6000, 0xc0ed, 0x6002, 0x017f, + 0x8108, 0x00f0, 0x4243, 0x0c7f, 0x157f, 0x2009, 0x07d0, 0x2011, + 0x4265, 0x1078, 0x5181, 0x0f7f, 0x007c, 0x2011, 0x4265, 0x1078, + 0x50f2, 0x157e, 0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, + 0x1078, 0x3f8e, 0x00c0, 0x429b, 0x6000, 0xd0ec, 0x0040, 0x429b, + 0x047e, 0x62a0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, + 0x1078, 0x86f5, 0x6000, 0xc0e5, 0xc0ec, 0x6002, 0x6004, 0xa084, + 0x00ff, 0xa085, 0x0700, 0x6006, 0x2019, 0x0029, 0x1078, 0x54f0, + 0x087e, 0x2041, 0x0000, 0x1078, 0x5419, 0x2009, 0x0000, 0x1078, + 0x84d2, 0x087f, 0x047f, 0x017f, 0x8108, 0x00f0, 0x426f, 0x0c7f, + 0x157f, 0x007c, 0x0c7e, 0x6018, 0x2060, 0x6000, 0xc0ec, 0x6002, + 0x0c7f, 0x007c, 0x2071, 0x8913, 0x7003, 0x0001, 0x7007, 0x0000, + 0x7013, 0x0000, 0x7017, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000, + 0x704b, 0x0001, 0x704f, 0x0000, 0x705b, 0x0020, 0x705f, 0x0040, + 0x707f, 0x0000, 0x2071, 0x8a7c, 0x7003, 0x8913, 0x7007, 0x0000, + 0x700b, 0x0000, 0x700f, 0x8a5c, 0x7013, 0x0020, 0x7017, 0x0040, + 0x7037, 0x0000, 0x007c, 0x017e, 0x0e7e, 0x2071, 0x8a34, 0xa00e, + 0x7186, 0x718a, 0x7097, 0x0001, 0x2001, 0x8852, 0x2004, 0xd0fc, + 0x00c0, 0x42ed, 0x2001, 0x8852, 0x2004, 0xa00e, 0xd09c, 0x0040, + 0x42ea, 0x8108, 0x7102, 0x0078, 0x4340, 0x2001, 0x8871, 0x200c, + 0xa184, 0x000f, 0x2009, 0x8872, 0x210c, 0x0079, 0x42f7, 0x42e2, + 0x4318, 0x4320, 0x432b, 0x4331, 0x42e2, 0x42e2, 0x42e2, 0x4307, + 0x42e2, 0x42e2, 0x42e2, 0x42e2, 0x42e2, 0x42e2, 0x42e2, 0x7003, + 0x0004, 0x137e, 0x147e, 0x157e, 0x2099, 0x8875, 0x20a1, 0x8a85, + 0x20a9, 0x0004, 0x53a3, 0x157f, 0x147f, 0x137f, 0x0078, 0x4340, + 0x708f, 0x0005, 0x7007, 0x0122, 0x2001, 0x0002, 0x0078, 0x4326, + 0x708f, 0x0002, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002, 0x7097, + 0x0001, 0x0078, 0x433d, 0x7007, 0x0122, 0x2001, 0x0002, 0x0078, + 0x4335, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002, 0xa006, 0x7096, + 0x708e, 0xa184, 0xff00, 0x8007, 0x709a, 0xa184, 0x00ff, 0x7092, + 0x0e7f, 0x017f, 0x007c, 0x0e7e, 0x2071, 0x8913, 0x684c, 0xa005, + 0x00c0, 0x4351, 0x7028, 0xc085, 0x702a, 0xa085, 0x0001, 0x0078, + 0x4374, 0x6a60, 0x7236, 0x6b64, 0x733a, 0x6868, 0x703e, 0x7076, + 0x686c, 0x7042, 0x707a, 0x684c, 0x702e, 0x6844, 0x7032, 0x2009, + 0x000d, 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, + 0xffc0, 0xa210, 0x2100, 0xa319, 0x726e, 0x7372, 0x7028, 0xc084, + 0x702a, 0x7007, 0x0001, 0xa006, 0x0e7f, 0x007c, 0x0e7e, 0x027e, + 0x6838, 0xd0fc, 0x00c0, 0x43cc, 0x6804, 0xa00d, 0x0040, 0x4392, + 0x0d7e, 0x2071, 0x8800, 0xa016, 0x702c, 0x2168, 0x6904, 0x206a, + 0x8210, 0x2d00, 0x81ff, 0x00c0, 0x4385, 0x702e, 0x70a4, 0xa200, + 0x70a6, 0x0d7f, 0x2071, 0x8913, 0x701c, 0xa005, 0x00c0, 0x43de, + 0x0068, 0x43dc, 0x2071, 0x8a34, 0x7200, 0x82ff, 0x0040, 0x43dc, + 0x6934, 0xa186, 0x0103, 0x00c0, 0x43ef, 0x6948, 0x6844, 0xa105, + 0x00c0, 0x43cf, 0x2009, 0x8020, 0x2200, 0x0079, 0x43af, 0x43dc, + 0x43b4, 0x440c, 0x441a, 0x43dc, 0x2071, 0x0000, 0x7018, 0xd084, + 0x00c0, 0x43dc, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b, + 0x0001, 0x2091, 0x4080, 0x2071, 0x8800, 0x702c, 0x206a, 0x2d00, + 0x702e, 0x70a4, 0x8000, 0x70a6, 0x027f, 0x0e7f, 0x007c, 0x6844, + 0xa086, 0x0100, 0x00c0, 0x43dc, 0x6868, 0xa005, 0x00c0, 0x43dc, + 0x2009, 0x8020, 0x0078, 0x43ac, 0x2071, 0x8913, 0x2d08, 0x206b, + 0x0000, 0x7010, 0x8000, 0x7012, 0x7018, 0xa06d, 0x711a, 0x0040, + 0x43ec, 0x6902, 0x0078, 0x43ed, 0x711e, 0x0078, 0x43cc, 0xa18c, + 0x00ff, 0xa186, 0x0017, 0x0040, 0x43fd, 0xa186, 0x001e, 0x0040, + 0x43fd, 0xa18e, 0x001f, 0x00c0, 0x43dc, 0x684c, 0xd0cc, 0x0040, + 0x43dc, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0, 0x43dc, + 0x2009, 0x8021, 0x0078, 0x43ac, 0x7084, 0x8008, 0xa092, 0x001e, + 0x00c8, 0x43dc, 0x7186, 0xae90, 0x0003, 0xa210, 0x683c, 0x2012, + 0x0078, 0x442a, 0x7084, 0x8008, 0xa092, 0x000f, 0x00c8, 0x43dc, + 0x7186, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210, + 0x6840, 0x2012, 0x7088, 0xa10a, 0x0048, 0x43c3, 0x718c, 0x7084, + 0xa10a, 0x0048, 0x43c3, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, + 0x43c3, 0x2071, 0x8a34, 0x7000, 0xa086, 0x0002, 0x00c0, 0x444a, + 0x1078, 0x46a6, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, + 0x0078, 0x43c3, 0x1078, 0x46d1, 0x2071, 0x0000, 0x701b, 0x0001, + 0x2091, 0x4080, 0x0078, 0x43c3, 0x007e, 0x684c, 0x007e, 0x6837, + 0x0103, 0x20a9, 0x001c, 0xad80, 0x0011, 0x20a0, 0x2001, 0x0000, + 0x40a4, 0x007f, 0xa084, 0x00ff, 0x684e, 0x007f, 0x684a, 0x6952, + 0x007c, 0x2071, 0x8913, 0x7004, 0x0079, 0x446e, 0x4478, 0x4487, + 0x4677, 0x4678, 0x469f, 0x46a5, 0x4479, 0x4665, 0x4608, 0x4688, + 0x007c, 0x127e, 0x2091, 0x8000, 0x0068, 0x4486, 0x2009, 0x000d, + 0x7030, 0x200a, 0x2091, 0x4080, 0x7007, 0x0001, 0x127f, 0x2069, + 0x8ab5, 0x6844, 0xa005, 0x0050, 0x44af, 0x00c0, 0x44af, 0x127e, + 0x2091, 0x8000, 0x2069, 0x0000, 0x6934, 0x2001, 0x891f, 0x2004, + 0xa10a, 0x0040, 0x44aa, 0x0068, 0x44af, 0x2069, 0x0000, 0x6818, + 0xd084, 0x00c0, 0x44ae, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, + 0x2091, 0x4080, 0x2069, 0x8ab5, 0x6847, 0xffff, 0x127f, 0x2069, + 0x8800, 0x6844, 0x6960, 0xa102, 0x2069, 0x8a34, 0x688a, 0x6984, + 0x701c, 0xa06d, 0x0040, 0x44c1, 0x81ff, 0x0040, 0x4509, 0x0078, + 0x44d7, 0x81ff, 0x0040, 0x45db, 0x2071, 0x8a34, 0x7184, 0x7088, + 0xa10a, 0x00c8, 0x44d7, 0x7190, 0x2071, 0x8ab5, 0x7040, 0xa005, + 0x0040, 0x44d7, 0x00d0, 0x45db, 0x7142, 0x0078, 0x45db, 0x2071, + 0x8a34, 0x718c, 0x127e, 0x2091, 0x8000, 0x7084, 0xa10a, 0x0048, + 0x45dc, 0x0068, 0x458d, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, + 0x458d, 0x2001, 0xffff, 0x2071, 0x8ab5, 0x7042, 0x2071, 0x8a34, + 0x7000, 0xa086, 0x0002, 0x00c0, 0x44ff, 0x1078, 0x46a6, 0x2071, + 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x458d, 0x1078, + 0x46d1, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, + 0x458d, 0x2071, 0x8a34, 0x7000, 0xa005, 0x0040, 0x45ba, 0x6934, + 0xa186, 0x0103, 0x00c0, 0x4590, 0x684c, 0xd0bc, 0x00c0, 0x45ba, + 0x6948, 0x6844, 0xa105, 0x00c0, 0x45ad, 0x2071, 0x8a34, 0x7000, + 0x0079, 0x4522, 0x45ba, 0x4570, 0x4548, 0x455a, 0x4527, 0x137e, + 0x147e, 0x157e, 0x2099, 0x8875, 0x20a1, 0x8a85, 0x20a9, 0x0004, + 0x53a3, 0x157f, 0x147f, 0x137f, 0x2071, 0x8a7c, 0xad80, 0x000f, + 0x700e, 0x7013, 0x0002, 0x7007, 0x0002, 0x700b, 0x0000, 0x2e10, + 0x1078, 0x137b, 0x2071, 0x8913, 0x7007, 0x0009, 0x0078, 0x45db, + 0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x45db, 0xae90, 0x0003, + 0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0x8913, 0x1078, 0x4731, + 0x0078, 0x45db, 0x7084, 0x8008, 0xa092, 0x000f, 0x00c8, 0x45db, + 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210, 0x6840, + 0x2012, 0x7186, 0x2071, 0x8913, 0x1078, 0x4731, 0x0078, 0x45db, + 0x2009, 0x8020, 0x127e, 0x2091, 0x8000, 0x0068, 0x458d, 0x2071, + 0x0000, 0x7018, 0xd084, 0x00c0, 0x458d, 0x7122, 0x683c, 0x7026, + 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x127f, 0x2071, + 0x8913, 0x1078, 0x4731, 0x0078, 0x45db, 0x127f, 0x0078, 0x45db, + 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0040, 0x459e, 0xa186, 0x001e, + 0x0040, 0x459e, 0xa18e, 0x001f, 0x00c0, 0x45ba, 0x684c, 0xd0cc, + 0x0040, 0x45ba, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0, + 0x45ba, 0x2009, 0x8021, 0x0078, 0x4572, 0x6844, 0xa086, 0x0100, + 0x00c0, 0x45ba, 0x6868, 0xa005, 0x00c0, 0x45ba, 0x2009, 0x8020, + 0x0078, 0x4572, 0x2071, 0x8913, 0x1078, 0x4745, 0x0040, 0x45db, + 0x2071, 0x8913, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, + 0x0003, 0x00c0, 0x45d2, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0040, + 0x45d2, 0x710e, 0x7007, 0x0003, 0x1078, 0x4765, 0x7050, 0xa086, + 0x0100, 0x0040, 0x4678, 0x007c, 0x2071, 0x8913, 0x1078, 0x4745, + 0x0040, 0x4605, 0x2071, 0x8a34, 0x7084, 0x700a, 0x20a9, 0x0020, + 0x2099, 0x8a35, 0x20a1, 0x8a5c, 0x53a3, 0x7087, 0x0000, 0x2071, + 0x8913, 0x2069, 0x8a7c, 0x706c, 0x6826, 0x7070, 0x682a, 0x7074, + 0x682e, 0x7078, 0x6832, 0x2d10, 0x1078, 0x137b, 0x7007, 0x0008, + 0x2001, 0xffff, 0x2071, 0x8ab5, 0x7042, 0x127f, 0x0078, 0x45db, + 0x2069, 0x8a7c, 0x6808, 0xa08e, 0x0000, 0x0040, 0x4664, 0xa08e, + 0x0200, 0x0040, 0x4662, 0xa08e, 0x0100, 0x00c0, 0x4664, 0x127e, + 0x2091, 0x8000, 0x0068, 0x465f, 0x2069, 0x0000, 0x6818, 0xd084, + 0x00c0, 0x465f, 0x702c, 0x7130, 0x8108, 0xa102, 0x0048, 0x462f, + 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0078, 0x4639, 0x706c, + 0xa080, 0x0040, 0x706e, 0x00c8, 0x4639, 0x7070, 0xa081, 0x0000, + 0x7072, 0x7132, 0x6936, 0x2001, 0x8a59, 0x2004, 0xa005, 0x00c0, + 0x4656, 0x6934, 0x2069, 0x8a34, 0x689c, 0x699e, 0x2069, 0x8ab5, + 0xa102, 0x00c0, 0x464f, 0x6844, 0xa005, 0x00d0, 0x465d, 0x2001, + 0x8a5a, 0x200c, 0x810d, 0x6946, 0x0078, 0x465d, 0x2009, 0x8040, + 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x127f, + 0x0078, 0x4664, 0x7007, 0x0005, 0x007c, 0x701c, 0xa06d, 0x0040, + 0x4676, 0x1078, 0x4745, 0x0040, 0x4676, 0x7007, 0x0003, 0x1078, + 0x4765, 0x7050, 0xa086, 0x0100, 0x0040, 0x4678, 0x007c, 0x007c, + 0x7050, 0xa09e, 0x0100, 0x00c0, 0x4681, 0x7007, 0x0004, 0x0078, + 0x469f, 0xa086, 0x0200, 0x00c0, 0x4687, 0x7007, 0x0005, 0x007c, + 0x2001, 0x8a7e, 0x2004, 0xa08e, 0x0100, 0x00c0, 0x4694, 0x7007, + 0x0001, 0x1078, 0x4731, 0x007c, 0xa08e, 0x0000, 0x0040, 0x4693, + 0xa08e, 0x0200, 0x00c0, 0x4693, 0x7007, 0x0005, 0x007c, 0x1078, + 0x46f9, 0x7006, 0x1078, 0x4731, 0x007c, 0x007c, 0x0e7e, 0x157e, + 0x2071, 0x8a34, 0x7184, 0x81ff, 0x0040, 0x46ce, 0xa006, 0x7086, + 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, + 0x0070, 0x46cb, 0x2014, 0x722a, 0x8000, 0x0070, 0x46cb, 0x2014, + 0x722e, 0x8000, 0x0070, 0x46cb, 0x2014, 0x723a, 0x8000, 0x0070, + 0x46cb, 0x2014, 0x723e, 0xa180, 0x8030, 0x7022, 0x157f, 0x0e7f, + 0x007c, 0x0e7e, 0x157e, 0x2071, 0x8a34, 0x7184, 0x81ff, 0x0040, + 0x46f6, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, + 0x2014, 0x7226, 0x8000, 0x2014, 0x722a, 0x8000, 0x0070, 0x46ef, + 0x2014, 0x723a, 0x8000, 0x2014, 0x723e, 0x0078, 0x46f3, 0x2001, + 0x8020, 0x0078, 0x46f5, 0xa180, 0x8042, 0x7022, 0x157f, 0x0e7f, + 0x007c, 0x702c, 0x7130, 0x8108, 0xa102, 0x0048, 0x4706, 0xa00e, + 0x7034, 0x706e, 0x7038, 0x7072, 0x0078, 0x4710, 0x706c, 0xa080, + 0x0040, 0x706e, 0x00c8, 0x4710, 0x7070, 0xa081, 0x0000, 0x7072, + 0x7132, 0x700c, 0x8001, 0x700e, 0x00c0, 0x472a, 0x127e, 0x2091, + 0x8000, 0x0068, 0x472d, 0x2001, 0x000d, 0x2102, 0x2091, 0x4080, + 0x2001, 0x0001, 0x127f, 0x007c, 0x2001, 0x000d, 0x2102, 0x2001, + 0x0001, 0x007c, 0x2001, 0x0007, 0x007c, 0x2001, 0x0006, 0x127f, + 0x007c, 0x701c, 0xa06d, 0x0040, 0x4744, 0x127e, 0x2091, 0x8000, + 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, 0xa005, 0x00c0, 0x4741, + 0x701a, 0x127f, 0x1078, 0x1344, 0x007c, 0x2019, 0x000d, 0x2304, + 0x230c, 0xa10e, 0x0040, 0x4754, 0x2304, 0x230c, 0xa10e, 0x0040, + 0x4754, 0xa006, 0x0078, 0x4764, 0x732c, 0x8319, 0x7130, 0xa102, + 0x00c0, 0x475e, 0x2300, 0xa005, 0x0078, 0x4764, 0x0048, 0x4763, + 0xa302, 0x0078, 0x4764, 0x8002, 0x007c, 0x2d00, 0x7026, 0xa080, + 0x000d, 0x7056, 0x7053, 0x0000, 0x127e, 0x2091, 0x8000, 0x2009, + 0x8ac7, 0x2104, 0xc08d, 0x200a, 0x127f, 0x1078, 0x1395, 0x007c, + 0x2071, 0x88e1, 0x7003, 0x0000, 0x7007, 0x0000, 0x700f, 0x0000, + 0x702b, 0x0001, 0x704f, 0x0000, 0x7053, 0x0001, 0x705f, 0x0020, + 0x7063, 0x0040, 0x7083, 0x0000, 0x708b, 0x0000, 0x708f, 0x0001, + 0x70bf, 0x0000, 0x007c, 0x0e7e, 0x2071, 0x88e1, 0x6848, 0xa005, + 0x00c0, 0x47a1, 0x7028, 0xc085, 0x702a, 0xa085, 0x0001, 0x0078, + 0x47c6, 0x6a50, 0x7236, 0x6b54, 0x733a, 0x6858, 0x703e, 0x707a, + 0x685c, 0x7042, 0x707e, 0x6848, 0x702e, 0x6840, 0x7032, 0x2009, + 0x000c, 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, + 0xffc0, 0xa210, 0x2100, 0xa319, 0x7272, 0x7376, 0x7028, 0xc084, + 0x702a, 0x7007, 0x0001, 0x700f, 0x0000, 0xa006, 0x0e7f, 0x007c, + 0x2b78, 0x2071, 0x88e1, 0x7004, 0x1079, 0x4826, 0x700c, 0x0079, + 0x47d1, 0x47d6, 0x47cb, 0x47cb, 0x47cb, 0x47cb, 0x007c, 0x700c, + 0x0079, 0x47da, 0x47df, 0x4824, 0x4824, 0x4825, 0x4825, 0x7830, + 0x7930, 0xa106, 0x0040, 0x47e9, 0x7830, 0x7930, 0xa106, 0x00c0, + 0x480f, 0x7030, 0xa10a, 0x0040, 0x480f, 0x00c8, 0x47f1, 0x712c, + 0xa10a, 0xa18a, 0x0002, 0x00c8, 0x4810, 0x1078, 0x1310, 0x0040, + 0x480f, 0x2d00, 0x705a, 0x7063, 0x0040, 0x2001, 0x0003, 0x7057, + 0x0000, 0x127e, 0x007e, 0x2091, 0x8000, 0x2009, 0x8ac7, 0x2104, + 0xc085, 0x200a, 0x007f, 0x700e, 0x127f, 0x1078, 0x1395, 0x007c, + 0x1078, 0x1310, 0x0040, 0x480f, 0x2d00, 0x705a, 0x1078, 0x1310, + 0x00c0, 0x481c, 0x0078, 0x47fb, 0x2d00, 0x7086, 0x7063, 0x0080, + 0x2001, 0x0004, 0x0078, 0x47ff, 0x007c, 0x007c, 0x4837, 0x4838, + 0x486f, 0x4870, 0x4824, 0x48a6, 0x48ab, 0x48e2, 0x48e3, 0x48fe, + 0x48ff, 0x4900, 0x4901, 0x4902, 0x4903, 0x496c, 0x4996, 0x007c, + 0x700c, 0x0079, 0x483b, 0x4840, 0x4843, 0x4853, 0x486e, 0x486e, + 0x1078, 0x47d7, 0x007c, 0x127e, 0x8001, 0x700e, 0x7058, 0x007e, + 0x1078, 0x4c96, 0x0040, 0x4850, 0x2091, 0x8000, 0x1078, 0x47d7, + 0x0d7f, 0x0078, 0x485c, 0x127e, 0x8001, 0x700e, 0x1078, 0x4c96, + 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, + 0x6834, 0xa084, 0x00ff, 0xa08a, 0x0020, 0x00c8, 0x486b, 0x1079, + 0x4886, 0x127f, 0x007c, 0x127f, 0x1078, 0x4904, 0x007c, 0x007c, + 0x007c, 0x0e7e, 0x2071, 0x88e1, 0x700c, 0x0079, 0x4877, 0x487c, + 0x487c, 0x487c, 0x487e, 0x4882, 0x0e7f, 0x007c, 0x700f, 0x0001, + 0x0078, 0x4884, 0x700f, 0x0002, 0x0e7f, 0x007c, 0x4904, 0x4904, + 0x4920, 0x4904, 0x4a0b, 0x4904, 0x4904, 0x4904, 0x4904, 0x4904, + 0x4920, 0x4a55, 0x4aa2, 0x4afb, 0x4b11, 0x4904, 0x4904, 0x493c, + 0x4920, 0x4904, 0x4904, 0x4952, 0x4bac, 0x4bca, 0x4904, 0x493c, + 0x4904, 0x4904, 0x4904, 0x4904, 0x4952, 0x4bca, 0x7020, 0x2068, + 0x1078, 0x1344, 0x007c, 0x700c, 0x0079, 0x48ae, 0x48b3, 0x48b6, + 0x48c6, 0x48e1, 0x48e1, 0x1078, 0x47d7, 0x007c, 0x127e, 0x8001, + 0x700e, 0x7058, 0x007e, 0x1078, 0x4c96, 0x0040, 0x48c3, 0x2091, + 0x8000, 0x1078, 0x47d7, 0x0d7f, 0x0078, 0x48cf, 0x127e, 0x8001, + 0x700e, 0x1078, 0x4c96, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, + 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x001a, + 0x00c8, 0x48de, 0x1079, 0x48e4, 0x127f, 0x007c, 0x127f, 0x1078, + 0x4904, 0x007c, 0x007c, 0x007c, 0x4904, 0x4920, 0x49f5, 0x4904, + 0x4920, 0x4904, 0x4920, 0x4920, 0x4904, 0x4920, 0x49f5, 0x4920, + 0x4920, 0x4920, 0x4920, 0x4920, 0x4904, 0x4920, 0x49f5, 0x4904, + 0x4904, 0x4920, 0x4904, 0x4904, 0x4904, 0x4920, 0x007c, 0x007c, + 0x007c, 0x007c, 0x007c, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, + 0x00ff, 0xc0d5, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4376, + 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0e5, + 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4376, 0x127f, 0x007c, + 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed, 0x683a, 0x127e, + 0x2091, 0x8000, 0x1078, 0x4376, 0x127f, 0x007c, 0x7007, 0x0001, + 0x6838, 0xa084, 0x00ff, 0xc0dd, 0x683a, 0x127e, 0x2091, 0x8000, + 0x1078, 0x4376, 0x127f, 0x007c, 0x6834, 0x8007, 0xa084, 0x00ff, + 0x0040, 0x4912, 0x8001, 0x00c0, 0x4949, 0x7007, 0x0001, 0x0078, + 0x49d2, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, + 0x49d2, 0x007c, 0x2d00, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, + 0x0024, 0x2098, 0x20a1, 0x890c, 0x53a3, 0x6858, 0x7012, 0xa082, + 0x0401, 0x00c8, 0x492e, 0x6884, 0xa08a, 0x0003, 0x00c8, 0x492e, + 0xa080, 0x49c3, 0x2004, 0x70c6, 0x7010, 0xa015, 0x0040, 0x49b6, + 0x1078, 0x1310, 0x00c0, 0x4977, 0x7007, 0x000f, 0x007c, 0x2d00, + 0x7022, 0x70c4, 0x2060, 0x6000, 0x6836, 0x6004, 0xad00, 0x7096, + 0x6008, 0xa20a, 0x00c8, 0x4986, 0xa00e, 0x2200, 0x7112, 0x620c, + 0x8003, 0x800b, 0xa296, 0x0004, 0x0040, 0x498f, 0xa108, 0x719a, + 0x810b, 0x719e, 0xae90, 0x0022, 0x1078, 0x137b, 0x7090, 0xa08e, + 0x0100, 0x0040, 0x49aa, 0xa086, 0x0200, 0x0040, 0x49a2, 0x7007, + 0x0010, 0x007c, 0x7020, 0x2068, 0x1078, 0x1344, 0x7014, 0x2068, + 0x0078, 0x492e, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807, 0x0000, + 0x2d08, 0x2068, 0x6906, 0x711a, 0x0078, 0x496c, 0x7014, 0x2068, + 0x7007, 0x0001, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x0040, + 0x4be7, 0x0078, 0x49d2, 0x49c6, 0x49ca, 0x49ce, 0x0002, 0x0011, + 0x0007, 0x0004, 0x000a, 0x000f, 0x0005, 0x0006, 0x0012, 0x000f, + 0x0005, 0x0006, 0x2009, 0x882d, 0x210c, 0x81ff, 0x00c0, 0x49ef, + 0x6838, 0xa084, 0x00ff, 0x683a, 0x6853, 0x0000, 0x1078, 0x3d8b, + 0x00c0, 0x49e3, 0x007c, 0x1078, 0x4454, 0x127e, 0x2091, 0x8000, + 0x1078, 0x7a46, 0x1078, 0x4376, 0x127f, 0x0078, 0x49e2, 0x2001, + 0x0028, 0x2009, 0x0000, 0x0078, 0x49e3, 0x7018, 0x6802, 0x2d08, + 0x2068, 0x6906, 0x711a, 0x7010, 0x8001, 0x7012, 0x0040, 0x4a04, + 0x7007, 0x0006, 0x0078, 0x4a0a, 0x7014, 0x2068, 0x7007, 0x0001, + 0x7048, 0x107a, 0x007c, 0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, + 0x00ff, 0x6848, 0xa084, 0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, + 0x0040, 0x4a34, 0x2009, 0x0000, 0x20a9, 0x007e, 0xa096, 0x0002, + 0x0040, 0x4a34, 0xa005, 0x00c0, 0x4a47, 0x6944, 0x810f, 0xa18c, + 0x00ff, 0x1078, 0x3f8e, 0x00c0, 0x4a47, 0x067e, 0x6e50, 0x1078, + 0x4057, 0x067f, 0x0078, 0x4a47, 0x047e, 0x2011, 0x880c, 0x2224, + 0xc484, 0xc48c, 0x2412, 0x047f, 0x0c7e, 0x1078, 0x3f8e, 0x00c0, + 0x4a43, 0x1078, 0x41ea, 0x8108, 0x00f0, 0x4a3d, 0x0c7f, 0x684c, + 0xd084, 0x00c0, 0x4a4e, 0x1078, 0x1344, 0x007c, 0x127e, 0x2091, + 0x8000, 0x1078, 0x4376, 0x127f, 0x007c, 0x127e, 0x2091, 0x8000, + 0x7007, 0x0001, 0x2001, 0x8852, 0x2004, 0xd0a4, 0x0040, 0x4a99, + 0x2061, 0x8b24, 0x6100, 0xd184, 0x0040, 0x4a79, 0x6858, 0xa084, + 0x00ff, 0x00c0, 0x4a9c, 0x6000, 0xd084, 0x0040, 0x4a99, 0x6004, + 0xa005, 0x00c0, 0x4a9f, 0x6003, 0x0000, 0x600b, 0x0000, 0x0078, + 0x4a96, 0x2011, 0x0001, 0x6860, 0xa005, 0x00c0, 0x4a81, 0x2001, + 0x001e, 0x8000, 0x6016, 0x6858, 0xa084, 0x00ff, 0x0040, 0x4a99, + 0x6006, 0x6858, 0x8007, 0xa084, 0x00ff, 0x0040, 0x4a99, 0x600a, + 0x6858, 0x8000, 0x00c0, 0x4a95, 0xc28d, 0x6202, 0x127f, 0x0078, + 0x4c85, 0x127f, 0x0078, 0x4c7d, 0x127f, 0x0078, 0x4c75, 0x127f, + 0x0078, 0x4c79, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, + 0x8852, 0x2004, 0xd0a4, 0x0040, 0x4af8, 0x2061, 0x8b24, 0x6000, + 0xd084, 0x0040, 0x4af8, 0x6204, 0x6308, 0xd08c, 0x00c0, 0x4aea, + 0x6c48, 0xa484, 0x0003, 0x0040, 0x4ad0, 0x6958, 0xa18c, 0x00ff, + 0x8001, 0x00c0, 0x4ac9, 0x2100, 0xa210, 0x0048, 0x4af5, 0x0078, + 0x4ad0, 0x8001, 0x00c0, 0x4af5, 0x2100, 0xa212, 0x0048, 0x4af5, + 0xa484, 0x000c, 0x0040, 0x4aea, 0x6958, 0x810f, 0xa18c, 0x00ff, + 0xa082, 0x0004, 0x00c0, 0x4ae2, 0x2100, 0xa318, 0x0048, 0x4af5, + 0x0078, 0x4aea, 0xa082, 0x0004, 0x00c0, 0x4af5, 0x2100, 0xa31a, + 0x0048, 0x4af5, 0x6860, 0xa005, 0x0040, 0x4af0, 0x8000, 0x6016, + 0x6206, 0x630a, 0x127f, 0x0078, 0x4c85, 0x127f, 0x0078, 0x4c81, + 0x127f, 0x0078, 0x4c7d, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, + 0x2061, 0x8b24, 0x6300, 0xd38c, 0x00c0, 0x4b0b, 0x6308, 0x8318, + 0x0048, 0x4b0e, 0x630a, 0x127f, 0x0078, 0x4c93, 0x127f, 0x0078, + 0x4c81, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, + 0xd0ac, 0x0040, 0x4b25, 0x0c7e, 0x2061, 0x8b24, 0x6000, 0xa084, + 0xfcff, 0x6002, 0x0c7f, 0x0078, 0x4b68, 0x6858, 0xa005, 0x0040, + 0x4b7f, 0x685c, 0xa065, 0x0040, 0x4b7b, 0x2001, 0x882d, 0x2004, + 0xa005, 0x0040, 0x4b37, 0x1078, 0x79a8, 0x0078, 0x4b45, 0x6013, + 0x0400, 0x6027, 0x0000, 0x694c, 0xd1a4, 0x0040, 0x4b41, 0x6950, + 0x6126, 0x2009, 0x0041, 0x1078, 0x6939, 0x6958, 0xa18c, 0xff00, + 0xa186, 0x2000, 0x0040, 0x4b60, 0xa186, 0x0400, 0x0040, 0x4b60, + 0xa186, 0x1000, 0x0040, 0x4b56, 0x0078, 0x4b68, 0x0c7e, 0x2061, + 0x8b24, 0x6000, 0xa084, 0xfdff, 0x6002, 0x0c7f, 0x0078, 0x4b68, + 0x027e, 0x2009, 0x0000, 0x2011, 0xfdff, 0x1078, 0x5243, 0x027f, + 0x684c, 0xd0c4, 0x0040, 0x4b77, 0x2061, 0x8b24, 0x6000, 0xd08c, + 0x00c0, 0x4b77, 0x6008, 0x8000, 0x0048, 0x4b7b, 0x600a, 0x0c7f, + 0x127f, 0x0078, 0x4c85, 0x0c7f, 0x127f, 0x0078, 0x4c7d, 0x6954, + 0xa186, 0x002a, 0x00c0, 0x4b8b, 0x2001, 0x880c, 0x200c, 0xc194, + 0x2102, 0x0078, 0x4b68, 0xa186, 0x0020, 0x0040, 0x4ba4, 0xa186, + 0x0029, 0x0040, 0x4b97, 0xa186, 0x002d, 0x00c0, 0x4b7b, 0x6944, + 0xa18c, 0xff00, 0x810f, 0x1078, 0x3f8e, 0x00c0, 0x4b68, 0x6000, + 0xc0e4, 0x6002, 0x0078, 0x4b68, 0x685c, 0xa065, 0x0040, 0x4b7b, + 0x6017, 0x0014, 0x0078, 0x4b68, 0x2061, 0x8b24, 0x6000, 0xd084, + 0x0040, 0x4bc6, 0xd08c, 0x00c0, 0x4c93, 0x2091, 0x8000, 0x6204, + 0x8210, 0x0048, 0x4bc0, 0x6206, 0x2091, 0x8001, 0x0078, 0x4c93, + 0x2091, 0x8001, 0x6853, 0x0016, 0x0078, 0x4c8c, 0x6853, 0x0007, + 0x0078, 0x4c8c, 0x6834, 0x8007, 0xa084, 0x00ff, 0x00c0, 0x4bd4, + 0x1078, 0x4912, 0x0078, 0x4be6, 0x2030, 0x8001, 0x00c0, 0x4bde, + 0x7007, 0x0001, 0x1078, 0x4be7, 0x0078, 0x4be6, 0x7007, 0x0006, + 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x4be7, 0x007c, 0x0e7e, + 0x127e, 0x2091, 0x8000, 0x2009, 0x882d, 0x210c, 0x81ff, 0x00c0, + 0x4c67, 0x2009, 0x880c, 0x210c, 0xd194, 0x00c0, 0x4c71, 0x6848, + 0x2070, 0xae82, 0x8f00, 0x0048, 0x4c57, 0x2001, 0x8815, 0x2004, + 0xae02, 0x00c8, 0x4c57, 0x2061, 0x8b24, 0x6100, 0xa184, 0x0001, + 0x0040, 0x4c3c, 0xa184, 0x0100, 0x00c0, 0x4c5b, 0xa184, 0x0200, + 0x00c0, 0x4c5f, 0x601c, 0xa005, 0x00c0, 0x4c63, 0x711c, 0xa186, + 0x0006, 0x00c0, 0x4c42, 0x7018, 0xa005, 0x0040, 0x4c67, 0x2004, + 0xd0e4, 0x00c0, 0x4c6b, 0x6853, 0x0000, 0x6803, 0x0000, 0x2d08, + 0x7010, 0xa005, 0x00c0, 0x4c33, 0x7112, 0x2e60, 0x1078, 0x5198, + 0x127f, 0x0e7f, 0x007c, 0x2068, 0x6800, 0xa005, 0x00c0, 0x4c33, + 0x6902, 0x127f, 0x0e7f, 0x007c, 0x127f, 0x0e7f, 0x6853, 0x0006, + 0x0078, 0x4c8c, 0x6944, 0xa18c, 0xff00, 0x810f, 0x1078, 0x3f8e, + 0x00c0, 0x4c6b, 0x6000, 0xd0e4, 0x00c0, 0x4c6b, 0x711c, 0xa186, + 0x0007, 0x00c0, 0x4c57, 0x6853, 0x0002, 0x0078, 0x4c6d, 0x6853, + 0x0008, 0x0078, 0x4c6d, 0x6853, 0x000e, 0x0078, 0x4c6d, 0x6853, + 0x0017, 0x0078, 0x4c6d, 0x6853, 0x0035, 0x0078, 0x4c6d, 0x6853, + 0x0028, 0x0078, 0x4c6d, 0x6853, 0x0029, 0x127f, 0x0e7f, 0x0078, + 0x4c8c, 0x6853, 0x002a, 0x0078, 0x4c6d, 0x2009, 0x003e, 0x0078, + 0x4c87, 0x2009, 0x0004, 0x0078, 0x4c87, 0x2009, 0x0006, 0x0078, + 0x4c87, 0x2009, 0x0016, 0x0078, 0x4c87, 0x2009, 0x0001, 0x6854, + 0xa084, 0xff00, 0xa105, 0x6856, 0x2091, 0x8000, 0x1078, 0x4376, + 0x2091, 0x8001, 0x007c, 0x1078, 0x1344, 0x007c, 0x702c, 0x7130, + 0x8108, 0xa102, 0x0048, 0x4ca3, 0xa00e, 0x7034, 0x7072, 0x7038, + 0x7076, 0x0078, 0x4caf, 0x7070, 0xa080, 0x0040, 0x7072, 0x00c8, + 0x4caf, 0x7074, 0xa081, 0x0000, 0x7076, 0xa085, 0x0001, 0x7932, + 0x7132, 0x007c, 0x0d7e, 0x1078, 0x518f, 0x0d7f, 0x007c, 0x0d7e, 0x2011, 0x0004, 0x2204, 0xa085, 0x8002, 0x2012, 0x0d7f, 0x007c, 0x20e1, 0x0002, 0x3d08, 0x20e1, 0x2000, 0x3d00, 0xa084, 0x7000, - 0x0040, 0x42a6, 0xa086, 0x1000, 0x00c0, 0x42c2, 0x20e1, 0x0004, - 0x3d60, 0xd1bc, 0x00c0, 0x42ad, 0x3e60, 0xac84, 0x0007, 0x00c0, - 0x42c2, 0xac82, 0x7e00, 0x0048, 0x42c2, 0x6854, 0xac02, 0x00c8, - 0x42c2, 0x2009, 0x0047, 0x1078, 0x5d41, 0x7a1c, 0xd284, 0x00c0, - 0x4298, 0x007c, 0xa016, 0x1078, 0x156a, 0x0078, 0x42bd, 0x157e, + 0x0040, 0x4cce, 0xa086, 0x1000, 0x00c0, 0x4cea, 0x20e1, 0x0004, + 0x3d60, 0xd1bc, 0x00c0, 0x4cd5, 0x3e60, 0xac84, 0x0003, 0x00c0, + 0x4cea, 0xac82, 0x8f00, 0x0048, 0x4cea, 0x6854, 0xac02, 0x00c8, + 0x4cea, 0x2009, 0x0047, 0x1078, 0x6939, 0x7a1c, 0xd284, 0x00c0, + 0x4cc0, 0x007c, 0xa016, 0x1078, 0x1594, 0x0078, 0x4ce5, 0x157e, 0x137e, 0x147e, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584, 0x0070, - 0x00c0, 0x42f0, 0xa484, 0x7000, 0xa086, 0x1000, 0x00c0, 0x42f0, - 0x1078, 0x42fd, 0x0040, 0x42f0, 0x20e1, 0x3000, 0x7828, 0x7828, - 0x1078, 0x431b, 0x147f, 0x137f, 0x157f, 0x2009, 0x793e, 0x2104, - 0xa005, 0x00c0, 0x42ec, 0x007c, 0x1078, 0x4d96, 0x0078, 0x42eb, - 0x1078, 0x7674, 0x1078, 0x42fd, 0x20e1, 0x3000, 0x7828, 0x7828, - 0x147f, 0x137f, 0x157f, 0x0078, 0x42eb, 0xa484, 0x01ff, 0x687a, - 0xa005, 0x0040, 0x430f, 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac, - 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x007c, 0x20a9, - 0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085, - 0x0001, 0x0078, 0x430e, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000, - 0x8007, 0xa196, 0x0000, 0x00c0, 0x4328, 0x0078, 0x449c, 0x007c, - 0xa196, 0x2000, 0x00c0, 0x4339, 0x6900, 0xa18e, 0x0001, 0x00c0, - 0x4335, 0x1078, 0x2ec1, 0x0078, 0x4327, 0x1078, 0x4341, 0x0078, - 0x4327, 0xa196, 0x8000, 0x00c0, 0x4327, 0x1078, 0x4522, 0x0078, - 0x4327, 0x0c7e, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa196, 0x0001, - 0x0040, 0x434e, 0xa196, 0x0023, 0x00c0, 0x4443, 0xa08e, 0x0023, - 0x00c0, 0x437f, 0x1078, 0x4599, 0x0040, 0x4443, 0x7124, 0x610a, - 0x7030, 0xa08e, 0x0200, 0x00c0, 0x4367, 0x7034, 0xa005, 0x00c0, - 0x4443, 0x2009, 0x0015, 0x1078, 0x5d41, 0x0078, 0x4443, 0xa08e, - 0x0210, 0x00c0, 0x4371, 0x2009, 0x0015, 0x1078, 0x5d41, 0x0078, - 0x4443, 0xa08e, 0x0100, 0x00c0, 0x4443, 0x7034, 0xa005, 0x00c0, - 0x4443, 0x2009, 0x0016, 0x1078, 0x5d41, 0x0078, 0x4443, 0xa08e, - 0x0022, 0x00c0, 0x4443, 0x7030, 0xa08e, 0x0300, 0x00c0, 0x4390, - 0x7034, 0xa005, 0x00c0, 0x4443, 0x2009, 0x0017, 0x0078, 0x440f, - 0xa08e, 0x0500, 0x00c0, 0x439c, 0x7034, 0xa005, 0x00c0, 0x4443, - 0x2009, 0x0018, 0x0078, 0x440f, 0xa08e, 0x2010, 0x00c0, 0x43a4, - 0x2009, 0x0019, 0x0078, 0x440f, 0xa08e, 0x2110, 0x00c0, 0x43ac, - 0x2009, 0x001a, 0x0078, 0x440f, 0xa08e, 0x5200, 0x00c0, 0x43b8, - 0x7034, 0xa005, 0x00c0, 0x4443, 0x2009, 0x001b, 0x0078, 0x440f, - 0xa08e, 0x5000, 0x00c0, 0x43c4, 0x7034, 0xa005, 0x00c0, 0x4443, - 0x2009, 0x001c, 0x0078, 0x440f, 0xa08e, 0x1200, 0x00c0, 0x43d0, - 0x7034, 0xa005, 0x00c0, 0x4443, 0x2009, 0x0024, 0x0078, 0x440f, - 0xa08c, 0xff00, 0xa18e, 0x2400, 0x00c0, 0x43da, 0x2009, 0x002d, - 0x0078, 0x440f, 0xa08c, 0xff00, 0xa18e, 0x5300, 0x00c0, 0x43e4, - 0x2009, 0x002a, 0x0078, 0x440f, 0xa08e, 0x0f00, 0x00c0, 0x43ec, - 0x2009, 0x0020, 0x0078, 0x440f, 0xa08e, 0x5300, 0x00c0, 0x43f2, - 0x0078, 0x440d, 0xa08e, 0x6104, 0x00c0, 0x440d, 0x2011, 0x7c8d, - 0x8208, 0x2204, 0xa082, 0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011, - 0x8015, 0x211c, 0x8108, 0x2124, 0x1078, 0x2d59, 0x8108, 0x00f0, - 0x43ff, 0x2009, 0x0023, 0x0078, 0x440f, 0x2009, 0x001d, 0x017e, - 0x2011, 0x7c83, 0x2204, 0x8211, 0x220c, 0x1078, 0x207f, 0x00c0, - 0x4445, 0x1078, 0x3811, 0x00c0, 0x4445, 0x6612, 0x6516, 0x86ff, - 0x0040, 0x4435, 0x017f, 0x017e, 0xa186, 0x0017, 0x00c0, 0x4435, - 0x6864, 0xa606, 0x00c0, 0x4435, 0x6868, 0xa506, 0xa084, 0xff00, - 0x00c0, 0x4435, 0x6000, 0xc0f5, 0x6002, 0x0c7e, 0x1078, 0x5cb4, - 0x0040, 0x4448, 0x017f, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, - 0x017f, 0x1078, 0x5d41, 0x0c7f, 0x007c, 0x017f, 0x0078, 0x4443, - 0x0c7f, 0x0078, 0x4445, 0x0e7e, 0x0d7e, 0x2028, 0x2130, 0xa696, - 0x00ff, 0x00c0, 0x446b, 0xa596, 0xfffd, 0x00c0, 0x445b, 0x2009, - 0x007f, 0x0078, 0x4498, 0xa596, 0xfffe, 0x00c0, 0x4463, 0x2009, - 0x007e, 0x0078, 0x4498, 0xa596, 0xfffc, 0x00c0, 0x446b, 0x2009, - 0x0080, 0x0078, 0x4498, 0x2011, 0x0000, 0x2021, 0x007e, 0x20a9, - 0x0082, 0x2071, 0x789e, 0x2e1c, 0x83ff, 0x00c0, 0x447d, 0x82ff, - 0x00c0, 0x448c, 0x2410, 0x0078, 0x448c, 0x2368, 0x6b10, 0x007e, - 0x2100, 0xa31e, 0x007f, 0x00c0, 0x448c, 0x6b14, 0xa31e, 0x00c0, - 0x448c, 0x2408, 0x0078, 0x4498, 0x8420, 0x8e70, 0x00f0, 0x4473, - 0x82ff, 0x00c0, 0x4497, 0xa085, 0x0001, 0x0078, 0x4499, 0x2208, - 0xa006, 0x0d7f, 0x0e7f, 0x007c, 0xa084, 0x0007, 0x0079, 0x44a1, - 0x007c, 0x44a9, 0x44a9, 0x44a9, 0x44a9, 0x44a9, 0x44aa, 0x44c3, - 0x450b, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x44c2, 0x7120, 0x2160, - 0xac8c, 0x0007, 0x00c0, 0x44c2, 0xac8a, 0x7e00, 0x0048, 0x44c2, - 0x6854, 0xac02, 0x00c8, 0x44c2, 0x7124, 0x610a, 0x2009, 0x0046, - 0x1078, 0x5d41, 0x007c, 0x0c7e, 0x7110, 0xd1bc, 0x00c0, 0x4509, - 0x2011, 0x7c83, 0x2204, 0x8211, 0x220c, 0x1078, 0x207f, 0x00c0, - 0x4509, 0x1078, 0x384c, 0x00c0, 0x4509, 0x6204, 0xa294, 0xff00, - 0x8217, 0xa286, 0x0006, 0x00c0, 0x44ee, 0x0c7e, 0x1078, 0x5cb4, - 0x017f, 0x0040, 0x4509, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, - 0x2009, 0x0044, 0x1078, 0x5d41, 0x0078, 0x4509, 0x0c7e, 0x1078, - 0x5cb4, 0x017f, 0x0040, 0x4509, 0x611a, 0x601f, 0x0004, 0x7120, - 0x610a, 0xa286, 0x0004, 0x00c0, 0x4501, 0x6007, 0x0005, 0x0078, - 0x4503, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x498e, 0x1078, - 0x4d96, 0x0c7f, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x4521, 0x7020, - 0x2060, 0xac84, 0x0007, 0x00c0, 0x4521, 0xac82, 0x7e00, 0x0048, - 0x4521, 0x6854, 0xac02, 0x00c8, 0x4521, 0x2009, 0x0045, 0x1078, - 0x5d41, 0x007c, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000, - 0x00c0, 0x4532, 0xa084, 0x000f, 0xa08a, 0x0006, 0x10c8, 0x12cd, - 0x1079, 0x4533, 0x007c, 0x4539, 0x453a, 0x4539, 0x4539, 0x457b, - 0x458a, 0x007c, 0x7110, 0xd1bc, 0x00c0, 0x457a, 0x700c, 0x7108, - 0x1078, 0x207f, 0x00c0, 0x457a, 0x1078, 0x3811, 0x00c0, 0x457a, - 0x6612, 0x6516, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, - 0x00c0, 0x4563, 0x0c7e, 0x1078, 0x5cb4, 0x017f, 0x0040, 0x457a, - 0x611a, 0x601f, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x1078, - 0x5d41, 0x0078, 0x457a, 0x0c7e, 0x1078, 0x5cb4, 0x017f, 0x0040, - 0x457a, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0xa286, 0x0004, - 0x00c0, 0x4576, 0x2009, 0x0005, 0x0078, 0x4578, 0x2009, 0x0001, - 0x1078, 0x5d41, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x4589, 0x1078, - 0x4599, 0x0040, 0x4589, 0x7124, 0x610a, 0x2009, 0x0089, 0x1078, - 0x5d41, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x4598, 0x1078, 0x4599, - 0x0040, 0x4598, 0x7124, 0x610a, 0x2009, 0x008a, 0x1078, 0x5d41, - 0x007c, 0x7020, 0x2060, 0xac84, 0x0007, 0x00c0, 0x45ac, 0xac82, - 0x7e00, 0x0048, 0x45ac, 0x2001, 0x7715, 0x2004, 0xac02, 0x00c8, - 0x45ac, 0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x45ab, 0x2071, - 0x7949, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, 0x7012, - 0x7017, 0x7e00, 0x7007, 0x0000, 0x7026, 0x702b, 0x56a9, 0x7032, - 0x7037, 0x56ea, 0x703b, 0x0002, 0x703f, 0x0000, 0x007c, 0x2071, - 0x7949, 0x00e0, 0x4676, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, - 0x00c0, 0x463f, 0x700f, 0x0361, 0x7007, 0x0001, 0x127e, 0x2091, - 0x8000, 0x7138, 0x8109, 0x713a, 0x00c0, 0x463d, 0x703b, 0x0002, - 0x2009, 0x0100, 0x2104, 0xa082, 0x0003, 0x00c8, 0x463d, 0x703c, - 0xa086, 0x0001, 0x00c0, 0x461a, 0x0d7e, 0x2069, 0x0140, 0x6804, - 0xa084, 0x4000, 0x0040, 0x45f8, 0x6803, 0x1000, 0x0078, 0x45ff, - 0x6804, 0xa084, 0x1000, 0x0040, 0x45ff, 0x6803, 0x0100, 0x6803, - 0x0000, 0x703f, 0x0000, 0x2069, 0x7936, 0x6804, 0xa082, 0x0006, - 0x00c0, 0x460c, 0x6807, 0x0000, 0x6830, 0xa082, 0x0003, 0x00c0, - 0x4613, 0x6833, 0x0000, 0x1078, 0x4d96, 0x1078, 0x4e56, 0x0d7f, - 0x0078, 0x463d, 0x0d7e, 0x2069, 0x7700, 0x6944, 0x6860, 0xa102, - 0x00c8, 0x463c, 0x2069, 0x7936, 0x6804, 0xa086, 0x0000, 0x00c0, - 0x463c, 0x6830, 0xa086, 0x0000, 0x00c0, 0x463c, 0x703f, 0x0001, - 0x6807, 0x0006, 0x6833, 0x0003, 0x2069, 0x0100, 0x6830, 0x689e, - 0x2069, 0x0140, 0x6803, 0x0600, 0x0d7f, 0x0078, 0x4642, 0x127e, - 0x2091, 0x8000, 0x7024, 0xa00d, 0x0040, 0x4653, 0x7020, 0x8001, - 0x7022, 0x00c0, 0x4653, 0x7023, 0x0009, 0x8109, 0x7126, 0x00c0, - 0x4653, 0x7028, 0x107a, 0x7030, 0xa00d, 0x0040, 0x4664, 0x702c, - 0x8001, 0x702e, 0x00c0, 0x4664, 0x702f, 0x0009, 0x8109, 0x7132, - 0x00c0, 0x4664, 0x7034, 0x107a, 0x7018, 0xa00d, 0x0040, 0x4675, - 0x7008, 0x8001, 0x700a, 0x00c0, 0x4675, 0x700b, 0x0009, 0x8109, - 0x711a, 0x00c0, 0x4675, 0x701c, 0x107a, 0x127f, 0x7004, 0x0079, - 0x4679, 0x46a0, 0x46a1, 0x46bd, 0x0e7e, 0x2071, 0x7949, 0x7018, - 0xa005, 0x00c0, 0x4687, 0x711a, 0x721e, 0x700b, 0x0009, 0x0e7f, - 0x007c, 0x0e7e, 0x007e, 0x2071, 0x7949, 0x701c, 0xa206, 0x00c0, - 0x4693, 0x701a, 0x701e, 0x007f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, - 0x7949, 0x6088, 0xa102, 0x0048, 0x469e, 0x618a, 0x0e7f, 0x007c, - 0x007c, 0x7110, 0x1078, 0x384c, 0x00c0, 0x46b3, 0x6088, 0x8001, - 0x0048, 0x46b3, 0x608a, 0x00c0, 0x46b3, 0x127e, 0x2091, 0x8000, - 0x1078, 0x4d96, 0x127f, 0x8108, 0xa182, 0x00ff, 0x0048, 0x46bb, - 0xa00e, 0x7007, 0x0002, 0x7112, 0x007c, 0x7014, 0x2060, 0x127e, - 0x2091, 0x8000, 0x6014, 0xa005, 0x0040, 0x46ec, 0x8001, 0x6016, - 0x00c0, 0x46ec, 0x611c, 0xa186, 0x0003, 0x0040, 0x46d3, 0xa186, - 0x0006, 0x00c0, 0x46ea, 0x6010, 0x2068, 0x6854, 0xa08a, 0x199a, - 0x0048, 0x46ea, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a, 0x0048, - 0x46e3, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, - 0x0078, 0x46ec, 0x1078, 0x68e3, 0x127f, 0xac88, 0x0008, 0x7116, - 0x2001, 0x7716, 0x2004, 0xa102, 0x0048, 0x46fa, 0x7017, 0x7e00, - 0x7007, 0x0000, 0x007c, 0x0e7e, 0x2071, 0x7949, 0x7027, 0x07d0, - 0x7023, 0x0009, 0x703b, 0x0002, 0x0e7f, 0x007c, 0x2001, 0x7952, - 0x2003, 0x0000, 0x007c, 0x0e7e, 0x2071, 0x7949, 0x7033, 0x07d0, - 0x702f, 0x0009, 0x0e7f, 0x007c, 0x2011, 0x7955, 0x2013, 0x0000, - 0x007c, 0x0e7e, 0x2071, 0x7949, 0x711a, 0x721e, 0x700b, 0x0009, - 0x0e7f, 0x007c, 0x0c7e, 0x2061, 0x79da, 0x0c7f, 0x007c, 0xa184, - 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x79da, 0x2060, 0x007c, - 0x6854, 0xa08a, 0x199a, 0x0048, 0x4737, 0x2001, 0x1999, 0xa005, - 0x00c0, 0x4747, 0x6944, 0x0c7e, 0x1078, 0x4727, 0x6014, 0x0c7f, - 0xa005, 0x00c0, 0x474c, 0x2001, 0x001e, 0x0078, 0x474c, 0xa08e, - 0xffff, 0x00c0, 0x474c, 0xa006, 0x8003, 0x800b, 0x810b, 0xa108, - 0x6116, 0x684c, 0xa08c, 0x00c0, 0xa18e, 0x00c0, 0x0040, 0x4787, - 0xd0b4, 0x00c0, 0x4763, 0xd0bc, 0x00c0, 0x4775, 0x2009, 0x0006, - 0x1078, 0x47aa, 0x007c, 0xd0fc, 0x0040, 0x4770, 0xa084, 0x0003, - 0xa08e, 0x0003, 0x0040, 0x47a3, 0xa08e, 0x0000, 0x00c0, 0x47a3, - 0x2009, 0x0043, 0x1078, 0x5d41, 0x007c, 0xd0fc, 0x0040, 0x4782, - 0xa084, 0x0003, 0xa08e, 0x0003, 0x0040, 0x47a3, 0xa08e, 0x0000, - 0x00c0, 0x47a3, 0x2009, 0x0042, 0x1078, 0x5d41, 0x007c, 0xd0fc, - 0x0040, 0x4799, 0xa084, 0x0003, 0xa08e, 0x0003, 0x0040, 0x47a3, - 0xa08e, 0x0002, 0x0040, 0x479d, 0x2009, 0x0041, 0x1078, 0x5d41, - 0x007c, 0x1078, 0x47a8, 0x0078, 0x4798, 0x2009, 0x0043, 0x1078, - 0x5d41, 0x0078, 0x4798, 0x2009, 0x0004, 0x1078, 0x47aa, 0x007c, - 0x2009, 0x0001, 0x6010, 0xa0ec, 0xf000, 0x0040, 0x47cf, 0x2068, - 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x00c0, 0x47c9, 0x694c, - 0xa18c, 0x8100, 0xa18e, 0x8100, 0x00c0, 0x47c9, 0x0c7e, 0x2009, - 0x0000, 0x1078, 0x4727, 0x6204, 0x8210, 0x0048, 0x47c8, 0x6206, - 0x0c7f, 0x1078, 0x3b92, 0x6010, 0xa06d, 0x10c0, 0x4730, 0x007c, - 0x157e, 0x0c7e, 0x20a9, 0x0010, 0x2061, 0x79da, 0x6000, 0x81ff, - 0x0040, 0x47dd, 0xa205, 0x0078, 0x47de, 0xa204, 0x6002, 0xace0, - 0x0008, 0x00f0, 0x47d6, 0x0c7f, 0x157f, 0x007c, 0x6808, 0xa005, - 0x0040, 0x47ee, 0x8001, 0x680a, 0xa085, 0x0001, 0x007c, 0x127e, - 0x2091, 0x2200, 0x2079, 0x7936, 0x127f, 0x0d7e, 0x2069, 0x7936, - 0x6803, 0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, 0x206a, - 0x0d7f, 0x007c, 0x0c7e, 0x6027, 0x0001, 0x7804, 0xa084, 0x0007, - 0x0079, 0x480a, 0x4814, 0x4839, 0x4894, 0x481a, 0x4839, 0x4812, - 0x4812, 0x4812, 0x1078, 0x12cd, 0x1078, 0x4706, 0x1078, 0x4d96, - 0x0c7f, 0x007c, 0x62c0, 0x82ff, 0x00c0, 0x4820, 0x0c7f, 0x007c, - 0x2011, 0x3558, 0x1078, 0x4689, 0x7828, 0xa092, 0x0002, 0x00c8, - 0x482f, 0x8000, 0x782a, 0x1078, 0x3588, 0x0078, 0x481e, 0x1078, - 0x3558, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0078, - 0x481e, 0x1078, 0x4706, 0x3c00, 0x007e, 0x2011, 0x0209, 0x20e1, - 0x4000, 0x2214, 0x007f, 0x20e0, 0x82ff, 0x0040, 0x4857, 0x62c0, - 0x82ff, 0x00c0, 0x4857, 0x782b, 0x0000, 0x7824, 0xa065, 0x1040, - 0x12cd, 0x2009, 0x0013, 0x1078, 0x5d41, 0x0c7f, 0x007c, 0x3900, - 0xa082, 0x7a7a, 0x00c8, 0x485e, 0x1078, 0x5c44, 0x0c7e, 0x7824, - 0xa065, 0x1040, 0x12cd, 0x7804, 0xa086, 0x0004, 0x0040, 0x48d9, - 0x7828, 0xa092, 0x2710, 0x00c8, 0x4874, 0x8000, 0x782a, 0x0c7f, - 0x1078, 0x568e, 0x0078, 0x4855, 0x6104, 0xa186, 0x0003, 0x00c0, - 0x488b, 0x0e7e, 0x2071, 0x7700, 0x70c8, 0x0e7f, 0xd08c, 0x0040, - 0x488b, 0x0c7e, 0x0e7e, 0x2061, 0x0100, 0x2071, 0x7700, 0x1078, - 0x3591, 0x0e7f, 0x0c7f, 0x1078, 0x76c7, 0x2009, 0x0014, 0x1078, - 0x5d41, 0x0c7f, 0x0078, 0x4855, 0x2001, 0x7952, 0x2003, 0x0000, - 0x62c0, 0x82ff, 0x00c0, 0x48a8, 0x782b, 0x0000, 0x7824, 0xa065, - 0x1040, 0x12cd, 0x2009, 0x0013, 0x1078, 0x5d8f, 0x0c7f, 0x007c, - 0x0c7e, 0x0d7e, 0x3900, 0xa082, 0x7a7a, 0x00c8, 0x48b1, 0x1078, - 0x5c44, 0x7824, 0xa005, 0x1040, 0x12cd, 0x781c, 0xa06d, 0x1040, - 0x12cd, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x1078, 0x5d1a, - 0x693c, 0x81ff, 0x1040, 0x12cd, 0x8109, 0x693e, 0x6854, 0xa015, - 0x0040, 0x48cd, 0x7a1e, 0x0078, 0x48cf, 0x7918, 0x791e, 0x7807, - 0x0000, 0x7827, 0x0000, 0x0d7f, 0x0c7f, 0x1078, 0x4d96, 0x0078, - 0x48a6, 0x6104, 0xa186, 0x0002, 0x0040, 0x48e4, 0xa186, 0x0004, - 0x0040, 0x48e4, 0x0078, 0x4868, 0x7808, 0xac06, 0x0040, 0x4868, - 0x1078, 0x4c9d, 0x1078, 0x498e, 0x0c7f, 0x1078, 0x4d96, 0x0078, - 0x4855, 0x0c7e, 0x6027, 0x0002, 0x2011, 0x7955, 0x2013, 0x0000, - 0x62c8, 0x82ff, 0x00c0, 0x490b, 0x62c4, 0x82ff, 0x00c0, 0x490b, - 0x793c, 0xa1e5, 0x0000, 0x0040, 0x4909, 0x2009, 0x0049, 0x1078, - 0x5d41, 0x0c7f, 0x007c, 0x3908, 0xa192, 0x7a7a, 0x00c8, 0x4912, - 0x1078, 0x5c44, 0x6017, 0x0010, 0x793c, 0x81ff, 0x0040, 0x4909, - 0x7944, 0xa192, 0x7530, 0x00c8, 0x4931, 0x8108, 0x7946, 0x1078, - 0x470b, 0x793c, 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0, - 0x492d, 0x6017, 0x0012, 0x0078, 0x4909, 0x6017, 0x0016, 0x0078, - 0x4909, 0x037e, 0x2019, 0x0001, 0x1078, 0x5880, 0x037f, 0x1078, - 0x76c7, 0x793c, 0x2160, 0x2009, 0x004a, 0x1078, 0x5d41, 0x0078, - 0x4909, 0x007e, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f, - 0x0000, 0x2c08, 0x2061, 0x7936, 0x6020, 0x8000, 0x6022, 0x6010, - 0xa005, 0x0040, 0x495c, 0xa080, 0x0003, 0x2102, 0x6112, 0x127f, - 0x0c7f, 0x017f, 0x007f, 0x007c, 0x6116, 0x6112, 0x0078, 0x4957, - 0x0d7e, 0x2069, 0x7936, 0x6000, 0xd0d4, 0x0040, 0x4975, 0x6820, - 0x8000, 0x6822, 0xa086, 0x0001, 0x00c0, 0x4970, 0x2c00, 0x681e, - 0x6804, 0xa084, 0x0007, 0x0079, 0x4d9e, 0xc0d5, 0x6002, 0x6818, - 0xa005, 0x0040, 0x4987, 0x6056, 0x605b, 0x0000, 0x007e, 0x2c00, - 0x681a, 0x0d7f, 0x685a, 0x2069, 0x7936, 0x0078, 0x4967, 0x6056, - 0x605a, 0x2c00, 0x681a, 0x681e, 0x0078, 0x4967, 0x007e, 0x017e, + 0x00c0, 0x4d31, 0xa484, 0x7000, 0xa086, 0x1000, 0x00c0, 0x4d20, + 0xa584, 0x0007, 0xd094, 0x00c0, 0x4d31, 0xd09c, 0x00c0, 0x4d31, + 0x1078, 0x4d4a, 0x0040, 0x4d31, 0x20e1, 0x3000, 0x7828, 0x7828, + 0x1078, 0x4d68, 0x147f, 0x137f, 0x157f, 0x2009, 0x8aaa, 0x2104, + 0xa005, 0x00c0, 0x4d1c, 0x007c, 0x1078, 0x5888, 0x0078, 0x4d1b, + 0xa484, 0x7000, 0x00c0, 0x4d31, 0x1078, 0x4d4a, 0x0040, 0x4d41, + 0x7000, 0xa084, 0xff00, 0xa086, 0x8100, 0x0040, 0x4d0c, 0x0078, + 0x4d41, 0x1078, 0x872e, 0xd5a4, 0x0040, 0x4d3f, 0x1078, 0x19e5, + 0x20e1, 0x9010, 0x2001, 0x0138, 0x2202, 0x0078, 0x4d45, 0x1078, + 0x4d4a, 0x20e1, 0x3000, 0x7828, 0x7828, 0x147f, 0x137f, 0x157f, + 0x0078, 0x4d1b, 0xa484, 0x01ff, 0x687e, 0xa005, 0x0040, 0x4d5c, + 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac, 0x20e1, 0x1000, 0x2ea0, + 0x2099, 0x020a, 0x53a5, 0x007c, 0x20a9, 0x000c, 0x20e1, 0x1000, + 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085, 0x0001, 0x0078, 0x4d5b, + 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000, 0x8007, 0xa196, 0x0000, + 0x00c0, 0x4d75, 0x0078, 0x4eef, 0x007c, 0xa196, 0x2000, 0x00c0, + 0x4d86, 0x6900, 0xa18e, 0x0001, 0x00c0, 0x4d82, 0x1078, 0x3541, + 0x0078, 0x4d74, 0x1078, 0x4d8e, 0x0078, 0x4d74, 0xa196, 0x8000, + 0x00c0, 0x4d74, 0x1078, 0x4f7b, 0x0078, 0x4d74, 0x0c7e, 0x7110, + 0xa18c, 0xff00, 0x810f, 0xa196, 0x0001, 0x0040, 0x4d9b, 0xa196, + 0x0023, 0x00c0, 0x4e90, 0xa08e, 0x0023, 0x00c0, 0x4dcc, 0x1078, + 0x4fee, 0x0040, 0x4e90, 0x7124, 0x610a, 0x7030, 0xa08e, 0x0200, + 0x00c0, 0x4db4, 0x7034, 0xa005, 0x00c0, 0x4e90, 0x2009, 0x0015, + 0x1078, 0x6939, 0x0078, 0x4e90, 0xa08e, 0x0210, 0x00c0, 0x4dbe, + 0x2009, 0x0015, 0x1078, 0x6939, 0x0078, 0x4e90, 0xa08e, 0x0100, + 0x00c0, 0x4e90, 0x7034, 0xa005, 0x00c0, 0x4e90, 0x2009, 0x0016, + 0x1078, 0x6939, 0x0078, 0x4e90, 0xa08e, 0x0022, 0x00c0, 0x4e90, + 0x7030, 0xa08e, 0x0300, 0x00c0, 0x4ddd, 0x7034, 0xa005, 0x00c0, + 0x4e90, 0x2009, 0x0017, 0x0078, 0x4e5c, 0xa08e, 0x0500, 0x00c0, + 0x4de9, 0x7034, 0xa005, 0x00c0, 0x4e90, 0x2009, 0x0018, 0x0078, + 0x4e5c, 0xa08e, 0x2010, 0x00c0, 0x4df1, 0x2009, 0x0019, 0x0078, + 0x4e5c, 0xa08e, 0x2110, 0x00c0, 0x4df9, 0x2009, 0x001a, 0x0078, + 0x4e5c, 0xa08e, 0x5200, 0x00c0, 0x4e05, 0x7034, 0xa005, 0x00c0, + 0x4e90, 0x2009, 0x001b, 0x0078, 0x4e5c, 0xa08e, 0x5000, 0x00c0, + 0x4e11, 0x7034, 0xa005, 0x00c0, 0x4e90, 0x2009, 0x001c, 0x0078, + 0x4e5c, 0xa08e, 0x1200, 0x00c0, 0x4e1d, 0x7034, 0xa005, 0x00c0, + 0x4e90, 0x2009, 0x0024, 0x0078, 0x4e5c, 0xa08c, 0xff00, 0xa18e, + 0x2400, 0x00c0, 0x4e27, 0x2009, 0x002d, 0x0078, 0x4e5c, 0xa08c, + 0xff00, 0xa18e, 0x5300, 0x00c0, 0x4e31, 0x2009, 0x002a, 0x0078, + 0x4e5c, 0xa08e, 0x0f00, 0x00c0, 0x4e39, 0x2009, 0x0020, 0x0078, + 0x4e5c, 0xa08e, 0x5300, 0x00c0, 0x4e3f, 0x0078, 0x4e5a, 0xa08e, + 0x6104, 0x00c0, 0x4e5a, 0x2011, 0x8d8d, 0x8208, 0x2204, 0xa082, + 0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011, 0x8015, 0x211c, 0x8108, + 0x2124, 0x1078, 0x317a, 0x8108, 0x00f0, 0x4e4c, 0x2009, 0x0023, + 0x0078, 0x4e5c, 0x2009, 0x001d, 0x017e, 0x2011, 0x8d83, 0x2204, + 0x8211, 0x220c, 0x1078, 0x2245, 0x00c0, 0x4e92, 0x1078, 0x3f53, + 0x00c0, 0x4e92, 0x6612, 0x6516, 0x86ff, 0x0040, 0x4e82, 0x017f, + 0x017e, 0xa186, 0x0017, 0x00c0, 0x4e82, 0x6868, 0xa606, 0x00c0, + 0x4e82, 0x686c, 0xa506, 0xa084, 0xff00, 0x00c0, 0x4e82, 0x6000, + 0xc0f5, 0x6002, 0x0c7e, 0x1078, 0x68a8, 0x0040, 0x4e95, 0x017f, + 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x017f, 0x1078, 0x6939, + 0x0c7f, 0x007c, 0x017f, 0x0078, 0x4e90, 0x0c7f, 0x0078, 0x4e92, + 0x0e7e, 0x0d7e, 0x2028, 0x2130, 0xa696, 0x00ff, 0x00c0, 0x4eb8, + 0xa596, 0xfffd, 0x00c0, 0x4ea8, 0x2009, 0x007f, 0x0078, 0x4eeb, + 0xa596, 0xfffe, 0x00c0, 0x4eb0, 0x2009, 0x007e, 0x0078, 0x4eeb, + 0xa596, 0xfffc, 0x00c0, 0x4eb8, 0x2009, 0x0080, 0x0078, 0x4eeb, + 0x2011, 0x0000, 0x2021, 0x0081, 0x20a9, 0x007e, 0x2071, 0x89b5, + 0x2e1c, 0x83ff, 0x00c0, 0x4eca, 0x82ff, 0x00c0, 0x4edf, 0x2410, + 0x0078, 0x4edf, 0x2368, 0x6f10, 0x007e, 0x2100, 0xa706, 0x007f, + 0x6b14, 0x00c0, 0x4ed9, 0xa346, 0x00c0, 0x4ed9, 0x2408, 0x0078, + 0x4eeb, 0x87ff, 0x00c0, 0x4edf, 0x83ff, 0x0040, 0x4ec4, 0x8420, + 0x8e70, 0x00f0, 0x4ec0, 0x82ff, 0x00c0, 0x4eea, 0xa085, 0x0001, + 0x0078, 0x4eec, 0x2208, 0xa006, 0x0d7f, 0x0e7f, 0x007c, 0xa084, + 0x0007, 0x0079, 0x4ef4, 0x007c, 0x4efc, 0x4efc, 0x4efc, 0x4efc, + 0x4efc, 0x4efd, 0x4f16, 0x4f64, 0x007c, 0x7110, 0xd1bc, 0x0040, + 0x4f15, 0x7120, 0x2160, 0xac8c, 0x0003, 0x00c0, 0x4f15, 0xac8a, + 0x8f00, 0x0048, 0x4f15, 0x6854, 0xac02, 0x00c8, 0x4f15, 0x7124, + 0x610a, 0x2009, 0x0046, 0x1078, 0x6939, 0x007c, 0x0c7e, 0x7110, + 0xd1bc, 0x00c0, 0x4f62, 0x2011, 0x8d83, 0x2204, 0x8211, 0x220c, + 0x1078, 0x2245, 0x00c0, 0x4f62, 0x1078, 0x3f8e, 0x00c0, 0x4f62, + 0x6000, 0xd0ec, 0x00c0, 0x4f62, 0x6204, 0xa294, 0xff00, 0x8217, + 0xa286, 0x0006, 0x00c0, 0x4f47, 0x0c7e, 0x1078, 0x68a8, 0x017f, + 0x0040, 0x4f62, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130, + 0x6122, 0x2009, 0x0044, 0x1078, 0x6939, 0x0078, 0x4f62, 0x0c7e, + 0x1078, 0x68a8, 0x017f, 0x0040, 0x4f62, 0x611a, 0x601f, 0x0004, + 0x7120, 0x610a, 0xa286, 0x0004, 0x00c0, 0x4f5a, 0x6007, 0x0005, + 0x0078, 0x4f5c, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x53e6, + 0x1078, 0x5888, 0x0c7f, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x4f7a, + 0x7020, 0x2060, 0xac84, 0x0003, 0x00c0, 0x4f7a, 0xac82, 0x8f00, + 0x0048, 0x4f7a, 0x6854, 0xac02, 0x00c8, 0x4f7a, 0x2009, 0x0045, + 0x1078, 0x6939, 0x007c, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa18e, + 0x0000, 0x00c0, 0x4f8b, 0xa084, 0x000f, 0xa08a, 0x0006, 0x10c8, + 0x12d2, 0x1079, 0x4f8c, 0x007c, 0x4f92, 0x4f93, 0x4f92, 0x4f92, + 0x4fd0, 0x4fdf, 0x007c, 0x7110, 0xd1bc, 0x00c0, 0x4fcf, 0x700c, + 0x7108, 0x1078, 0x2245, 0x00c0, 0x4fcf, 0x1078, 0x3f53, 0x00c0, + 0x4fcf, 0x6612, 0x6516, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, + 0x0004, 0x0040, 0x4faf, 0xa286, 0x0006, 0x00c0, 0x4fc0, 0x0c7e, + 0x1078, 0x68a8, 0x017f, 0x0040, 0x4fcf, 0x611a, 0x601f, 0x0005, + 0x7120, 0x610a, 0x2009, 0x0088, 0x1078, 0x6939, 0x0078, 0x4fcf, + 0x0c7e, 0x1078, 0x68a8, 0x017f, 0x0040, 0x4fcf, 0x611a, 0x601f, + 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x1078, 0x6939, 0x007c, + 0x7110, 0xd1bc, 0x0040, 0x4fde, 0x1078, 0x4fee, 0x0040, 0x4fde, + 0x7124, 0x610a, 0x2009, 0x0089, 0x1078, 0x6939, 0x007c, 0x7110, + 0xd1bc, 0x0040, 0x4fed, 0x1078, 0x4fee, 0x0040, 0x4fed, 0x7124, + 0x610a, 0x2009, 0x008a, 0x1078, 0x6939, 0x007c, 0x7020, 0x2060, + 0xac84, 0x0003, 0x00c0, 0x5001, 0xac82, 0x8f00, 0x0048, 0x5001, + 0x2001, 0x8815, 0x2004, 0xac02, 0x00c8, 0x5001, 0xa085, 0x0001, + 0x007c, 0xa006, 0x0078, 0x5000, 0x2071, 0x8ab5, 0x7003, 0x0003, + 0x700f, 0x0361, 0xa006, 0x701a, 0x7012, 0x7017, 0x8f00, 0x7007, + 0x0000, 0x7026, 0x702b, 0x623f, 0x7032, 0x7037, 0x6280, 0x703b, + 0x0002, 0x703f, 0x0000, 0x7043, 0xffff, 0x7047, 0xffff, 0x007c, + 0x2071, 0x8ab5, 0x00e0, 0x50df, 0x2091, 0x6000, 0x700c, 0x8001, + 0x700e, 0x00c0, 0x5098, 0x700f, 0x0361, 0x7007, 0x0001, 0x127e, + 0x2091, 0x8000, 0x7138, 0x8109, 0x713a, 0x00c0, 0x5096, 0x703b, + 0x0002, 0x2009, 0x0100, 0x2104, 0xa082, 0x0003, 0x00c8, 0x5096, + 0x703c, 0xa086, 0x0001, 0x00c0, 0x5073, 0x0d7e, 0x2069, 0x0140, + 0x6804, 0xa084, 0x4000, 0x0040, 0x5051, 0x6803, 0x1000, 0x0078, + 0x5058, 0x6804, 0xa084, 0x1000, 0x0040, 0x5058, 0x6803, 0x0100, + 0x6803, 0x0000, 0x703f, 0x0000, 0x2069, 0x8aa2, 0x6804, 0xa082, + 0x0006, 0x00c0, 0x5065, 0x6807, 0x0000, 0x6830, 0xa082, 0x0003, + 0x00c0, 0x506c, 0x6833, 0x0000, 0x1078, 0x5888, 0x1078, 0x5948, + 0x0d7f, 0x0078, 0x5096, 0x0d7e, 0x2069, 0x8800, 0x6944, 0x6860, + 0xa102, 0x00c8, 0x5095, 0x2069, 0x8aa2, 0x6804, 0xa086, 0x0000, + 0x00c0, 0x5095, 0x6830, 0xa086, 0x0000, 0x00c0, 0x5095, 0x703f, + 0x0001, 0x6807, 0x0006, 0x6833, 0x0003, 0x2069, 0x0100, 0x6830, + 0x689e, 0x2069, 0x0140, 0x6803, 0x0600, 0x0d7f, 0x0078, 0x509b, + 0x127e, 0x2091, 0x8000, 0x7024, 0xa00d, 0x0040, 0x50ac, 0x7020, + 0x8001, 0x7022, 0x00c0, 0x50ac, 0x7023, 0x0009, 0x8109, 0x7126, + 0x00c0, 0x50ac, 0x7028, 0x107a, 0x7030, 0xa00d, 0x0040, 0x50bd, + 0x702c, 0x8001, 0x702e, 0x00c0, 0x50bd, 0x702f, 0x0009, 0x8109, + 0x7132, 0x00c0, 0x50bd, 0x7034, 0x107a, 0x7040, 0xa005, 0x0040, + 0x50c5, 0x0050, 0x50c5, 0x8001, 0x7042, 0x7044, 0xa005, 0x0040, + 0x50cd, 0x0050, 0x50cd, 0x8001, 0x7046, 0x7018, 0xa00d, 0x0040, + 0x50de, 0x7008, 0x8001, 0x700a, 0x00c0, 0x50de, 0x700b, 0x0009, + 0x8109, 0x711a, 0x00c0, 0x50de, 0x701c, 0x107a, 0x127f, 0x7004, + 0x0079, 0x50e2, 0x5109, 0x510a, 0x5126, 0x0e7e, 0x2071, 0x8ab5, + 0x7018, 0xa005, 0x00c0, 0x50f0, 0x711a, 0x721e, 0x700b, 0x0009, + 0x0e7f, 0x007c, 0x0e7e, 0x007e, 0x2071, 0x8ab5, 0x701c, 0xa206, + 0x00c0, 0x50fc, 0x701a, 0x701e, 0x007f, 0x0e7f, 0x007c, 0x0e7e, + 0x2071, 0x8ab5, 0x6088, 0xa102, 0x0048, 0x5107, 0x618a, 0x0e7f, + 0x007c, 0x007c, 0x7110, 0x1078, 0x3f8e, 0x00c0, 0x511c, 0x6088, + 0x8001, 0x0048, 0x511c, 0x608a, 0x00c0, 0x511c, 0x127e, 0x2091, + 0x8000, 0x1078, 0x5888, 0x127f, 0x8108, 0xa182, 0x00ff, 0x0048, + 0x5124, 0xa00e, 0x7007, 0x0002, 0x7112, 0x007c, 0x7014, 0x2060, + 0x127e, 0x2091, 0x8000, 0x6014, 0xa005, 0x0040, 0x5155, 0x8001, + 0x6016, 0x00c0, 0x5155, 0x611c, 0xa186, 0x0003, 0x0040, 0x513c, + 0xa186, 0x0006, 0x00c0, 0x5153, 0x6010, 0x2068, 0x6854, 0xa08a, + 0x199a, 0x0048, 0x5153, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a, + 0x0048, 0x514c, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, + 0x6116, 0x0078, 0x5155, 0x1078, 0x7632, 0x127f, 0xac88, 0x000c, + 0x7116, 0x2001, 0x8816, 0x2004, 0xa102, 0x0048, 0x5163, 0x7017, + 0x8f00, 0x7007, 0x0000, 0x007c, 0x0e7e, 0x2071, 0x8ab5, 0x7027, + 0x07d0, 0x7023, 0x0009, 0x703b, 0x0002, 0x0e7f, 0x007c, 0x2001, + 0x8abe, 0x2003, 0x0000, 0x007c, 0x0e7e, 0x2071, 0x8ab5, 0x7132, + 0x702f, 0x0009, 0x0e7f, 0x007c, 0x2011, 0x8ac1, 0x2013, 0x0000, + 0x007c, 0x0e7e, 0x2071, 0x8ab5, 0x711a, 0x721e, 0x700b, 0x0009, + 0x0e7f, 0x007c, 0x0c7e, 0x2061, 0x8b24, 0x0c7f, 0x007c, 0xa184, + 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x8b24, 0x2060, 0x007c, + 0x6854, 0xa08a, 0x199a, 0x0048, 0x519f, 0x2001, 0x1999, 0xa005, + 0x00c0, 0x51ae, 0x0c7e, 0x2061, 0x8b24, 0x6014, 0x0c7f, 0xa005, + 0x00c0, 0x51b3, 0x2001, 0x001e, 0x0078, 0x51b3, 0xa08e, 0xffff, + 0x00c0, 0x51b3, 0xa006, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, + 0x684c, 0xa08c, 0x00c0, 0xa18e, 0x00c0, 0x0040, 0x51fc, 0xd0b4, + 0x00c0, 0x51ca, 0xd0bc, 0x00c0, 0x51ec, 0x2009, 0x0006, 0x1078, + 0x521b, 0x007c, 0xd0fc, 0x0040, 0x51d5, 0xa084, 0x0003, 0x0040, + 0x51d5, 0xa086, 0x0003, 0x00c0, 0x5214, 0x2009, 0x8873, 0x2104, + 0xd084, 0x0040, 0x51e7, 0x6118, 0xa188, 0x0027, 0x2104, 0xd08c, + 0x00c0, 0x51e7, 0x2009, 0x0042, 0x1078, 0x6939, 0x007c, 0x2009, + 0x0043, 0x1078, 0x6939, 0x007c, 0xd0fc, 0x0040, 0x51f7, 0xa084, + 0x0003, 0x0040, 0x51f7, 0xa086, 0x0003, 0x00c0, 0x5214, 0x2009, + 0x0042, 0x1078, 0x6939, 0x007c, 0xd0fc, 0x0040, 0x520a, 0xa084, + 0x0003, 0xa08e, 0x0002, 0x0040, 0x520e, 0x2009, 0x0041, 0x1078, + 0x6939, 0x007c, 0x1078, 0x5219, 0x0078, 0x5209, 0x2009, 0x0043, + 0x1078, 0x6939, 0x0078, 0x5209, 0x2009, 0x0004, 0x1078, 0x521b, + 0x007c, 0x2009, 0x0001, 0x6010, 0xa0ec, 0xf000, 0x0040, 0x5242, + 0x2068, 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x00c0, 0x523c, + 0x694c, 0xa18c, 0x8100, 0xa18e, 0x8100, 0x00c0, 0x523c, 0x0c7e, + 0x2061, 0x8b24, 0x6200, 0xd28c, 0x00c0, 0x523b, 0x6204, 0x8210, + 0x0048, 0x523b, 0x6206, 0x0c7f, 0x1078, 0x4376, 0x6010, 0xa06d, + 0x10c0, 0x5198, 0x007c, 0x157e, 0x0c7e, 0x2061, 0x8b24, 0x6000, + 0x81ff, 0x0040, 0x524e, 0xa205, 0x0078, 0x524f, 0xa204, 0x6002, + 0x0c7f, 0x157f, 0x007c, 0x6800, 0xd08c, 0x00c0, 0x525f, 0x6808, + 0xa005, 0x0040, 0x525f, 0x8001, 0x680a, 0xa085, 0x0001, 0x007c, + 0x127e, 0x2091, 0x2200, 0x2079, 0x8aa2, 0x127f, 0x0d7e, 0x2069, + 0x8aa2, 0x6803, 0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, + 0x206a, 0x0d7f, 0x007c, 0x0c7e, 0x6027, 0x0001, 0x7804, 0xa084, + 0x0007, 0x0079, 0x527b, 0x5285, 0x52aa, 0x5305, 0x528b, 0x52aa, + 0x5285, 0x5283, 0x5283, 0x1078, 0x12d2, 0x1078, 0x516f, 0x1078, + 0x5888, 0x0c7f, 0x007c, 0x62c0, 0x82ff, 0x00c0, 0x5291, 0x0c7f, + 0x007c, 0x2011, 0x3c35, 0x1078, 0x50f2, 0x7828, 0xa092, 0x0002, + 0x00c8, 0x52a0, 0x8000, 0x782a, 0x1078, 0x3c6a, 0x0078, 0x528f, + 0x1078, 0x3c35, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, + 0x0078, 0x528f, 0x1078, 0x516f, 0x3c00, 0x007e, 0x2011, 0x0209, + 0x20e1, 0x4000, 0x2214, 0x007f, 0x20e0, 0x82ff, 0x0040, 0x52c8, + 0x62c0, 0x82ff, 0x00c0, 0x52c8, 0x782b, 0x0000, 0x7824, 0xa065, + 0x1040, 0x12d2, 0x2009, 0x0013, 0x1078, 0x6939, 0x0c7f, 0x007c, + 0x3900, 0xa082, 0x8bc4, 0x00c8, 0x52cf, 0x1078, 0x683b, 0x0c7e, + 0x7824, 0xa065, 0x1040, 0x12d2, 0x7804, 0xa086, 0x0004, 0x0040, + 0x534a, 0x7828, 0xa092, 0x2710, 0x00c8, 0x52e5, 0x8000, 0x782a, + 0x0c7f, 0x1078, 0x6224, 0x0078, 0x52c6, 0x6104, 0xa186, 0x0003, + 0x00c0, 0x52fc, 0x0e7e, 0x2071, 0x8800, 0x70cc, 0x0e7f, 0xd08c, + 0x0040, 0x52fc, 0x0c7e, 0x0e7e, 0x2061, 0x0100, 0x2071, 0x8800, + 0x1078, 0x3c73, 0x0e7f, 0x0c7f, 0x1078, 0x8781, 0x2009, 0x0014, + 0x1078, 0x6939, 0x0c7f, 0x0078, 0x52c6, 0x2001, 0x8abe, 0x2003, + 0x0000, 0x62c0, 0x82ff, 0x00c0, 0x5319, 0x782b, 0x0000, 0x7824, + 0xa065, 0x1040, 0x12d2, 0x2009, 0x0013, 0x1078, 0x6990, 0x0c7f, + 0x007c, 0x0c7e, 0x0d7e, 0x3900, 0xa082, 0x8bc4, 0x00c8, 0x5322, + 0x1078, 0x683b, 0x7824, 0xa005, 0x1040, 0x12d2, 0x781c, 0xa06d, + 0x1040, 0x12d2, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x1078, + 0x690e, 0x693c, 0x81ff, 0x1040, 0x12d2, 0x8109, 0x693e, 0x6854, + 0xa015, 0x0040, 0x533e, 0x7a1e, 0x0078, 0x5340, 0x7918, 0x791e, + 0x7807, 0x0000, 0x7827, 0x0000, 0x0d7f, 0x0c7f, 0x1078, 0x5888, + 0x0078, 0x5317, 0x6104, 0xa186, 0x0002, 0x0040, 0x5355, 0xa186, + 0x0004, 0x0040, 0x5355, 0x0078, 0x52d9, 0x7808, 0xac06, 0x0040, + 0x52d9, 0x1078, 0x578f, 0x1078, 0x53e6, 0x0c7f, 0x1078, 0x5888, + 0x0078, 0x52c6, 0x0c7e, 0x6027, 0x0002, 0x62c8, 0x82ff, 0x00c0, + 0x537c, 0x62c4, 0x82ff, 0x00c0, 0x537c, 0x793c, 0xa1e5, 0x0000, + 0x0040, 0x5376, 0x2009, 0x0049, 0x1078, 0x6939, 0x2011, 0x8ac1, + 0x2013, 0x0000, 0x0c7f, 0x007c, 0x3908, 0xa192, 0x8bc4, 0x00c8, + 0x5383, 0x1078, 0x683b, 0x6017, 0x0010, 0x793c, 0x81ff, 0x0040, + 0x5376, 0x793c, 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0, + 0x5395, 0x6017, 0x0012, 0x0078, 0x537a, 0x6017, 0x0016, 0x0078, + 0x537a, 0x007e, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f, + 0x0000, 0x2c08, 0x2061, 0x8aa2, 0x6020, 0x8000, 0x6022, 0x6010, + 0xa005, 0x0040, 0x53b4, 0xa080, 0x0003, 0x2102, 0x6112, 0x127f, + 0x0c7f, 0x017f, 0x007f, 0x007c, 0x6116, 0x6112, 0x0078, 0x53af, + 0x0d7e, 0x2069, 0x8aa2, 0x6000, 0xd0d4, 0x0040, 0x53cd, 0x6820, + 0x8000, 0x6822, 0xa086, 0x0001, 0x00c0, 0x53c8, 0x2c00, 0x681e, + 0x6804, 0xa084, 0x0007, 0x0079, 0x5890, 0xc0d5, 0x6002, 0x6818, + 0xa005, 0x0040, 0x53df, 0x6056, 0x605b, 0x0000, 0x007e, 0x2c00, + 0x681a, 0x0d7f, 0x685a, 0x2069, 0x8aa2, 0x0078, 0x53bf, 0x6056, + 0x605a, 0x2c00, 0x681a, 0x681e, 0x0078, 0x53bf, 0x007e, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, - 0x7936, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040, 0x49a9, + 0x8aa2, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040, 0x5401, 0xa080, 0x0003, 0x2102, 0x610a, 0x127f, 0x0c7f, 0x017f, 0x007f, - 0x007c, 0x610e, 0x610a, 0x0078, 0x49a4, 0x0c7e, 0x600f, 0x0000, - 0x2c08, 0x2061, 0x7936, 0x6034, 0xa005, 0x0040, 0x49bd, 0xa080, + 0x007c, 0x610e, 0x610a, 0x0078, 0x53fc, 0x0c7e, 0x600f, 0x0000, + 0x2c08, 0x2061, 0x8aa2, 0x6034, 0xa005, 0x0040, 0x5415, 0xa080, 0x0003, 0x2102, 0x6136, 0x0c7f, 0x007c, 0x613a, 0x6136, 0x0078, - 0x49bb, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x007e, - 0x127e, 0x2071, 0x7936, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, - 0x8cff, 0x0040, 0x4a23, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, - 0x00c0, 0x4a1e, 0x703c, 0xac06, 0x00c0, 0x49e3, 0x6003, 0x000a, - 0x630a, 0x0078, 0x4a1e, 0x7038, 0xac36, 0x00c0, 0x49e9, 0x660c, - 0x763a, 0x7034, 0xac36, 0x00c0, 0x49f7, 0x2c00, 0xaf36, 0x0040, - 0x49f5, 0x2f00, 0x7036, 0x0078, 0x49f7, 0x7037, 0x0000, 0x660c, - 0x067e, 0x2c00, 0xaf06, 0x0040, 0x4a00, 0x7e0e, 0x0078, 0x4a01, - 0x2678, 0x600f, 0x0000, 0x1078, 0x6a58, 0x0040, 0x4a19, 0x6010, - 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x4a2c, 0x6837, 0x0103, - 0x6b4a, 0x6847, 0x0000, 0x1078, 0x6c54, 0x1078, 0x3b92, 0x1078, - 0x6ba9, 0x1078, 0x6bb6, 0x0c7f, 0x0078, 0x49d0, 0x2c78, 0x600c, - 0x2060, 0x0078, 0x49d0, 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, - 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, - 0x4a0e, 0x1078, 0x75fd, 0x0078, 0x4a19, 0x007e, 0x067e, 0x0c7e, - 0x0d7e, 0x0f7e, 0x2031, 0x0000, 0x127e, 0x2091, 0x8000, 0x2079, - 0x7936, 0x7838, 0xa065, 0x0040, 0x4a6c, 0x600c, 0x007e, 0x600f, - 0x0000, 0x783c, 0xac06, 0x00c0, 0x4a53, 0x6003, 0x000a, 0x630a, - 0x2c30, 0x0078, 0x4a69, 0x1078, 0x6a58, 0x0040, 0x4a67, 0x6010, - 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x4a75, 0x6837, 0x0103, - 0x6b4a, 0x6847, 0x0000, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x1078, - 0x6bb6, 0x007f, 0x0078, 0x4a42, 0x7e3a, 0x7e36, 0x127f, 0x0f7f, - 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x601c, 0xa086, 0x0006, - 0x00c0, 0x4a5e, 0x1078, 0x75fd, 0x0078, 0x4a67, 0x027e, 0x1078, - 0x4a92, 0x1078, 0x4b2b, 0x027f, 0x007c, 0x0f7e, 0x127e, 0x2079, - 0x7936, 0x2091, 0x8000, 0x1078, 0x4bc2, 0x1078, 0x4c2a, 0x127f, - 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e, - 0x127e, 0x2091, 0x8000, 0x2071, 0x7936, 0x7614, 0x2660, 0x2678, - 0x8cff, 0x0040, 0x4b1a, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, - 0x00c0, 0x4b15, 0x7024, 0xac06, 0x00c0, 0x4ad8, 0x2069, 0x0100, - 0x68c0, 0xa005, 0x0040, 0x4ad3, 0x1078, 0x569c, 0x68c3, 0x0000, - 0x1078, 0x5b4a, 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, - 0xa384, 0x1000, 0x0040, 0x4ac8, 0x6803, 0x0100, 0x6803, 0x0000, - 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x4ad0, 0x6827, 0x0001, - 0x037f, 0x0078, 0x4ad8, 0x6003, 0x0009, 0x630a, 0x0078, 0x4b15, - 0x7014, 0xac36, 0x00c0, 0x4ade, 0x660c, 0x7616, 0x7010, 0xac36, - 0x00c0, 0x4aec, 0x2c00, 0xaf36, 0x0040, 0x4aea, 0x2f00, 0x7012, - 0x0078, 0x4aec, 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, - 0x0040, 0x4af5, 0x7e0e, 0x0078, 0x4af6, 0x2678, 0x600f, 0x0000, - 0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, 0x4b0e, 0x601c, 0xa086, - 0x0003, 0x00c0, 0x4b22, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, - 0x1078, 0x6c54, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x1078, 0x6bb6, - 0x1078, 0x5a1a, 0x0c7f, 0x0078, 0x4aa0, 0x2c78, 0x600c, 0x2060, - 0x0078, 0x4aa0, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, - 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x4b03, 0x1078, - 0x75fd, 0x0078, 0x4b0e, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, - 0xa280, 0x7820, 0x2004, 0xa065, 0x0040, 0x4bbe, 0x0f7e, 0x0e7e, - 0x0d7e, 0x067e, 0x2071, 0x7936, 0x6654, 0x7018, 0xac06, 0x00c0, - 0x4b42, 0x761a, 0x701c, 0xac06, 0x00c0, 0x4b4e, 0x86ff, 0x00c0, - 0x4b4d, 0x7018, 0x701e, 0x0078, 0x4b4e, 0x761e, 0x6058, 0xa07d, - 0x0040, 0x4b53, 0x7e56, 0xa6ed, 0x0000, 0x0040, 0x4b59, 0x2f00, - 0x685a, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, - 0x6002, 0x1078, 0x37c5, 0x0040, 0x4bba, 0x7624, 0x86ff, 0x0040, - 0x4baa, 0xa680, 0x0004, 0x2004, 0xad06, 0x00c0, 0x4baa, 0x0d7e, - 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x4ba1, 0x1078, 0x569c, - 0x68c3, 0x0000, 0x1078, 0x5b4a, 0x7027, 0x0000, 0x037e, 0x2069, - 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x4b8a, 0x6803, 0x0100, - 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x4b92, - 0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040, - 0x4b9b, 0x8001, 0x603e, 0x2660, 0x1078, 0x6bb6, 0x0c7f, 0x0078, - 0x4baa, 0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, - 0x0078, 0x4b61, 0x8dff, 0x0040, 0x4bb6, 0x6837, 0x0103, 0x6b4a, - 0x6847, 0x0000, 0x1078, 0x6c54, 0x1078, 0x3b92, 0x1078, 0x5a1a, - 0x0078, 0x4b61, 0x067f, 0x0d7f, 0x0e7f, 0x0f7f, 0x127f, 0x007f, - 0x0c7f, 0x007c, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x2031, 0x0000, - 0x7814, 0xa065, 0x0040, 0x4c1a, 0x600c, 0x007e, 0x600f, 0x0000, - 0x7824, 0xac06, 0x00c0, 0x4bff, 0x2069, 0x0100, 0x68c0, 0xa005, - 0x0040, 0x4bf9, 0x1078, 0x569c, 0x68c3, 0x0000, 0x1078, 0x5b4a, - 0x7827, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, - 0x0040, 0x4bee, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, - 0x6824, 0xd084, 0x0040, 0x4bf6, 0x6827, 0x0001, 0x037f, 0x0078, - 0x4bff, 0x6003, 0x0009, 0x630a, 0x2c30, 0x0078, 0x4c17, 0x6010, - 0x2068, 0x1078, 0x6a58, 0x0040, 0x4c13, 0x601c, 0xa086, 0x0003, - 0x00c0, 0x4c21, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, - 0x3b92, 0x1078, 0x6ba9, 0x1078, 0x6bb6, 0x1078, 0x5a1a, 0x007f, - 0x0078, 0x4bc9, 0x7e16, 0x7e12, 0x0d7f, 0x0c7f, 0x067f, 0x007f, - 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x4c0a, 0x1078, 0x75fd, - 0x0078, 0x4c13, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x7818, 0xa065, - 0x0040, 0x4c96, 0x6054, 0x007e, 0x6057, 0x0000, 0x605b, 0x0000, - 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x37c5, 0x0040, 0x4c93, - 0x7e24, 0x86ff, 0x0040, 0x4c85, 0xa680, 0x0004, 0x2004, 0xad06, - 0x00c0, 0x4c85, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, - 0x4c7c, 0x1078, 0x569c, 0x68c3, 0x0000, 0x1078, 0x5b4a, 0x7827, + 0x5413, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x017e, + 0x007e, 0x127e, 0x2071, 0x8aa2, 0x7638, 0x2660, 0x2678, 0x2091, + 0x8000, 0x8cff, 0x0040, 0x548c, 0x6018, 0xa080, 0x0028, 0x2004, + 0xa206, 0x00c0, 0x5487, 0x88ff, 0x0040, 0x543a, 0x6020, 0xa106, + 0x00c0, 0x5487, 0x703c, 0xac06, 0x00c0, 0x544c, 0x037e, 0x2019, + 0x0001, 0x1078, 0x642d, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, + 0x0000, 0x7047, 0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x5452, + 0x660c, 0x763a, 0x7034, 0xac36, 0x00c0, 0x5460, 0x2c00, 0xaf36, + 0x0040, 0x545e, 0x2f00, 0x7036, 0x0078, 0x5460, 0x7037, 0x0000, + 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5469, 0x7e0e, 0x0078, + 0x546a, 0x2678, 0x600f, 0x0000, 0x1078, 0x77ed, 0x0040, 0x5482, + 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5496, 0x6837, + 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x7a46, 0x1078, 0x4376, + 0x1078, 0x799b, 0x1078, 0x79a8, 0x0c7f, 0x0078, 0x5429, 0x2c78, + 0x600c, 0x2060, 0x0078, 0x5429, 0x127f, 0x007f, 0x017f, 0x027f, + 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086, + 0x0006, 0x00c0, 0x5477, 0x1078, 0x86aa, 0x0078, 0x5482, 0x007e, + 0x067e, 0x0c7e, 0x0d7e, 0x0f7e, 0x2031, 0x0000, 0x127e, 0x2091, + 0x8000, 0x2079, 0x8aa2, 0x7838, 0xa065, 0x0040, 0x54de, 0x600c, + 0x007e, 0x600f, 0x0000, 0x783c, 0xac06, 0x00c0, 0x54c5, 0x037e, + 0x2019, 0x0001, 0x1078, 0x642d, 0x7833, 0x0000, 0x783f, 0x0000, + 0x7843, 0x0000, 0x7847, 0x0000, 0x037f, 0x1078, 0x77ed, 0x0040, + 0x54d9, 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x54e7, + 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4376, 0x1078, + 0x799b, 0x1078, 0x79a8, 0x007f, 0x0078, 0x54ac, 0x7e3a, 0x7e36, + 0x127f, 0x0f7f, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x601c, + 0xa086, 0x0006, 0x00c0, 0x54d0, 0x1078, 0x86aa, 0x0078, 0x54d9, + 0x017e, 0x027e, 0x087e, 0x2041, 0x0000, 0x1078, 0x550a, 0x1078, + 0x55ae, 0x087f, 0x027f, 0x017f, 0x007c, 0x0f7e, 0x127e, 0x2079, + 0x8aa2, 0x2091, 0x8000, 0x1078, 0x5647, 0x1078, 0x56b1, 0x127f, + 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x017e, + 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0x8aa2, 0x7614, 0x2660, + 0x2678, 0x8cff, 0x0040, 0x559c, 0x6018, 0xa080, 0x0028, 0x2004, + 0xa206, 0x00c0, 0x5597, 0x88ff, 0x0040, 0x552a, 0x6020, 0xa106, + 0x00c0, 0x5597, 0x7024, 0xac06, 0x00c0, 0x555a, 0x2069, 0x0100, + 0x68c0, 0xa005, 0x0040, 0x5555, 0x1078, 0x516f, 0x1078, 0x6232, + 0x68c3, 0x0000, 0x1078, 0x6741, 0x7027, 0x0000, 0x037e, 0x2069, + 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x554a, 0x6803, 0x0100, + 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x5552, + 0x6827, 0x0001, 0x037f, 0x0078, 0x555a, 0x6003, 0x0009, 0x630a, + 0x0078, 0x5597, 0x7014, 0xac36, 0x00c0, 0x5560, 0x660c, 0x7616, + 0x7010, 0xac36, 0x00c0, 0x556e, 0x2c00, 0xaf36, 0x0040, 0x556c, + 0x2f00, 0x7012, 0x0078, 0x556e, 0x7013, 0x0000, 0x660c, 0x067e, + 0x2c00, 0xaf06, 0x0040, 0x5577, 0x7e0e, 0x0078, 0x5578, 0x2678, + 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, 0x5590, + 0x601c, 0xa086, 0x0003, 0x00c0, 0x55a5, 0x6837, 0x0103, 0x6b4a, + 0x6847, 0x0000, 0x1078, 0x7a46, 0x1078, 0x4376, 0x1078, 0x799b, + 0x1078, 0x79a8, 0x1078, 0x6601, 0x0c7f, 0x0078, 0x5519, 0x2c78, + 0x600c, 0x2060, 0x0078, 0x5519, 0x127f, 0x007f, 0x017f, 0x067f, + 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, + 0x00c0, 0x5585, 0x1078, 0x86aa, 0x0078, 0x5590, 0x0c7e, 0x007e, + 0x127e, 0x2091, 0x8000, 0xa280, 0x8934, 0x2004, 0xa065, 0x0040, + 0x5643, 0x0f7e, 0x0e7e, 0x0d7e, 0x067e, 0x2071, 0x8aa2, 0x6654, + 0x7018, 0xac06, 0x00c0, 0x55c5, 0x761a, 0x701c, 0xac06, 0x00c0, + 0x55d1, 0x86ff, 0x00c0, 0x55d0, 0x7018, 0x701e, 0x0078, 0x55d1, + 0x761e, 0x6058, 0xa07d, 0x0040, 0x55d6, 0x7e56, 0xa6ed, 0x0000, + 0x0040, 0x55dc, 0x2f00, 0x685a, 0x6057, 0x0000, 0x605b, 0x0000, + 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x3ed6, 0x0040, 0x563f, + 0x7624, 0x86ff, 0x0040, 0x562f, 0xa680, 0x0004, 0x2004, 0xad06, + 0x00c0, 0x562f, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, + 0x5626, 0x1078, 0x516f, 0x1078, 0x6232, 0x68c3, 0x0000, 0x1078, + 0x6741, 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, + 0x1000, 0x0040, 0x560f, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, + 0x0100, 0x6824, 0xd084, 0x0040, 0x5617, 0x6827, 0x0001, 0x037f, + 0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040, 0x5620, 0x8001, 0x603e, + 0x2660, 0x1078, 0x79a8, 0x0c7f, 0x0078, 0x562f, 0x0d7f, 0x0c7e, + 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x55e4, 0x8dff, + 0x0040, 0x563b, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, + 0x7a46, 0x1078, 0x4376, 0x1078, 0x6601, 0x0078, 0x55e4, 0x067f, + 0x0d7f, 0x0e7f, 0x0f7f, 0x127f, 0x007f, 0x0c7f, 0x007c, 0x007e, + 0x067e, 0x0c7e, 0x0d7e, 0x2031, 0x0000, 0x7814, 0xa065, 0x0040, + 0x56a1, 0x600c, 0x007e, 0x600f, 0x0000, 0x7824, 0xac06, 0x00c0, + 0x5686, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x5680, 0x1078, + 0x516f, 0x1078, 0x6232, 0x68c3, 0x0000, 0x1078, 0x6741, 0x7827, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, - 0x4c65, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, - 0xd084, 0x0040, 0x4c6d, 0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e, - 0x603c, 0xa005, 0x0040, 0x4c76, 0x8001, 0x603e, 0x2660, 0x1078, - 0x6bb6, 0x0c7f, 0x0078, 0x4c85, 0x0d7f, 0x0c7e, 0x2660, 0x6003, - 0x0009, 0x630a, 0x0c7f, 0x0078, 0x4c3c, 0x8dff, 0x0040, 0x4c8f, - 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x3b92, 0x1078, - 0x5a1a, 0x0078, 0x4c3c, 0x007f, 0x0078, 0x4c2f, 0x781e, 0x781a, - 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x0e7e, 0x0c7e, 0x2071, - 0x7936, 0x7004, 0xa084, 0x0007, 0x0079, 0x4ca6, 0x4cb0, 0x4cb3, - 0x4ccc, 0x4ce8, 0x4d2d, 0x4cb0, 0x4cb0, 0x4cae, 0x1078, 0x12cd, - 0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065, 0x0040, 0x4cc1, 0x7020, - 0x8001, 0x7022, 0x600c, 0xa015, 0x0040, 0x4cc8, 0x7216, 0x600f, - 0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, - 0x7216, 0x7212, 0x0078, 0x4cc1, 0x6018, 0x2060, 0x1078, 0x37c5, - 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022, 0x0040, 0x4cdd, - 0x6054, 0xa015, 0x0040, 0x4ce4, 0x721e, 0x7007, 0x0000, 0x7027, - 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7218, 0x721e, 0x0078, 0x4cdd, - 0x7024, 0xa065, 0x0040, 0x4d2a, 0x700c, 0xac06, 0x00c0, 0x4cff, - 0x1078, 0x5a1a, 0x600c, 0xa015, 0x0040, 0x4cfb, 0x720e, 0x600f, - 0x0000, 0x0078, 0x4d28, 0x720e, 0x720a, 0x0078, 0x4d28, 0x7014, - 0xac06, 0x00c0, 0x4d12, 0x1078, 0x5a1a, 0x600c, 0xa015, 0x0040, - 0x4d0e, 0x7216, 0x600f, 0x0000, 0x0078, 0x4d28, 0x7216, 0x7212, - 0x0078, 0x4d28, 0x6018, 0x2060, 0x1078, 0x37c5, 0x6000, 0xc0dc, - 0x6002, 0x1078, 0x5a1a, 0x701c, 0xa065, 0x0040, 0x4d28, 0x6054, - 0xa015, 0x0040, 0x4d26, 0x721e, 0x0078, 0x4d28, 0x7218, 0x721e, - 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065, 0x0040, - 0x4d3a, 0x1078, 0x5a1a, 0x600c, 0xa015, 0x0040, 0x4d41, 0x720e, - 0x600f, 0x0000, 0x1078, 0x5b4a, 0x7027, 0x0000, 0x0c7f, 0x0e7f, - 0x007c, 0x720e, 0x720a, 0x0078, 0x4d3a, 0x0d7e, 0x2069, 0x7936, - 0x6830, 0xa084, 0x0003, 0x0079, 0x4d4d, 0x4d53, 0x4d55, 0x4d7b, - 0x4d53, 0x1078, 0x12cd, 0x0d7f, 0x007c, 0x0c7e, 0x6840, 0xa086, - 0x0001, 0x0040, 0x4d71, 0x683c, 0xa065, 0x0040, 0x4d66, 0x600c, - 0xa015, 0x0040, 0x4d6d, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, - 0x683f, 0x0000, 0x0c7f, 0x0d7f, 0x007c, 0x683a, 0x6836, 0x0078, - 0x4d66, 0x6843, 0x0000, 0x6838, 0xa065, 0x0040, 0x4d66, 0x6003, - 0x0003, 0x0078, 0x4d66, 0x0c7e, 0x6843, 0x0000, 0x6847, 0x0000, - 0x683c, 0xa065, 0x0040, 0x4d93, 0x600c, 0xa015, 0x0040, 0x4d8f, - 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000, 0x0078, 0x4d93, 0x683f, - 0x0000, 0x683a, 0x6836, 0x0c7f, 0x0d7f, 0x007c, 0x0d7e, 0x2069, - 0x7936, 0x6804, 0xa084, 0x0007, 0x0079, 0x4d9e, 0x4da8, 0x4e45, - 0x4e45, 0x4e45, 0x4e45, 0x4e47, 0x4e45, 0x4da6, 0x1078, 0x12cd, - 0x6820, 0xa005, 0x00c0, 0x4dae, 0x0d7f, 0x007c, 0x0c7e, 0x680c, - 0xa065, 0x0040, 0x4dbd, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, - 0x1078, 0x4e8d, 0x0c7f, 0x0d7f, 0x007c, 0x6814, 0xa065, 0x0040, - 0x4dcb, 0x6807, 0x0001, 0x6826, 0x682b, 0x0000, 0x1078, 0x4e8d, - 0x0c7f, 0x0d7f, 0x007c, 0x0e7e, 0x037e, 0x6a1c, 0xa2f5, 0x0000, - 0x0040, 0x4e40, 0x704c, 0xa00d, 0x0040, 0x4dda, 0x7088, 0xa005, - 0x0040, 0x4df2, 0x7054, 0xa075, 0x0040, 0x4de3, 0xa20e, 0x0040, - 0x4e40, 0x0078, 0x4de8, 0x6818, 0xa20e, 0x0040, 0x4e40, 0x2070, - 0x704c, 0xa00d, 0x0040, 0x4dda, 0x7088, 0xa005, 0x00c0, 0x4dda, - 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, 0x00c8, 0x4dda, 0x1078, - 0x5ce9, 0x0040, 0x4e40, 0x8318, 0x733e, 0x6112, 0x2e10, 0x621a, - 0xa180, 0x0015, 0x2004, 0xa08a, 0x199a, 0x0048, 0x4e09, 0x2001, - 0x1999, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x037f, 0x0f7e, - 0x2c78, 0x71a0, 0xd1bc, 0x0040, 0x4e22, 0x7100, 0xd1f4, 0x0040, - 0x4e1e, 0x7114, 0xa18c, 0x00ff, 0x0078, 0x4e27, 0x2009, 0x0000, - 0x0078, 0x4e27, 0xa1e0, 0x2329, 0x2c0c, 0xa18c, 0x00ff, 0x2061, - 0x0100, 0x619a, 0x1078, 0x52de, 0x7300, 0xc3dd, 0x7302, 0x6807, - 0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000, 0x781f, 0x0003, 0x7803, - 0x0001, 0x7807, 0x0040, 0x0f7f, 0x0e7f, 0x0c7f, 0x0d7f, 0x007c, - 0x037f, 0x0e7f, 0x0c7f, 0x0078, 0x4e3e, 0x0d7f, 0x007c, 0x0c7e, - 0x680c, 0xa065, 0x0040, 0x4e53, 0x6807, 0x0004, 0x6826, 0x682b, - 0x0000, 0x1078, 0x4e8d, 0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0d7e, - 0x2069, 0x7936, 0x6830, 0xa086, 0x0000, 0x00c0, 0x4e74, 0x6838, - 0xa07d, 0x0040, 0x4e74, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, - 0x127e, 0x0f7e, 0x2091, 0x2200, 0x027f, 0x1078, 0x1a44, 0x00c0, - 0x4e77, 0x127f, 0x1078, 0x5571, 0x0d7f, 0x0f7f, 0x007c, 0x127f, - 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0xa015, 0x0040, 0x4e89, - 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0078, - 0x4e74, 0x683a, 0x6836, 0x0078, 0x4e83, 0x601c, 0xa084, 0x000f, - 0x1079, 0x4e93, 0x007c, 0x4e9c, 0x4ea1, 0x51a8, 0x529e, 0x4ea1, - 0x51a8, 0x529e, 0x4e9c, 0x4ea1, 0x1078, 0x4c9d, 0x1078, 0x4d96, - 0x007c, 0x157e, 0x137e, 0x147e, 0x0c7e, 0x0f7e, 0x6004, 0xa08a, - 0x0030, 0x10c8, 0x12cd, 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, - 0x4ebe, 0x7900, 0xd1f4, 0x0040, 0x4eba, 0x7914, 0xa18c, 0x00ff, - 0x0078, 0x4ec3, 0x2009, 0x0000, 0x0078, 0x4ec3, 0xa1f8, 0x2329, - 0x2f0c, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0x1079, - 0x4ecf, 0x0f7f, 0x0c7f, 0x147f, 0x137f, 0x157f, 0x007c, 0x4f01, - 0x4f39, 0x4f51, 0x4fd0, 0x4ffd, 0x5005, 0x5026, 0x5037, 0x5048, - 0x5050, 0x5061, 0x5050, 0x50a9, 0x5037, 0x50ca, 0x50d2, 0x5048, - 0x50d2, 0x50e3, 0x4eff, 0x4eff, 0x4eff, 0x4eff, 0x4eff, 0x4eff, - 0x4eff, 0x4eff, 0x4eff, 0x4eff, 0x4eff, 0x4eff, 0x5758, 0x576d, - 0x5790, 0x57b4, 0x5026, 0x4eff, 0x5026, 0x5050, 0x4eff, 0x4f51, - 0x4fd0, 0x4eff, 0x5c64, 0x5050, 0x4eff, 0x5c87, 0x5050, 0x1078, - 0x12cd, 0x20a1, 0x020b, 0x1078, 0x50f8, 0x20a3, 0x5200, 0x20a3, - 0x0000, 0x0d7e, 0x2069, 0x7751, 0x6804, 0xd084, 0x0040, 0x4f1b, - 0x6828, 0x20a3, 0x0000, 0x017e, 0x1078, 0x2094, 0x21a2, 0x017f, - 0x0d7f, 0x0078, 0x4f20, 0x0d7f, 0x20a3, 0x0000, 0x20a3, 0x0000, - 0x20a9, 0x0004, 0x2099, 0x7705, 0x53a6, 0x20a9, 0x0004, 0x2099, - 0x7701, 0x53a6, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, - 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, 0x5688, - 0x007c, 0x20a1, 0x020b, 0x1078, 0x50f8, 0x20a3, 0x0500, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a9, - 0x0004, 0x2099, 0x7705, 0x53a6, 0x60c3, 0x0010, 0x1078, 0x5688, - 0x007c, 0x20a1, 0x020b, 0x1078, 0x50f8, 0x7818, 0xa080, 0x0028, - 0x2004, 0xa086, 0x007e, 0x00c0, 0x4f64, 0x20a3, 0x0400, 0x620c, - 0xc2b4, 0x620e, 0x0078, 0x4f66, 0x20a3, 0x0300, 0x20a3, 0x0000, - 0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, 0x4f9f, - 0x2099, 0x7920, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, 0xa084, - 0x3fff, 0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000, - 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0x7705, - 0x53a6, 0x20a9, 0x0004, 0x2099, 0x7701, 0x53a6, 0x20a9, 0x0010, - 0x20a3, 0x0000, 0x00f0, 0x4f90, 0x2099, 0x7928, 0x33a6, 0x20a9, - 0x0007, 0x20a3, 0x0000, 0x00f0, 0x4f99, 0x0078, 0x4fbf, 0x2099, - 0x7920, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004, 0x2099, 0x7705, - 0x53a6, 0x20a9, 0x0004, 0x2099, 0x7701, 0x53a6, 0x20a9, 0x0008, - 0x20a3, 0x0000, 0x00f0, 0x4fb0, 0x20a9, 0x0008, 0x20a3, 0x0000, - 0x00f0, 0x4fb6, 0x2099, 0x7928, 0x20a9, 0x0008, 0x53a6, 0x20a9, - 0x0008, 0x20a3, 0x0000, 0x00f0, 0x4fc1, 0x20a9, 0x000a, 0x20a3, - 0x0000, 0x00f0, 0x4fc7, 0x60c3, 0x0074, 0x1078, 0x5688, 0x007c, - 0x20a1, 0x020b, 0x1078, 0x50f8, 0x20a3, 0x2010, 0x20a3, 0x0014, - 0x20a3, 0x0800, 0x20a3, 0x2000, 0xa006, 0x20a2, 0x20a2, 0x20a2, - 0x20a2, 0x20a2, 0x0f7e, 0x2079, 0x7751, 0x7904, 0x0f7f, 0xd1ac, - 0x00c0, 0x4fec, 0xa085, 0x0020, 0xd1a4, 0x0040, 0x4ff1, 0xa085, - 0x0010, 0xa085, 0x0002, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, - 0x60c3, 0x0014, 0x1078, 0x5688, 0x007c, 0x20a1, 0x020b, 0x1078, - 0x50f8, 0x20a3, 0x5000, 0x0078, 0x4f66, 0x20a1, 0x020b, 0x1078, - 0x50f8, 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, - 0x0000, 0x60c3, 0x0014, 0x1078, 0x5688, 0x007c, 0x20a1, 0x020b, - 0x1078, 0x516f, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000, - 0x20a3, 0x0000, 0x60c3, 0x0004, 0x1078, 0x5688, 0x007c, 0x20a1, - 0x020b, 0x1078, 0x516f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, - 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x1078, 0x5688, 0x007c, - 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0200, 0x0078, 0x4f66, - 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0100, 0x20a3, 0x0000, - 0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x5688, - 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0210, - 0x20a3, 0x0014, 0x20a3, 0x0800, 0x7818, 0x2068, 0x6894, 0xa086, - 0x0014, 0x00c0, 0x5087, 0x6998, 0xa184, 0xc000, 0x00c0, 0x5083, - 0xd1ec, 0x0040, 0x507f, 0x20a3, 0x2100, 0x0078, 0x5089, 0x20a3, - 0x0100, 0x0078, 0x5089, 0x20a3, 0x0400, 0x0078, 0x5089, 0x20a3, - 0x0700, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e, - 0x2079, 0x7751, 0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x5099, 0xa085, - 0x0020, 0xd1a4, 0x0040, 0x509e, 0xa085, 0x0010, 0xa085, 0x0002, - 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x0014, 0x1078, 0x5688, 0x0d7f, - 0x007c, 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0210, 0x20a3, - 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, - 0x5688, 0x007c, 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0200, - 0x0078, 0x4f07, 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0100, - 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, - 0x1078, 0x5688, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, - 0x020b, 0x1078, 0x516f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, - 0x000b, 0x20a3, 0x0000, 0x60c3, 0x0008, 0x1078, 0x5688, 0x007c, - 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, - 0x2014, 0xa286, 0x007e, 0x00c0, 0x510b, 0x20a3, 0x22ff, 0x20a3, - 0xfffe, 0x0078, 0x5139, 0xa286, 0x007f, 0x00c0, 0x5116, 0x0d7e, - 0x20a3, 0x22ff, 0x20a3, 0xfffd, 0x0078, 0x512d, 0xd2bc, 0x0040, - 0x5135, 0xa286, 0x0080, 0x0d7e, 0x00c0, 0x5124, 0x20a3, 0x22ff, - 0x20a3, 0xfffc, 0x0078, 0x512d, 0xa2e8, 0x7820, 0x2d6c, 0x6810, - 0xa085, 0x2200, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719, 0x2da6, - 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x513d, 0x20a3, 0x2200, 0x6298, - 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0129, 0x20a3, - 0x0000, 0x1078, 0x5677, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, + 0x5675, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, + 0xd084, 0x0040, 0x567d, 0x6827, 0x0001, 0x037f, 0x0078, 0x5686, + 0x6003, 0x0009, 0x630a, 0x2c30, 0x0078, 0x569e, 0x6010, 0x2068, + 0x1078, 0x77ed, 0x0040, 0x569a, 0x601c, 0xa086, 0x0003, 0x00c0, + 0x56a8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4376, + 0x1078, 0x799b, 0x1078, 0x79a8, 0x1078, 0x6601, 0x007f, 0x0078, + 0x564e, 0x7e16, 0x7e12, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, + 0x601c, 0xa086, 0x0006, 0x00c0, 0x5691, 0x1078, 0x86aa, 0x0078, + 0x569a, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x7818, 0xa065, 0x0040, + 0x571f, 0x6054, 0x007e, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, + 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x3ed6, 0x0040, 0x571c, 0x7e24, + 0x86ff, 0x0040, 0x570e, 0xa680, 0x0004, 0x2004, 0xad06, 0x00c0, + 0x570e, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x5705, + 0x1078, 0x516f, 0x1078, 0x6232, 0x68c3, 0x0000, 0x1078, 0x6741, + 0x7827, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, + 0x0040, 0x56ee, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, + 0x6824, 0xd084, 0x0040, 0x56f6, 0x6827, 0x0001, 0x037f, 0x0d7f, + 0x0c7e, 0x603c, 0xa005, 0x0040, 0x56ff, 0x8001, 0x603e, 0x2660, + 0x1078, 0x79a8, 0x0c7f, 0x0078, 0x570e, 0x0d7f, 0x0c7e, 0x2660, + 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x56c3, 0x8dff, 0x0040, + 0x5718, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4376, + 0x1078, 0x6601, 0x0078, 0x56c3, 0x007f, 0x0078, 0x56b6, 0x781e, + 0x781a, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x0e7e, 0x0d7e, + 0x067e, 0x6000, 0xd0dc, 0x0040, 0x5743, 0x604c, 0xa06d, 0x0040, + 0x5743, 0x6848, 0xa606, 0x00c0, 0x5743, 0x2071, 0x8aa2, 0x7024, + 0xa035, 0x0040, 0x5743, 0xa080, 0x0004, 0x2004, 0xad06, 0x00c0, + 0x5743, 0x1078, 0x5747, 0x067f, 0x0d7f, 0x0e7f, 0x007c, 0x0f7e, + 0x2079, 0x0100, 0x78c0, 0xa005, 0x00c0, 0x5756, 0x0c7e, 0x2660, + 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x578d, 0x1078, 0x6232, + 0x78c3, 0x0000, 0x1078, 0x6741, 0x7027, 0x0000, 0x037e, 0x2079, + 0x0140, 0x7b04, 0xa384, 0x1000, 0x0040, 0x576a, 0x7803, 0x0100, + 0x7803, 0x0000, 0x2079, 0x0100, 0x7824, 0xd084, 0x0040, 0x5772, + 0x7827, 0x0001, 0x1078, 0x6741, 0x037f, 0x1078, 0x3ed6, 0x0c7e, + 0x603c, 0xa005, 0x0040, 0x577e, 0x8001, 0x603e, 0x2660, 0x1078, + 0x690e, 0x0c7f, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, + 0x7a46, 0x1078, 0x4376, 0x1078, 0x6601, 0x0f7f, 0x007c, 0x0e7e, + 0x0c7e, 0x2071, 0x8aa2, 0x7004, 0xa084, 0x0007, 0x0079, 0x5798, + 0x57a2, 0x57a5, 0x57be, 0x57da, 0x581f, 0x57a2, 0x57a2, 0x57a0, + 0x1078, 0x12d2, 0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065, 0x0040, + 0x57b3, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015, 0x0040, 0x57ba, + 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x0c7f, + 0x0e7f, 0x007c, 0x7216, 0x7212, 0x0078, 0x57b3, 0x6018, 0x2060, + 0x1078, 0x3ed6, 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022, + 0x0040, 0x57cf, 0x6054, 0xa015, 0x0040, 0x57d6, 0x721e, 0x7007, + 0x0000, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7218, 0x721e, + 0x0078, 0x57cf, 0x7024, 0xa065, 0x0040, 0x581c, 0x700c, 0xac06, + 0x00c0, 0x57f1, 0x1078, 0x6601, 0x600c, 0xa015, 0x0040, 0x57ed, + 0x720e, 0x600f, 0x0000, 0x0078, 0x581a, 0x720e, 0x720a, 0x0078, + 0x581a, 0x7014, 0xac06, 0x00c0, 0x5804, 0x1078, 0x6601, 0x600c, + 0xa015, 0x0040, 0x5800, 0x7216, 0x600f, 0x0000, 0x0078, 0x581a, + 0x7216, 0x7212, 0x0078, 0x581a, 0x6018, 0x2060, 0x1078, 0x3ed6, + 0x6000, 0xc0dc, 0x6002, 0x1078, 0x6601, 0x701c, 0xa065, 0x0040, + 0x581a, 0x6054, 0xa015, 0x0040, 0x5818, 0x721e, 0x0078, 0x581a, + 0x7218, 0x721e, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7024, + 0xa065, 0x0040, 0x582c, 0x1078, 0x6601, 0x600c, 0xa015, 0x0040, + 0x5833, 0x720e, 0x600f, 0x0000, 0x1078, 0x6741, 0x7027, 0x0000, + 0x0c7f, 0x0e7f, 0x007c, 0x720e, 0x720a, 0x0078, 0x582c, 0x0d7e, + 0x2069, 0x8aa2, 0x6830, 0xa084, 0x0003, 0x0079, 0x583f, 0x5845, + 0x5847, 0x586d, 0x5845, 0x1078, 0x12d2, 0x0d7f, 0x007c, 0x0c7e, + 0x6840, 0xa086, 0x0001, 0x0040, 0x5863, 0x683c, 0xa065, 0x0040, + 0x5858, 0x600c, 0xa015, 0x0040, 0x585f, 0x6a3a, 0x600f, 0x0000, + 0x6833, 0x0000, 0x683f, 0x0000, 0x0c7f, 0x0d7f, 0x007c, 0x683a, + 0x6836, 0x0078, 0x5858, 0x6843, 0x0000, 0x6838, 0xa065, 0x0040, + 0x5858, 0x6003, 0x0003, 0x0078, 0x5858, 0x0c7e, 0x6843, 0x0000, + 0x6847, 0x0000, 0x683c, 0xa065, 0x0040, 0x5885, 0x600c, 0xa015, + 0x0040, 0x5881, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000, 0x0078, + 0x5885, 0x683f, 0x0000, 0x683a, 0x6836, 0x0c7f, 0x0d7f, 0x007c, + 0x0d7e, 0x2069, 0x8aa2, 0x6804, 0xa084, 0x0007, 0x0079, 0x5890, + 0x589a, 0x5937, 0x5937, 0x5937, 0x5937, 0x5939, 0x5937, 0x5898, + 0x1078, 0x12d2, 0x6820, 0xa005, 0x00c0, 0x58a0, 0x0d7f, 0x007c, + 0x0c7e, 0x680c, 0xa065, 0x0040, 0x58af, 0x6807, 0x0004, 0x6826, + 0x682b, 0x0000, 0x1078, 0x597f, 0x0c7f, 0x0d7f, 0x007c, 0x6814, + 0xa065, 0x0040, 0x58bd, 0x6807, 0x0001, 0x6826, 0x682b, 0x0000, + 0x1078, 0x597f, 0x0c7f, 0x0d7f, 0x007c, 0x0e7e, 0x037e, 0x6a1c, + 0xa2f5, 0x0000, 0x0040, 0x5932, 0x704c, 0xa00d, 0x0040, 0x58cc, + 0x7088, 0xa005, 0x0040, 0x58e4, 0x7054, 0xa075, 0x0040, 0x58d5, + 0xa20e, 0x0040, 0x5932, 0x0078, 0x58da, 0x6818, 0xa20e, 0x0040, + 0x5932, 0x2070, 0x704c, 0xa00d, 0x0040, 0x58cc, 0x7088, 0xa005, + 0x00c0, 0x58cc, 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, 0x00c8, + 0x58cc, 0x1078, 0x68dd, 0x0040, 0x5932, 0x8318, 0x733e, 0x6112, + 0x2e10, 0x621a, 0xa180, 0x0015, 0x2004, 0xa08a, 0x199a, 0x0048, + 0x58fb, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, + 0x037f, 0x0f7e, 0x2c78, 0x71a0, 0xd1bc, 0x0040, 0x5914, 0x7100, + 0xd1f4, 0x0040, 0x5910, 0x7114, 0xa18c, 0x00ff, 0x0078, 0x5919, + 0x2009, 0x0000, 0x0078, 0x5919, 0xa1e0, 0x25b2, 0x2c0c, 0xa18c, + 0x00ff, 0x2061, 0x0100, 0x619a, 0x1078, 0x5e16, 0x7300, 0xc3dd, + 0x7302, 0x6807, 0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000, 0x781f, + 0x0003, 0x7803, 0x0001, 0x7807, 0x0040, 0x0f7f, 0x0e7f, 0x0c7f, + 0x0d7f, 0x007c, 0x037f, 0x0e7f, 0x0c7f, 0x0078, 0x5930, 0x0d7f, + 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, 0x5945, 0x6807, 0x0004, + 0x6826, 0x682b, 0x0000, 0x1078, 0x597f, 0x0c7f, 0x0d7f, 0x007c, + 0x0f7e, 0x0d7e, 0x2069, 0x8aa2, 0x6830, 0xa086, 0x0000, 0x00c0, + 0x5966, 0x6838, 0xa07d, 0x0040, 0x5966, 0x6833, 0x0001, 0x683e, + 0x6847, 0x0000, 0x127e, 0x0f7e, 0x2091, 0x2200, 0x027f, 0x1078, + 0x1b84, 0x00c0, 0x5969, 0x127f, 0x1078, 0x60fc, 0x0d7f, 0x0f7f, + 0x007c, 0x127f, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0xa015, + 0x0040, 0x597b, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, + 0x0000, 0x0078, 0x5966, 0x683a, 0x6836, 0x0078, 0x5975, 0x601c, + 0xa084, 0x000f, 0x1079, 0x5985, 0x007c, 0x598e, 0x5993, 0x5cc7, + 0x5dd3, 0x5993, 0x5cc7, 0x5dd3, 0x598e, 0x5993, 0x1078, 0x578f, + 0x1078, 0x5888, 0x007c, 0x157e, 0x137e, 0x147e, 0x0c7e, 0x0f7e, + 0x6004, 0xa08a, 0x0040, 0x10c8, 0x12d2, 0x6118, 0x2178, 0x79a0, + 0xd1bc, 0x0040, 0x59b0, 0x7900, 0xd1f4, 0x0040, 0x59ac, 0x7914, + 0xa18c, 0x00ff, 0x0078, 0x59b5, 0x2009, 0x0000, 0x0078, 0x59b5, + 0xa1f8, 0x25b2, 0x2f0c, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, + 0x619a, 0x1079, 0x59c1, 0x0f7f, 0x0c7f, 0x147f, 0x137f, 0x157f, + 0x007c, 0x5a08, 0x5a40, 0x5a58, 0x5ad7, 0x5b04, 0x5b0c, 0x5b2d, + 0x5b3e, 0x5b4f, 0x5b57, 0x5b68, 0x5b57, 0x5bba, 0x5b3e, 0x5bdb, + 0x5be3, 0x5b4f, 0x5be3, 0x5bf4, 0x5a01, 0x5a01, 0x5a01, 0x5a01, + 0x5a01, 0x5a01, 0x5a01, 0x5a01, 0x5a01, 0x5a01, 0x5a01, 0x5a01, + 0x62e5, 0x62fa, 0x631d, 0x6341, 0x5b2d, 0x5a01, 0x5b2d, 0x5b57, + 0x5a01, 0x5a58, 0x5ad7, 0x5a01, 0x685b, 0x5b57, 0x5a01, 0x687b, + 0x5b57, 0x5a01, 0x5a01, 0x5a03, 0x5a01, 0x5a01, 0x5a01, 0x5a01, + 0x5a01, 0x5a01, 0x5a01, 0x5a01, 0x5a01, 0x5a01, 0x6356, 0x5a01, + 0x5a01, 0x1078, 0x12d2, 0x6030, 0x609a, 0x1078, 0x621e, 0x007c, + 0x20a1, 0x020b, 0x1078, 0x5c09, 0x20a3, 0x5200, 0x20a3, 0x0000, + 0x0d7e, 0x2069, 0x8851, 0x6804, 0xd084, 0x0040, 0x5a22, 0x6828, + 0x20a3, 0x0000, 0x017e, 0x1078, 0x225c, 0x21a2, 0x017f, 0x0d7f, + 0x0078, 0x5a27, 0x0d7f, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, + 0x0004, 0x2099, 0x8805, 0x53a6, 0x20a9, 0x0004, 0x2099, 0x8801, + 0x53a6, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, 0x621e, 0x007c, + 0x20a1, 0x020b, 0x1078, 0x5c09, 0x20a3, 0x0500, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a9, 0x0004, + 0x2099, 0x8805, 0x53a6, 0x60c3, 0x0010, 0x1078, 0x621e, 0x007c, + 0x20a1, 0x020b, 0x1078, 0x5c09, 0x7818, 0xa080, 0x0028, 0x2004, + 0xa086, 0x007e, 0x00c0, 0x5a6b, 0x20a3, 0x0400, 0x620c, 0xc2b4, + 0x620e, 0x0078, 0x5a6d, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x7818, + 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, 0x5aa6, 0x2099, + 0x8a8c, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, 0xa084, 0x3fff, + 0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0x8805, 0x53a6, + 0x20a9, 0x0004, 0x2099, 0x8801, 0x53a6, 0x20a9, 0x0010, 0x20a3, + 0x0000, 0x00f0, 0x5a97, 0x2099, 0x8a94, 0x33a6, 0x20a9, 0x0007, + 0x20a3, 0x0000, 0x00f0, 0x5aa0, 0x0078, 0x5ac6, 0x2099, 0x8a8c, + 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004, 0x2099, 0x8805, 0x53a6, + 0x20a9, 0x0004, 0x2099, 0x8801, 0x53a6, 0x20a9, 0x0008, 0x20a3, + 0x0000, 0x00f0, 0x5ab7, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, + 0x5abd, 0x2099, 0x8a94, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0008, + 0x20a3, 0x0000, 0x00f0, 0x5ac8, 0x20a9, 0x000a, 0x20a3, 0x0000, + 0x00f0, 0x5ace, 0x60c3, 0x0074, 0x1078, 0x621e, 0x007c, 0x20a1, + 0x020b, 0x1078, 0x5c09, 0x20a3, 0x2010, 0x20a3, 0x0014, 0x20a3, + 0x0800, 0x20a3, 0x2000, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, + 0x20a2, 0x0f7e, 0x2079, 0x8851, 0x7904, 0x0f7f, 0xd1ac, 0x00c0, + 0x5af3, 0xa085, 0x0020, 0xd1a4, 0x0040, 0x5af8, 0xa085, 0x0010, + 0xa085, 0x0002, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, + 0x0014, 0x1078, 0x621e, 0x007c, 0x20a1, 0x020b, 0x1078, 0x5c09, + 0x20a3, 0x5000, 0x0078, 0x5a6d, 0x20a1, 0x020b, 0x1078, 0x5c09, + 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0014, 0x1078, 0x621e, 0x007c, 0x20a1, 0x020b, 0x1078, + 0x5c87, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x60c3, 0x0004, 0x1078, 0x621e, 0x007c, 0x20a1, 0x020b, + 0x1078, 0x5c87, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, + 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x1078, 0x621e, 0x007c, 0x20a1, + 0x020b, 0x1078, 0x5c87, 0x20a3, 0x0200, 0x0078, 0x5a6d, 0x20a1, + 0x020b, 0x1078, 0x5c87, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, + 0x0003, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x621e, 0x007c, + 0x0d7e, 0x20a1, 0x020b, 0x1078, 0x5c87, 0x20a3, 0x0210, 0x20a3, + 0x0014, 0x20a3, 0x0800, 0x7818, 0x2068, 0x6894, 0xa086, 0x0014, + 0x00c0, 0x5b8e, 0x6998, 0xa184, 0xc000, 0x00c0, 0x5b8a, 0xd1ec, + 0x0040, 0x5b86, 0x20a3, 0x2100, 0x0078, 0x5b90, 0x20a3, 0x0100, + 0x0078, 0x5b90, 0x20a3, 0x0400, 0x0078, 0x5b90, 0x20a3, 0x0700, + 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e, 0x2079, + 0x8851, 0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x5ba0, 0xa085, 0x0020, + 0xd1a4, 0x0040, 0x5ba5, 0xa085, 0x0010, 0x2009, 0x8873, 0x210c, + 0xd184, 0x0040, 0x5baf, 0x699c, 0xd18c, 0x0040, 0x5bb1, 0xa085, + 0x0002, 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x0014, 0x1078, 0x621e, + 0x0d7f, 0x007c, 0x20a1, 0x020b, 0x1078, 0x5c87, 0x20a3, 0x0210, + 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, + 0x1078, 0x621e, 0x007c, 0x20a1, 0x020b, 0x1078, 0x5c87, 0x20a3, + 0x0200, 0x0078, 0x5a0e, 0x20a1, 0x020b, 0x1078, 0x5c87, 0x20a3, + 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, + 0x0008, 0x1078, 0x621e, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, + 0x20a1, 0x020b, 0x1078, 0x5c87, 0x20a3, 0x0100, 0x20a3, 0x0000, + 0x20a3, 0x000b, 0x20a3, 0x0000, 0x60c3, 0x0008, 0x1078, 0x621e, + 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, + 0x0028, 0x2014, 0xa286, 0x007e, 0x00c0, 0x5c1c, 0x20a3, 0x22ff, + 0x20a3, 0xfffe, 0x0078, 0x5c51, 0xa286, 0x007f, 0x00c0, 0x5c27, + 0x0d7e, 0x20a3, 0x22ff, 0x20a3, 0xfffd, 0x0078, 0x5c3e, 0xd2bc, + 0x0040, 0x5c46, 0xa286, 0x0080, 0x0d7e, 0x00c0, 0x5c35, 0x20a3, + 0x22ff, 0x20a3, 0xfffc, 0x0078, 0x5c3e, 0xa2e8, 0x8934, 0x2d6c, + 0x6810, 0xa085, 0x2200, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x881a, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5c55, 0x0d7e, 0xa2e8, + 0x8934, 0x2d6c, 0x6810, 0xa085, 0x2200, 0x20a2, 0x6814, 0x20a2, + 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0129, 0x20a3, + 0x0000, 0x1078, 0x620d, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, 0x2011, 0xfffc, - 0x22a2, 0x0d7e, 0x2069, 0x7719, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, - 0x20a3, 0x2029, 0x20a3, 0x0000, 0x0078, 0x5141, 0x20a3, 0x0100, + 0x22a2, 0x0d7e, 0x2069, 0x881a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, + 0x20a3, 0x2029, 0x20a3, 0x0000, 0x0078, 0x5c59, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, - 0xa092, 0x007e, 0x0048, 0x518e, 0x0d7e, 0xa0e8, 0x7820, 0x2d6c, - 0x6810, 0xa085, 0x2300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719, - 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5196, 0x20a3, 0x2300, - 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0198, - 0x20a3, 0x0000, 0x1078, 0x5677, 0x22a2, 0x20a3, 0x0000, 0x7a08, - 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, - 0x0c7e, 0x0f7e, 0x6004, 0xa08a, 0x0085, 0x1048, 0x12cd, 0xa08a, - 0x008c, 0x10c8, 0x12cd, 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, - 0x51c6, 0x7900, 0xd1f4, 0x0040, 0x51c2, 0x7914, 0xa18c, 0x00ff, - 0x0078, 0x51cb, 0x2009, 0x0000, 0x0078, 0x51cb, 0xa1f8, 0x2329, - 0x2f0c, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa082, - 0x0085, 0x1079, 0x51d6, 0x0f7f, 0x0c7f, 0x007c, 0x51df, 0x51ea, - 0x5204, 0x51dd, 0x51dd, 0x51dd, 0x51df, 0x1078, 0x12cd, 0x147e, - 0x20a1, 0x020b, 0x1078, 0x5217, 0x60c3, 0x0000, 0x1078, 0x5688, - 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078, 0x5244, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, 0x2fa2, 0x20a3, 0x0000, + 0xa092, 0x007e, 0x0048, 0x5ca6, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, + 0x6810, 0xa085, 0x2300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x881a, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5cb5, 0x0d7e, 0xa0e8, + 0x8934, 0x2d6c, 0x6810, 0xa085, 0x2300, 0x20a2, 0x6814, 0x20a2, + 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0198, 0x20a3, + 0x0000, 0x1078, 0x620d, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, + 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0c7e, + 0x0f7e, 0x6004, 0xa08a, 0x0085, 0x1048, 0x12d2, 0xa08a, 0x008c, + 0x10c8, 0x12d2, 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, 0x5ce5, + 0x7900, 0xd1f4, 0x0040, 0x5ce1, 0x7914, 0xa18c, 0x00ff, 0x0078, + 0x5cea, 0x2009, 0x0000, 0x0078, 0x5cea, 0xa1f8, 0x25b2, 0x2f0c, + 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa082, 0x0085, + 0x1079, 0x5cf5, 0x0f7f, 0x0c7f, 0x007c, 0x5cfe, 0x5d09, 0x5d24, + 0x5cfc, 0x5cfc, 0x5cfc, 0x5cfe, 0x1078, 0x12d2, 0x147e, 0x20a1, + 0x020b, 0x1078, 0x5d37, 0x60c3, 0x0000, 0x1078, 0x621e, 0x147f, + 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078, 0x5d6b, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c, - 0x1078, 0x5688, 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078, - 0x5271, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3, - 0x0000, 0x60c3, 0x0004, 0x1078, 0x5688, 0x147f, 0x007c, 0x027e, + 0x1078, 0x621e, 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078, + 0x5d9f, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x60c3, 0x0004, 0x1078, 0x621e, 0x147f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, - 0xa092, 0x007e, 0x0048, 0x5236, 0x0d7e, 0xa0e8, 0x7820, 0x2d6c, - 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719, - 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x523e, 0x20a3, 0x8100, - 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0009, - 0x20a3, 0x0000, 0x0078, 0x5141, 0x027e, 0x20e1, 0x9080, 0x20e1, - 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, - 0x5263, 0x0d7e, 0xa0e8, 0x7820, 0x2d6c, 0x6810, 0xa085, 0x8400, - 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719, 0x2da6, 0x8d68, 0x2da6, - 0x0d7f, 0x0078, 0x526b, 0x20a3, 0x8400, 0x6298, 0x22a2, 0x20a3, - 0x0000, 0x6230, 0x22a2, 0x20a3, 0x00d1, 0x20a3, 0x0000, 0x0078, - 0x519a, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, - 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x5290, 0x0d7e, 0xa0e8, - 0x7820, 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, - 0x2069, 0x7719, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5298, - 0x20a3, 0x8500, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, - 0x20a3, 0x00d1, 0x20a3, 0x0000, 0x0078, 0x519a, 0x0c7e, 0x0f7e, - 0x2c78, 0x7804, 0xa08a, 0x0040, 0x1048, 0x12cd, 0xa08a, 0x0050, - 0x10c8, 0x12cd, 0x7918, 0x2160, 0x61a0, 0xd1bc, 0x0040, 0x52bd, - 0x6100, 0xd1f4, 0x0040, 0x52b9, 0x6114, 0xa18c, 0x00ff, 0x0078, - 0x52c2, 0x2009, 0x0000, 0x0078, 0x52c2, 0xa1e0, 0x2329, 0x2c0c, - 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0xa082, 0x0040, 0x1079, - 0x52cc, 0x0f7f, 0x0c7f, 0x007c, 0x52de, 0x53c4, 0x536c, 0x54ec, - 0x52dc, 0x52dc, 0x52dc, 0x52dc, 0x52dc, 0x52dc, 0x52dc, 0x5933, - 0x5944, 0x5955, 0x5966, 0x52dc, 0x1078, 0x12cd, 0x0d7e, 0x157e, - 0x147e, 0x20a1, 0x020b, 0x1078, 0x532f, 0x7910, 0x2168, 0x6948, - 0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184, 0x0006, - 0x8004, 0x20a2, 0xd1ac, 0x0040, 0x52f9, 0x20a3, 0x0002, 0x0078, - 0x5305, 0xd1b4, 0x0040, 0x5300, 0x20a3, 0x0001, 0x0078, 0x5305, - 0x20a3, 0x0000, 0x2230, 0x0078, 0x5307, 0x6a80, 0x6e7c, 0x20a9, + 0xa092, 0x007e, 0x0048, 0x5d56, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, + 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x881a, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5d65, 0x0d7e, 0xa0e8, + 0x8934, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, + 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0009, 0x20a3, + 0x0000, 0x0078, 0x5c59, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, + 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x5d8a, + 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2, + 0x6814, 0x20a2, 0x2069, 0x881a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, + 0x0078, 0x5d99, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, + 0x8400, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, + 0x22a2, 0x20a3, 0x00d1, 0x20a3, 0x0000, 0x0078, 0x5cb9, 0x027e, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, + 0xa092, 0x007e, 0x0048, 0x5dbe, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, + 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x881a, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5dcd, 0x0d7e, 0xa0e8, + 0x8934, 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, + 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x00d1, 0x20a3, + 0x0000, 0x0078, 0x5cb9, 0x0c7e, 0x0f7e, 0x2c78, 0x7804, 0xa08a, + 0x0040, 0x1048, 0x12d2, 0xa08a, 0x0053, 0x10c8, 0x12d2, 0x7918, + 0x2160, 0x61a0, 0xd1bc, 0x0040, 0x5df2, 0x6100, 0xd1f4, 0x0040, + 0x5dee, 0x6114, 0xa18c, 0x00ff, 0x0078, 0x5df7, 0x2009, 0x0000, + 0x0078, 0x5df7, 0xa1e0, 0x25b2, 0x2c0c, 0xa18c, 0x00ff, 0x2061, + 0x0100, 0x619a, 0xa082, 0x0040, 0x1079, 0x5e01, 0x0f7f, 0x0c7f, + 0x007c, 0x5e16, 0x5f1a, 0x5ebb, 0x6070, 0x5e14, 0x5e14, 0x5e14, + 0x5e14, 0x5e14, 0x5e14, 0x5e14, 0x651a, 0x652b, 0x653c, 0x654d, + 0x5e14, 0x5e14, 0x5e14, 0x6509, 0x1078, 0x12d2, 0x0d7e, 0x157e, + 0x147e, 0x20a1, 0x020b, 0x1078, 0x5e77, 0x7910, 0x2168, 0x6948, + 0x7922, 0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184, + 0x000f, 0x00c0, 0x5e2f, 0x2001, 0x0005, 0x0078, 0x5e39, 0xd184, + 0x0040, 0x5e36, 0x2001, 0x0004, 0x0078, 0x5e39, 0xa084, 0x0006, + 0x8004, 0x20a2, 0xd1ac, 0x0040, 0x5e41, 0x20a3, 0x0002, 0x0078, + 0x5e4d, 0xd1b4, 0x0040, 0x5e48, 0x20a3, 0x0001, 0x0078, 0x5e4d, + 0x20a3, 0x0000, 0x2230, 0x0078, 0x5e4f, 0x6a80, 0x6e7c, 0x20a9, 0x0008, 0xad80, 0x0017, 0x200c, 0x810f, 0x21a2, 0x8000, 0x00f0, - 0x530b, 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, 0x6014, - 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0x7952, 0x2003, - 0x07d0, 0x2001, 0x7951, 0x2003, 0x0009, 0x2001, 0x7957, 0x2003, - 0x0002, 0x1078, 0x14fc, 0x147f, 0x157f, 0x0d7f, 0x007c, 0x20e1, + 0x5e53, 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, 0x6014, + 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0x8abe, 0x2003, + 0x07d0, 0x2001, 0x8abd, 0x2003, 0x0009, 0x2001, 0x8ac3, 0x2003, + 0x0002, 0x1078, 0x1526, 0x147f, 0x157f, 0x0d7f, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, 0x2004, - 0xd0bc, 0x0040, 0x5355, 0x0d7e, 0xa0e8, 0x7820, 0x2d6c, 0x6810, - 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719, 0x2da6, - 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x535d, 0x20a3, 0x0600, 0x6198, - 0x21a2, 0x20a3, 0x0000, 0x6130, 0x21a2, 0x20a3, 0x0829, 0x20a3, - 0x0000, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, - 0x20a1, 0x020b, 0x1078, 0x538c, 0x7810, 0x2068, 0x6860, 0x20a2, - 0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2, - 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c, 0x1078, 0x5688, 0x147f, - 0x137f, 0x157f, 0x0d7f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, - 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x53aa, - 0x0d7e, 0xa0e8, 0x7820, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, - 0x6814, 0x20a2, 0x2069, 0x7719, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, - 0x0078, 0x53b2, 0x20a3, 0x0500, 0x6298, 0x22a2, 0x20a3, 0x0000, - 0x6230, 0x22a2, 0x20a3, 0x0889, 0x20a3, 0x0000, 0x1078, 0x5677, - 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, - 0x20a3, 0x0000, 0x027f, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, - 0x20a1, 0x020b, 0x1078, 0x54b4, 0x7810, 0x2068, 0xa016, 0x22a2, - 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810, 0xa084, 0xf000, 0x00c0, - 0x53e1, 0x7810, 0xa084, 0x0700, 0x8007, 0x1079, 0x53e9, 0x0078, - 0x53e4, 0xa006, 0x1079, 0x53e9, 0x147f, 0x137f, 0x157f, 0x0d7f, - 0x007c, 0x53f3, 0x5455, 0x5459, 0x547c, 0x5489, 0x549b, 0x549f, - 0x53f1, 0x1078, 0x12cd, 0x017e, 0x037e, 0x694c, 0xa18c, 0x0003, - 0xa186, 0x0000, 0x00c0, 0x5406, 0x6b78, 0x23a2, 0x6868, 0x20a2, - 0x6864, 0x20a2, 0x037f, 0x017f, 0x0078, 0x5480, 0xa186, 0x0001, - 0x00c0, 0x5450, 0x6b78, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, + 0xd0bc, 0x0040, 0x5e9d, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, 0x6810, + 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x881a, 0x2da6, + 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5eac, 0x0d7e, 0xa0e8, 0x8934, + 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x0d7f, + 0x20a3, 0x0000, 0x6130, 0x21a2, 0x20a3, 0x0829, 0x20a3, 0x0000, + 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x20a1, + 0x020b, 0x1078, 0x5edb, 0x7810, 0x2068, 0x6860, 0x20a2, 0x685c, + 0x20a2, 0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2, 0x20a2, + 0x20a2, 0x20a2, 0x60c3, 0x000c, 0x1078, 0x621e, 0x147f, 0x137f, + 0x157f, 0x0d7f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, + 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x5ef9, 0x0d7e, + 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, + 0x20a2, 0x2069, 0x881a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, + 0x5f08, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, 0x0500, + 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, + 0x20a3, 0x0889, 0x20a3, 0x0000, 0x1078, 0x620d, 0x22a2, 0x20a3, + 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x027f, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x20a1, 0x020b, + 0x1078, 0x6031, 0x7810, 0x2068, 0xa016, 0x22a2, 0x22a2, 0x22a2, + 0x22a2, 0x22a2, 0x7810, 0xa084, 0xf000, 0x00c0, 0x5f37, 0x7810, + 0xa084, 0x0700, 0x8007, 0x1079, 0x5f3f, 0x0078, 0x5f3a, 0xa006, + 0x1079, 0x5f3f, 0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c, 0x5f49, + 0x5fcf, 0x5fd3, 0x5ff6, 0x6003, 0x6018, 0x601c, 0x5f47, 0x1078, + 0x12d2, 0x017e, 0x037e, 0x694c, 0xa18c, 0x0003, 0x0040, 0x5f54, + 0xa186, 0x0003, 0x00c0, 0x5f5e, 0x6b78, 0x23a2, 0x6868, 0x20a2, + 0x6864, 0x20a2, 0x037f, 0x017f, 0x0078, 0x5ffa, 0xa186, 0x0001, + 0x10c0, 0x12d2, 0x6b78, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2, 0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, - 0xa384, 0x0300, 0x0040, 0x544f, 0xd3c4, 0x0040, 0x5421, 0x687c, - 0xa108, 0xd3cc, 0x0040, 0x5426, 0x6874, 0xa108, 0x157e, 0x20a9, + 0xa384, 0x0300, 0x0040, 0x5fc9, 0xd3c4, 0x0040, 0x5f79, 0x687c, + 0xa108, 0xd3cc, 0x0040, 0x5f7e, 0x6874, 0xa108, 0x157e, 0x20a9, 0x000d, 0xad80, 0x0020, 0x201c, 0x831f, 0x23a2, 0x8000, 0x00f0, - 0x542b, 0x157f, 0x22a2, 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0040, - 0x544f, 0x20a1, 0x020b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, - 0x0700, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, - 0x0898, 0x20a2, 0x1078, 0x5677, 0x22a2, 0x20a3, 0x0000, 0x61c2, - 0x037f, 0x017f, 0x1078, 0x5688, 0x007c, 0x20a3, 0x0008, 0x0078, - 0x547e, 0x20a3, 0x0302, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0012, - 0x22a2, 0x20a3, 0x0008, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, - 0x7000, 0x20a3, 0x0500, 0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2, - 0x20a3, 0x2500, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, - 0x0032, 0x1078, 0x5688, 0x007c, 0x20a3, 0x0028, 0x22a2, 0x22a2, - 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0018, 0x1078, 0x5688, - 0x007c, 0x20a3, 0x0100, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, - 0x20a3, 0x0008, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0020, - 0x1078, 0x5688, 0x007c, 0x20a3, 0x0008, 0x0078, 0x547e, 0x037e, - 0x7b10, 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001, 0x00c0, - 0x54ad, 0x22a2, 0x037f, 0x0078, 0x547e, 0x20a3, 0x0800, 0x22a2, - 0x20a2, 0x037f, 0x0078, 0x5480, 0x027e, 0x20e1, 0x9080, 0x20e1, - 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x54d2, - 0x0d7e, 0xa0e8, 0x7820, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, - 0x6814, 0x20a2, 0x2069, 0x7719, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, - 0x0078, 0x54da, 0x20a3, 0x0700, 0x6298, 0x22a2, 0x20a3, 0x0000, - 0x6230, 0x22a2, 0x20a3, 0x0898, 0x20a3, 0x0000, 0x1078, 0x5677, + 0x5f83, 0x157f, 0x22a2, 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0040, + 0x5fc9, 0x20a1, 0x020b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x007e, + 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x5fb1, 0x0d7e, + 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, + 0x20a2, 0x2069, 0x881a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, + 0x5fc0, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, 0x0700, + 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, + 0x007f, 0x20a3, 0x0898, 0x20a2, 0x1078, 0x620d, 0x22a2, 0x20a3, + 0x0000, 0x61c2, 0x037f, 0x017f, 0x1078, 0x621e, 0x007c, 0x20a3, + 0x0008, 0x0078, 0x5ff8, 0x20a3, 0x0302, 0x22a2, 0x22a2, 0x22a2, + 0x20a3, 0x0012, 0x22a2, 0x20a3, 0x0008, 0x22a2, 0x22a2, 0x22a2, + 0x22a2, 0x20a3, 0x7000, 0x20a3, 0x0500, 0x22a2, 0x20a3, 0x000a, + 0x22a2, 0x22a2, 0x20a3, 0x2500, 0x22a2, 0x22a2, 0x22a2, 0x22a2, + 0x22a2, 0x60c3, 0x0032, 0x1078, 0x621e, 0x007c, 0x20a3, 0x0028, + 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0018, + 0x1078, 0x621e, 0x007c, 0x20a3, 0x0100, 0x22a2, 0x22a2, 0x22a2, + 0x22a2, 0x22a2, 0x20a3, 0x0008, 0x22a2, 0x7824, 0xa084, 0x00ff, + 0x20a2, 0x22a2, 0x22a2, 0x60c3, 0x0020, 0x1078, 0x621e, 0x007c, + 0x20a3, 0x0008, 0x0078, 0x5ff8, 0x037e, 0x7b10, 0xa384, 0xff00, + 0x7812, 0xa384, 0x00ff, 0x8001, 0x00c0, 0x602a, 0x22a2, 0x037f, + 0x0078, 0x5ff8, 0x20a3, 0x0800, 0x22a2, 0x20a2, 0x037f, 0x0078, + 0x5ffa, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, + 0x0028, 0x2004, 0xd0bc, 0x0040, 0x604f, 0x0d7e, 0xa0e8, 0x8934, + 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, + 0x881a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x605e, 0x0d7e, + 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, + 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0898, + 0x20a3, 0x0000, 0x1078, 0x620d, 0x22a2, 0x20a3, 0x0000, 0x7a08, + 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, + 0x0d7e, 0x157e, 0x137e, 0x147e, 0x017e, 0x037e, 0x7810, 0xa084, + 0x0700, 0x8007, 0x1079, 0x6083, 0x037f, 0x017f, 0x147f, 0x137f, + 0x157f, 0x0d7f, 0x007c, 0x608b, 0x608b, 0x608d, 0x608b, 0x608b, + 0x608b, 0x60b2, 0x608b, 0x1078, 0x12d2, 0x7910, 0xa18c, 0xf8ff, + 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078, + 0x60bc, 0x0d7e, 0x2069, 0x8851, 0x6804, 0xd0bc, 0x0040, 0x60a7, + 0x682c, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x0078, 0x60a9, 0x20a3, + 0x3f00, 0x0d7f, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, 0x1078, + 0x621e, 0x007c, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078, 0x60bc, + 0x20a3, 0x7f00, 0x0078, 0x60aa, 0x027e, 0x20e1, 0x9080, 0x20e1, + 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x60da, + 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2, + 0x6814, 0x20a2, 0x2069, 0x881a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, + 0x0078, 0x60e9, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, + 0x0100, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, + 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x1078, 0x620d, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, - 0x20a3, 0x0000, 0x027f, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, - 0x017e, 0x037e, 0x7810, 0xa084, 0x0700, 0x8007, 0x1079, 0x54ff, - 0x037f, 0x017f, 0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c, 0x5507, - 0x5507, 0x5509, 0x5507, 0x5507, 0x5507, 0x552e, 0x5507, 0x1078, - 0x12cd, 0x7910, 0xa18c, 0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1, - 0x020b, 0x2009, 0x0003, 0x1078, 0x5538, 0x0d7e, 0x2069, 0x7751, - 0x6804, 0xd0bc, 0x0040, 0x5523, 0x682c, 0xa084, 0x00ff, 0x8007, - 0x20a2, 0x0078, 0x5525, 0x20a3, 0x3f00, 0x0d7f, 0x22a2, 0x22a2, - 0x22a2, 0x60c3, 0x0001, 0x1078, 0x5688, 0x007c, 0x20a1, 0x020b, - 0x2009, 0x0003, 0x1078, 0x5538, 0x20a3, 0x7f00, 0x0078, 0x5526, - 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, - 0x2004, 0xd0bc, 0x0040, 0x5556, 0x0d7e, 0xa0e8, 0x7820, 0x2d6c, - 0x6810, 0xa085, 0x0100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719, - 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x555e, 0x20a3, 0x0100, - 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0888, - 0xa18d, 0x0008, 0x21a2, 0x1078, 0x5677, 0x22a2, 0x20a3, 0x0000, - 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, - 0x007c, 0x0e7e, 0x0d7e, 0x0c7e, 0x057e, 0x047e, 0x037e, 0x2061, - 0x0100, 0x2071, 0x7700, 0x6130, 0x7818, 0x2068, 0x68a0, 0x2028, - 0xd0bc, 0x00c0, 0x558a, 0xa080, 0x2329, 0x2014, 0xa294, 0x00ff, - 0x0078, 0x558e, 0x6910, 0x6a14, 0x7364, 0x7468, 0x781c, 0xa086, - 0x0006, 0x0040, 0x55e2, 0xd5bc, 0x0040, 0x559e, 0xa185, 0x0100, - 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x55a4, 0x6063, 0x0100, - 0x6266, 0x606b, 0x0000, 0x616e, 0x6073, 0x0809, 0x6077, 0x0008, - 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, - 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, 0x7810, 0x2070, 0x7014, - 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, 0x60ca, 0x686c, - 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, - 0x0080, 0x0048, 0x55d6, 0x6a00, 0xd2f4, 0x0040, 0x55d4, 0x6a14, - 0xa294, 0x00ff, 0x0078, 0x55d6, 0x2011, 0x0000, 0x629e, 0x6017, - 0x0016, 0x1078, 0x470b, 0x037f, 0x047f, 0x057f, 0x0c7f, 0x0d7f, - 0x0e7f, 0x007c, 0x7810, 0x2070, 0x704c, 0xa084, 0x0003, 0xa086, - 0x0002, 0x0040, 0x5631, 0xd5bc, 0x0040, 0x55f6, 0xa185, 0x0100, - 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x55fc, 0x6063, 0x0100, - 0x6266, 0x606b, 0x0000, 0x616e, 0x6073, 0x0880, 0x6077, 0x0008, - 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, - 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, 0x7060, 0x608a, 0x705c, - 0x608e, 0x7080, 0x60c6, 0x707c, 0x60ca, 0x686c, 0x60ce, 0x60ab, - 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, - 0x562c, 0x6a00, 0xd2f4, 0x0040, 0x562a, 0x6a14, 0xa294, 0x00ff, - 0x0078, 0x562c, 0x2011, 0x0000, 0x629e, 0x6017, 0x0012, 0x0078, - 0x55d9, 0xd5bc, 0x0040, 0x563c, 0xa185, 0x0700, 0x6062, 0x6266, - 0x636a, 0x646e, 0x0078, 0x5642, 0x6063, 0x0700, 0x6266, 0x606b, - 0x0000, 0x616e, 0x6073, 0x0898, 0x6077, 0x0000, 0x688c, 0x8000, - 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, - 0x6086, 0x7808, 0x6082, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, - 0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, - 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, 0x5672, 0x6a00, - 0xd2f4, 0x0040, 0x5670, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x5672, - 0x2011, 0x0000, 0x629e, 0x6017, 0x0016, 0x0078, 0x55d9, 0x7a18, - 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, - 0x007c, 0x0d7e, 0x2069, 0x7936, 0x6843, 0x0001, 0x0d7f, 0x007c, - 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x1078, 0x5693, - 0x1078, 0x46fb, 0x007c, 0x007e, 0x6014, 0xa084, 0x0004, 0xa085, - 0x0009, 0x6016, 0x007f, 0x007c, 0x007e, 0x0c7e, 0x2061, 0x0100, - 0x6014, 0xa084, 0x0004, 0xa085, 0x0008, 0x6016, 0x0c7f, 0x007f, - 0x007c, 0x0c7e, 0x0d7e, 0x017e, 0x027e, 0x1078, 0x4706, 0x2061, - 0x0100, 0x2069, 0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x56e6, - 0x1078, 0x569c, 0x6803, 0x1000, 0x6803, 0x0000, 0x0c7e, 0x2061, - 0x7936, 0x6128, 0xa192, 0x0002, 0x00c8, 0x56d3, 0x8108, 0x612a, - 0x6124, 0x0c7f, 0x81ff, 0x0040, 0x56e1, 0x1078, 0x46fb, 0x1078, - 0x5693, 0x0078, 0x56e1, 0x6124, 0xa1e5, 0x0000, 0x0040, 0x56de, - 0x1078, 0x76c7, 0x2009, 0x0014, 0x1078, 0x5d41, 0x0c7f, 0x0078, - 0x56e1, 0x027f, 0x017f, 0x0d7f, 0x0c7f, 0x007c, 0x1078, 0x3591, - 0x0078, 0x56e1, 0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x027e, 0x1078, - 0x4714, 0x2071, 0x7936, 0x713c, 0x81ff, 0x0040, 0x5714, 0x2061, - 0x0100, 0x2069, 0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x571a, - 0x6803, 0x1000, 0x6803, 0x0000, 0x037e, 0x2019, 0x0001, 0x1078, - 0x5880, 0x037f, 0x713c, 0x2160, 0x1078, 0x76c7, 0x2009, 0x004a, - 0x1078, 0x5d41, 0x0078, 0x5714, 0x027f, 0x017f, 0x0e7f, 0x0d7f, - 0x0c7f, 0x007c, 0x7144, 0xa192, 0x0002, 0x00c8, 0x5704, 0x8108, - 0x7146, 0x1078, 0x470b, 0x0078, 0x5714, 0x0e7e, 0x0d7e, 0x0c7e, - 0x067e, 0x057e, 0x047e, 0x007e, 0x127e, 0x2091, 0x8000, 0x6018, - 0x2068, 0x6ca0, 0x2071, 0x7936, 0x7018, 0x2068, 0x8dff, 0x0040, - 0x574f, 0x68a0, 0xa406, 0x0040, 0x5741, 0x6854, 0x2068, 0x0078, - 0x5736, 0x6010, 0x2060, 0x643c, 0x6540, 0x6e48, 0x2d60, 0x1078, - 0x3991, 0x0040, 0x574f, 0x1078, 0x5a1a, 0xa085, 0x0001, 0x127f, - 0x007f, 0x047f, 0x057f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, - 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x50f8, 0x20a3, 0x0f00, - 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, 0x60c3, 0x0008, - 0x1078, 0x5688, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1, - 0x020b, 0x1078, 0x516f, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a9, - 0x0006, 0x2011, 0x7740, 0x2019, 0x7741, 0x23a6, 0x22a6, 0xa398, - 0x0002, 0xa290, 0x0002, 0x00f0, 0x577d, 0x20a3, 0x0000, 0x20a3, - 0x0000, 0x60c3, 0x001c, 0x1078, 0x5688, 0x147f, 0x157f, 0x007c, - 0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b, 0x1078, 0x514f, - 0x1078, 0x5166, 0x7810, 0x007e, 0xa080, 0x0015, 0x2098, 0x7808, - 0xa088, 0x0002, 0x21a8, 0x53a6, 0xa080, 0x0004, 0x8003, 0x60c2, - 0x007f, 0xa080, 0x0001, 0x2004, 0x7812, 0x1078, 0x5688, 0x027f, - 0x017f, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, - 0x1078, 0x50f8, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, - 0x7808, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x5688, 0x147f, 0x157f, - 0x007c, 0x0e7e, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, - 0x7936, 0x700c, 0x2060, 0x8cff, 0x0040, 0x57e5, 0x1078, 0x6be3, - 0x00c0, 0x57dc, 0x1078, 0x5f6d, 0x600c, 0x007e, 0x1078, 0x5d1a, - 0x1078, 0x5a1a, 0x0c7f, 0x0078, 0x57d3, 0x700f, 0x0000, 0x700b, - 0x0000, 0x127f, 0x007f, 0x0c7f, 0x0e7f, 0x007c, 0x127e, 0x157e, - 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x027e, 0x017e, 0x007e, 0x2091, - 0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x7936, 0x7024, - 0x2060, 0x8cff, 0x0040, 0x583e, 0x1078, 0x569c, 0x68c3, 0x0000, - 0x1078, 0x4706, 0x2009, 0x0013, 0x1078, 0x5d41, 0x20a9, 0x01f4, - 0x6824, 0xd094, 0x0040, 0x5821, 0x6827, 0x0004, 0x7804, 0xa084, - 0x4000, 0x0040, 0x5833, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, - 0x5833, 0xd084, 0x0040, 0x5828, 0x6827, 0x0001, 0x0078, 0x582a, - 0x00f0, 0x5810, 0x7804, 0xa084, 0x1000, 0x0040, 0x5833, 0x7803, + 0x20a3, 0x0000, 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x0c7e, 0x057e, + 0x047e, 0x037e, 0x2061, 0x0100, 0x2071, 0x8800, 0x6130, 0x7818, + 0x2068, 0x68a0, 0x2028, 0xd0bc, 0x00c0, 0x6113, 0x6910, 0x6a14, + 0x6430, 0x0078, 0x6117, 0x6910, 0x6a14, 0x7368, 0x746c, 0x781c, + 0xa086, 0x0006, 0x0040, 0x6176, 0xd5bc, 0x0040, 0x6127, 0xa185, + 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x612e, 0xa185, + 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x6073, 0x0809, + 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, + 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, 0x7810, + 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, + 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, + 0x0000, 0xa582, 0x0080, 0x0048, 0x6160, 0x6a00, 0xd2f4, 0x0040, + 0x615e, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6160, 0x2011, 0x0000, + 0x629e, 0x6017, 0x0016, 0x2009, 0x07d0, 0x60c4, 0xa084, 0xfff0, + 0xa005, 0x0040, 0x616d, 0x2009, 0x1b58, 0x1078, 0x5174, 0x037f, + 0x047f, 0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7810, 0x2070, + 0x704c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0040, 0x61c6, 0xd5bc, + 0x0040, 0x618a, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, + 0x0078, 0x6191, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, + 0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, + 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, + 0x7808, 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6, + 0x707c, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, + 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, 0x61c1, 0x6a00, 0xd2f4, + 0x0040, 0x61bf, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x61c1, 0x2011, + 0x0000, 0x629e, 0x6017, 0x0012, 0x0078, 0x6163, 0xd5bc, 0x0040, + 0x61d1, 0xa185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, + 0x61d8, 0xa185, 0x0700, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, + 0x6073, 0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, + 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, + 0x6082, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, + 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, + 0x0000, 0xa582, 0x0080, 0x0048, 0x6208, 0x6a00, 0xd2f4, 0x0040, + 0x6206, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6208, 0x2011, 0x0000, + 0x629e, 0x6017, 0x0016, 0x0078, 0x6163, 0x7a18, 0xa280, 0x0023, + 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, 0x007c, 0x0d7e, + 0x2069, 0x8aa2, 0x6843, 0x0001, 0x0d7f, 0x007c, 0x20e1, 0x9080, + 0x60a3, 0x0056, 0x60a7, 0x9575, 0x1078, 0x6229, 0x1078, 0x5164, + 0x007c, 0x007e, 0x6014, 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, + 0x007f, 0x007c, 0x007e, 0x0c7e, 0x2061, 0x0100, 0x6014, 0xa084, + 0x0004, 0xa085, 0x0008, 0x6016, 0x0c7f, 0x007f, 0x007c, 0x0c7e, + 0x0d7e, 0x017e, 0x027e, 0x1078, 0x516f, 0x2061, 0x0100, 0x2069, + 0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x627c, 0x1078, 0x6232, + 0x6803, 0x1000, 0x6803, 0x0000, 0x0c7e, 0x2061, 0x8aa2, 0x6128, + 0xa192, 0x0002, 0x00c8, 0x6269, 0x8108, 0x612a, 0x6124, 0x0c7f, + 0x81ff, 0x0040, 0x6277, 0x1078, 0x5164, 0x1078, 0x6229, 0x0078, + 0x6277, 0x6124, 0xa1e5, 0x0000, 0x0040, 0x6274, 0x1078, 0x8781, + 0x2009, 0x0014, 0x1078, 0x6939, 0x0c7f, 0x0078, 0x6277, 0x027f, + 0x017f, 0x0d7f, 0x0c7f, 0x007c, 0x1078, 0x3c73, 0x0078, 0x6277, + 0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x027e, 0x1078, 0x517c, 0x2071, + 0x8aa2, 0x713c, 0x81ff, 0x0040, 0x62aa, 0x2061, 0x0100, 0x2069, + 0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x62b0, 0x6803, 0x1000, + 0x6803, 0x0000, 0x037e, 0x2019, 0x0001, 0x1078, 0x642d, 0x037f, + 0x713c, 0x2160, 0x1078, 0x8781, 0x2009, 0x004a, 0x1078, 0x6939, + 0x0078, 0x62aa, 0x027f, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c, + 0x0078, 0x629a, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x057e, 0x047e, + 0x007e, 0x127e, 0x2091, 0x8000, 0x6018, 0x2068, 0x6ca0, 0x2071, + 0x8aa2, 0x7018, 0x2068, 0x8dff, 0x0040, 0x62dc, 0x68a0, 0xa406, + 0x0040, 0x62ce, 0x6854, 0x2068, 0x0078, 0x62c3, 0x6010, 0x2060, + 0x643c, 0x6540, 0x6e48, 0x2d60, 0x1078, 0x40da, 0x0040, 0x62dc, + 0x1078, 0x6601, 0xa085, 0x0001, 0x127f, 0x007f, 0x047f, 0x057f, + 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x157e, 0x147e, 0x20a1, + 0x020b, 0x1078, 0x5c09, 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x7808, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x621e, 0x147f, + 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x5c87, + 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a9, 0x0006, 0x2011, 0x8840, + 0x2019, 0x8841, 0x23a6, 0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, + 0x00f0, 0x630a, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, + 0x1078, 0x621e, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x017e, + 0x027e, 0x20a1, 0x020b, 0x1078, 0x5c67, 0x1078, 0x5c7e, 0x7810, + 0x007e, 0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, + 0x53a6, 0xa080, 0x0004, 0x8003, 0x60c2, 0x007f, 0xa080, 0x0001, + 0x2004, 0x7812, 0x1078, 0x621e, 0x027f, 0x017f, 0x147f, 0x157f, + 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x5c09, 0x20a3, + 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, 0x60c3, + 0x0008, 0x1078, 0x621e, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, + 0x017e, 0x027e, 0x20a1, 0x020b, 0x1078, 0x5c09, 0x7810, 0x007e, + 0xa080, 0x0017, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6, + 0x8003, 0x60c2, 0x007f, 0xa080, 0x0001, 0x2004, 0x7812, 0x1078, + 0x621e, 0x027f, 0x017f, 0x147f, 0x157f, 0x007c, 0x0e7e, 0x0c7e, + 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0x8aa2, 0x700c, 0x2060, + 0x8cff, 0x0040, 0x6392, 0x1078, 0x79d5, 0x00c0, 0x6389, 0x1078, + 0x6bc7, 0x600c, 0x007e, 0x1078, 0x690e, 0x1078, 0x6601, 0x0c7f, + 0x0078, 0x6380, 0x700f, 0x0000, 0x700b, 0x0000, 0x127f, 0x007f, + 0x0c7f, 0x0e7f, 0x007c, 0x127e, 0x157e, 0x0f7e, 0x0e7e, 0x0d7e, + 0x0c7e, 0x027e, 0x017e, 0x007e, 0x2091, 0x8000, 0x2069, 0x0100, + 0x2079, 0x0140, 0x2071, 0x8aa2, 0x7024, 0x2060, 0x8cff, 0x0040, + 0x63eb, 0x1078, 0x6232, 0x68c3, 0x0000, 0x1078, 0x516f, 0x2009, + 0x0013, 0x1078, 0x6939, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040, + 0x63ce, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x63e0, + 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0x63e0, 0xd084, 0x0040, + 0x63d5, 0x6827, 0x0001, 0x0078, 0x63d7, 0x00f0, 0x63bd, 0x7804, + 0xa084, 0x1000, 0x0040, 0x63e0, 0x7803, 0x0100, 0x7803, 0x0000, + 0x6824, 0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, + 0x157f, 0x127f, 0x007c, 0x2001, 0x8800, 0x2004, 0xa096, 0x0001, + 0x0040, 0x6423, 0xa096, 0x0004, 0x0040, 0x6423, 0x6817, 0x0008, + 0x68c3, 0x0000, 0x2011, 0x3c35, 0x1078, 0x50f2, 0x20a9, 0x01f4, + 0x6824, 0xd094, 0x0040, 0x6411, 0x6827, 0x0004, 0x7804, 0xa084, + 0x4000, 0x0040, 0x6423, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, + 0x6423, 0xd084, 0x0040, 0x6418, 0x6827, 0x0001, 0x0078, 0x641a, + 0x00f0, 0x6400, 0x7804, 0xa084, 0x1000, 0x0040, 0x6423, 0x7803, + 0x0100, 0x7803, 0x0000, 0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, + 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c, 0x127e, 0x157e, 0x0f7e, + 0x0e7e, 0x0d7e, 0x0c7e, 0x027e, 0x017e, 0x007e, 0x2091, 0x8000, + 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x8aa2, 0x703c, 0x2060, + 0x8cff, 0x0040, 0x64a4, 0x6817, 0x0010, 0x68c7, 0x0000, 0x68cb, + 0x0000, 0x1078, 0x517c, 0x1078, 0x1d84, 0x047e, 0x057e, 0x2009, + 0x017f, 0x212c, 0x200b, 0x00a5, 0x2021, 0x0169, 0x2404, 0xa084, + 0x000f, 0xa086, 0x0004, 0x00c0, 0x6473, 0x68c7, 0x0000, 0x68cb, + 0x0008, 0x0e7e, 0x0f7e, 0x2079, 0x0020, 0x2071, 0x8af9, 0x6814, + 0xa084, 0x0004, 0xa085, 0x0012, 0x6816, 0x7803, 0x0008, 0x7003, + 0x0000, 0x0f7f, 0x0e7f, 0x250a, 0x057f, 0x047f, 0xa39d, 0x0000, + 0x00c0, 0x647e, 0x2009, 0x0049, 0x1078, 0x6939, 0x20a9, 0x03e8, + 0x6824, 0xd094, 0x0040, 0x6491, 0x6827, 0x0004, 0x7804, 0xa084, + 0x4000, 0x0040, 0x64a3, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, + 0x64a3, 0xd094, 0x0040, 0x6498, 0x6827, 0x0002, 0x0078, 0x649a, + 0x00f0, 0x6480, 0x7804, 0xa084, 0x1000, 0x0040, 0x64a3, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x007f, 0x017f, 0x027f, 0x0c7f, - 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c, 0x2001, 0x7700, - 0x2004, 0xa096, 0x0001, 0x0040, 0x5876, 0xa096, 0x0004, 0x0040, - 0x5876, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, 0x3558, 0x1078, - 0x4689, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040, 0x5864, 0x6827, - 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x5876, 0x7803, 0x1000, - 0x7803, 0x0000, 0x0078, 0x5876, 0xd084, 0x0040, 0x586b, 0x6827, - 0x0001, 0x0078, 0x586d, 0x00f0, 0x5853, 0x7804, 0xa084, 0x1000, - 0x0040, 0x5876, 0x7803, 0x0100, 0x7803, 0x0000, 0x007f, 0x017f, - 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c, - 0x127e, 0x157e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x027e, 0x017e, - 0x007e, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, - 0x7936, 0x703c, 0x2060, 0x8cff, 0x0040, 0x58ce, 0x6817, 0x0010, - 0x68cb, 0x0000, 0x68c7, 0x0000, 0x1078, 0x4714, 0x1078, 0x1c13, - 0xa39d, 0x0000, 0x00c0, 0x58a8, 0x2009, 0x0049, 0x1078, 0x5d41, - 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0040, 0x58bb, 0x6827, 0x0004, - 0x7804, 0xa084, 0x4000, 0x0040, 0x58cd, 0x7803, 0x1000, 0x7803, - 0x0000, 0x0078, 0x58cd, 0xd094, 0x0040, 0x58c2, 0x6827, 0x0002, - 0x0078, 0x58c4, 0x00f0, 0x58aa, 0x7804, 0xa084, 0x1000, 0x0040, - 0x58cd, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x007f, 0x017f, - 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c, - 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0x7936, 0x6a06, 0x127f, - 0x0d7f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0x7936, - 0x6a32, 0x127f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e, - 0x007e, 0x127e, 0x2071, 0x7936, 0x7614, 0x2660, 0x2678, 0x2091, - 0x8000, 0x8cff, 0x0040, 0x592c, 0x601c, 0xa206, 0x00c0, 0x5927, - 0x7014, 0xac36, 0x00c0, 0x5906, 0x660c, 0x7616, 0x7010, 0xac36, - 0x00c0, 0x5914, 0x2c00, 0xaf36, 0x0040, 0x5912, 0x2f00, 0x7012, - 0x0078, 0x5914, 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, - 0x0040, 0x591d, 0x7e0e, 0x0078, 0x591e, 0x2678, 0x600f, 0x0000, - 0x1078, 0x6bb6, 0x1078, 0x5a1a, 0x0c7f, 0x0078, 0x58f9, 0x2c78, - 0x600c, 0x2060, 0x0078, 0x58f9, 0x127f, 0x007f, 0x067f, 0x0c7f, - 0x0e7f, 0x0f7f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, - 0x532f, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, - 0x20a3, 0x4000, 0x0078, 0x5975, 0x157e, 0x147e, 0x20a1, 0x020b, - 0x1078, 0x532f, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, - 0x20a2, 0x20a3, 0x2000, 0x0078, 0x5975, 0x157e, 0x147e, 0x20a1, - 0x020b, 0x1078, 0x532f, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, - 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078, 0x5975, 0x157e, 0x147e, - 0x20a1, 0x020b, 0x1078, 0x532f, 0x7810, 0x20a2, 0xa006, 0x20a2, - 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200, 0x1078, 0x5a25, 0x60c3, - 0x0020, 0x1078, 0x5688, 0x147f, 0x157f, 0x007c, 0x127e, 0x0c7e, - 0x2091, 0x8000, 0x2061, 0x0100, 0x6120, 0xd1b4, 0x00c0, 0x598d, - 0xd1bc, 0x00c0, 0x59d7, 0x0078, 0x5a17, 0x2009, 0x017f, 0x200b, - 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069, 0x0140, 0x20a9, 0x001e, - 0x2009, 0x0169, 0x6804, 0xa084, 0x4000, 0x0040, 0x59ce, 0x6020, - 0xd0b4, 0x0040, 0x59ce, 0x6024, 0xd094, 0x00c0, 0x59ce, 0x2104, - 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x59ce, 0x00f0, 0x599a, - 0x027e, 0x6198, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c, 0x00ff, - 0xa10d, 0x6088, 0x628c, 0x618e, 0x608b, 0xbc91, 0x6043, 0x0001, - 0x6043, 0x0000, 0x608a, 0x628e, 0x6024, 0xd094, 0x00c0, 0x59cd, - 0x6a04, 0xa294, 0x4000, 0x00c0, 0x59c4, 0x027f, 0x0d7f, 0x007f, - 0x157f, 0x2009, 0x017f, 0x200b, 0x0000, 0x0078, 0x5a17, 0x2009, - 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069, 0x0140, - 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000, 0x0040, - 0x5a10, 0x6020, 0xd0bc, 0x0040, 0x5a10, 0x2104, 0xa084, 0x000f, - 0xa086, 0x0004, 0x00c0, 0x5a10, 0x00f0, 0x59e4, 0x027e, 0x6164, - 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c, 0x00ff, 0xa10d, 0x6088, - 0x628c, 0x608b, 0xbc91, 0x618e, 0x6043, 0x0001, 0x6043, 0x0000, - 0x608a, 0x628e, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x5a0a, 0x027f, - 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000, 0x0c7f, - 0x127f, 0x007c, 0x0e7e, 0x2071, 0x7936, 0x7020, 0xa005, 0x0040, - 0x5a23, 0x8001, 0x7022, 0x0e7f, 0x007c, 0x20a9, 0x0008, 0x20a2, - 0x00f0, 0x5a27, 0x20a2, 0x20a2, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, - 0x0c7e, 0x077e, 0x067e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, - 0x7936, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001, 0x87ff, 0x0040, - 0x5abd, 0x8cff, 0x0040, 0x5abd, 0x601c, 0xa086, 0x0006, 0x00c0, - 0x5ab8, 0x88ff, 0x0040, 0x5a54, 0x2800, 0xac06, 0x00c0, 0x5ab8, - 0x2039, 0x0000, 0x0078, 0x5a58, 0x6018, 0xa206, 0x00c0, 0x5ab8, - 0x7024, 0xac06, 0x00c0, 0x5a86, 0x2069, 0x0100, 0x68c0, 0xa005, - 0x0040, 0x5a81, 0x6817, 0x0008, 0x68c3, 0x0000, 0x1078, 0x5b4a, + 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c, 0x0d7e, 0x127e, + 0x2091, 0x8000, 0x2069, 0x8aa2, 0x6a06, 0x127f, 0x0d7f, 0x007c, + 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0x8aa2, 0x6a32, 0x127f, + 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e, 0x007e, 0x127e, + 0x2071, 0x8aa2, 0x7614, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, + 0x0040, 0x6502, 0x601c, 0xa206, 0x00c0, 0x64fd, 0x7014, 0xac36, + 0x00c0, 0x64dc, 0x660c, 0x7616, 0x7010, 0xac36, 0x00c0, 0x64ea, + 0x2c00, 0xaf36, 0x0040, 0x64e8, 0x2f00, 0x7012, 0x0078, 0x64ea, + 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x64f3, + 0x7e0e, 0x0078, 0x64f4, 0x2678, 0x600f, 0x0000, 0x1078, 0x79a8, + 0x1078, 0x6601, 0x0c7f, 0x0078, 0x64cf, 0x2c78, 0x600c, 0x2060, + 0x0078, 0x64cf, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0e7f, 0x0f7f, + 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x5e77, 0x7810, + 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x1000, + 0x0078, 0x655c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x5e77, + 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, + 0x4000, 0x0078, 0x655c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, + 0x5e77, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, + 0x20a3, 0x2000, 0x0078, 0x655c, 0x157e, 0x147e, 0x20a1, 0x020b, + 0x1078, 0x5e77, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, + 0x20a2, 0x20a3, 0x0400, 0x0078, 0x655c, 0x157e, 0x147e, 0x20a1, + 0x020b, 0x1078, 0x5e77, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, + 0x20a2, 0x20a2, 0x20a3, 0x0200, 0x1078, 0x660c, 0x60c3, 0x0020, + 0x1078, 0x621e, 0x147f, 0x157f, 0x007c, 0x127e, 0x0c7e, 0x2091, + 0x8000, 0x2061, 0x0100, 0x6120, 0xd1b4, 0x00c0, 0x6574, 0xd1bc, + 0x00c0, 0x65be, 0x0078, 0x65fe, 0x2009, 0x017f, 0x200b, 0x00a1, + 0x157e, 0x007e, 0x0d7e, 0x2069, 0x0140, 0x20a9, 0x001e, 0x2009, + 0x0169, 0x6804, 0xa084, 0x4000, 0x0040, 0x65b5, 0x6020, 0xd0b4, + 0x0040, 0x65b5, 0x6024, 0xd094, 0x00c0, 0x65b5, 0x2104, 0xa084, + 0x000f, 0xa086, 0x0004, 0x00c0, 0x65b5, 0x00f0, 0x6581, 0x027e, + 0x6198, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c, 0x00ff, 0xa10d, + 0x6088, 0x628c, 0x618e, 0x608b, 0xbc91, 0x6043, 0x0001, 0x6043, + 0x0000, 0x608a, 0x628e, 0x6024, 0xd094, 0x00c0, 0x65b4, 0x6a04, + 0xa294, 0x4000, 0x00c0, 0x65ab, 0x027f, 0x0d7f, 0x007f, 0x157f, + 0x2009, 0x017f, 0x200b, 0x0000, 0x0078, 0x65fe, 0x2009, 0x017f, + 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069, 0x0140, 0x20a9, + 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000, 0x0040, 0x65f7, + 0x6020, 0xd0bc, 0x0040, 0x65f7, 0x2104, 0xa084, 0x000f, 0xa086, + 0x0004, 0x00c0, 0x65f7, 0x00f0, 0x65cb, 0x027e, 0x6164, 0xa18c, + 0x00ff, 0x8107, 0x6130, 0xa18c, 0x00ff, 0xa10d, 0x6088, 0x628c, + 0x608b, 0xbc91, 0x618e, 0x6043, 0x0001, 0x6043, 0x0000, 0x608a, + 0x628e, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x65f1, 0x027f, 0x0d7f, + 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000, 0x0c7f, 0x127f, + 0x007c, 0x0e7e, 0x2071, 0x8aa2, 0x7020, 0xa005, 0x0040, 0x660a, + 0x8001, 0x7022, 0x0e7f, 0x007c, 0x20a9, 0x0008, 0x20a2, 0x00f0, + 0x660e, 0x20a2, 0x20a2, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, + 0x077e, 0x067e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0x8aa2, + 0x7614, 0x2660, 0x2678, 0x2039, 0x0001, 0x87ff, 0x0040, 0x66ad, + 0x8cff, 0x0040, 0x66ad, 0x601c, 0xa086, 0x0006, 0x00c0, 0x66a8, + 0x88ff, 0x0040, 0x663b, 0x2800, 0xac06, 0x00c0, 0x66a8, 0x2039, + 0x0000, 0x0078, 0x6646, 0x6018, 0xa206, 0x00c0, 0x66a8, 0x85ff, + 0x0040, 0x6646, 0x6020, 0xa106, 0x00c0, 0x66a8, 0x7024, 0xac06, + 0x00c0, 0x6676, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x6671, + 0x1078, 0x516f, 0x6817, 0x0008, 0x68c3, 0x0000, 0x1078, 0x6741, 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, - 0x0040, 0x5a76, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, - 0x6824, 0xd084, 0x0040, 0x5a7e, 0x6827, 0x0001, 0x037f, 0x0078, - 0x5a86, 0x6003, 0x0009, 0x630a, 0x0078, 0x5ab8, 0x7014, 0xac36, - 0x00c0, 0x5a8c, 0x660c, 0x7616, 0x7010, 0xac36, 0x00c0, 0x5a9a, - 0x2c00, 0xaf36, 0x0040, 0x5a98, 0x2f00, 0x7012, 0x0078, 0x5a9a, - 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5aa3, - 0x7e0e, 0x0078, 0x5aa4, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, - 0x1078, 0x6a58, 0x0040, 0x5aae, 0x1078, 0x75fd, 0x1078, 0x6bb6, - 0x1078, 0x5a1a, 0x88ff, 0x00c0, 0x5ac7, 0x0c7f, 0x0078, 0x5a3e, - 0x2c78, 0x600c, 0x2060, 0x0078, 0x5a3e, 0xa006, 0x127f, 0x007f, + 0x0040, 0x6666, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, + 0x6824, 0xd084, 0x0040, 0x666e, 0x6827, 0x0001, 0x037f, 0x0078, + 0x6676, 0x6003, 0x0009, 0x630a, 0x0078, 0x66a8, 0x7014, 0xac36, + 0x00c0, 0x667c, 0x660c, 0x7616, 0x7010, 0xac36, 0x00c0, 0x668a, + 0x2c00, 0xaf36, 0x0040, 0x6688, 0x2f00, 0x7012, 0x0078, 0x668a, + 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x6693, + 0x7e0e, 0x0078, 0x6694, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, + 0x1078, 0x77ed, 0x0040, 0x669e, 0x1078, 0x86aa, 0x1078, 0x79a8, + 0x1078, 0x6601, 0x88ff, 0x00c0, 0x66b7, 0x0c7f, 0x0078, 0x6625, + 0x2c78, 0x600c, 0x2060, 0x0078, 0x6625, 0xa006, 0x127f, 0x007f, 0x067f, 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x6017, - 0x0000, 0x0c7f, 0xa8c5, 0x0001, 0x0078, 0x5abe, 0x0f7e, 0x0e7e, + 0x0000, 0x0c7f, 0xa8c5, 0x0001, 0x0078, 0x66ae, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x007e, 0x127e, 0x2091, 0x8000, - 0x2071, 0x7936, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0040, 0x5b39, - 0x601c, 0xa086, 0x0006, 0x00c0, 0x5b34, 0x88ff, 0x0040, 0x5aee, - 0x2800, 0xac06, 0x00c0, 0x5b34, 0x0078, 0x5af2, 0x6018, 0xa206, - 0x00c0, 0x5b34, 0x703c, 0xac06, 0x00c0, 0x5b04, 0x037e, 0x2019, - 0x0001, 0x1078, 0x5880, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, - 0x0000, 0x7047, 0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x5b0a, - 0x660c, 0x763a, 0x7034, 0xac36, 0x00c0, 0x5b18, 0x2c00, 0xaf36, - 0x0040, 0x5b16, 0x2f00, 0x7036, 0x0078, 0x5b18, 0x7037, 0x0000, - 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5b21, 0x7e0e, 0x0078, - 0x5b22, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x6a58, - 0x0040, 0x5b2c, 0x1078, 0x75fd, 0x1078, 0x6bb6, 0x88ff, 0x00c0, - 0x5b43, 0x0c7f, 0x0078, 0x5add, 0x2c78, 0x600c, 0x2060, 0x0078, - 0x5add, 0xa006, 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0d7f, - 0x0e7f, 0x0f7f, 0x007c, 0x6017, 0x0000, 0x0c7f, 0xa8c5, 0x0001, - 0x0078, 0x5b3a, 0x0e7e, 0x2071, 0x7936, 0x2001, 0x7700, 0x2004, - 0xa086, 0x0002, 0x00c0, 0x5b58, 0x7007, 0x0005, 0x0078, 0x5b5a, - 0x7007, 0x0000, 0x0e7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e, - 0x027e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0x7936, 0x2c10, - 0x7638, 0x2660, 0x2678, 0x8cff, 0x0040, 0x5b9a, 0x2200, 0xac06, - 0x00c0, 0x5b95, 0x7038, 0xac36, 0x00c0, 0x5b78, 0x660c, 0x763a, - 0x7034, 0xac36, 0x00c0, 0x5b86, 0x2c00, 0xaf36, 0x0040, 0x5b84, - 0x2f00, 0x7036, 0x0078, 0x5b86, 0x7037, 0x0000, 0x660c, 0x2c00, - 0xaf06, 0x0040, 0x5b8e, 0x7e0e, 0x0078, 0x5b8f, 0x2678, 0x600f, - 0x0000, 0xa085, 0x0001, 0x0078, 0x5b9a, 0x2c78, 0x600c, 0x2060, - 0x0078, 0x5b6b, 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0e7f, - 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e, - 0x127e, 0x2091, 0x8000, 0x2071, 0x7936, 0x760c, 0x2660, 0x2678, - 0x8cff, 0x0040, 0x5c33, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, - 0x00c0, 0x5c2e, 0x7024, 0xac06, 0x00c0, 0x5be1, 0x2069, 0x0100, - 0x68c0, 0xa005, 0x0040, 0x5be1, 0x1078, 0x569c, 0x68c3, 0x0000, - 0x1078, 0x5b4a, 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, - 0xa384, 0x1000, 0x0040, 0x5bd8, 0x6803, 0x0100, 0x6803, 0x0000, - 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x5be0, 0x6827, 0x0001, - 0x037f, 0x700c, 0xac36, 0x00c0, 0x5be7, 0x660c, 0x760e, 0x7008, - 0xac36, 0x00c0, 0x5bf5, 0x2c00, 0xaf36, 0x0040, 0x5bf3, 0x2f00, - 0x700a, 0x0078, 0x5bf5, 0x700b, 0x0000, 0x660c, 0x067e, 0x2c00, - 0xaf06, 0x0040, 0x5bfe, 0x7e0e, 0x0078, 0x5bff, 0x2678, 0x600f, - 0x0000, 0x1078, 0x6bcf, 0x00c0, 0x5c09, 0x1078, 0x22d7, 0x0078, - 0x5c25, 0x1078, 0x6be3, 0x00c0, 0x5c11, 0x1078, 0x5f6d, 0x0078, - 0x5c25, 0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, 0x5c25, 0x601c, - 0xa086, 0x0003, 0x00c0, 0x5c3b, 0x6837, 0x0103, 0x6b4a, 0x6847, - 0x0000, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x6003, 0x0000, 0x1078, - 0x6bb6, 0x1078, 0x5a1a, 0x0c7f, 0x0078, 0x5bb0, 0x2c78, 0x600c, - 0x2060, 0x0078, 0x5bb0, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f, - 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x5c1c, - 0x1078, 0x75fd, 0x0078, 0x5c25, 0x037e, 0x157e, 0x137e, 0x147e, - 0x3908, 0xa006, 0xa190, 0x0020, 0x221c, 0xa39e, 0x2149, 0x00c0, - 0x5c55, 0x8210, 0x8000, 0x0078, 0x5c4c, 0xa005, 0x0040, 0x5c5f, - 0x20a9, 0x0020, 0x2198, 0xa110, 0x22a0, 0x22c8, 0x53a3, 0x147f, - 0x137f, 0x157f, 0x037f, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078, - 0x516f, 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x20a3, 0x514c, 0x20a3, 0x4f47, 0x20a3, - 0x4943, 0x20a3, 0x2020, 0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x1078, 0x5688, 0x0d7f, 0x007c, 0x20a1, - 0x020b, 0x1078, 0x516f, 0x20a3, 0x0210, 0x20a3, 0x0018, 0x20a3, - 0x0800, 0x7810, 0xa084, 0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7810, - 0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, - 0x0018, 0x1078, 0x5688, 0x007c, 0x2061, 0x7e00, 0x2a70, 0x7060, - 0x7046, 0x704b, 0x7e00, 0x007c, 0x0e7e, 0x127e, 0x2071, 0x7700, - 0x2091, 0x8000, 0x7544, 0xa582, 0x0001, 0x0048, 0x5ce6, 0x7048, - 0x2060, 0x6000, 0xa086, 0x0000, 0x0040, 0x5cd2, 0xace0, 0x0008, - 0x7054, 0xac02, 0x00c8, 0x5cce, 0x0078, 0x5cc1, 0x2061, 0x7e00, - 0x0078, 0x5cc1, 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8, 0x0008, - 0x7054, 0xa502, 0x00c8, 0x5ce2, 0x754a, 0xa085, 0x0001, 0x127f, - 0x0e7f, 0x007c, 0x704b, 0x7e00, 0x0078, 0x5cdd, 0xa006, 0x0078, - 0x5cdf, 0x0e7e, 0x2071, 0x7700, 0x7544, 0xa582, 0x0001, 0x0048, - 0x5d17, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040, 0x5d04, - 0xace0, 0x0008, 0x7054, 0xac02, 0x00c8, 0x5d00, 0x0078, 0x5cf3, - 0x2061, 0x7e00, 0x0078, 0x5cf3, 0x6003, 0x0008, 0x8529, 0x7546, - 0xaca8, 0x0008, 0x7054, 0xa502, 0x00c8, 0x5d13, 0x754a, 0xa085, - 0x0001, 0x0e7f, 0x007c, 0x704b, 0x7e00, 0x0078, 0x5d0f, 0xa006, - 0x0078, 0x5d11, 0xac82, 0x7e00, 0x1048, 0x12cd, 0x2001, 0x7715, - 0x2004, 0xac02, 0x10c8, 0x12cd, 0xa006, 0x6006, 0x600a, 0x600e, - 0x6012, 0x6016, 0x601a, 0x601f, 0x0000, 0x6003, 0x0000, 0x2061, - 0x7700, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0040, 0x5d39, - 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x4d96, 0x127f, 0x0078, - 0x5d38, 0x601c, 0xa084, 0x000f, 0x0079, 0x5d46, 0x5d4f, 0x5d57, - 0x5d73, 0x5d8f, 0x6c60, 0x6c7c, 0x6c98, 0x5d4f, 0x5d57, 0xa18e, - 0x0047, 0x00c0, 0x5d56, 0xa016, 0x1078, 0x156a, 0x007c, 0x067e, - 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12cd, 0x1079, 0x5d61, 0x067f, - 0x007c, 0x5d71, 0x5e58, 0x5f88, 0x5d71, 0x5fdf, 0x5d71, 0x5d71, - 0x5d71, 0x5e07, 0x6298, 0x5d71, 0x5d71, 0x5d71, 0x5d71, 0x5d71, - 0x5d71, 0x1078, 0x12cd, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, - 0x12cd, 0x1079, 0x5d7d, 0x067f, 0x007c, 0x5d8d, 0x5d8d, 0x5d8d, - 0x5d8d, 0x5d8d, 0x5d8d, 0x5d8d, 0x5d8d, 0x670c, 0x67d2, 0x5d8d, - 0x6725, 0x677e, 0x6725, 0x677e, 0x5d8d, 0x1078, 0x12cd, 0x067e, - 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12cd, 0x1079, 0x5d99, 0x067f, - 0x007c, 0x5da9, 0x62d6, 0x637c, 0x643e, 0x6596, 0x5da9, 0x5da9, - 0x5da9, 0x62b4, 0x66c1, 0x66c5, 0x5da9, 0x5da9, 0x5da9, 0x5da9, - 0x66eb, 0x1078, 0x12cd, 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0, - 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420, 0x9398, 0x94a0, 0x3318, - 0x3428, 0x222e, 0x2326, 0xa290, 0x0002, 0xa5a8, 0x0002, 0xa398, - 0x0002, 0xa4a0, 0x0002, 0x00f0, 0x5db9, 0x0e7e, 0x1078, 0x6a58, - 0x0040, 0x5dd0, 0x6010, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103, - 0x0e7f, 0x1078, 0x5d1a, 0x007c, 0x0d7e, 0x037e, 0x7330, 0xa386, - 0x0200, 0x00c0, 0x5de1, 0x6018, 0x2068, 0x6813, 0x00ff, 0x6817, - 0xfffd, 0x6010, 0xa005, 0x0040, 0x5deb, 0x2068, 0x6807, 0x0000, - 0x6837, 0x0103, 0x6b32, 0x1078, 0x5d1a, 0x037f, 0x0d7f, 0x007c, - 0x0d7e, 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0, 0x53a3, 0xa1b6, - 0x0015, 0x00c0, 0x5e04, 0x6018, 0x2068, 0x7038, 0x680a, 0x703c, - 0x680e, 0x6800, 0xc08d, 0x6802, 0x0d7f, 0x0078, 0x5dc5, 0x2100, - 0xa1b2, 0x0030, 0x10c8, 0x12cd, 0x0079, 0x5e0e, 0x5e40, 0x5e4c, - 0x5e40, 0x5e40, 0x5e40, 0x5e40, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, - 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, - 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, - 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e40, 0x5e3e, 0x5e40, - 0x5e40, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e40, 0x5e3e, - 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x1078, 0x12cd, - 0x6003, 0x0001, 0x6106, 0x1078, 0x498e, 0x127e, 0x2091, 0x8000, - 0x1078, 0x4d96, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078, - 0x498e, 0x127e, 0x2091, 0x8000, 0x1078, 0x4d96, 0x127f, 0x007c, - 0x6004, 0xa0b2, 0x0030, 0x10c8, 0x12cd, 0xa1b6, 0x0013, 0x00c0, - 0x5e64, 0x2008, 0x0079, 0x5eeb, 0xa1b6, 0x0027, 0x00c0, 0x5eb9, - 0x1078, 0x4c9d, 0x6004, 0x1078, 0x6bcf, 0x0040, 0x5e7d, 0x1078, - 0x6be3, 0x0040, 0x5eb1, 0xa08e, 0x0021, 0x0040, 0x5eb5, 0xa08e, - 0x0022, 0x0040, 0x5eb1, 0x0078, 0x5eac, 0x1078, 0x22d7, 0x2001, - 0x0007, 0x1078, 0x37f4, 0x6018, 0xa080, 0x0028, 0x200c, 0x1078, - 0x5f6d, 0xa186, 0x007e, 0x00c0, 0x5e92, 0x2001, 0x772f, 0x2014, - 0xc285, 0x2202, 0x017e, 0x027e, 0x037e, 0x2110, 0x2019, 0x0028, - 0x1078, 0x4a7e, 0x1078, 0x49c1, 0x0c7e, 0x6018, 0xa065, 0x0040, - 0x5ea3, 0x1078, 0x3a36, 0x0c7f, 0x2c08, 0x1078, 0x747b, 0x037f, - 0x027f, 0x017f, 0x1078, 0x3834, 0x1078, 0x5d1a, 0x1078, 0x4d96, - 0x007c, 0x1078, 0x5f6d, 0x0078, 0x5eac, 0x1078, 0x5f7c, 0x0078, - 0x5eac, 0xa186, 0x0014, 0x00c0, 0x5eb0, 0x1078, 0x4c9d, 0x1078, - 0x22b5, 0x1078, 0x6bcf, 0x00c0, 0x5ed8, 0x1078, 0x22d7, 0x6018, - 0xa080, 0x0028, 0x200c, 0x1078, 0x5f6d, 0xa186, 0x007e, 0x00c0, - 0x5ed6, 0x2001, 0x772f, 0x200c, 0xc185, 0x2102, 0x0078, 0x5eac, - 0x1078, 0x6be3, 0x00c0, 0x5ee0, 0x1078, 0x5f6d, 0x0078, 0x5eac, - 0x6004, 0xa08e, 0x0021, 0x0040, 0x5edc, 0xa08e, 0x0022, 0x1040, - 0x5f7c, 0x0078, 0x5eac, 0x5f1d, 0x5f1f, 0x5f23, 0x5f27, 0x5f2b, - 0x5f2f, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, - 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, - 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, - 0x5f1b, 0x5f33, 0x5f39, 0x5f1b, 0x5f43, 0x5f39, 0x5f1b, 0x5f1b, - 0x5f1b, 0x5f1b, 0x5f1b, 0x5f39, 0x5f39, 0x5f1b, 0x5f1b, 0x5f1b, - 0x5f1b, 0x5f1b, 0x5f1b, 0x1078, 0x12cd, 0x0078, 0x5f39, 0x2001, - 0x000b, 0x0078, 0x5f4c, 0x2001, 0x0003, 0x0078, 0x5f4c, 0x2001, - 0x0005, 0x0078, 0x5f4c, 0x2001, 0x0001, 0x0078, 0x5f4c, 0x2001, - 0x0009, 0x0078, 0x5f4c, 0x1078, 0x12cd, 0x0078, 0x5f4b, 0x1078, - 0x37f4, 0x1078, 0x4c9d, 0x6003, 0x0002, 0x6017, 0x0028, 0x1078, - 0x4d96, 0x0078, 0x5f4b, 0x1078, 0x4c9d, 0x6003, 0x0004, 0x6017, - 0x0028, 0x1078, 0x4d96, 0x007c, 0x1078, 0x37f4, 0x1078, 0x4c9d, - 0x6003, 0x0002, 0x037e, 0x2019, 0x775c, 0x2304, 0xa084, 0xff00, - 0x00c0, 0x5f5e, 0x2019, 0x0028, 0x0078, 0x5f67, 0x8007, 0xa09a, - 0x0004, 0x0048, 0x5f5a, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, - 0x037f, 0x1078, 0x4d96, 0x0078, 0x5f4b, 0x0e7e, 0x1078, 0x6a58, - 0x0040, 0x5f7a, 0x6010, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103, - 0x7033, 0x0100, 0x0e7f, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74, - 0x7000, 0x2070, 0x7037, 0x0103, 0x7023, 0x8001, 0x0e7f, 0x007c, - 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084, 0x00ff, 0x0d7f, 0xa0b2, - 0x000c, 0x10c8, 0x12cd, 0x6604, 0xa6b6, 0x0028, 0x00c0, 0x5f9c, - 0x1078, 0x6c18, 0x0078, 0x5fce, 0x6604, 0xa6b6, 0x0029, 0x00c0, - 0x5fa5, 0x1078, 0x6c32, 0x0078, 0x5fce, 0x6604, 0xa6b6, 0x001f, - 0x00c0, 0x5fae, 0x1078, 0x5dab, 0x0078, 0x5fce, 0x6604, 0xa6b6, - 0x0000, 0x00c0, 0x5fb7, 0x1078, 0x5df0, 0x0078, 0x5fce, 0x6604, - 0xa6b6, 0x0022, 0x00c0, 0x5fc0, 0x1078, 0x5dd4, 0x0078, 0x5fce, - 0xa1b6, 0x0015, 0x00c0, 0x5fc8, 0x1079, 0x5fd3, 0x0078, 0x5fce, - 0xa1b6, 0x0016, 0x00c0, 0x5fcf, 0x1079, 0x6110, 0x007c, 0x1078, - 0x5d4f, 0x0078, 0x5fce, 0x5ff7, 0x5ffa, 0x5ff7, 0x603b, 0x5ff7, - 0x60ac, 0x5ff7, 0x5ff7, 0x5ff7, 0x60e8, 0x5ff7, 0x60fe, 0xa1b6, - 0x0048, 0x0040, 0x5feb, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, - 0x1078, 0x156a, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000, - 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x5d1a, 0x007c, 0x0005, - 0x0005, 0x007c, 0x0e7e, 0x2071, 0x7700, 0x7078, 0xa086, 0x0074, - 0x00c0, 0x6024, 0x1078, 0x744f, 0x00c0, 0x6016, 0x0d7e, 0x6018, - 0x2068, 0x1078, 0x6028, 0x0d7f, 0x2001, 0x0006, 0x1078, 0x37f4, - 0x1078, 0x22d7, 0x1078, 0x5d1a, 0x0078, 0x6026, 0x2001, 0x000a, - 0x1078, 0x37f4, 0x1078, 0x22d7, 0x6003, 0x0001, 0x6007, 0x0001, - 0x1078, 0x498e, 0x0078, 0x6026, 0x1078, 0x609c, 0x0e7f, 0x007c, - 0x6800, 0xd084, 0x0040, 0x603a, 0x2001, 0x0000, 0x1078, 0x37e0, - 0x2069, 0x7751, 0x6804, 0xd0a4, 0x0040, 0x603a, 0x2001, 0x0006, - 0x1078, 0x3802, 0x007c, 0x0d7e, 0x2011, 0x771e, 0x2204, 0xa086, - 0x0074, 0x00c0, 0x6098, 0x1078, 0x61ea, 0x6018, 0x2068, 0xa080, - 0x0028, 0x2014, 0xa286, 0x007e, 0x0040, 0x6063, 0xa286, 0x0080, - 0x00c0, 0x608c, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005, - 0x0040, 0x6082, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833, - 0x0200, 0x0078, 0x6082, 0x0e7e, 0x0f7e, 0x6813, 0x00ff, 0x6817, - 0xfffe, 0x2071, 0x772f, 0x2e04, 0xa085, 0x0003, 0x2072, 0x2071, - 0x7c80, 0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0x7719, - 0x206a, 0x78e6, 0x8e70, 0x2e04, 0x2069, 0x771a, 0x206a, 0x78ea, - 0x0f7f, 0x0e7f, 0x2001, 0x0006, 0x1078, 0x37f4, 0x1078, 0x22d7, - 0x1078, 0x5d1a, 0x0078, 0x609a, 0x2001, 0x0004, 0x1078, 0x37f4, - 0x6003, 0x0001, 0x6007, 0x0003, 0x1078, 0x498e, 0x0078, 0x609a, - 0x1078, 0x609c, 0x0d7f, 0x007c, 0x2001, 0x7700, 0x2004, 0xa086, - 0x0003, 0x0040, 0x60a7, 0x2001, 0x0007, 0x1078, 0x37f4, 0x1078, - 0x22d7, 0x1078, 0x5d1a, 0x007c, 0x0e7e, 0x2071, 0x7700, 0x7078, - 0xa086, 0x0014, 0x00c0, 0x60e2, 0x7000, 0xa086, 0x0003, 0x00c0, - 0x60bf, 0x6010, 0xa005, 0x00c0, 0x60bf, 0x1078, 0x2dd7, 0x0d7e, - 0x6018, 0x2068, 0x1078, 0x38c8, 0x1078, 0x6028, 0x0d7f, 0x1078, - 0x61f4, 0x00c0, 0x60e2, 0x2001, 0x0006, 0x1078, 0x37f4, 0x0e7e, - 0x6010, 0xa005, 0x0040, 0x60db, 0x2070, 0x7007, 0x0000, 0x7037, - 0x0103, 0x7033, 0x0200, 0x0e7f, 0x1078, 0x22d7, 0x1078, 0x5d1a, - 0x0078, 0x60e6, 0x1078, 0x5f6d, 0x1078, 0x609c, 0x0e7f, 0x007c, - 0x2011, 0x771e, 0x2204, 0xa086, 0x0014, 0x00c0, 0x60fb, 0x2001, - 0x0002, 0x1078, 0x37f4, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, - 0x498e, 0x0078, 0x60fd, 0x1078, 0x609c, 0x007c, 0x2011, 0x771e, - 0x2204, 0xa086, 0x0004, 0x00c0, 0x610d, 0x2001, 0x0007, 0x1078, - 0x37f4, 0x1078, 0x5d1a, 0x0078, 0x610f, 0x1078, 0x609c, 0x007c, - 0x5ff7, 0x611c, 0x5ff7, 0x6142, 0x5ff7, 0x619d, 0x5ff7, 0x5ff7, - 0x5ff7, 0x61b2, 0x5ff7, 0x61c5, 0x0c7e, 0x1078, 0x61d8, 0x00c0, - 0x6131, 0x2001, 0x0000, 0x1078, 0x37e0, 0x2001, 0x0002, 0x1078, - 0x37f4, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x498e, 0x0078, - 0x6140, 0x2009, 0x7c8f, 0x2104, 0xa084, 0xff00, 0xa086, 0x1900, - 0x00c0, 0x613e, 0x1078, 0x5d1a, 0x0078, 0x6140, 0x1078, 0x609c, - 0x0c7f, 0x007c, 0x1078, 0x61e7, 0x00c0, 0x6156, 0x2001, 0x0000, - 0x1078, 0x37e0, 0x2001, 0x0002, 0x1078, 0x37f4, 0x6003, 0x0001, - 0x6007, 0x0002, 0x1078, 0x498e, 0x0078, 0x6178, 0x1078, 0x5f6d, - 0x2009, 0x7c8e, 0x2134, 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x0040, - 0x6179, 0x2009, 0x7c8f, 0x2104, 0xa084, 0xff00, 0xa086, 0x1900, - 0x00c0, 0x6176, 0xa686, 0x0009, 0x0040, 0x6179, 0x2001, 0x0004, - 0x1078, 0x37f4, 0x1078, 0x5d1a, 0x0078, 0x6178, 0x1078, 0x609c, - 0x007c, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, 0x6187, - 0x6838, 0xd0fc, 0x0040, 0x6187, 0x0d7f, 0x0078, 0x6176, 0x6018, - 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, 0x6198, 0x8001, - 0x6842, 0x6017, 0x000a, 0x6007, 0x0016, 0x0d7f, 0x0078, 0x6178, - 0x1078, 0x22b5, 0x0d7f, 0x0078, 0x6176, 0x1078, 0x61e7, 0x00c0, - 0x61ad, 0x2001, 0x0004, 0x1078, 0x37f4, 0x6003, 0x0001, 0x6007, - 0x0003, 0x1078, 0x498e, 0x0078, 0x61b1, 0x1078, 0x5f6d, 0x1078, - 0x609c, 0x007c, 0x1078, 0x61e7, 0x00c0, 0x61c2, 0x2001, 0x0008, - 0x1078, 0x37f4, 0x6003, 0x0001, 0x6007, 0x0005, 0x1078, 0x498e, - 0x0078, 0x61c4, 0x1078, 0x609c, 0x007c, 0x1078, 0x61e7, 0x00c0, - 0x61d5, 0x2001, 0x000a, 0x1078, 0x37f4, 0x6003, 0x0001, 0x6007, - 0x0001, 0x1078, 0x498e, 0x0078, 0x61d7, 0x1078, 0x609c, 0x007c, - 0x2009, 0x7c8e, 0x2104, 0xa086, 0x0003, 0x00c0, 0x61e6, 0x2009, - 0x7c8f, 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, 0x007c, 0xa085, - 0x0001, 0x007c, 0x0c7e, 0x017e, 0xac88, 0x0006, 0x2164, 0x1078, - 0x385e, 0x017f, 0x0c7f, 0x007c, 0x0e7e, 0x2071, 0x7c8c, 0x7004, - 0xa086, 0x0014, 0x00c0, 0x6217, 0x7008, 0xa086, 0x0800, 0x00c0, - 0x6217, 0x700c, 0xd0ec, 0x0040, 0x6215, 0xa084, 0x0f00, 0xa086, - 0x0100, 0x00c0, 0x6215, 0x7024, 0xd0a4, 0x0040, 0x6215, 0xd08c, - 0x0040, 0x6215, 0xa006, 0x0078, 0x6217, 0xa085, 0x0001, 0x0e7f, - 0x007c, 0x0e7e, 0x0d7e, 0x0c7e, 0x077e, 0x057e, 0x047e, 0x027e, - 0x007e, 0x127e, 0x2091, 0x8000, 0x2029, 0x793f, 0x252c, 0x2021, - 0x7945, 0x2424, 0x2061, 0x7e00, 0x2071, 0x7700, 0x7244, 0x7060, - 0xa202, 0x00c8, 0x626e, 0x1078, 0x7659, 0x0040, 0x6266, 0x671c, - 0xa786, 0x0001, 0x0040, 0x6266, 0xa786, 0x0007, 0x0040, 0x6266, - 0x2500, 0xac06, 0x0040, 0x6266, 0x2400, 0xac06, 0x0040, 0x6266, - 0x0c7e, 0x6000, 0xa086, 0x0004, 0x00c0, 0x6250, 0x1078, 0x166e, - 0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, 0x6263, 0xa786, 0x0003, - 0x00c0, 0x6278, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, - 0x3b92, 0x1078, 0x6ba9, 0x1078, 0x6bb6, 0x0c7f, 0xace0, 0x0008, - 0x7054, 0xac02, 0x00c8, 0x626e, 0x0078, 0x622e, 0x127f, 0x007f, - 0x027f, 0x047f, 0x057f, 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, - 0xa786, 0x0006, 0x00c0, 0x625a, 0x1078, 0x75fd, 0x0078, 0x6263, - 0x220c, 0x2304, 0xa106, 0x00c0, 0x628b, 0x8210, 0x8318, 0x00f0, - 0x6280, 0xa006, 0x007c, 0x2304, 0xa102, 0x0048, 0x6293, 0x2001, - 0x0001, 0x0078, 0x6295, 0x2001, 0x0000, 0xa18d, 0x0001, 0x007c, - 0x6004, 0xa08a, 0x0030, 0x10c8, 0x12cd, 0x1078, 0x6bcf, 0x0040, - 0x62a7, 0x1078, 0x6be3, 0x0040, 0x62b0, 0x0078, 0x62a9, 0x1078, - 0x22d7, 0x1078, 0x4c9d, 0x1078, 0x5d1a, 0x1078, 0x4d96, 0x007c, - 0x1078, 0x5f6d, 0x0078, 0x62a9, 0xa182, 0x0040, 0x0079, 0x62b8, - 0x62c8, 0x62c8, 0x62c8, 0x62c8, 0x62c8, 0x62c8, 0x62c8, 0x62c8, - 0x62c8, 0x62c8, 0x62c8, 0x62ca, 0x62ca, 0x62ca, 0x62ca, 0x62c8, - 0x1078, 0x12cd, 0x6003, 0x0001, 0x6106, 0x1078, 0x4941, 0x127e, - 0x2091, 0x8000, 0x1078, 0x4d96, 0x127f, 0x007c, 0xa186, 0x0013, - 0x00c0, 0x62df, 0x6004, 0xa082, 0x0040, 0x0079, 0x6355, 0xa186, - 0x0027, 0x00c0, 0x62fc, 0x1078, 0x4c9d, 0x1078, 0x22b5, 0x0d7e, - 0x6110, 0x2168, 0x1078, 0x6a58, 0x0040, 0x62f6, 0x6837, 0x0103, - 0x684b, 0x0029, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x0d7f, 0x1078, - 0x5d1a, 0x1078, 0x4d96, 0x007c, 0xa186, 0x0014, 0x00c0, 0x6305, - 0x6004, 0xa082, 0x0040, 0x0079, 0x6325, 0xa186, 0x0047, 0x10c0, - 0x12cd, 0x2001, 0x0109, 0x2004, 0xd084, 0x0040, 0x6322, 0x127e, - 0x2091, 0x2200, 0x007e, 0x017e, 0x027e, 0x1078, 0x4802, 0x027f, - 0x017f, 0x007f, 0x127f, 0x6000, 0xa086, 0x0002, 0x00c0, 0x6322, - 0x0078, 0x637c, 0x1078, 0x5d4f, 0x007c, 0x6337, 0x6335, 0x6335, - 0x6335, 0x6335, 0x6335, 0x6335, 0x6335, 0x6335, 0x6335, 0x6335, - 0x634e, 0x634e, 0x634e, 0x634e, 0x6335, 0x1078, 0x12cd, 0x1078, - 0x4c9d, 0x0d7e, 0x6110, 0x2168, 0x1078, 0x6a58, 0x0040, 0x6348, - 0x6837, 0x0103, 0x684b, 0x0006, 0x1078, 0x3b92, 0x1078, 0x6ba9, - 0x0d7f, 0x1078, 0x5d1a, 0x1078, 0x4d96, 0x007c, 0x1078, 0x4c9d, - 0x1078, 0x5d1a, 0x1078, 0x4d96, 0x007c, 0x6367, 0x6365, 0x6365, - 0x6365, 0x6365, 0x6365, 0x6365, 0x6365, 0x6365, 0x6365, 0x6365, - 0x6375, 0x6375, 0x6375, 0x6375, 0x6365, 0x1078, 0x12cd, 0x1078, - 0x4c9d, 0x6003, 0x0002, 0x1078, 0x4d96, 0x6010, 0xa088, 0x0013, - 0x2104, 0xa085, 0x0400, 0x200a, 0x007c, 0x1078, 0x4c9d, 0x6003, - 0x000f, 0x1078, 0x4d96, 0x007c, 0xa182, 0x0040, 0x0079, 0x6380, - 0x6390, 0x6390, 0x6390, 0x6390, 0x6390, 0x6392, 0x641b, 0x6433, - 0x6390, 0x6390, 0x6390, 0x6390, 0x6390, 0x6390, 0x6390, 0x6390, - 0x1078, 0x12cd, 0x0e7e, 0x0d7e, 0x2071, 0x7c8c, 0x6110, 0x2168, - 0x7614, 0xa6b4, 0x0fff, 0x86ff, 0x0040, 0x63ff, 0xa68c, 0x00ff, - 0xa186, 0x0002, 0x0040, 0x63c4, 0xa186, 0x0028, 0x00c0, 0x63ae, - 0x1078, 0x6bbd, 0x684b, 0x001c, 0x0078, 0x63c6, 0xd6dc, 0x0040, - 0x63b9, 0x684b, 0x0015, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0x0078, - 0x63c6, 0xd6d4, 0x0040, 0x63c4, 0x684b, 0x0007, 0x7318, 0x6b62, - 0x731c, 0x6b5e, 0x0078, 0x63c6, 0x684b, 0x0000, 0x6837, 0x0103, - 0x6e46, 0xa01e, 0xd6c4, 0x0040, 0x63d9, 0x7328, 0x732c, 0x6b56, - 0x037e, 0x2308, 0x2019, 0x7c98, 0xad90, 0x0019, 0x1078, 0x6841, - 0x037f, 0xd6cc, 0x0040, 0x640f, 0x7124, 0x695a, 0xa192, 0x0021, - 0x00c8, 0x63ed, 0x2071, 0x7c98, 0x831c, 0x2300, 0xae18, 0xad90, - 0x001d, 0x1078, 0x6841, 0x0078, 0x640f, 0x6838, 0xd0fc, 0x0040, - 0x63f6, 0x2009, 0x0020, 0x695a, 0x0078, 0x63e2, 0x0f7e, 0x2d78, - 0x1078, 0x67d9, 0x0f7f, 0x1078, 0x682e, 0x0078, 0x6411, 0x684b, - 0x0000, 0x6837, 0x0103, 0x6e46, 0x684c, 0xd0ac, 0x0040, 0x640f, - 0x6810, 0x6914, 0xa115, 0x0040, 0x640f, 0x1078, 0x6587, 0x1078, - 0x3b92, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x0d7f, 0x0e7f, - 0x1078, 0x5d1a, 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0x7c8c, - 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, - 0x7e0a, 0x7d0e, 0x0f7f, 0x2c10, 0x1078, 0x19c7, 0x1078, 0x49ad, - 0x1078, 0x4e56, 0x007c, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, - 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x156a, 0x007c, 0xa182, 0x0040, - 0x0079, 0x6442, 0x6452, 0x6452, 0x6452, 0x6452, 0x6452, 0x6454, - 0x64eb, 0x6452, 0x6452, 0x6501, 0x6563, 0x6452, 0x6452, 0x6452, - 0x6452, 0x656e, 0x1078, 0x12cd, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, - 0x2071, 0x7c8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46, - 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, - 0x86ff, 0x0040, 0x64e6, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0040, - 0x6475, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0040, - 0x64e6, 0x1078, 0x1327, 0x1040, 0x12cd, 0x2d00, 0x784a, 0x7f4c, - 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e, - 0x7840, 0x6842, 0x6e46, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040, - 0x64af, 0xa186, 0x0028, 0x00c0, 0x6499, 0x684b, 0x001c, 0x0078, - 0x64b1, 0xd6dc, 0x0040, 0x64a4, 0x684b, 0x0015, 0x7318, 0x6b62, - 0x731c, 0x6b5e, 0x0078, 0x64b1, 0xd6d4, 0x0040, 0x64af, 0x684b, - 0x0007, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0x0078, 0x64b1, 0x684b, - 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, - 0x0040, 0x64c6, 0x7328, 0x732c, 0x6b56, 0x037e, 0x2308, 0x2019, - 0x7c98, 0xad90, 0x0019, 0x1078, 0x6841, 0x037f, 0xd6cc, 0x0040, - 0x64e6, 0x7124, 0x695a, 0xa192, 0x0021, 0x00c8, 0x64da, 0x2071, - 0x7c98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x6841, - 0x0078, 0x64e6, 0x7838, 0xd0fc, 0x0040, 0x64e3, 0x2009, 0x0020, - 0x695a, 0x0078, 0x64cf, 0x2d78, 0x1078, 0x67d9, 0x0d7f, 0x0e7f, - 0x0f7f, 0x077f, 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0x7c8c, - 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, - 0x7e0a, 0x7d0e, 0x0f7f, 0x2c10, 0x1078, 0x19c7, 0x1078, 0x5681, - 0x007c, 0x0d7e, 0x6003, 0x0002, 0x1078, 0x4d45, 0x1078, 0x4e56, - 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040, 0x6561, 0xd1cc, 0x0040, - 0x653c, 0x6948, 0x6838, 0xd0fc, 0x0040, 0x6534, 0x017e, 0x684c, - 0x007e, 0x6850, 0x007e, 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, - 0x0020, 0x157e, 0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x00f0, - 0x6523, 0x157f, 0x007f, 0x6852, 0x007f, 0x684e, 0x017f, 0x2168, - 0x1078, 0x1350, 0x0078, 0x655f, 0x017e, 0x1078, 0x1350, 0x0d7f, - 0x1078, 0x682e, 0x0078, 0x655f, 0x6837, 0x0103, 0x6944, 0xa184, - 0x00ff, 0xa186, 0x0002, 0x0040, 0x655b, 0xa086, 0x0028, 0x00c0, - 0x654d, 0x684b, 0x001c, 0x0078, 0x655d, 0xd1dc, 0x0040, 0x6554, - 0x684b, 0x0015, 0x0078, 0x655d, 0xd1d4, 0x0040, 0x655b, 0x684b, - 0x0007, 0x0078, 0x655d, 0x684b, 0x0000, 0x1078, 0x3b92, 0x1078, - 0x5d1a, 0x0d7f, 0x007c, 0x2019, 0x0001, 0x1078, 0x5880, 0x6003, - 0x0002, 0x1078, 0x4d45, 0x1078, 0x4e56, 0x007c, 0x1078, 0x4d45, - 0x1078, 0x22b5, 0x0d7e, 0x6110, 0x2168, 0x1078, 0x6a58, 0x0040, - 0x6581, 0x6837, 0x0103, 0x684b, 0x0029, 0x1078, 0x3b92, 0x1078, - 0x6ba9, 0x0d7f, 0x1078, 0x5d1a, 0x1078, 0x4e56, 0x007c, 0x684b, - 0x0015, 0xd1fc, 0x0040, 0x6593, 0x684b, 0x0007, 0x8002, 0x8000, - 0x810a, 0xa189, 0x0000, 0x6962, 0x685e, 0x007c, 0xa182, 0x0040, - 0x0079, 0x659a, 0x65aa, 0x65aa, 0x65aa, 0x65aa, 0x65aa, 0x65ac, - 0x65aa, 0x6650, 0x6658, 0x65aa, 0x65aa, 0x65aa, 0x65aa, 0x65aa, - 0x65aa, 0x65aa, 0x1078, 0x12cd, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, - 0x2071, 0x7c8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46, - 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, - 0x86ff, 0x0040, 0x6642, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0040, - 0x65cd, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0040, - 0x663f, 0x1078, 0x1327, 0x1040, 0x12cd, 0x2d00, 0x784a, 0x7f4c, - 0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c, - 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x00ff, 0xa186, 0x0002, - 0x0040, 0x6608, 0xa186, 0x0028, 0x00c0, 0x65f2, 0x684b, 0x001c, - 0x0078, 0x660a, 0xd6dc, 0x0040, 0x65fd, 0x684b, 0x0015, 0x7318, - 0x6b62, 0x731c, 0x6b5e, 0x0078, 0x660a, 0xd6d4, 0x0040, 0x6608, - 0x684b, 0x0007, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0x0078, 0x660a, - 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, - 0xd6c4, 0x0040, 0x661f, 0x7328, 0x732c, 0x6b56, 0x037e, 0x2308, - 0x2019, 0x7c98, 0xad90, 0x0019, 0x1078, 0x6841, 0x037f, 0xd6cc, - 0x0040, 0x663f, 0x7124, 0x695a, 0xa192, 0x0021, 0x00c8, 0x6633, - 0x2071, 0x7c98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, - 0x6841, 0x0078, 0x663f, 0x7838, 0xd0fc, 0x0040, 0x663c, 0x2009, - 0x0020, 0x695a, 0x0078, 0x6628, 0x2d78, 0x1078, 0x67d9, 0xd6dc, - 0x00c0, 0x6645, 0xa006, 0x0078, 0x6649, 0x2001, 0x0001, 0x7218, - 0x731c, 0x1078, 0x15ae, 0x0d7f, 0x0e7f, 0x0f7f, 0x077f, 0x007c, - 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x156a, 0x007c, - 0x0d7e, 0x6003, 0x0002, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040, - 0x66bf, 0xd1cc, 0x0040, 0x668f, 0x6948, 0x6838, 0xd0fc, 0x0040, - 0x6687, 0x017e, 0x684c, 0x007e, 0x6850, 0x007e, 0xad90, 0x000d, - 0xa198, 0x000d, 0x2009, 0x0020, 0x157e, 0x21a8, 0x2304, 0x2012, - 0x8318, 0x8210, 0x00f0, 0x6676, 0x157f, 0x007f, 0x6852, 0x007f, - 0x684e, 0x017f, 0x2168, 0x1078, 0x1350, 0x0078, 0x66bd, 0x017e, - 0x1078, 0x1350, 0x0d7f, 0x1078, 0x682e, 0x0078, 0x66bd, 0x6837, - 0x0103, 0x6944, 0xa184, 0x00ff, 0xa186, 0x0002, 0x0040, 0x66ae, - 0xa086, 0x0028, 0x00c0, 0x66a0, 0x684b, 0x001c, 0x0078, 0x66bb, - 0xd1dc, 0x0040, 0x66a7, 0x684b, 0x0015, 0x0078, 0x66bb, 0xd1d4, - 0x0040, 0x66ae, 0x684b, 0x0007, 0x0078, 0x66bb, 0x684b, 0x0000, - 0x684c, 0xd0ac, 0x0040, 0x66bb, 0x6810, 0x6914, 0xa115, 0x0040, - 0x66bb, 0x1078, 0x6587, 0x1078, 0x3b92, 0x1078, 0x5d1a, 0x0d7f, - 0x007c, 0x1078, 0x4c9d, 0x0078, 0x66c7, 0x1078, 0x4d45, 0x1078, - 0x6a58, 0x0040, 0x66de, 0x0d7e, 0x6110, 0x2168, 0x6837, 0x0103, - 0x2009, 0x770c, 0x210c, 0xd18c, 0x00c0, 0x66e7, 0xd184, 0x00c0, - 0x66e3, 0x6108, 0x694a, 0x1078, 0x3b92, 0x0d7f, 0x1078, 0x5d1a, - 0x1078, 0x4d96, 0x007c, 0x684b, 0x0004, 0x0078, 0x66db, 0x684b, - 0x0004, 0x0078, 0x66db, 0xa182, 0x0040, 0x0079, 0x66ef, 0x66ff, - 0x66ff, 0x66ff, 0x66ff, 0x66ff, 0x6701, 0x66ff, 0x6704, 0x66ff, - 0x66ff, 0x66ff, 0x66ff, 0x66ff, 0x66ff, 0x66ff, 0x66ff, 0x1078, - 0x12cd, 0x1078, 0x5d1a, 0x007c, 0x007e, 0x027e, 0xa016, 0x1078, - 0x156a, 0x027f, 0x007f, 0x007c, 0xa182, 0x0085, 0x0079, 0x6710, - 0x6719, 0x6717, 0x6717, 0x6717, 0x6717, 0x6717, 0x6717, 0x1078, - 0x12cd, 0x6003, 0x0001, 0x6106, 0x1078, 0x4941, 0x127e, 0x2091, - 0x8000, 0x1078, 0x4d96, 0x127f, 0x007c, 0xa186, 0x0013, 0x00c0, - 0x672f, 0x6004, 0xa082, 0x0085, 0x2008, 0x0079, 0x6763, 0xa186, - 0x0027, 0x00c0, 0x6750, 0x1078, 0x4c9d, 0x1078, 0x22b5, 0x0d7e, - 0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, 0x6746, 0x6837, 0x0103, - 0x684b, 0x0029, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x0d7f, 0x1078, - 0x5d1a, 0x1078, 0x4d96, 0x007c, 0x1078, 0x5d4f, 0x0078, 0x674b, - 0xa186, 0x0014, 0x00c0, 0x674c, 0x1078, 0x4c9d, 0x0d7e, 0x6010, - 0x2068, 0x1078, 0x6a58, 0x0040, 0x6746, 0x6837, 0x0103, 0x684b, - 0x0006, 0x0078, 0x6742, 0x676c, 0x676a, 0x676a, 0x676a, 0x676a, - 0x676a, 0x6775, 0x1078, 0x12cd, 0x1078, 0x4c9d, 0x6017, 0x0014, - 0x6003, 0x000c, 0x1078, 0x4d96, 0x007c, 0x1078, 0x4c9d, 0x6017, - 0x0014, 0x6003, 0x000e, 0x1078, 0x4d96, 0x007c, 0xa182, 0x008c, - 0x00c8, 0x6788, 0xa182, 0x0085, 0x0048, 0x6788, 0x0079, 0x678b, - 0x1078, 0x5d4f, 0x007c, 0x6792, 0x6792, 0x6792, 0x6792, 0x6794, - 0x67b3, 0x6792, 0x1078, 0x12cd, 0x0d7e, 0x1078, 0x6ba9, 0x1078, - 0x6a58, 0x0040, 0x67af, 0x6010, 0x2068, 0x6837, 0x0103, 0x6850, - 0xd0b4, 0x0040, 0x67a7, 0x684b, 0x0006, 0x0078, 0x67ab, 0x684b, - 0x0005, 0x1078, 0x6c5c, 0x6847, 0x0000, 0x1078, 0x3b92, 0x1078, - 0x5d1a, 0x0d7f, 0x007c, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x6a58, - 0x0040, 0x67ce, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040, 0x67c4, - 0x684b, 0x0006, 0x0078, 0x67c8, 0x684b, 0x0005, 0x1078, 0x6c5c, - 0x6847, 0x0000, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x0d7f, 0x1078, - 0x5d1a, 0x007c, 0x1078, 0x4c9d, 0x1078, 0x5d1a, 0x1078, 0x4d96, + 0x2071, 0x8aa2, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0040, 0x6730, + 0x601c, 0xa086, 0x0006, 0x00c0, 0x672b, 0x88ff, 0x0040, 0x66de, + 0x2800, 0xac06, 0x00c0, 0x672b, 0x0078, 0x66e9, 0x6018, 0xa206, + 0x00c0, 0x672b, 0x85ff, 0x0040, 0x66e9, 0x6020, 0xa106, 0x00c0, + 0x672b, 0x703c, 0xac06, 0x00c0, 0x66fb, 0x037e, 0x2019, 0x0001, + 0x1078, 0x642d, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, + 0x7047, 0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x6701, 0x660c, + 0x763a, 0x7034, 0xac36, 0x00c0, 0x670f, 0x2c00, 0xaf36, 0x0040, + 0x670d, 0x2f00, 0x7036, 0x0078, 0x670f, 0x7037, 0x0000, 0x660c, + 0x067e, 0x2c00, 0xaf06, 0x0040, 0x6718, 0x7e0e, 0x0078, 0x6719, + 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, + 0x6723, 0x1078, 0x86aa, 0x1078, 0x79a8, 0x88ff, 0x00c0, 0x673a, + 0x0c7f, 0x0078, 0x66cd, 0x2c78, 0x600c, 0x2060, 0x0078, 0x66cd, + 0xa006, 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, + 0x0f7f, 0x007c, 0x6017, 0x0000, 0x0c7f, 0xa8c5, 0x0001, 0x0078, + 0x6731, 0x0e7e, 0x2071, 0x8aa2, 0x2001, 0x8800, 0x2004, 0xa086, + 0x0002, 0x00c0, 0x674f, 0x7007, 0x0005, 0x0078, 0x6751, 0x7007, + 0x0000, 0x0e7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e, 0x027e, + 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0x8aa2, 0x2c10, 0x7638, + 0x2660, 0x2678, 0x8cff, 0x0040, 0x6791, 0x2200, 0xac06, 0x00c0, + 0x678c, 0x7038, 0xac36, 0x00c0, 0x676f, 0x660c, 0x763a, 0x7034, + 0xac36, 0x00c0, 0x677d, 0x2c00, 0xaf36, 0x0040, 0x677b, 0x2f00, + 0x7036, 0x0078, 0x677d, 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06, + 0x0040, 0x6785, 0x7e0e, 0x0078, 0x6786, 0x2678, 0x600f, 0x0000, + 0xa085, 0x0001, 0x0078, 0x6791, 0x2c78, 0x600c, 0x2060, 0x0078, + 0x6762, 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0e7f, 0x0f7f, + 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e, 0x127e, + 0x2091, 0x8000, 0x2071, 0x8aa2, 0x760c, 0x2660, 0x2678, 0x8cff, + 0x0040, 0x682a, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, + 0x6825, 0x7024, 0xac06, 0x00c0, 0x67d8, 0x2069, 0x0100, 0x68c0, + 0xa005, 0x0040, 0x67d8, 0x1078, 0x6232, 0x68c3, 0x0000, 0x1078, + 0x6741, 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, + 0x1000, 0x0040, 0x67cf, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, + 0x0100, 0x6824, 0xd084, 0x0040, 0x67d7, 0x6827, 0x0001, 0x037f, + 0x700c, 0xac36, 0x00c0, 0x67de, 0x660c, 0x760e, 0x7008, 0xac36, + 0x00c0, 0x67ec, 0x2c00, 0xaf36, 0x0040, 0x67ea, 0x2f00, 0x700a, + 0x0078, 0x67ec, 0x700b, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, + 0x0040, 0x67f5, 0x7e0e, 0x0078, 0x67f6, 0x2678, 0x600f, 0x0000, + 0x1078, 0x79c1, 0x00c0, 0x6800, 0x1078, 0x24e5, 0x0078, 0x681c, + 0x1078, 0x79d5, 0x00c0, 0x6808, 0x1078, 0x6bc7, 0x0078, 0x681c, + 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, 0x681c, 0x601c, 0xa086, + 0x0003, 0x00c0, 0x6832, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, + 0x1078, 0x4376, 0x1078, 0x799b, 0x6003, 0x0000, 0x1078, 0x79a8, + 0x1078, 0x6601, 0x0c7f, 0x0078, 0x67a7, 0x2c78, 0x600c, 0x2060, + 0x0078, 0x67a7, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, + 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x6813, 0x1078, + 0x86aa, 0x0078, 0x681c, 0x037e, 0x157e, 0x137e, 0x147e, 0x3908, + 0xa006, 0xa190, 0x0020, 0x221c, 0xa39e, 0x231e, 0x00c0, 0x684c, + 0x8210, 0x8000, 0x0078, 0x6843, 0xa005, 0x0040, 0x6856, 0x20a9, + 0x0020, 0x2198, 0xa110, 0x22a0, 0x22c8, 0x53a3, 0x147f, 0x137f, + 0x157f, 0x037f, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078, 0x5c87, + 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x2099, 0x8a9c, 0x20a9, 0x0004, 0x53a6, 0x20a3, + 0x0004, 0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x1078, + 0x621e, 0x0d7f, 0x007c, 0x20a1, 0x020b, 0x1078, 0x5c87, 0x20a3, + 0x0210, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084, 0xff00, + 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x7810, 0xa084, 0x00ff, 0x20a2, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x1078, 0x621e, 0x007c, + 0x2061, 0x8f00, 0x2a70, 0x7060, 0x7046, 0x704b, 0x8f00, 0x007c, + 0x0e7e, 0x127e, 0x2071, 0x8800, 0x2091, 0x8000, 0x7544, 0xa582, + 0x0001, 0x0048, 0x68da, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, + 0x0040, 0x68c6, 0xace0, 0x000c, 0x7054, 0xac02, 0x00c8, 0x68c2, + 0x0078, 0x68b5, 0x2061, 0x8f00, 0x0078, 0x68b5, 0x6003, 0x0008, + 0x8529, 0x7546, 0xaca8, 0x000c, 0x7054, 0xa502, 0x00c8, 0x68d6, + 0x754a, 0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704b, 0x8f00, + 0x0078, 0x68d1, 0xa006, 0x0078, 0x68d3, 0x0e7e, 0x2071, 0x8800, + 0x7544, 0xa582, 0x0001, 0x0048, 0x690b, 0x7048, 0x2060, 0x6000, + 0xa086, 0x0000, 0x0040, 0x68f8, 0xace0, 0x000c, 0x7054, 0xac02, + 0x00c8, 0x68f4, 0x0078, 0x68e7, 0x2061, 0x8f00, 0x0078, 0x68e7, + 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8, 0x000c, 0x7054, 0xa502, + 0x00c8, 0x6907, 0x754a, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x704b, + 0x8f00, 0x0078, 0x6903, 0xa006, 0x0078, 0x6905, 0xac82, 0x8f00, + 0x1048, 0x12d2, 0x2001, 0x8815, 0x2004, 0xac02, 0x10c8, 0x12d2, + 0xa006, 0x6006, 0x600a, 0x600e, 0x6012, 0x6016, 0x601a, 0x601f, + 0x0000, 0x6003, 0x0000, 0x6022, 0x6026, 0x602a, 0x602e, 0x2061, + 0x8800, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0040, 0x6931, + 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x5888, 0x127f, 0x0078, + 0x6930, 0x601c, 0xa084, 0x000f, 0x0079, 0x693e, 0x6947, 0x6958, + 0x6974, 0x6990, 0x7a52, 0x7a6e, 0x7a8a, 0x6947, 0x6958, 0xa186, + 0x0013, 0x00c0, 0x6950, 0x1078, 0x578f, 0x1078, 0x5888, 0x007c, + 0xa18e, 0x0047, 0x00c0, 0x6957, 0xa016, 0x1078, 0x1594, 0x007c, + 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12d2, 0x1079, 0x6962, + 0x067f, 0x007c, 0x6972, 0x6a89, 0x6be6, 0x6972, 0x6c46, 0x6972, + 0x6972, 0x6972, 0x6a28, 0x6f24, 0x6972, 0x6972, 0x6972, 0x6972, + 0x6972, 0x6972, 0x1078, 0x12d2, 0x067e, 0x6000, 0xa0b2, 0x0010, + 0x10c8, 0x12d2, 0x1079, 0x697e, 0x067f, 0x007c, 0x698e, 0x698e, + 0x698e, 0x698e, 0x698e, 0x698e, 0x698e, 0x698e, 0x7419, 0x74f8, + 0x698e, 0x7432, 0x7492, 0x7432, 0x7492, 0x698e, 0x1078, 0x12d2, + 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12d2, 0x1079, 0x699a, + 0x067f, 0x007c, 0x69aa, 0x6f65, 0x7020, 0x70fa, 0x7257, 0x69aa, + 0x69aa, 0x69aa, 0x6f40, 0x73c7, 0x73cb, 0x69aa, 0x69aa, 0x69aa, + 0x69aa, 0x73f5, 0x1078, 0x12d2, 0x20a9, 0x000e, 0x2e98, 0x6010, + 0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420, 0x9398, 0x94a0, + 0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002, 0xa5a8, 0x0002, + 0xa398, 0x0002, 0xa4a0, 0x0002, 0x00f0, 0x69ba, 0x0e7e, 0x1078, + 0x77ed, 0x0040, 0x69d1, 0x6010, 0x2070, 0x7007, 0x0000, 0x7037, + 0x0103, 0x0e7f, 0x1078, 0x690e, 0x007c, 0x0d7e, 0x037e, 0x7330, + 0xa386, 0x0200, 0x00c0, 0x69e2, 0x6018, 0x2068, 0x6813, 0x00ff, + 0x6817, 0xfffd, 0x6010, 0xa005, 0x0040, 0x69ec, 0x2068, 0x6807, + 0x0000, 0x6837, 0x0103, 0x6b32, 0x1078, 0x690e, 0x037f, 0x0d7f, + 0x007c, 0x017e, 0x20a9, 0x002a, 0xae80, 0x000c, 0x2098, 0x6010, + 0xa080, 0x0002, 0x20a0, 0x53a3, 0x20a9, 0x002a, 0x6010, 0xa080, + 0x0001, 0x2004, 0xa080, 0x0002, 0x20a0, 0x53a3, 0x0e7e, 0x6010, + 0x2004, 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x690e, 0x017f, + 0x007c, 0x0d7e, 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0, 0x53a3, + 0xa1b6, 0x0015, 0x00c0, 0x6a25, 0x6018, 0x2068, 0x7038, 0x680a, + 0x703c, 0x680e, 0x6800, 0xc08d, 0x6802, 0x0d7f, 0x0078, 0x69c6, + 0x2100, 0xa1b2, 0x0040, 0x10c8, 0x12d2, 0x0079, 0x6a2f, 0x6a71, + 0x6a7d, 0x6a71, 0x6a71, 0x6a71, 0x6a71, 0x6a6f, 0x6a6f, 0x6a6f, + 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, + 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, + 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a71, 0x6a6f, + 0x6a71, 0x6a71, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a71, + 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, + 0x6a6f, 0x6a71, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, + 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a71, 0x6a6f, 0x6a6f, 0x1078, + 0x12d2, 0x6003, 0x0001, 0x6106, 0x1078, 0x53e6, 0x127e, 0x2091, + 0x8000, 0x1078, 0x5888, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, + 0x1078, 0x53e6, 0x127e, 0x2091, 0x8000, 0x1078, 0x5888, 0x127f, + 0x007c, 0x6004, 0xa0b2, 0x0040, 0x10c8, 0x12d2, 0xa1b6, 0x0013, + 0x00c0, 0x6a95, 0x2008, 0x0079, 0x6b35, 0xa1b6, 0x0027, 0x00c0, + 0x6af2, 0x1078, 0x578f, 0x6004, 0x1078, 0x79c1, 0x0040, 0x6ab2, + 0x1078, 0x79d5, 0x0040, 0x6aea, 0xa08e, 0x0021, 0x0040, 0x6aee, + 0xa08e, 0x0022, 0x0040, 0x6aea, 0xa08e, 0x003d, 0x0040, 0x6aee, + 0x0078, 0x6ae5, 0x1078, 0x24e5, 0x2001, 0x0007, 0x1078, 0x3f05, + 0x6018, 0xa080, 0x0028, 0x200c, 0x1078, 0x6bc7, 0xa186, 0x007e, + 0x00c0, 0x6ac7, 0x2001, 0x8830, 0x2014, 0xc285, 0x2202, 0x017e, + 0x027e, 0x037e, 0x2110, 0x2019, 0x0028, 0x1078, 0x54f0, 0x087e, + 0x2041, 0x0000, 0x1078, 0x5419, 0x0c7e, 0x6018, 0xa065, 0x0040, + 0x6adb, 0x1078, 0x418b, 0x0c7f, 0x2c08, 0x1078, 0x84d2, 0x087f, + 0x037f, 0x027f, 0x017f, 0x1078, 0x3f76, 0x1078, 0x690e, 0x1078, + 0x5888, 0x007c, 0x1078, 0x6bc7, 0x0078, 0x6ae5, 0x1078, 0x6bda, + 0x0078, 0x6ae5, 0xa186, 0x0014, 0x00c0, 0x6ae9, 0x1078, 0x578f, + 0x1078, 0x24bf, 0x1078, 0x79c1, 0x00c0, 0x6b11, 0x1078, 0x24e5, + 0x6018, 0xa080, 0x0028, 0x200c, 0x1078, 0x6bc7, 0xa186, 0x007e, + 0x00c0, 0x6b0f, 0x2001, 0x8830, 0x200c, 0xc185, 0x2102, 0x0078, + 0x6ae5, 0x1078, 0x79d5, 0x00c0, 0x6b19, 0x1078, 0x6bc7, 0x0078, + 0x6ae5, 0x6004, 0xa08e, 0x0032, 0x00c0, 0x6b2a, 0x0e7e, 0x0f7e, + 0x2071, 0x8881, 0x2079, 0x0000, 0x1078, 0x27c9, 0x0f7f, 0x0e7f, + 0x0078, 0x6ae5, 0x6004, 0xa08e, 0x0021, 0x0040, 0x6b15, 0xa08e, + 0x0022, 0x1040, 0x6bda, 0x0078, 0x6ae5, 0x6b77, 0x6b79, 0x6b7d, + 0x6b81, 0x6b85, 0x6b89, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, + 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, + 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, + 0x6b75, 0x6b75, 0x6b75, 0x6b8d, 0x6b93, 0x6b75, 0x6b9d, 0x6b93, + 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b93, 0x6b93, 0x6b75, + 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, + 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, + 0x6b75, 0x6b75, 0x6b93, 0x6b75, 0x6b75, 0x1078, 0x12d2, 0x0078, + 0x6b93, 0x2001, 0x000b, 0x0078, 0x6ba6, 0x2001, 0x0003, 0x0078, + 0x6ba6, 0x2001, 0x0005, 0x0078, 0x6ba6, 0x2001, 0x0001, 0x0078, + 0x6ba6, 0x2001, 0x0009, 0x0078, 0x6ba6, 0x1078, 0x12d2, 0x0078, + 0x6ba5, 0x1078, 0x3f05, 0x1078, 0x578f, 0x6003, 0x0002, 0x6017, + 0x0028, 0x1078, 0x5888, 0x0078, 0x6ba5, 0x1078, 0x578f, 0x6003, + 0x0004, 0x6017, 0x0028, 0x1078, 0x5888, 0x007c, 0x1078, 0x3f05, + 0x1078, 0x578f, 0x6003, 0x0002, 0x037e, 0x2019, 0x885c, 0x2304, + 0xa084, 0xff00, 0x00c0, 0x6bb8, 0x2019, 0x0028, 0x0078, 0x6bc1, + 0x8007, 0xa09a, 0x0004, 0x0048, 0x6bb4, 0x8003, 0x801b, 0x831b, + 0xa318, 0x6316, 0x037f, 0x1078, 0x5888, 0x0078, 0x6ba5, 0x0e7e, + 0x1078, 0x77ed, 0x0040, 0x6bd8, 0x6010, 0x2070, 0x7038, 0xd0fc, + 0x0040, 0x6bd8, 0x7007, 0x0000, 0x7037, 0x0103, 0x7033, 0x0100, + 0x0e7f, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, + 0x7037, 0x0103, 0x7023, 0x8001, 0x0e7f, 0x007c, 0x0d7e, 0x6618, + 0x2668, 0x6804, 0xa084, 0x00ff, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, + 0x12d2, 0x6604, 0xa6b6, 0x0028, 0x00c0, 0x6bfa, 0x1078, 0x7a0a, + 0x0078, 0x6c35, 0x6604, 0xa6b6, 0x0029, 0x00c0, 0x6c03, 0x1078, + 0x7a24, 0x0078, 0x6c35, 0x6604, 0xa6b6, 0x001f, 0x00c0, 0x6c0c, + 0x1078, 0x69ac, 0x0078, 0x6c35, 0x6604, 0xa6b6, 0x0000, 0x00c0, + 0x6c15, 0x1078, 0x6a11, 0x0078, 0x6c35, 0x6604, 0xa6b6, 0x0022, + 0x00c0, 0x6c1e, 0x1078, 0x69d5, 0x0078, 0x6c35, 0x6604, 0xa6b6, + 0x003d, 0x00c0, 0x6c27, 0x1078, 0x69f1, 0x0078, 0x6c35, 0xa1b6, + 0x0015, 0x00c0, 0x6c2f, 0x1079, 0x6c3a, 0x0078, 0x6c35, 0xa1b6, + 0x0016, 0x00c0, 0x6c36, 0x1079, 0x6d93, 0x007c, 0x1078, 0x6950, + 0x0078, 0x6c35, 0x6c5e, 0x6c61, 0x6c5e, 0x6ca2, 0x6c5e, 0x6d2f, + 0x6c5e, 0x6c5e, 0x6c5e, 0x6d6b, 0x6c5e, 0x6d81, 0xa1b6, 0x0048, + 0x0040, 0x6c52, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, + 0x1594, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, + 0x7037, 0x0103, 0x0e7f, 0x1078, 0x690e, 0x007c, 0x0005, 0x0005, + 0x007c, 0x0e7e, 0x2071, 0x8800, 0x707c, 0xa086, 0x0074, 0x00c0, + 0x6c8b, 0x1078, 0x84a6, 0x00c0, 0x6c7d, 0x0d7e, 0x6018, 0x2068, + 0x1078, 0x6c8f, 0x0d7f, 0x2001, 0x0006, 0x1078, 0x3f05, 0x1078, + 0x24e5, 0x1078, 0x690e, 0x0078, 0x6c8d, 0x2001, 0x000a, 0x1078, + 0x3f05, 0x1078, 0x24e5, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, + 0x53e6, 0x0078, 0x6c8d, 0x1078, 0x6d1f, 0x0e7f, 0x007c, 0x6800, + 0xd084, 0x0040, 0x6ca1, 0x2001, 0x0000, 0x1078, 0x3ef1, 0x2069, + 0x8851, 0x6804, 0xd0a4, 0x0040, 0x6ca1, 0x2001, 0x0006, 0x1078, + 0x3f2c, 0x007c, 0x0d7e, 0x2011, 0x881f, 0x2204, 0xa086, 0x0074, + 0x00c0, 0x6d1b, 0x1078, 0x6e79, 0x6018, 0x2068, 0xa080, 0x0028, + 0x2014, 0xa286, 0x007e, 0x0040, 0x6cca, 0xa286, 0x0080, 0x00c0, + 0x6cf3, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005, 0x0040, + 0x6ce9, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833, 0x0200, + 0x0078, 0x6ce9, 0x0e7e, 0x0f7e, 0x6813, 0x00ff, 0x6817, 0xfffe, + 0x2071, 0x8830, 0x2e04, 0xa085, 0x0003, 0x2072, 0x2071, 0x8d80, + 0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0x881a, 0x206a, + 0x78e6, 0x8e70, 0x2e04, 0x2069, 0x881b, 0x206a, 0x78ea, 0x0f7f, + 0x0e7f, 0x2001, 0x0006, 0x1078, 0x3f05, 0x1078, 0x24e5, 0x1078, + 0x690e, 0x0078, 0x6d1d, 0x0e7e, 0x2071, 0x8830, 0x2e04, 0xd09c, + 0x0040, 0x6d0e, 0x2071, 0x8d80, 0x7108, 0x720c, 0xa18c, 0x00ff, + 0x00c0, 0x6d06, 0xa284, 0xff00, 0x0040, 0x6d0e, 0x6018, 0x2070, + 0x70a0, 0xd0bc, 0x00c0, 0x6d0e, 0x7112, 0x7216, 0x0e7f, 0x2001, + 0x0004, 0x1078, 0x3f05, 0x6003, 0x0001, 0x6007, 0x0003, 0x1078, + 0x53e6, 0x0078, 0x6d1d, 0x1078, 0x6d1f, 0x0d7f, 0x007c, 0x2001, + 0x8800, 0x2004, 0xa086, 0x0003, 0x0040, 0x6d2a, 0x2001, 0x0007, + 0x1078, 0x3f05, 0x1078, 0x24e5, 0x1078, 0x690e, 0x007c, 0x0e7e, + 0x2071, 0x8800, 0x707c, 0xa086, 0x0014, 0x00c0, 0x6d65, 0x7000, + 0xa086, 0x0003, 0x00c0, 0x6d42, 0x6010, 0xa005, 0x00c0, 0x6d42, + 0x1078, 0x31f8, 0x0d7e, 0x6018, 0x2068, 0x1078, 0x400a, 0x1078, + 0x6c8f, 0x0d7f, 0x1078, 0x6e83, 0x00c0, 0x6d65, 0x2001, 0x0006, + 0x1078, 0x3f05, 0x0e7e, 0x6010, 0xa005, 0x0040, 0x6d5e, 0x2070, + 0x7007, 0x0000, 0x7037, 0x0103, 0x7033, 0x0200, 0x0e7f, 0x1078, + 0x24e5, 0x1078, 0x690e, 0x0078, 0x6d69, 0x1078, 0x6bc7, 0x1078, + 0x6d1f, 0x0e7f, 0x007c, 0x2011, 0x881f, 0x2204, 0xa086, 0x0014, + 0x00c0, 0x6d7e, 0x2001, 0x0002, 0x1078, 0x3f05, 0x6003, 0x0001, + 0x6007, 0x0001, 0x1078, 0x53e6, 0x0078, 0x6d80, 0x1078, 0x6d1f, + 0x007c, 0x2011, 0x881f, 0x2204, 0xa086, 0x0004, 0x00c0, 0x6d90, + 0x2001, 0x0007, 0x1078, 0x3f05, 0x1078, 0x690e, 0x0078, 0x6d92, + 0x1078, 0x6d1f, 0x007c, 0x6c5e, 0x6d9f, 0x6c5e, 0x6dc7, 0x6c5e, + 0x6e2c, 0x6c5e, 0x6c5e, 0x6c5e, 0x6e41, 0x6c5e, 0x6e54, 0x0d7e, + 0x0c7e, 0x1078, 0x6e67, 0x00c0, 0x6db5, 0x2001, 0x0000, 0x1078, + 0x3ef1, 0x2001, 0x0002, 0x1078, 0x3f05, 0x6003, 0x0001, 0x6007, + 0x0002, 0x1078, 0x53e6, 0x0078, 0x6dc4, 0x2009, 0x8d8f, 0x2104, + 0xa084, 0xff00, 0xa086, 0x1900, 0x00c0, 0x6dc2, 0x1078, 0x690e, + 0x0078, 0x6dc4, 0x1078, 0x6d1f, 0x0c7f, 0x0d7f, 0x007c, 0x1078, + 0x6e76, 0x00c0, 0x6ddb, 0x2001, 0x0000, 0x1078, 0x3ef1, 0x2001, + 0x0002, 0x1078, 0x3f05, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, + 0x53e6, 0x0078, 0x6e07, 0x1078, 0x6bc7, 0x2009, 0x8d8e, 0x2134, + 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x0040, 0x6e08, 0xa686, 0x000b, + 0x0040, 0x6e05, 0x2009, 0x8d8f, 0x2104, 0xa084, 0xff00, 0x00c0, + 0x6df5, 0xa686, 0x0009, 0x0040, 0x6e08, 0xa086, 0x1900, 0x00c0, + 0x6e05, 0xa686, 0x0009, 0x0040, 0x6e08, 0x2001, 0x0004, 0x1078, + 0x3f05, 0x1078, 0x690e, 0x0078, 0x6e07, 0x1078, 0x6d1f, 0x007c, + 0x0d7e, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, 0x6e16, 0x6838, + 0xd0fc, 0x0040, 0x6e16, 0x0d7f, 0x0078, 0x6e05, 0x6018, 0x2068, + 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, 0x6e27, 0x8001, 0x6842, + 0x6017, 0x000a, 0x6007, 0x0016, 0x0d7f, 0x0078, 0x6e07, 0x1078, + 0x24bf, 0x0d7f, 0x0078, 0x6e05, 0x1078, 0x6e76, 0x00c0, 0x6e3c, + 0x2001, 0x0004, 0x1078, 0x3f05, 0x6003, 0x0001, 0x6007, 0x0003, + 0x1078, 0x53e6, 0x0078, 0x6e40, 0x1078, 0x6bc7, 0x1078, 0x6d1f, + 0x007c, 0x1078, 0x6e76, 0x00c0, 0x6e51, 0x2001, 0x0008, 0x1078, + 0x3f05, 0x6003, 0x0001, 0x6007, 0x0005, 0x1078, 0x53e6, 0x0078, + 0x6e53, 0x1078, 0x6d1f, 0x007c, 0x1078, 0x6e76, 0x00c0, 0x6e64, + 0x2001, 0x000a, 0x1078, 0x3f05, 0x6003, 0x0001, 0x6007, 0x0001, + 0x1078, 0x53e6, 0x0078, 0x6e66, 0x1078, 0x6d1f, 0x007c, 0x2009, + 0x8d8e, 0x2104, 0xa086, 0x0003, 0x00c0, 0x6e75, 0x2009, 0x8d8f, + 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, 0x007c, 0xa085, 0x0001, + 0x007c, 0x0c7e, 0x017e, 0xac88, 0x0006, 0x2164, 0x1078, 0x3fa0, + 0x017f, 0x0c7f, 0x007c, 0x0e7e, 0x2071, 0x8d8c, 0x7004, 0xa086, + 0x0014, 0x00c0, 0x6ea3, 0x7008, 0xa086, 0x0800, 0x00c0, 0x6ea3, + 0x700c, 0xd0ec, 0x0040, 0x6ea1, 0xa084, 0x0f00, 0xa086, 0x0100, + 0x00c0, 0x6ea1, 0x7024, 0xd0a4, 0x0040, 0x6ea1, 0xa006, 0x0078, + 0x6ea3, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x0e7e, 0x0d7e, 0x0c7e, + 0x077e, 0x057e, 0x047e, 0x027e, 0x007e, 0x127e, 0x2091, 0x8000, + 0x2029, 0x8aab, 0x252c, 0x2021, 0x8ab1, 0x2424, 0x2061, 0x8f00, + 0x2071, 0x8800, 0x7244, 0x7060, 0xa202, 0x00c8, 0x6efa, 0x1078, + 0x870c, 0x0040, 0x6ef2, 0x671c, 0xa786, 0x0001, 0x0040, 0x6ef2, + 0xa786, 0x0007, 0x0040, 0x6ef2, 0x2500, 0xac06, 0x0040, 0x6ef2, + 0x2400, 0xac06, 0x0040, 0x6ef2, 0x0c7e, 0x6000, 0xa086, 0x0004, + 0x00c0, 0x6edc, 0x1078, 0x16af, 0x6010, 0x2068, 0x1078, 0x77ed, + 0x0040, 0x6eef, 0xa786, 0x0003, 0x00c0, 0x6f04, 0x6837, 0x0103, + 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4376, 0x1078, 0x799b, 0x1078, + 0x79a8, 0x0c7f, 0xace0, 0x000c, 0x7054, 0xac02, 0x00c8, 0x6efa, + 0x0078, 0x6eba, 0x127f, 0x007f, 0x027f, 0x047f, 0x057f, 0x077f, + 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0, 0x6ee6, + 0x1078, 0x86aa, 0x0078, 0x6eef, 0x220c, 0x2304, 0xa106, 0x00c0, + 0x6f17, 0x8210, 0x8318, 0x00f0, 0x6f0c, 0xa006, 0x007c, 0x2304, + 0xa102, 0x0048, 0x6f1f, 0x2001, 0x0001, 0x0078, 0x6f21, 0x2001, + 0x0000, 0xa18d, 0x0001, 0x007c, 0x6004, 0xa08a, 0x0040, 0x10c8, + 0x12d2, 0x1078, 0x79c1, 0x0040, 0x6f33, 0x1078, 0x79d5, 0x0040, + 0x6f3c, 0x0078, 0x6f35, 0x1078, 0x24e5, 0x1078, 0x578f, 0x1078, + 0x690e, 0x1078, 0x5888, 0x007c, 0x1078, 0x6bc7, 0x0078, 0x6f35, + 0xa182, 0x0040, 0x0079, 0x6f44, 0x6f57, 0x6f57, 0x6f57, 0x6f57, + 0x6f57, 0x6f57, 0x6f57, 0x6f57, 0x6f57, 0x6f57, 0x6f57, 0x6f59, + 0x6f59, 0x6f59, 0x6f59, 0x6f57, 0x6f57, 0x6f57, 0x6f59, 0x1078, + 0x12d2, 0x6003, 0x0001, 0x6106, 0x1078, 0x5399, 0x127e, 0x2091, + 0x8000, 0x1078, 0x5888, 0x127f, 0x007c, 0xa186, 0x0013, 0x00c0, + 0x6f6e, 0x6004, 0xa082, 0x0040, 0x0079, 0x6ff6, 0xa186, 0x0027, + 0x00c0, 0x6f8d, 0x1078, 0x578f, 0x1078, 0x24bf, 0x0d7e, 0x6110, + 0x2168, 0x1078, 0x77ed, 0x0040, 0x6f87, 0x6837, 0x0103, 0x684b, + 0x0029, 0x6847, 0x0000, 0x1078, 0x4376, 0x1078, 0x799b, 0x0d7f, + 0x1078, 0x690e, 0x1078, 0x5888, 0x007c, 0xa186, 0x0014, 0x00c0, + 0x6f96, 0x6004, 0xa082, 0x0040, 0x0079, 0x6fbe, 0xa186, 0x0046, + 0x0040, 0x6fa2, 0xa186, 0x0045, 0x0040, 0x6fa2, 0xa186, 0x0047, + 0x10c0, 0x12d2, 0x2001, 0x0109, 0x2004, 0xd084, 0x0040, 0x6fbb, + 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x027e, 0x1078, 0x5273, + 0x027f, 0x017f, 0x007f, 0x127f, 0x6000, 0xa086, 0x0002, 0x00c0, + 0x6fbb, 0x0078, 0x7020, 0x1078, 0x6950, 0x007c, 0x6fd3, 0x6fd1, + 0x6fd1, 0x6fd1, 0x6fd1, 0x6fd1, 0x6fd1, 0x6fd1, 0x6fd1, 0x6fd1, + 0x6fd1, 0x6fef, 0x6fef, 0x6fef, 0x6fef, 0x6fd1, 0x6fd1, 0x6fd1, + 0x6fef, 0x1078, 0x12d2, 0x1078, 0x578f, 0x0d7e, 0x6110, 0x2168, + 0x1078, 0x77ed, 0x0040, 0x6fe9, 0x6837, 0x0103, 0x684b, 0x0006, + 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x1078, 0x4376, 0x1078, + 0x799b, 0x0d7f, 0x1078, 0x690e, 0x1078, 0x5888, 0x007c, 0x1078, + 0x578f, 0x1078, 0x690e, 0x1078, 0x5888, 0x007c, 0x700b, 0x7009, + 0x7009, 0x7009, 0x7009, 0x7009, 0x7009, 0x7009, 0x7009, 0x7009, + 0x7009, 0x7019, 0x7019, 0x7019, 0x7019, 0x7009, 0x7009, 0x7009, + 0x7019, 0x1078, 0x12d2, 0x1078, 0x578f, 0x6003, 0x0002, 0x1078, + 0x5888, 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, + 0x007c, 0x1078, 0x578f, 0x6003, 0x000f, 0x1078, 0x5888, 0x007c, + 0xa182, 0x0040, 0x0079, 0x7024, 0x7037, 0x7037, 0x7037, 0x7037, + 0x7037, 0x7039, 0x70cf, 0x70ef, 0x7037, 0x7037, 0x7037, 0x7037, + 0x7037, 0x7037, 0x7037, 0x7037, 0x7037, 0x7037, 0x7037, 0x1078, + 0x12d2, 0x0e7e, 0x0d7e, 0x2071, 0x8d8c, 0x6110, 0x2168, 0x7614, + 0xa6b4, 0x0fff, 0x86ff, 0x0040, 0x70b3, 0xa68c, 0x0c00, 0x0040, + 0x704d, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, + 0x0002, 0x0040, 0x706b, 0xa186, 0x0028, 0x00c0, 0x705d, 0x1078, + 0x79af, 0x684b, 0x001c, 0x0078, 0x706d, 0xd6dc, 0x0040, 0x7064, + 0x684b, 0x0015, 0x0078, 0x706d, 0xd6d4, 0x0040, 0x706b, 0x684b, + 0x0007, 0x0078, 0x706d, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, + 0xa01e, 0xd6c4, 0x0040, 0x708d, 0xa686, 0x0100, 0x00c0, 0x7081, + 0x2001, 0x8d99, 0x2004, 0xa005, 0x00c0, 0x7081, 0xc6c4, 0x0078, + 0x7042, 0x7328, 0x732c, 0x6b56, 0x037e, 0x2308, 0x2019, 0x8d98, + 0xad90, 0x0019, 0x1078, 0x7589, 0x037f, 0xd6cc, 0x0040, 0x70c3, + 0x7124, 0x695a, 0xa192, 0x0021, 0x00c8, 0x70a1, 0x2071, 0x8d98, + 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x7589, 0x0078, + 0x70c3, 0x6838, 0xd0fc, 0x0040, 0x70aa, 0x2009, 0x0020, 0x695a, + 0x0078, 0x7096, 0x0f7e, 0x2d78, 0x1078, 0x7521, 0x0f7f, 0x1078, + 0x7576, 0x0078, 0x70c5, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, + 0x684c, 0xd0ac, 0x0040, 0x70c3, 0x6810, 0x6914, 0xa115, 0x0040, + 0x70c3, 0x1078, 0x7248, 0x1078, 0x4376, 0x6218, 0x2268, 0x6a3c, + 0x8211, 0x6a3e, 0x0d7f, 0x0e7f, 0x1078, 0x690e, 0x007c, 0x0f7e, + 0x6003, 0x0003, 0x2079, 0x8d8c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, + 0x6010, 0x2078, 0x784c, 0xd0ac, 0x0040, 0x70e2, 0x6003, 0x0002, + 0x0f7f, 0x007c, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x0f7f, 0x2c10, + 0x1078, 0x1b07, 0x1078, 0x5405, 0x1078, 0x5948, 0x007c, 0x6003, + 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, + 0x1594, 0x007c, 0xa182, 0x0040, 0x0079, 0x70fe, 0x7111, 0x7111, + 0x7111, 0x7111, 0x7111, 0x7113, 0x71aa, 0x7111, 0x7111, 0x71c0, + 0x7222, 0x7111, 0x7111, 0x7111, 0x7111, 0x722d, 0x7111, 0x7111, + 0x7111, 0x1078, 0x12d2, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071, + 0x8d8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, + 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, + 0x0040, 0x71a5, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0040, 0x7134, + 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0040, 0x71a5, + 0x1078, 0x132b, 0x1040, 0x12d2, 0x2d00, 0x784a, 0x7f4c, 0xc7cd, + 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e, 0x7840, + 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0040, 0x7152, 0x7318, 0x6b62, + 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040, 0x716e, + 0xa186, 0x0028, 0x00c0, 0x7160, 0x684b, 0x001c, 0x0078, 0x7170, + 0xd6dc, 0x0040, 0x7167, 0x684b, 0x0015, 0x0078, 0x7170, 0xd6d4, + 0x0040, 0x716e, 0x684b, 0x0007, 0x0078, 0x7170, 0x684b, 0x0000, + 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0040, + 0x7185, 0x7328, 0x732c, 0x6b56, 0x037e, 0x2308, 0x2019, 0x8d98, + 0xad90, 0x0019, 0x1078, 0x7589, 0x037f, 0xd6cc, 0x0040, 0x71a5, + 0x7124, 0x695a, 0xa192, 0x0021, 0x00c8, 0x7199, 0x2071, 0x8d98, + 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x7589, 0x0078, + 0x71a5, 0x7838, 0xd0fc, 0x0040, 0x71a2, 0x2009, 0x0020, 0x695a, + 0x0078, 0x718e, 0x2d78, 0x1078, 0x7521, 0x0d7f, 0x0e7f, 0x0f7f, + 0x077f, 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0x8d8c, 0x7c04, + 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, + 0x7d0e, 0x0f7f, 0x2c10, 0x1078, 0x1b07, 0x1078, 0x6217, 0x007c, + 0x0d7e, 0x6003, 0x0002, 0x1078, 0x5837, 0x1078, 0x5948, 0x6110, + 0x2168, 0x694c, 0xd1e4, 0x0040, 0x7220, 0xd1cc, 0x0040, 0x71fb, + 0x6948, 0x6838, 0xd0fc, 0x0040, 0x71f3, 0x017e, 0x684c, 0x007e, + 0x6850, 0x007e, 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0020, + 0x157e, 0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x00f0, 0x71e2, + 0x157f, 0x007f, 0x6852, 0x007f, 0x684e, 0x017f, 0x2168, 0x1078, + 0x1354, 0x0078, 0x721e, 0x017e, 0x1078, 0x1354, 0x0d7f, 0x1078, + 0x7576, 0x0078, 0x721e, 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, + 0xa0b6, 0x0002, 0x0040, 0x721a, 0xa086, 0x0028, 0x00c0, 0x720c, + 0x684b, 0x001c, 0x0078, 0x721c, 0xd1dc, 0x0040, 0x7213, 0x684b, + 0x0015, 0x0078, 0x721c, 0xd1d4, 0x0040, 0x721a, 0x684b, 0x0007, + 0x0078, 0x721c, 0x684b, 0x0000, 0x1078, 0x4376, 0x1078, 0x690e, + 0x0d7f, 0x007c, 0x2019, 0x0001, 0x1078, 0x642d, 0x6003, 0x0002, + 0x1078, 0x5837, 0x1078, 0x5948, 0x007c, 0x1078, 0x5837, 0x1078, + 0x24bf, 0x0d7e, 0x6110, 0x2168, 0x1078, 0x77ed, 0x0040, 0x7242, + 0x6837, 0x0103, 0x684b, 0x0029, 0x6847, 0x0000, 0x1078, 0x4376, + 0x1078, 0x799b, 0x0d7f, 0x1078, 0x690e, 0x1078, 0x5948, 0x007c, + 0x684b, 0x0015, 0xd1fc, 0x0040, 0x7254, 0x684b, 0x0007, 0x8002, + 0x8000, 0x810a, 0xa189, 0x0000, 0x6962, 0x685e, 0x007c, 0xa182, + 0x0040, 0x0079, 0x725b, 0x726e, 0x726e, 0x726e, 0x726e, 0x726e, + 0x7270, 0x726e, 0x7324, 0x732c, 0x726e, 0x726e, 0x726e, 0x726e, + 0x726e, 0x726e, 0x726e, 0x726e, 0x726e, 0x726e, 0x1078, 0x12d2, + 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071, 0x8d8c, 0x6110, 0x2178, + 0x7614, 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, + 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x7314, 0xa694, + 0xff00, 0xa284, 0x0c00, 0x0040, 0x7291, 0x7018, 0x7862, 0x701c, + 0x785e, 0xa284, 0x0300, 0x0040, 0x7311, 0xa686, 0x0100, 0x00c0, + 0x72a3, 0x2001, 0x8d99, 0x2004, 0xa005, 0x00c0, 0x72a3, 0xc6c4, + 0x7e46, 0x0078, 0x7284, 0x1078, 0x132b, 0x1040, 0x12d2, 0x2d00, + 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838, + 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, + 0x0040, 0x72be, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, + 0xa186, 0x0002, 0x0040, 0x72da, 0xa186, 0x0028, 0x00c0, 0x72cc, + 0x684b, 0x001c, 0x0078, 0x72dc, 0xd6dc, 0x0040, 0x72d3, 0x684b, + 0x0015, 0x0078, 0x72dc, 0xd6d4, 0x0040, 0x72da, 0x684b, 0x0007, + 0x0078, 0x72dc, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, + 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x72f1, 0x7328, 0x732c, 0x6b56, + 0x037e, 0x2308, 0x2019, 0x8d98, 0xad90, 0x0019, 0x1078, 0x7589, + 0x037f, 0xd6cc, 0x0040, 0x7311, 0x7124, 0x695a, 0xa192, 0x0021, + 0x00c8, 0x7305, 0x2071, 0x8d98, 0x831c, 0x2300, 0xae18, 0xad90, + 0x001d, 0x1078, 0x7589, 0x0078, 0x7311, 0x7838, 0xd0fc, 0x0040, + 0x730e, 0x2009, 0x0020, 0x695a, 0x0078, 0x72fa, 0x2d78, 0x1078, + 0x7521, 0xd6dc, 0x00c0, 0x7317, 0xa006, 0x0078, 0x731d, 0x2001, + 0x0001, 0x2071, 0x8d8c, 0x7218, 0x731c, 0x1078, 0x15e5, 0x0d7f, + 0x0e7f, 0x0f7f, 0x077f, 0x007c, 0x20e1, 0x0005, 0x3d18, 0x3e20, + 0x2c10, 0x1078, 0x1594, 0x007c, 0x0d7e, 0x6003, 0x0002, 0x6110, + 0x2168, 0x694c, 0xd1e4, 0x0040, 0x73c5, 0xd1cc, 0x0040, 0x7395, + 0x6948, 0x6838, 0xd0fc, 0x0040, 0x7371, 0x017e, 0x684c, 0x007e, + 0x6850, 0x007e, 0x684c, 0xd0ac, 0x0040, 0x7357, 0x6810, 0x6914, + 0xa115, 0x0040, 0x7357, 0x1078, 0x7248, 0x0f7e, 0x6948, 0x2178, + 0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0x0f7f, 0x6948, + 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0020, 0x157e, 0x21a8, + 0x2304, 0x2012, 0x8318, 0x8210, 0x00f0, 0x7360, 0x157f, 0x007f, + 0x6852, 0x007f, 0x684e, 0x017f, 0x2168, 0x1078, 0x1354, 0x0078, + 0x73c3, 0x017e, 0x684c, 0xd0ac, 0x0040, 0x7389, 0x6810, 0x6914, + 0xa115, 0x0040, 0x7389, 0x1078, 0x7248, 0x0f7e, 0x6948, 0x2178, + 0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0x684c, 0x784e, + 0x0f7f, 0x6948, 0xa188, 0x0013, 0x684c, 0x200a, 0x1078, 0x1354, + 0x0d7f, 0x1078, 0x7576, 0x0078, 0x73c3, 0x6837, 0x0103, 0x6944, + 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040, 0x73b4, 0xa086, 0x0028, + 0x00c0, 0x73a6, 0x684b, 0x001c, 0x0078, 0x73c1, 0xd1dc, 0x0040, + 0x73ad, 0x684b, 0x0015, 0x0078, 0x73c1, 0xd1d4, 0x0040, 0x73b4, + 0x684b, 0x0007, 0x0078, 0x73c1, 0x684b, 0x0000, 0x684c, 0xd0ac, + 0x0040, 0x73c1, 0x6810, 0x6914, 0xa115, 0x0040, 0x73c1, 0x1078, + 0x7248, 0x1078, 0x4376, 0x1078, 0x690e, 0x0d7f, 0x007c, 0x1078, + 0x578f, 0x0078, 0x73cd, 0x1078, 0x5837, 0x1078, 0x77ed, 0x0040, + 0x73e6, 0x0d7e, 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0x880c, + 0x210c, 0xd18c, 0x00c0, 0x73f1, 0xd184, 0x00c0, 0x73ed, 0x6108, + 0x694a, 0x6847, 0x0000, 0x1078, 0x4376, 0x0d7f, 0x1078, 0x690e, + 0x1078, 0x5888, 0x1078, 0x5948, 0x007c, 0x684b, 0x0004, 0x0078, + 0x73e1, 0x684b, 0x0004, 0x0078, 0x73e1, 0xa182, 0x0040, 0x0079, + 0x73f9, 0x740c, 0x740c, 0x740c, 0x740c, 0x740c, 0x740e, 0x740c, + 0x7411, 0x740c, 0x740c, 0x740c, 0x740c, 0x740c, 0x740c, 0x740c, + 0x740c, 0x740c, 0x740c, 0x740c, 0x1078, 0x12d2, 0x1078, 0x690e, + 0x007c, 0x007e, 0x027e, 0xa016, 0x1078, 0x1594, 0x027f, 0x007f, + 0x007c, 0xa182, 0x0085, 0x0079, 0x741d, 0x7426, 0x7424, 0x7424, + 0x7424, 0x7424, 0x7424, 0x7424, 0x1078, 0x12d2, 0x6003, 0x000b, + 0x6106, 0x1078, 0x5399, 0x127e, 0x2091, 0x8000, 0x1078, 0x5888, + 0x127f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x743c, 0x6004, 0xa082, + 0x0085, 0x2008, 0x0079, 0x7477, 0xa186, 0x0027, 0x00c0, 0x745f, + 0x1078, 0x578f, 0x1078, 0x24bf, 0x0d7e, 0x6010, 0x2068, 0x1078, + 0x77ed, 0x0040, 0x7455, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b, + 0x0029, 0x1078, 0x4376, 0x1078, 0x799b, 0x0d7f, 0x1078, 0x690e, + 0x1078, 0x5888, 0x007c, 0x1078, 0x6950, 0x0078, 0x745a, 0xa186, + 0x0014, 0x00c0, 0x745b, 0x1078, 0x578f, 0x0d7e, 0x6010, 0x2068, + 0x1078, 0x77ed, 0x0040, 0x7455, 0x6837, 0x0103, 0x6847, 0x0000, + 0x684b, 0x0006, 0x6850, 0xc0ec, 0x6852, 0x0078, 0x7451, 0x7480, + 0x747e, 0x747e, 0x747e, 0x747e, 0x747e, 0x7489, 0x1078, 0x12d2, + 0x1078, 0x578f, 0x6017, 0x0014, 0x6003, 0x000c, 0x1078, 0x5888, + 0x007c, 0x1078, 0x578f, 0x6017, 0x0014, 0x6003, 0x000e, 0x1078, + 0x5888, 0x007c, 0xa182, 0x008c, 0x00c8, 0x749c, 0xa182, 0x0085, + 0x0048, 0x749c, 0x0079, 0x749f, 0x1078, 0x6950, 0x007c, 0x74a6, + 0x74a6, 0x74a6, 0x74a6, 0x74a8, 0x74d0, 0x74a6, 0x1078, 0x12d2, + 0x0d7e, 0x1078, 0x799b, 0x1078, 0x77ed, 0x0040, 0x74cc, 0x6010, + 0x2068, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040, 0x74bd, 0x684b, + 0x0006, 0xc0ec, 0x6852, 0x0078, 0x74c8, 0xd0bc, 0x0040, 0x74c4, + 0x684b, 0x0002, 0x0078, 0x74c8, 0x684b, 0x0005, 0x1078, 0x7a4e, + 0x6847, 0x0000, 0x1078, 0x4376, 0x1078, 0x690e, 0x0d7f, 0x007c, + 0x0d7e, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, 0x74f4, 0x6837, + 0x0103, 0x6850, 0xd0b4, 0x0040, 0x74e3, 0xc0ec, 0x6852, 0x684b, + 0x0006, 0x0078, 0x74ee, 0xd0bc, 0x0040, 0x74ea, 0x684b, 0x0002, + 0x0078, 0x74ee, 0x684b, 0x0005, 0x1078, 0x7a4e, 0x6847, 0x0000, + 0x1078, 0x4376, 0x1078, 0x799b, 0x0d7f, 0x1078, 0x690e, 0x007c, + 0x017e, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, 0x7508, + 0x6837, 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x1078, 0x4376, + 0x0d7f, 0x017f, 0xa186, 0x0013, 0x0040, 0x751a, 0xa186, 0x0014, + 0x0040, 0x751a, 0xa186, 0x0027, 0x0040, 0x751a, 0x1078, 0x6950, + 0x0078, 0x7520, 0x1078, 0x578f, 0x1078, 0x79a8, 0x1078, 0x5888, 0x007c, 0x057e, 0x067e, 0x0d7e, 0x0f7e, 0x2029, 0x0001, 0xa182, - 0x0101, 0x00c8, 0x67e5, 0x0078, 0x67e7, 0x2009, 0x0100, 0x2130, - 0x2069, 0x7c98, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, 0xaf90, - 0x001d, 0x1078, 0x6841, 0xa6b2, 0x0020, 0x7804, 0xa06d, 0x0040, - 0x67fb, 0x1078, 0x1350, 0x1078, 0x1327, 0x0040, 0x6825, 0x8528, + 0x0101, 0x00c8, 0x752d, 0x0078, 0x752f, 0x2009, 0x0100, 0x2130, + 0x2069, 0x8d98, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, 0xaf90, + 0x001d, 0x1078, 0x7589, 0xa6b2, 0x0020, 0x7804, 0xa06d, 0x0040, + 0x7543, 0x1078, 0x1354, 0x1078, 0x132b, 0x0040, 0x756d, 0x8528, 0x6837, 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d, - 0x00c8, 0x6811, 0x2608, 0xad90, 0x000f, 0x1078, 0x6841, 0x0078, - 0x6825, 0xa6b2, 0x003c, 0x2009, 0x003c, 0x2d78, 0xad90, 0x000f, - 0x1078, 0x6841, 0x0078, 0x67fb, 0x0f7f, 0x852f, 0xa5ad, 0x0003, - 0x7d36, 0xa5ac, 0x0000, 0x0078, 0x682a, 0x0f7f, 0x852f, 0xa5ad, + 0x00c8, 0x7559, 0x2608, 0xad90, 0x000f, 0x1078, 0x7589, 0x0078, + 0x756d, 0xa6b2, 0x003c, 0x2009, 0x003c, 0x2d78, 0xad90, 0x000f, + 0x1078, 0x7589, 0x0078, 0x7543, 0x0f7f, 0x852f, 0xa5ad, 0x0003, + 0x7d36, 0xa5ac, 0x0000, 0x0078, 0x7572, 0x0f7f, 0x852f, 0xa5ad, 0x0003, 0x7d36, 0x0d7f, 0x067f, 0x057f, 0x007c, 0x0f7e, 0x8dff, - 0x0040, 0x683f, 0x6804, 0xa07d, 0x0040, 0x683d, 0x6807, 0x0000, - 0x1078, 0x3b92, 0x2f68, 0x0078, 0x6832, 0x1078, 0x3b92, 0x0f7f, - 0x007c, 0x157e, 0xa184, 0x0001, 0x0040, 0x6847, 0x8108, 0x810c, - 0x21a8, 0x2304, 0x8007, 0x2012, 0x8318, 0x8210, 0x00f0, 0x6849, + 0x0040, 0x7587, 0x6804, 0xa07d, 0x0040, 0x7585, 0x6807, 0x0000, + 0x1078, 0x4376, 0x2f68, 0x0078, 0x757a, 0x1078, 0x4376, 0x0f7f, + 0x007c, 0x157e, 0xa184, 0x0001, 0x0040, 0x758f, 0x8108, 0x810c, + 0x21a8, 0x2304, 0x8007, 0x2012, 0x8318, 0x8210, 0x00f0, 0x7591, 0x157f, 0x007c, 0x127e, 0x2091, 0x8000, 0x601c, 0xa084, 0x000f, - 0x1079, 0x685c, 0x127f, 0x007c, 0x686b, 0x6864, 0x6866, 0x6884, - 0x6864, 0x6866, 0x6866, 0x6866, 0x1078, 0x12cd, 0xa006, 0x007c, - 0xa085, 0x0001, 0x007c, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x6a58, - 0x0040, 0x6881, 0xa00e, 0x2001, 0x0005, 0x1078, 0x3c22, 0x1078, - 0x6c5c, 0x1078, 0x3b92, 0x1078, 0x5d1a, 0xa085, 0x0001, 0x0d7f, - 0x007c, 0xa006, 0x0078, 0x687f, 0x6000, 0xa08a, 0x0010, 0x10c8, - 0x12cd, 0x1079, 0x688c, 0x007c, 0x689c, 0x68b9, 0x689e, 0x68ca, - 0x68b5, 0x689c, 0x6866, 0x686b, 0x686b, 0x6866, 0x6866, 0x6866, - 0x6866, 0x6866, 0x6866, 0x6866, 0x1078, 0x12cd, 0x0d7e, 0x6010, - 0x2068, 0x1078, 0x6a58, 0x0040, 0x68a7, 0x1078, 0x6c5c, 0x0d7f, - 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078, 0x4941, - 0x1078, 0x4d96, 0xa085, 0x0001, 0x007c, 0x1078, 0x166e, 0x0078, - 0x689e, 0x0e7e, 0x2071, 0x7936, 0x7024, 0xac06, 0x00c0, 0x68c2, - 0x1078, 0x57ee, 0x1078, 0x5725, 0x0e7f, 0x00c0, 0x689e, 0x1078, - 0x6866, 0x007c, 0x037e, 0x0e7e, 0x2071, 0x7936, 0x703c, 0xac06, - 0x00c0, 0x68da, 0x2019, 0x0000, 0x1078, 0x5880, 0x0e7f, 0x037f, - 0x0078, 0x689e, 0x1078, 0x5b5c, 0x0e7f, 0x037f, 0x00c0, 0x689e, - 0x1078, 0x6866, 0x007c, 0x0c7e, 0x601c, 0xa084, 0x000f, 0x1079, - 0x68eb, 0x0c7f, 0x007c, 0x68fa, 0x6957, 0x69fc, 0x68fe, 0x68fa, - 0x68fa, 0x72dd, 0x5d1a, 0x6957, 0x1078, 0x6be3, 0x00c0, 0x68fa, - 0x1078, 0x5f6d, 0x007c, 0x6017, 0x0001, 0x007c, 0x6000, 0xa08a, - 0x0010, 0x10c8, 0x12cd, 0x1079, 0x6906, 0x007c, 0x6916, 0x6918, - 0x6938, 0x694a, 0x694a, 0x6916, 0x68fa, 0x68fa, 0x68fa, 0x694a, - 0x694a, 0x6916, 0x6916, 0x6916, 0x6916, 0x6954, 0x1078, 0x12cd, - 0x0e7e, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071, 0x7936, - 0x7024, 0xac06, 0x0040, 0x6934, 0x1078, 0x5725, 0x6007, 0x0085, - 0x6003, 0x000b, 0x601f, 0x0002, 0x6017, 0x0014, 0x1078, 0x4941, - 0x1078, 0x4d96, 0x0e7f, 0x007c, 0x6017, 0x0001, 0x0078, 0x6932, - 0x0d7e, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x0d7f, 0x6007, - 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078, 0x4941, 0x1078, - 0x4d96, 0x007c, 0x0d7e, 0x6017, 0x0001, 0x6010, 0x2068, 0x6850, - 0xc0b5, 0x6852, 0x0d7f, 0x007c, 0x1078, 0x5d1a, 0x007c, 0x6000, - 0xa08a, 0x0010, 0x10c8, 0x12cd, 0x1079, 0x695f, 0x007c, 0x696f, - 0x68fb, 0x6971, 0x696f, 0x6971, 0x696f, 0x696f, 0x696f, 0x68f4, - 0x68f4, 0x696f, 0x696f, 0x696f, 0x696f, 0x696f, 0x696f, 0x1078, - 0x12cd, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f, - 0xa08a, 0x000c, 0x10c8, 0x12cd, 0x1079, 0x697f, 0x007c, 0x698b, - 0x69aa, 0x698b, 0x69aa, 0x698b, 0x69aa, 0x698d, 0x6996, 0x698b, - 0x69aa, 0x698b, 0x69a3, 0x1078, 0x12cd, 0x6004, 0xa08e, 0x0004, - 0x0040, 0x69a5, 0xa08e, 0x0002, 0x0040, 0x69a5, 0x6004, 0x1078, - 0x6be3, 0x0040, 0x69f4, 0xa08e, 0x0021, 0x0040, 0x69f8, 0xa08e, - 0x0022, 0x0040, 0x69f4, 0x1078, 0x22b5, 0x1078, 0x5f6d, 0x1078, - 0x5d1a, 0x007c, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016, 0x0040, - 0x69e4, 0xa186, 0x0002, 0x00c0, 0x69d3, 0x6018, 0x2068, 0x68a0, - 0xd0bc, 0x00c0, 0x69d3, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, - 0x69d3, 0x8001, 0x6842, 0x6013, 0x0000, 0x601f, 0x0007, 0x6017, - 0x0398, 0x1078, 0x5cb4, 0x0040, 0x69d3, 0x2d00, 0x601a, 0x601f, - 0x0001, 0x0078, 0x69e4, 0x0d7f, 0x0c7f, 0x1078, 0x5f6d, 0x1078, - 0x22b5, 0x0e7e, 0x127e, 0x2091, 0x8000, 0x1078, 0x22d7, 0x127f, - 0x0e7f, 0x1078, 0x5d1a, 0x007c, 0x2001, 0x0002, 0x1078, 0x37f4, - 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x498e, 0x1078, 0x4d96, - 0x0d7f, 0x0c7f, 0x0078, 0x69e3, 0x1078, 0x5f6d, 0x0078, 0x69a7, - 0x1078, 0x5f7c, 0x0078, 0x69a7, 0x6000, 0xa08a, 0x0010, 0x10c8, - 0x12cd, 0x1079, 0x6a04, 0x007c, 0x6a14, 0x6a14, 0x6a14, 0x6a14, - 0x6a14, 0x6a14, 0x6a14, 0x6a14, 0x6a14, 0x68fa, 0x6a14, 0x68fb, - 0x6a16, 0x68fb, 0x6a1f, 0x6a14, 0x1078, 0x12cd, 0x6007, 0x008b, - 0x6003, 0x000d, 0x1078, 0x4941, 0x1078, 0x4d96, 0x007c, 0x1078, - 0x6ba9, 0x1078, 0x6a58, 0x0040, 0x6a41, 0x1078, 0x22b5, 0x0d7e, - 0x1078, 0x6a58, 0x0040, 0x6a34, 0x6010, 0x2068, 0x6837, 0x0103, - 0x684b, 0x0006, 0x1078, 0x3b92, 0x0d7f, 0x601f, 0x0001, 0x6007, - 0x0001, 0x6003, 0x0001, 0x1078, 0x498e, 0x1078, 0x4d96, 0x0078, - 0x6a43, 0x1078, 0x5d1a, 0x007c, 0xa284, 0x0007, 0x00c0, 0x6a55, - 0xa282, 0x7e00, 0x0048, 0x6a55, 0x2001, 0x7715, 0x2004, 0xa202, - 0x00c8, 0x6a55, 0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x6a54, - 0x027e, 0x0e7e, 0x2071, 0x7700, 0x6210, 0x7058, 0xa202, 0x0048, - 0x6a6a, 0x705c, 0xa202, 0x00c8, 0x6a6a, 0xa085, 0x0001, 0x0e7f, - 0x027f, 0x007c, 0xa006, 0x0078, 0x6a67, 0x0e7e, 0x0c7e, 0x037e, - 0x007e, 0x127e, 0x2091, 0x8000, 0x2061, 0x7e00, 0x2071, 0x7700, - 0x7344, 0x7060, 0xa302, 0x00c8, 0x6a93, 0x601c, 0xa206, 0x00c0, - 0x6a8b, 0x1078, 0x6be3, 0x00c0, 0x6a87, 0x1078, 0x5f6d, 0x0c7e, - 0x1078, 0x5d1a, 0x0c7f, 0xace0, 0x0008, 0x7054, 0xac02, 0x00c8, - 0x6a93, 0x0078, 0x6a78, 0x127f, 0x007f, 0x037f, 0x0c7f, 0x0e7f, - 0x007c, 0x0e7e, 0x0c7e, 0x017e, 0xa188, 0x7820, 0x210c, 0x81ff, - 0x0040, 0x6ab1, 0x2061, 0x7e00, 0x2071, 0x7700, 0x017e, 0x1078, - 0x5cb4, 0x017f, 0x0040, 0x6ab4, 0x611a, 0x1078, 0x22b5, 0x1078, - 0x5d1a, 0xa006, 0x0078, 0x6ab6, 0xa085, 0x0001, 0x017f, 0x0c7f, - 0x0e7f, 0x007c, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x0c7e, - 0x1078, 0x5cb4, 0x057f, 0x0040, 0x6ad3, 0x6612, 0x651a, 0x601f, - 0x0003, 0x2009, 0x004b, 0x1078, 0x5d41, 0xa085, 0x0001, 0x127f, - 0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6acf, 0x0c7e, 0x057e, - 0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078, 0x5cb4, 0x057f, - 0x0040, 0x6afd, 0x6013, 0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e, - 0x2560, 0x1078, 0x3a36, 0x0c7f, 0x1078, 0x4a7e, 0x1078, 0x49c1, - 0x2c08, 0x1078, 0x747b, 0x2009, 0x004c, 0x1078, 0x5d41, 0xa085, - 0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6af9, - 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078, - 0x5cb4, 0x057f, 0x0040, 0x6b28, 0x6612, 0x651a, 0x601f, 0x0003, - 0x2019, 0x0005, 0x0c7e, 0x2560, 0x1078, 0x3a36, 0x0c7f, 0x1078, - 0x4a7e, 0x1078, 0x49c1, 0x2c08, 0x1078, 0x747b, 0x2009, 0x004d, - 0x1078, 0x5d41, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c, - 0xa006, 0x0078, 0x6b24, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, - 0x62a0, 0x0c7e, 0x1078, 0x5cb4, 0x057f, 0x0040, 0x6b53, 0x6612, - 0x651a, 0x601f, 0x0003, 0x2019, 0x0005, 0x0c7e, 0x2560, 0x1078, - 0x3a36, 0x0c7f, 0x1078, 0x4a7e, 0x1078, 0x49c1, 0x2c08, 0x1078, - 0x747b, 0x2009, 0x004e, 0x1078, 0x5d41, 0xa085, 0x0001, 0x127f, - 0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6b4f, 0x0c7e, 0x127e, - 0x2091, 0x8000, 0x0c7e, 0x1078, 0x5cb4, 0x017f, 0x0040, 0x6b6f, - 0x660a, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x001f, - 0x1078, 0x5d41, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, - 0x0078, 0x6b6c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, - 0x5cb4, 0x017f, 0x0040, 0x6b8b, 0x660a, 0x611a, 0x601f, 0x0008, - 0x2d00, 0x6012, 0x2009, 0x0021, 0x1078, 0x5d41, 0xa085, 0x0001, - 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6b88, 0x0c7e, 0x127e, - 0x2091, 0x8000, 0x0c7e, 0x1078, 0x5cb4, 0x017f, 0x0040, 0x6ba6, - 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x1078, - 0x5d41, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, - 0x6ba3, 0x027e, 0x0d7e, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0040, - 0x6bb3, 0x8211, 0x6a3e, 0x0d7f, 0x027f, 0x007c, 0x6013, 0x0000, - 0x601f, 0x0007, 0x6017, 0x0014, 0x007c, 0x067e, 0x0c7e, 0x0d7e, - 0x2031, 0x7752, 0x2634, 0xd6e4, 0x0040, 0x6bcb, 0x6618, 0x2660, - 0x6e48, 0x1078, 0x3942, 0x0d7f, 0x0c7f, 0x067f, 0x007c, 0x007e, - 0x017e, 0x6004, 0xa08e, 0x0002, 0x0040, 0x6be0, 0xa08e, 0x0003, - 0x0040, 0x6be0, 0xa08e, 0x0004, 0x0040, 0x6be0, 0xa085, 0x0001, - 0x017f, 0x007f, 0x007c, 0x007e, 0x017e, 0x6004, 0xa08e, 0x0000, - 0x0040, 0x6bf8, 0xa08e, 0x001f, 0x0040, 0x6bf8, 0xa08e, 0x0028, - 0x0040, 0x6bf8, 0xa08e, 0x0029, 0x0040, 0x6bf8, 0xa085, 0x0001, - 0x017f, 0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, - 0x1078, 0x5cb4, 0x017f, 0x0040, 0x6c15, 0x611a, 0x601f, 0x0001, - 0x2d00, 0x6012, 0x1078, 0x22b5, 0x2009, 0x0028, 0x1078, 0x5d41, - 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6c12, - 0xa186, 0x0015, 0x00c0, 0x6c2d, 0x2011, 0x771e, 0x2204, 0xa086, - 0x0074, 0x00c0, 0x6c2d, 0x1078, 0x61ea, 0x6003, 0x0001, 0x6007, - 0x0029, 0x1078, 0x498e, 0x0078, 0x6c31, 0x1078, 0x5f6d, 0x1078, - 0x5d1a, 0x007c, 0xa186, 0x0015, 0x00c0, 0x6c4f, 0x2011, 0x771e, - 0x2204, 0xa086, 0x0014, 0x00c0, 0x6c4f, 0x0d7e, 0x6018, 0x2068, - 0x1078, 0x38c8, 0x0d7f, 0x1078, 0x61f4, 0x00c0, 0x6c4f, 0x2001, - 0x0006, 0x1078, 0x37f4, 0x1078, 0x5dc5, 0x0078, 0x6c53, 0x1078, - 0x5f6d, 0x1078, 0x5d1a, 0x007c, 0x6848, 0xa086, 0x0005, 0x00c0, - 0x6c5b, 0x1078, 0x6c5c, 0x007c, 0x6850, 0xc0ad, 0x6852, 0x007c, - 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12cd, 0x1079, 0x6c6a, - 0x067f, 0x007c, 0x6c7a, 0x6e51, 0x6f32, 0x6c7a, 0x6c7a, 0x6c7a, - 0x6c7a, 0x6c7a, 0x6cb4, 0x6fa0, 0x6c7a, 0x6c7a, 0x6c7a, 0x6c7a, - 0x6c7a, 0x6c7a, 0x1078, 0x12cd, 0x067e, 0x6000, 0xa0b2, 0x0010, - 0x10c8, 0x12cd, 0x1079, 0x6c86, 0x067f, 0x007c, 0x6c96, 0x728c, - 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x7267, 0x72d6, - 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x1078, 0x12cd, - 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12cd, 0x1079, 0x6ca2, - 0x067f, 0x007c, 0x6cb2, 0x70d8, 0x714a, 0x716c, 0x71b8, 0x6cb2, - 0x6cb2, 0x7212, 0x6fac, 0x724f, 0x7253, 0x6cb2, 0x6cb2, 0x6cb2, - 0x6cb2, 0x6cb2, 0x1078, 0x12cd, 0xa1b2, 0x0030, 0x10c8, 0x12cd, - 0x2100, 0x0079, 0x6cbb, 0x6ceb, 0x6dc8, 0x6ceb, 0x6ceb, 0x6ceb, - 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, - 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, - 0x6ceb, 0x6ceb, 0x6ced, 0x6d1c, 0x6d27, 0x6d4f, 0x6d55, 0x6d89, - 0x6dc1, 0x6ceb, 0x6ceb, 0x6dd0, 0x6ceb, 0x6ceb, 0x6dd7, 0x6dde, - 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6dfb, 0x6ceb, 0x6ceb, - 0x6e06, 0x6ceb, 0x6ceb, 0x1078, 0x12cd, 0x1078, 0x3b3e, 0x6618, - 0x0c7e, 0x2660, 0x1078, 0x385e, 0x0c7f, 0xa6b0, 0x0001, 0x2634, - 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x6d0e, 0x1078, 0x73b7, - 0x00c0, 0x6d49, 0x1078, 0x7355, 0x00c0, 0x6d0a, 0x6007, 0x0008, - 0x0078, 0x6dc3, 0x6007, 0x0009, 0x0078, 0x6dc3, 0x1078, 0x754c, - 0x0040, 0x6d18, 0x1078, 0x73b7, 0x0040, 0x6d02, 0x0078, 0x6d49, - 0x6013, 0x1900, 0x0078, 0x6d0a, 0x6106, 0x1078, 0x7317, 0x6007, - 0x0006, 0x0078, 0x6dc3, 0x6007, 0x0007, 0x0078, 0x6dc3, 0x0d7e, - 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, - 0x0040, 0x6d39, 0xa686, 0x0004, 0x0040, 0x6d39, 0x0d7f, 0x0078, - 0x6d49, 0x1078, 0x7415, 0x00c0, 0x6d44, 0x1078, 0x38c8, 0x6007, - 0x000a, 0x0d7f, 0x0078, 0x6dc3, 0x6007, 0x000b, 0x0d7f, 0x0078, - 0x6dc3, 0x1078, 0x22b5, 0x6007, 0x0001, 0x0078, 0x6dc3, 0x1078, - 0x22b5, 0x6007, 0x000c, 0x0078, 0x6dc3, 0x1078, 0x3b3e, 0x6618, + 0x1079, 0x75a4, 0x127f, 0x007c, 0x75ba, 0x75ac, 0x75b5, 0x75d3, + 0x75ac, 0x75b5, 0x75ae, 0x75b5, 0x1078, 0x12d2, 0x037e, 0x2019, + 0x0010, 0x1078, 0x831c, 0x037f, 0x007c, 0xa006, 0x007c, 0xa085, + 0x0001, 0x007c, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, + 0x75d0, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4454, 0x1078, 0x7a4e, + 0x1078, 0x4376, 0x1078, 0x690e, 0xa085, 0x0001, 0x0d7f, 0x007c, + 0xa006, 0x0078, 0x75ce, 0x6000, 0xa08a, 0x0010, 0x10c8, 0x12d2, + 0x1079, 0x75db, 0x007c, 0x75eb, 0x7608, 0x75ed, 0x7619, 0x7604, + 0x75eb, 0x75b5, 0x75ba, 0x75ba, 0x75b5, 0x75b5, 0x75b5, 0x75b5, + 0x75b5, 0x75b5, 0x75b5, 0x1078, 0x12d2, 0x0d7e, 0x6010, 0x2068, + 0x1078, 0x77ed, 0x0040, 0x75f6, 0x1078, 0x7a4e, 0x0d7f, 0x6007, + 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078, 0x5399, 0x1078, + 0x5888, 0xa085, 0x0001, 0x007c, 0x1078, 0x16af, 0x0078, 0x75ed, + 0x0e7e, 0x2071, 0x8aa2, 0x7024, 0xac06, 0x00c0, 0x7611, 0x1078, + 0x639b, 0x1078, 0x62b2, 0x0e7f, 0x00c0, 0x75ed, 0x1078, 0x75b5, + 0x007c, 0x037e, 0x0e7e, 0x2071, 0x8aa2, 0x703c, 0xac06, 0x00c0, + 0x7629, 0x2019, 0x0000, 0x1078, 0x642d, 0x0e7f, 0x037f, 0x0078, + 0x75ed, 0x1078, 0x6753, 0x0e7f, 0x037f, 0x00c0, 0x75ed, 0x1078, + 0x75b5, 0x007c, 0x0c7e, 0x601c, 0xa084, 0x000f, 0x1079, 0x763a, + 0x0c7f, 0x007c, 0x7649, 0x76ae, 0x777b, 0x764d, 0x7649, 0x7649, + 0x8311, 0x690e, 0x76ae, 0x1078, 0x79d5, 0x00c0, 0x7649, 0x1078, + 0x6bc7, 0x007c, 0x6017, 0x0001, 0x007c, 0x6010, 0xa080, 0x0019, + 0x2c02, 0x6000, 0xa08a, 0x0010, 0x10c8, 0x12d2, 0x1079, 0x7659, + 0x007c, 0x7669, 0x766b, 0x768b, 0x769d, 0x76aa, 0x7669, 0x7649, + 0x7649, 0x7649, 0x769d, 0x769d, 0x7669, 0x7669, 0x7669, 0x7669, + 0x76a7, 0x1078, 0x12d2, 0x0e7e, 0x6010, 0x2070, 0x7050, 0xc0b5, + 0x7052, 0x2071, 0x8aa2, 0x7024, 0xac06, 0x0040, 0x7687, 0x1078, + 0x62b2, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6017, + 0x0014, 0x1078, 0x5399, 0x1078, 0x5888, 0x0e7f, 0x007c, 0x6017, + 0x0001, 0x0078, 0x7685, 0x0d7e, 0x6010, 0x2068, 0x6850, 0xc0b5, + 0x6852, 0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, + 0x1078, 0x5399, 0x1078, 0x5888, 0x007c, 0x0d7e, 0x6017, 0x0001, + 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x0d7f, 0x007c, 0x1078, + 0x690e, 0x007c, 0x1078, 0x16af, 0x0078, 0x768b, 0x6000, 0xa08a, + 0x0010, 0x10c8, 0x12d2, 0x1079, 0x76b6, 0x007c, 0x76c6, 0x764a, + 0x76c8, 0x76c6, 0x76c8, 0x76c6, 0x76c6, 0x76c6, 0x7643, 0x7643, + 0x76c6, 0x76c6, 0x76c6, 0x76c6, 0x76c6, 0x76c6, 0x1078, 0x12d2, + 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f, 0xa08a, + 0x000c, 0x10c8, 0x12d2, 0x1079, 0x76d6, 0x007c, 0x76e2, 0x7714, + 0x76e2, 0x7714, 0x76e2, 0x7714, 0x76e4, 0x76ed, 0x76e2, 0x7714, + 0x76e2, 0x76fe, 0x1078, 0x12d2, 0x6004, 0xa08e, 0x0004, 0x0040, + 0x770f, 0xa08e, 0x0002, 0x0040, 0x770f, 0x6004, 0x1078, 0x79d5, + 0x0040, 0x775e, 0xa08e, 0x0021, 0x0040, 0x7762, 0xa08e, 0x0022, + 0x0040, 0x775e, 0xa08e, 0x003d, 0x0040, 0x7762, 0xa08e, 0x0001, + 0x00c0, 0x770d, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, + 0x0d7f, 0xa086, 0x0006, 0x0040, 0x770f, 0x1078, 0x24bf, 0x1078, + 0x6bc7, 0x1078, 0x79a8, 0x007c, 0x0c7e, 0x0d7e, 0x6104, 0xa186, + 0x0016, 0x0040, 0x774e, 0xa186, 0x0002, 0x00c0, 0x773d, 0x6018, + 0x2068, 0x68a0, 0xd0bc, 0x00c0, 0x7766, 0x6840, 0xa084, 0x00ff, + 0xa005, 0x0040, 0x773d, 0x8001, 0x6842, 0x6013, 0x0000, 0x601f, + 0x0007, 0x6017, 0x0398, 0x1078, 0x68a8, 0x0040, 0x773d, 0x2d00, + 0x601a, 0x601f, 0x0001, 0x0078, 0x774e, 0x0d7f, 0x0c7f, 0x1078, + 0x6bc7, 0x1078, 0x24bf, 0x0e7e, 0x127e, 0x2091, 0x8000, 0x1078, + 0x24e5, 0x127f, 0x0e7f, 0x1078, 0x79a8, 0x007c, 0x2001, 0x0002, + 0x1078, 0x3f05, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x53e6, + 0x1078, 0x5888, 0x0d7f, 0x0c7f, 0x0078, 0x774d, 0x1078, 0x6bc7, + 0x0078, 0x7711, 0x1078, 0x6bda, 0x0078, 0x7711, 0x0d7f, 0x0c7f, + 0x1078, 0x6bc7, 0x1078, 0x24bf, 0x0e7e, 0x127e, 0x2091, 0x8000, + 0x1078, 0x24e5, 0x6013, 0x0000, 0x601f, 0x0007, 0x6017, 0x0398, + 0x127f, 0x0e7f, 0x007c, 0x6000, 0xa08a, 0x0010, 0x10c8, 0x12d2, + 0x1079, 0x7783, 0x007c, 0x7793, 0x7793, 0x7793, 0x7793, 0x7793, + 0x7793, 0x7793, 0x7793, 0x7793, 0x7649, 0x7793, 0x764a, 0x7795, + 0x764a, 0x779e, 0x7793, 0x1078, 0x12d2, 0x6007, 0x008b, 0x6003, + 0x000d, 0x1078, 0x5399, 0x1078, 0x5888, 0x007c, 0x1078, 0x799b, + 0x1078, 0x77ed, 0x0040, 0x77d6, 0x1078, 0x24bf, 0x0d7e, 0x1078, + 0x77ed, 0x0040, 0x77b8, 0x6010, 0x2068, 0x6837, 0x0103, 0x684b, + 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x1078, 0x4376, + 0x2c68, 0x1078, 0x68a8, 0x0040, 0x77c6, 0x6818, 0x601a, 0x0c7e, + 0x2d60, 0x1078, 0x79a8, 0x0c7f, 0x0078, 0x77c7, 0x2d60, 0x0d7f, + 0x6013, 0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, + 0x1078, 0x53e6, 0x1078, 0x5888, 0x0078, 0x77d8, 0x1078, 0x79a8, + 0x007c, 0xa284, 0x0003, 0x00c0, 0x77ea, 0xa282, 0x8f00, 0x0048, + 0x77ea, 0x2001, 0x8815, 0x2004, 0xa202, 0x00c8, 0x77ea, 0xa085, + 0x0001, 0x007c, 0xa006, 0x0078, 0x77e9, 0x027e, 0x0e7e, 0x2071, + 0x8800, 0x6210, 0x7058, 0xa202, 0x0048, 0x77ff, 0x705c, 0xa202, + 0x00c8, 0x77ff, 0xa085, 0x0001, 0x0e7f, 0x027f, 0x007c, 0xa006, + 0x0078, 0x77fc, 0x0e7e, 0x0c7e, 0x037e, 0x007e, 0x127e, 0x2091, + 0x8000, 0x2061, 0x8f00, 0x2071, 0x8800, 0x7344, 0x7060, 0xa302, + 0x00c8, 0x7828, 0x601c, 0xa206, 0x00c0, 0x7820, 0x1078, 0x79d5, + 0x00c0, 0x781c, 0x1078, 0x6bc7, 0x0c7e, 0x1078, 0x690e, 0x0c7f, + 0xace0, 0x000c, 0x7054, 0xac02, 0x00c8, 0x7828, 0x0078, 0x780d, + 0x127f, 0x007f, 0x037f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e, + 0x017e, 0xa188, 0x8934, 0x210c, 0x81ff, 0x0040, 0x7846, 0x2061, + 0x8f00, 0x2071, 0x8800, 0x017e, 0x1078, 0x68a8, 0x017f, 0x0040, + 0x7849, 0x611a, 0x1078, 0x24bf, 0x1078, 0x690e, 0xa006, 0x0078, + 0x784b, 0xa085, 0x0001, 0x017f, 0x0c7f, 0x0e7f, 0x007c, 0x0c7e, + 0x057e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x68a8, 0x057f, + 0x0040, 0x7868, 0x6612, 0x651a, 0x601f, 0x0003, 0x2009, 0x004b, + 0x1078, 0x6939, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c, + 0xa006, 0x0078, 0x7864, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, + 0x62a0, 0x0c7e, 0x1078, 0x68a8, 0x057f, 0x0040, 0x7896, 0x6013, + 0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e, 0x2560, 0x1078, 0x418b, + 0x0c7f, 0x1078, 0x54f0, 0x087e, 0x2041, 0x0000, 0x1078, 0x5419, + 0x2c08, 0x1078, 0x84d2, 0x087f, 0x2009, 0x004c, 0x1078, 0x6939, + 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, + 0x7892, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x68a8, 0x2c78, + 0x0c7f, 0x0040, 0x78b5, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, + 0x2021, 0x0005, 0x1078, 0x78f9, 0x0040, 0x78b5, 0x2f60, 0x2009, + 0x004d, 0x1078, 0x6939, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, + 0x007c, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x68a8, 0x2c78, + 0x0c7f, 0x0040, 0x78d5, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, + 0x2021, 0x0005, 0x1078, 0x78f9, 0x0040, 0x78d5, 0x2f60, 0x2009, + 0x004e, 0x1078, 0x6939, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, + 0x007c, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x68a8, 0x2c78, + 0x0c7f, 0x0040, 0x78f5, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, + 0x2021, 0x0004, 0x1078, 0x78f9, 0x0040, 0x78f5, 0x2f60, 0x2009, + 0x0052, 0x1078, 0x6939, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, + 0x007c, 0x097e, 0x087e, 0x127e, 0x2091, 0x8000, 0x1078, 0x4117, + 0x0040, 0x7906, 0x2001, 0x78fe, 0x0078, 0x790c, 0x1078, 0x40dd, + 0x0040, 0x7915, 0x2001, 0x7906, 0x007e, 0xa00e, 0x2400, 0x1078, + 0x4454, 0x1078, 0x4376, 0x007f, 0x007a, 0x2418, 0x1078, 0x5726, + 0x62a0, 0x2041, 0x0001, 0x2608, 0x1078, 0x550a, 0x1078, 0x5419, + 0x2f08, 0x2648, 0x1078, 0x84d2, 0x613c, 0x81ff, 0x1040, 0x55ae, + 0x127f, 0x087f, 0x097f, 0x007c, 0x0c7e, 0x127e, 0x2091, 0x8000, + 0x0c7e, 0x1078, 0x68a8, 0x017f, 0x0040, 0x7945, 0x660a, 0x611a, + 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x001f, 0x1078, 0x6939, + 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x7942, + 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x68a8, 0x017f, + 0x0040, 0x7961, 0x660a, 0x611a, 0x601f, 0x0008, 0x2d00, 0x6012, + 0x2009, 0x0021, 0x1078, 0x6939, 0xa085, 0x0001, 0x127f, 0x0c7f, + 0x007c, 0xa006, 0x0078, 0x795e, 0x0c7e, 0x127e, 0x2091, 0x8000, + 0x0c7e, 0x1078, 0x68a8, 0x017f, 0x0040, 0x797d, 0x660a, 0x611a, + 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x003d, 0x1078, 0x6939, + 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x797a, + 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x68a8, 0x017f, + 0x0040, 0x7998, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, + 0x0000, 0x1078, 0x6939, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, + 0xa006, 0x0078, 0x7995, 0x027e, 0x0d7e, 0x6218, 0x2268, 0x6a3c, + 0x82ff, 0x0040, 0x79a5, 0x8211, 0x6a3e, 0x0d7f, 0x027f, 0x007c, + 0x6013, 0x0000, 0x601f, 0x0007, 0x6017, 0x0014, 0x007c, 0x067e, + 0x0c7e, 0x0d7e, 0x2031, 0x8852, 0x2634, 0xd6e4, 0x0040, 0x79bd, + 0x6618, 0x2660, 0x6e48, 0x1078, 0x408b, 0x0d7f, 0x0c7f, 0x067f, + 0x007c, 0x007e, 0x017e, 0x6004, 0xa08e, 0x0002, 0x0040, 0x79d2, + 0xa08e, 0x0003, 0x0040, 0x79d2, 0xa08e, 0x0004, 0x0040, 0x79d2, + 0xa085, 0x0001, 0x017f, 0x007f, 0x007c, 0x007e, 0x017e, 0x6004, + 0xa08e, 0x0000, 0x0040, 0x79ea, 0xa08e, 0x001f, 0x0040, 0x79ea, + 0xa08e, 0x0028, 0x0040, 0x79ea, 0xa08e, 0x0029, 0x0040, 0x79ea, + 0xa085, 0x0001, 0x017f, 0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091, + 0x8000, 0x0c7e, 0x1078, 0x68a8, 0x017f, 0x0040, 0x7a07, 0x611a, + 0x601f, 0x0001, 0x2d00, 0x6012, 0x1078, 0x24bf, 0x2009, 0x0028, + 0x1078, 0x6939, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, + 0x0078, 0x7a04, 0xa186, 0x0015, 0x00c0, 0x7a1f, 0x2011, 0x881f, + 0x2204, 0xa086, 0x0074, 0x00c0, 0x7a1f, 0x1078, 0x6e79, 0x6003, + 0x0001, 0x6007, 0x0029, 0x1078, 0x53e6, 0x0078, 0x7a23, 0x1078, + 0x6bc7, 0x1078, 0x690e, 0x007c, 0xa186, 0x0015, 0x00c0, 0x7a41, + 0x2011, 0x881f, 0x2204, 0xa086, 0x0014, 0x00c0, 0x7a41, 0x0d7e, + 0x6018, 0x2068, 0x1078, 0x400a, 0x0d7f, 0x1078, 0x6e83, 0x00c0, + 0x7a41, 0x2001, 0x0006, 0x1078, 0x3f05, 0x1078, 0x69c6, 0x0078, + 0x7a45, 0x1078, 0x6bc7, 0x1078, 0x690e, 0x007c, 0x6848, 0xa086, + 0x0005, 0x00c0, 0x7a4d, 0x1078, 0x7a4e, 0x007c, 0x6850, 0xc0ad, + 0x6852, 0x007c, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12d2, + 0x1079, 0x7a5c, 0x067f, 0x007c, 0x7a6c, 0x7d34, 0x7e2d, 0x7a6c, + 0x7a6c, 0x7a6c, 0x7a6c, 0x7a6c, 0x7aa6, 0x7ea4, 0x7a6c, 0x7a6c, + 0x7a6c, 0x7a6c, 0x7a6c, 0x7a6c, 0x1078, 0x12d2, 0x067e, 0x6000, + 0xa0b2, 0x0010, 0x10c8, 0x12d2, 0x1079, 0x7a78, 0x067f, 0x007c, + 0x7a88, 0x82ac, 0x7a88, 0x7a88, 0x7a88, 0x7a88, 0x7a88, 0x7a88, + 0x8276, 0x82fa, 0x7a88, 0x7a88, 0x7a88, 0x7a88, 0x7a88, 0x7a88, + 0x1078, 0x12d2, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12d2, + 0x1079, 0x7a94, 0x067f, 0x007c, 0x7aa4, 0x7ff2, 0x80ac, 0x80d1, + 0x8120, 0x7aa4, 0x81df, 0x819b, 0x7eb0, 0x824e, 0x8262, 0x7aa4, + 0x7aa4, 0x7aa4, 0x7aa4, 0x7aa4, 0x1078, 0x12d2, 0xa1b2, 0x0040, + 0x10c8, 0x12d2, 0x2100, 0x0079, 0x7aad, 0x7aed, 0x7c63, 0x7aed, + 0x7aed, 0x7aed, 0x7c6b, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, + 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, + 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aef, 0x7b3d, 0x7b48, 0x7b82, + 0x7b9d, 0x7bf4, 0x7c4f, 0x7aed, 0x7aed, 0x7c6f, 0x7aed, 0x7aed, + 0x7c7e, 0x7c85, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7cb3, + 0x7aed, 0x7aed, 0x7cbe, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, + 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, + 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x1078, 0x12d2, 0x1078, + 0x42a2, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x6218, 0x2270, + 0x72a0, 0x027e, 0x2019, 0x0029, 0x1078, 0x54f0, 0x087e, 0x2041, + 0x0000, 0x1078, 0x5419, 0x2c08, 0x1078, 0x84d2, 0x087f, 0x017f, + 0x2e60, 0x1078, 0x418b, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f, + 0x6618, 0x0c7e, 0x2660, 0x1078, 0x3fa0, 0x0c7f, 0xa6b0, 0x0001, + 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x7b2f, 0x1078, + 0x8406, 0x00c0, 0x7b7c, 0x1078, 0x83a4, 0x00c0, 0x7b2b, 0x6007, + 0x0008, 0x0078, 0x7c5e, 0x6007, 0x0009, 0x0078, 0x7c5e, 0x1078, + 0x85aa, 0x0040, 0x7b39, 0x1078, 0x8406, 0x0040, 0x7b23, 0x0078, + 0x7b7c, 0x6013, 0x1900, 0x0078, 0x7b2b, 0x6106, 0x1078, 0x834f, + 0x6007, 0x0006, 0x0078, 0x7c5e, 0x6007, 0x0007, 0x0078, 0x7c5e, + 0x1078, 0x8727, 0x00c0, 0x7cd3, 0x0d7e, 0x6618, 0x2668, 0x6e04, + 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x7b5e, 0xa686, + 0x0004, 0x0040, 0x7b5e, 0x0d7f, 0x0078, 0x7b7c, 0x1078, 0x846c, + 0x00c0, 0x7b77, 0xa686, 0x0006, 0x00c0, 0x7b70, 0x027e, 0x6218, + 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x1078, 0x2507, 0x027f, + 0x1078, 0x400a, 0x6007, 0x000a, 0x0d7f, 0x0078, 0x7c5e, 0x6007, + 0x000b, 0x0d7f, 0x0078, 0x7c5e, 0x1078, 0x24bf, 0x6007, 0x0001, + 0x0078, 0x7c5e, 0x1078, 0x8727, 0x00c0, 0x7cd3, 0x6618, 0x0d7e, + 0x2668, 0x6e04, 0x0d7f, 0xa686, 0x0707, 0x0040, 0x7b7c, 0x027e, + 0x6218, 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x1078, 0x2507, + 0x027f, 0x6007, 0x000c, 0x0078, 0x7c5e, 0x1078, 0x42a2, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, - 0x6d76, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x00c0, 0x6d49, - 0x1078, 0x7424, 0x00c0, 0x6d70, 0x6007, 0x000e, 0x0078, 0x6dc3, - 0x1078, 0x22b5, 0x6007, 0x000f, 0x0078, 0x6dc3, 0x1078, 0x754c, - 0x0040, 0x6d83, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, - 0x6d68, 0x0078, 0x6d49, 0x6013, 0x1900, 0x6007, 0x0009, 0x0078, - 0x6dc3, 0x1078, 0x3b3e, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684, - 0x00ff, 0xa082, 0x0006, 0x0048, 0x6dae, 0xa6b4, 0xff00, 0x8637, - 0xa686, 0x0006, 0x00c0, 0x6d49, 0x1078, 0x744f, 0x00c0, 0x6da8, - 0x1078, 0x7355, 0x00c0, 0x6da8, 0x6007, 0x0010, 0x0078, 0x6dc3, - 0x1078, 0x22b5, 0x6007, 0x0011, 0x0078, 0x6dc3, 0x1078, 0x754c, - 0x0040, 0x6dbb, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, - 0x6d9c, 0x0078, 0x6d49, 0x6013, 0x1900, 0x6007, 0x0009, 0x0078, - 0x6dc3, 0x6007, 0x0012, 0x6003, 0x0001, 0x1078, 0x498e, 0x007c, - 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x498e, 0x0078, 0x6dc7, - 0x6007, 0x0020, 0x6003, 0x0001, 0x1078, 0x498e, 0x007c, 0x6007, - 0x0023, 0x6003, 0x0001, 0x1078, 0x498e, 0x007c, 0x017e, 0x027e, - 0x2011, 0x7c88, 0x2214, 0x2c08, 0x1078, 0x7614, 0x00c0, 0x6def, - 0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x0078, 0x6df4, 0x1078, - 0x5d1a, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x1078, 0x498e, - 0x027f, 0x017f, 0x007c, 0x6106, 0x1078, 0x6e0d, 0x6007, 0x002b, - 0x0078, 0x6dc3, 0x6007, 0x002c, 0x0078, 0x6dc3, 0x6106, 0x1078, - 0x6e12, 0x6007, 0x002e, 0x0078, 0x6dc3, 0x0d7e, 0x1078, 0x6e38, - 0x0d7f, 0x007c, 0x0d7e, 0x1078, 0x6e47, 0x00c0, 0x6e31, 0x680c, - 0xa08c, 0xff00, 0x6824, 0xa084, 0x00ff, 0xa115, 0x6212, 0xd1e4, - 0x0040, 0x6e26, 0x2009, 0x0001, 0x0078, 0x6e2d, 0xd1ec, 0x0040, - 0x6e31, 0x2009, 0x0000, 0xa294, 0x00ff, 0x1078, 0x22f9, 0x0078, - 0x6e35, 0xa085, 0x0001, 0x0078, 0x6e36, 0xa006, 0x0d7f, 0x007c, - 0x2069, 0x7c8d, 0x6800, 0xa082, 0x0010, 0x00c8, 0x6e45, 0x6013, - 0x0000, 0xa085, 0x0001, 0x0078, 0x6e46, 0xa006, 0x007c, 0x6013, - 0x0000, 0x2069, 0x7c8c, 0x6808, 0xa084, 0xff00, 0xa086, 0x0800, - 0x007c, 0x6004, 0xa0b2, 0x0030, 0x10c8, 0x12cd, 0xa1b6, 0x0013, - 0x00c0, 0x6e5d, 0x2008, 0x0079, 0x6e70, 0xa1b6, 0x0027, 0x0040, - 0x6e65, 0xa1b6, 0x0014, 0x10c0, 0x12cd, 0x2001, 0x0007, 0x1078, - 0x3802, 0x1078, 0x4c9d, 0x1078, 0x6bb6, 0x1078, 0x4d96, 0x007c, - 0x6ea0, 0x6ea2, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea2, 0x6eaa, 0x6f0d, - 0x6ed0, 0x6f0d, 0x6ee4, 0x6f0d, 0x6eaa, 0x6f0d, 0x6f05, 0x6f0d, - 0x6f05, 0x6f0d, 0x6f0d, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, - 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, - 0x6f0d, 0x6ea0, 0x6ea0, 0x6f0d, 0x6ea0, 0x6f0d, 0x6f0d, 0x6ea0, - 0x6ea0, 0x6ea0, 0x6ea0, 0x6f0d, 0x6f0d, 0x6ea0, 0x6f0d, 0x6f0d, - 0x1078, 0x12cd, 0x1078, 0x4c9d, 0x6003, 0x0002, 0x1078, 0x4d96, - 0x0078, 0x6f13, 0x0f7e, 0x2079, 0x7751, 0x7804, 0x0f7f, 0xd0ac, - 0x00c0, 0x6f0d, 0x2001, 0x0000, 0x1078, 0x37e0, 0x2001, 0x0002, - 0x1078, 0x37f4, 0x1078, 0x4c9d, 0x601f, 0x0001, 0x6003, 0x0001, - 0x6007, 0x0002, 0x1078, 0x498e, 0x1078, 0x4d96, 0x0c7e, 0x6118, - 0x2160, 0x2009, 0x0001, 0x1078, 0x4696, 0x0c7f, 0x0078, 0x6f13, - 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, 0xff00, 0x8637, - 0xa686, 0x0006, 0x0040, 0x6f0d, 0xa686, 0x0004, 0x0040, 0x6f0d, - 0x2001, 0x0004, 0x0078, 0x6f0b, 0x2001, 0x7700, 0x2004, 0xa086, - 0x0003, 0x00c0, 0x6eed, 0x1078, 0x2dd7, 0x2001, 0x0006, 0x1078, - 0x6f14, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, 0xff00, - 0x8637, 0xa686, 0x0006, 0x0040, 0x6f0d, 0x2001, 0x0006, 0x0078, - 0x6f0b, 0x2001, 0x0004, 0x0078, 0x6f0b, 0x2001, 0x0006, 0x1078, - 0x6f14, 0x0078, 0x6f0d, 0x1078, 0x3802, 0x1078, 0x4c9d, 0x1078, - 0x5d1a, 0x1078, 0x4d96, 0x007c, 0x017e, 0x0d7e, 0x6118, 0x2168, - 0x6900, 0xd184, 0x0040, 0x6f2f, 0x6104, 0xa18e, 0x000a, 0x00c0, - 0x6f27, 0x699c, 0xd1a4, 0x00c0, 0x6f27, 0x2001, 0x0007, 0x1078, - 0x37f4, 0x2001, 0x0000, 0x1078, 0x37e0, 0x1078, 0x22d7, 0x0d7f, - 0x017f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084, 0xff00, - 0x8007, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x12cd, 0xa1b6, 0x0015, - 0x00c0, 0x6f46, 0x1079, 0x6f4d, 0x0078, 0x6f4c, 0xa1b6, 0x0016, - 0x10c0, 0x12cd, 0x1079, 0x6f85, 0x007c, 0x5ff7, 0x5ff7, 0x5ff7, - 0x5ff7, 0x5ff7, 0x5ff7, 0x5ff7, 0x6f59, 0x5ff7, 0x5ff7, 0x5ff7, - 0x5ff7, 0x0f7e, 0x2079, 0x7751, 0x7804, 0x0f7f, 0xd0ac, 0x00c0, - 0x6f75, 0x2001, 0x0000, 0x1078, 0x37e0, 0x2001, 0x0002, 0x1078, - 0x37f4, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, - 0x498e, 0x1078, 0x4d96, 0x0078, 0x6f84, 0x2011, 0x7c83, 0x220c, - 0x017e, 0x0c7e, 0x1078, 0x384c, 0x00c0, 0x6f84, 0x1078, 0x3637, - 0x0c7f, 0x017f, 0x1078, 0x5d1a, 0x007c, 0x5ff7, 0x5ff7, 0x5ff7, - 0x5ff7, 0x5ff7, 0x5ff7, 0x5ff7, 0x6f91, 0x5ff7, 0x5ff7, 0x5ff7, - 0x5ff7, 0x1078, 0x61e7, 0x00c0, 0x6f9d, 0x6003, 0x0001, 0x6007, - 0x0001, 0x1078, 0x498e, 0x0078, 0x6f9f, 0x1078, 0x5d1a, 0x007c, - 0x6004, 0xa08a, 0x0030, 0x10c8, 0x12cd, 0x1078, 0x4c9d, 0x1078, - 0x6bb6, 0x1078, 0x4d96, 0x007c, 0xa182, 0x0040, 0x0079, 0x6fb0, - 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc2, 0x6fc0, 0x6fc0, 0x6fc0, - 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, - 0x1078, 0x12cd, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e, 0x027e, - 0x6106, 0x2071, 0x7c80, 0x7444, 0xa4a4, 0xe600, 0x0040, 0x7026, - 0x2009, 0x0000, 0x0c7e, 0x1078, 0x4727, 0x2c68, 0x0c7f, 0x6a00, - 0xa284, 0x0001, 0x0040, 0x7091, 0x1078, 0x47e6, 0x0040, 0x70bc, - 0xa295, 0x0200, 0x6a02, 0x0078, 0x6feb, 0x2009, 0x0001, 0x2011, - 0x0200, 0x1078, 0x47d0, 0x1078, 0x1327, 0x1040, 0x12cd, 0x6003, - 0x0007, 0x2d00, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, - 0x6c5a, 0x2c00, 0x685e, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, - 0x694a, 0xa084, 0xff00, 0x6846, 0x684f, 0x0000, 0x6857, 0x0036, - 0x1078, 0x3b92, 0xa486, 0x2000, 0x00c0, 0x7014, 0x2019, 0x0017, - 0x1078, 0x75d9, 0x0078, 0x707e, 0xa486, 0x0400, 0x00c0, 0x701e, - 0x2019, 0x0002, 0x1078, 0x75d9, 0x0078, 0x707e, 0xa486, 0x0200, - 0x00c0, 0x7024, 0x1078, 0x75ca, 0x0078, 0x707e, 0x2009, 0x0000, - 0x0c7e, 0x1078, 0x4727, 0x2c68, 0x0c7f, 0x6a00, 0xa284, 0x0001, - 0x0040, 0x70d4, 0xa284, 0x0300, 0x00c0, 0x70cc, 0x6804, 0xa005, - 0x0040, 0x70bc, 0x8001, 0x6806, 0x6003, 0x0007, 0x1078, 0x130c, - 0x0040, 0x7085, 0x6013, 0x0000, 0x6803, 0x0000, 0x6837, 0x0116, - 0x683b, 0x0000, 0x2c00, 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007, - 0x7130, 0x6986, 0x6846, 0x6853, 0x003d, 0x7044, 0xa084, 0x0003, - 0xa086, 0x0002, 0x00c0, 0x7060, 0x684f, 0x0040, 0x0078, 0x706a, - 0xa086, 0x0001, 0x00c0, 0x7068, 0x684f, 0x0080, 0x0078, 0x706a, - 0x684f, 0x0000, 0x20a9, 0x000a, 0x2001, 0x7c90, 0xad90, 0x0015, - 0x200c, 0x810f, 0x2112, 0x8000, 0x8210, 0x00f0, 0x7070, 0x200c, - 0x6982, 0x8000, 0x200c, 0x697e, 0x1078, 0x3b92, 0x027f, 0x047f, - 0x157f, 0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x6013, 0x0100, 0x6003, - 0x0001, 0x6007, 0x0041, 0x1078, 0x4941, 0x1078, 0x4d96, 0x0078, - 0x707e, 0x2069, 0x7c92, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200, - 0x00c0, 0x70b0, 0x2069, 0x7c80, 0x686c, 0xa084, 0x00ff, 0x017e, - 0x6110, 0xa18c, 0x0700, 0xa10d, 0x6112, 0x017f, 0x6003, 0x0001, - 0x6007, 0x0043, 0x1078, 0x4941, 0x1078, 0x4d96, 0x0078, 0x707e, - 0x6013, 0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x4941, - 0x1078, 0x4d96, 0x0078, 0x707e, 0x6013, 0x0300, 0x0078, 0x70c2, - 0x6013, 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x4941, - 0x1078, 0x4d96, 0x0078, 0x707e, 0x6013, 0x0500, 0x0078, 0x70c2, - 0x6013, 0x0600, 0x0078, 0x7091, 0x6013, 0x0200, 0x0078, 0x7091, - 0xa186, 0x0013, 0x00c0, 0x70ea, 0x6004, 0xa08a, 0x0040, 0x1048, - 0x12cd, 0xa08a, 0x0050, 0x10c8, 0x12cd, 0xa082, 0x0040, 0x2008, - 0x0079, 0x711b, 0xa186, 0x0047, 0x00c0, 0x70f0, 0x0078, 0x714a, - 0xa186, 0x0027, 0x0040, 0x70f8, 0xa186, 0x0014, 0x10c0, 0x12cd, - 0x6004, 0xa082, 0x0040, 0x2008, 0x0079, 0x70fe, 0x710e, 0x7110, - 0x7110, 0x710e, 0x710e, 0x710e, 0x710e, 0x710e, 0x710e, 0x710e, - 0x710e, 0x710e, 0x710e, 0x710e, 0x710e, 0x710e, 0x1078, 0x12cd, - 0x2001, 0x0007, 0x1078, 0x3802, 0x1078, 0x4c9d, 0x1078, 0x6bb6, - 0x1078, 0x4d96, 0x007c, 0x712b, 0x713b, 0x7134, 0x7144, 0x712b, - 0x712b, 0x712b, 0x712b, 0x712b, 0x712b, 0x712b, 0x712b, 0x712b, - 0x712b, 0x712b, 0x712b, 0x1078, 0x12cd, 0x6010, 0xa088, 0x0013, - 0x2104, 0xa085, 0x0400, 0x200a, 0x1078, 0x4c9d, 0x6003, 0x0002, - 0x1078, 0x4d96, 0x007c, 0x1078, 0x4c9d, 0x1078, 0x47a8, 0x1078, - 0x5d1a, 0x1078, 0x4d96, 0x007c, 0x1078, 0x4c9d, 0x2009, 0x0041, - 0x0078, 0x7212, 0xa182, 0x0040, 0x0079, 0x714e, 0x715e, 0x7160, - 0x715e, 0x715e, 0x715e, 0x715e, 0x715e, 0x7161, 0x715e, 0x715e, - 0x715e, 0x715e, 0x715e, 0x715e, 0x715e, 0x715e, 0x1078, 0x12cd, - 0x007c, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, - 0x2c10, 0x1078, 0x156a, 0x007c, 0xa182, 0x0040, 0x0079, 0x7170, - 0x7180, 0x7180, 0x7180, 0x7180, 0x7180, 0x7180, 0x7180, 0x7180, - 0x7180, 0x7182, 0x71a5, 0x7180, 0x7180, 0x7180, 0x7180, 0x71a5, - 0x1078, 0x12cd, 0x1078, 0x4d45, 0x1078, 0x4e56, 0x6010, 0x0d7e, - 0x2068, 0x684c, 0xd0fc, 0x0040, 0x7198, 0xa08c, 0x0003, 0xa18e, - 0x0002, 0x0040, 0x719e, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x7212, - 0x6003, 0x0007, 0x1078, 0x47a8, 0x0d7f, 0x007c, 0x1078, 0x47a8, - 0x1078, 0x5d1a, 0x0d7f, 0x0078, 0x719d, 0x037e, 0x1078, 0x4d45, - 0x1078, 0x4e56, 0x6010, 0x0d7e, 0x2068, 0x2019, 0x0004, 0x1078, - 0x75fd, 0x1078, 0x6bb6, 0x6017, 0x0028, 0x0d7f, 0x037f, 0x007c, - 0xa186, 0x0013, 0x00c0, 0x71c6, 0x6004, 0xa086, 0x0042, 0x10c0, - 0x12cd, 0x1078, 0x4c9d, 0x1078, 0x4d96, 0x007c, 0xa186, 0x0027, - 0x0040, 0x71ce, 0xa186, 0x0014, 0x00c0, 0x71de, 0x6004, 0xa086, - 0x0042, 0x10c0, 0x12cd, 0x2001, 0x0007, 0x1078, 0x3802, 0x1078, - 0x4c9d, 0x1078, 0x6bb6, 0x1078, 0x4d96, 0x007c, 0xa182, 0x0040, - 0x0079, 0x71e2, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2, - 0x71f2, 0x71f4, 0x7200, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2, - 0x71f2, 0x71f2, 0x1078, 0x12cd, 0x037e, 0x047e, 0x20e1, 0x0005, - 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x156a, 0x047f, 0x037f, 0x007c, - 0x6010, 0x0d7e, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x720c, 0x2009, - 0x0041, 0x0d7f, 0x0078, 0x7212, 0x6003, 0x0007, 0x1078, 0x47a8, - 0x0d7f, 0x007c, 0xa182, 0x0040, 0x0079, 0x7216, 0x7226, 0x7228, - 0x7234, 0x7240, 0x7226, 0x7226, 0x7226, 0x7226, 0x7226, 0x7226, - 0x7226, 0x7226, 0x7226, 0x7226, 0x7226, 0x7226, 0x1078, 0x12cd, - 0x6003, 0x0001, 0x6106, 0x1078, 0x4941, 0x127e, 0x2091, 0x8000, - 0x1078, 0x4d96, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078, - 0x4941, 0x127e, 0x2091, 0x8000, 0x1078, 0x4d96, 0x127f, 0x007c, - 0x6003, 0x0003, 0x6106, 0x2c10, 0x1078, 0x19c7, 0x127e, 0x2091, - 0x8000, 0x1078, 0x49ad, 0x1078, 0x4e56, 0x127f, 0x007c, 0x1078, - 0x4c9d, 0x0078, 0x7255, 0x1078, 0x4d45, 0x6110, 0x81ff, 0x0040, - 0x7262, 0x0d7e, 0x2168, 0x037e, 0x2019, 0x0029, 0x1078, 0x75fd, - 0x037f, 0x0d7f, 0x1078, 0x6bb6, 0x1078, 0x4d96, 0x007c, 0xa182, - 0x0085, 0x0079, 0x726b, 0x7272, 0x7272, 0x7272, 0x7274, 0x7272, - 0x7272, 0x7272, 0x1078, 0x12cd, 0x027e, 0x0e7e, 0x2071, 0x7c80, - 0x7220, 0x1078, 0x7517, 0x0040, 0x7281, 0x6007, 0x0086, 0x0078, - 0x7283, 0x6007, 0x0087, 0x6003, 0x0001, 0x1078, 0x4941, 0x1078, - 0x4d96, 0x0e7f, 0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x729d, - 0x6004, 0xa08a, 0x0085, 0x1048, 0x12cd, 0xa08a, 0x008c, 0x10c8, - 0x12cd, 0xa082, 0x0085, 0x0079, 0x72b0, 0xa186, 0x0027, 0x0040, - 0x72a5, 0xa186, 0x0014, 0x10c0, 0x12cd, 0x2001, 0x0007, 0x1078, - 0x3802, 0x1078, 0x4c9d, 0x1078, 0x6bb6, 0x1078, 0x4d96, 0x007c, - 0x72b7, 0x72b9, 0x72b9, 0x72b7, 0x72b7, 0x72b7, 0x72b7, 0x1078, - 0x12cd, 0x1078, 0x4c9d, 0x1078, 0x5d1a, 0x1078, 0x4d96, 0x007c, - 0xa182, 0x0085, 0x1048, 0x12cd, 0xa182, 0x008c, 0x10c8, 0x12cd, - 0xa182, 0x0085, 0x0079, 0x72cc, 0x72d3, 0x72d3, 0x72d3, 0x72d5, - 0x72d3, 0x72d3, 0x72d3, 0x1078, 0x12cd, 0x007c, 0x1078, 0x4c9d, - 0x1078, 0x6bb6, 0x1078, 0x4d96, 0x007c, 0x037e, 0x2019, 0x000b, - 0x1078, 0x72e6, 0x601f, 0x0006, 0x037f, 0x007c, 0x127e, 0x037e, - 0x087e, 0x2091, 0x8000, 0x2c40, 0x1078, 0x5a2d, 0x00c0, 0x7313, - 0x1078, 0x5ace, 0x00c0, 0x7313, 0x6000, 0xa086, 0x0000, 0x0040, - 0x7313, 0x601c, 0xa086, 0x0007, 0x0040, 0x7313, 0x0d7e, 0x6000, - 0xa086, 0x0004, 0x00c0, 0x7306, 0x1078, 0x166e, 0x6010, 0x2068, - 0x1078, 0x6a58, 0x0040, 0x730e, 0x1078, 0x75fd, 0x0d7f, 0x6013, + 0x7be1, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0004, 0x0040, 0x7bb4, + 0xa686, 0x0006, 0x00c0, 0x7b7c, 0x1078, 0x847b, 0x00c0, 0x7bbc, + 0x6007, 0x000e, 0x0078, 0x7c5e, 0x047e, 0x6418, 0xa4a0, 0x0028, + 0x2424, 0xa4a4, 0x00ff, 0x8427, 0x047e, 0x1078, 0x24bf, 0x047f, + 0x017e, 0xa006, 0x2009, 0x8852, 0x210c, 0xd1a4, 0x0040, 0x7bdb, + 0x2009, 0x0029, 0x1078, 0x86f5, 0x6018, 0x0d7e, 0x2068, 0x6800, + 0xc0e5, 0x6802, 0x0d7f, 0x017f, 0x047f, 0x6007, 0x0001, 0x0078, + 0x7c5e, 0x1078, 0x85aa, 0x0040, 0x7bee, 0xa6b4, 0xff00, 0x8637, + 0xa686, 0x0006, 0x0040, 0x7bb4, 0x0078, 0x7b7c, 0x6013, 0x1900, + 0x6007, 0x0009, 0x0078, 0x7c5e, 0x1078, 0x42a2, 0x6618, 0xa6b0, + 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x7c3c, + 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0004, 0x0040, 0x7c0b, 0xa686, + 0x0006, 0x00c0, 0x7b7c, 0x1078, 0x84a6, 0x00c0, 0x7c17, 0x1078, + 0x83a4, 0x00c0, 0x7c17, 0x6007, 0x0010, 0x0078, 0x7c5e, 0x047e, + 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427, 0x047e, + 0x1078, 0x24bf, 0x047f, 0x017e, 0xa006, 0x2009, 0x8852, 0x210c, + 0xd1a4, 0x0040, 0x7c36, 0x2009, 0x0029, 0x1078, 0x86f5, 0x6018, + 0x0d7e, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x0d7f, 0x017f, 0x047f, + 0x6007, 0x0001, 0x0078, 0x7c5e, 0x1078, 0x85aa, 0x0040, 0x7c49, + 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x7c0b, 0x0078, + 0x7b7c, 0x6013, 0x1900, 0x6007, 0x0009, 0x0078, 0x7c5e, 0x7030, + 0xa086, 0x6000, 0x0040, 0x7c5c, 0x1078, 0x8727, 0x00c0, 0x7cd3, + 0x1078, 0x7cd6, 0x00c0, 0x7b7c, 0x6007, 0x0012, 0x6003, 0x0001, + 0x1078, 0x53e6, 0x007c, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, + 0x53e6, 0x0078, 0x7c62, 0x6007, 0x0005, 0x0078, 0x7c65, 0x1078, + 0x8727, 0x00c0, 0x7cd3, 0x1078, 0x7cd6, 0x00c0, 0x7b7c, 0x6007, + 0x0020, 0x6003, 0x0001, 0x1078, 0x53e6, 0x007c, 0x6007, 0x0023, + 0x6003, 0x0001, 0x1078, 0x53e6, 0x007c, 0x1078, 0x8727, 0x00c0, + 0x7cd3, 0x1078, 0x7cd6, 0x00c0, 0x7b7c, 0x017e, 0x027e, 0x2011, + 0x8d90, 0x2214, 0x2c08, 0x1078, 0x86c1, 0x00c0, 0x7ca7, 0x2160, + 0x6007, 0x0026, 0x6013, 0x1700, 0x2011, 0x8d89, 0x2214, 0xa296, + 0xffff, 0x00c0, 0x7cac, 0x6007, 0x0025, 0x0078, 0x7cac, 0x1078, + 0x690e, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x1078, 0x53e6, + 0x027f, 0x017f, 0x007c, 0x6106, 0x1078, 0x7ce9, 0x6007, 0x002b, + 0x0078, 0x7c5e, 0x6007, 0x002c, 0x0078, 0x7c5e, 0x1078, 0x8727, + 0x00c0, 0x7cd3, 0x1078, 0x7cd6, 0x00c0, 0x7b7c, 0x6106, 0x1078, + 0x7cee, 0x00c0, 0x7ccf, 0x6007, 0x002e, 0x0078, 0x7c5e, 0x6007, + 0x002f, 0x0078, 0x7c5e, 0x1078, 0x690e, 0x007c, 0x0d7e, 0x6618, + 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, + 0x7ce7, 0xa686, 0x0004, 0x0040, 0x7ce7, 0xa085, 0x0001, 0x0d7f, + 0x007c, 0x0d7e, 0x1078, 0x7d1b, 0x0d7f, 0x007c, 0x0d7e, 0x1078, + 0x7d2a, 0x00c0, 0x7d14, 0x680c, 0xa08c, 0xff00, 0x6824, 0xa084, + 0x00ff, 0xa115, 0x6212, 0xd1e4, 0x0040, 0x7d02, 0x2009, 0x0001, + 0x0078, 0x7d10, 0xd1ec, 0x0040, 0x7d14, 0x6920, 0xa18c, 0x00ff, + 0x6824, 0x1078, 0x2245, 0x00c0, 0x7d14, 0x2110, 0x2009, 0x0000, + 0x1078, 0x2507, 0x0078, 0x7d18, 0xa085, 0x0001, 0x0078, 0x7d19, + 0xa006, 0x0d7f, 0x007c, 0x2069, 0x8d8d, 0x6800, 0xa082, 0x0010, + 0x00c8, 0x7d28, 0x6013, 0x0000, 0xa085, 0x0001, 0x0078, 0x7d29, + 0xa006, 0x007c, 0x6013, 0x0000, 0x2069, 0x8d8c, 0x6808, 0xa084, + 0xff00, 0xa086, 0x0800, 0x007c, 0x6004, 0xa0b2, 0x0040, 0x10c8, + 0x12d2, 0xa1b6, 0x0013, 0x00c0, 0x7d40, 0x2008, 0x0079, 0x7d53, + 0xa1b6, 0x0027, 0x0040, 0x7d48, 0xa1b6, 0x0014, 0x10c0, 0x12d2, + 0x2001, 0x0007, 0x1078, 0x3f2c, 0x1078, 0x578f, 0x1078, 0x79a8, + 0x1078, 0x5888, 0x007c, 0x7d93, 0x7d95, 0x7d93, 0x7d93, 0x7d93, + 0x7d95, 0x7d9d, 0x7e08, 0x7dcb, 0x7e08, 0x7ddf, 0x7e08, 0x7d9d, + 0x7e08, 0x7e00, 0x7e08, 0x7e00, 0x7e08, 0x7e08, 0x7d93, 0x7d93, + 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93, + 0x7d93, 0x7d93, 0x7d93, 0x7e08, 0x7d93, 0x7d93, 0x7e08, 0x7d93, + 0x7e08, 0x7e08, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7e08, 0x7e08, + 0x7d93, 0x7e08, 0x7e08, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93, + 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93, + 0x7d93, 0x7d93, 0x7d93, 0x1078, 0x12d2, 0x1078, 0x578f, 0x6003, + 0x0002, 0x1078, 0x5888, 0x0078, 0x7e0e, 0x0f7e, 0x2079, 0x8851, + 0x7804, 0x0f7f, 0xd0ac, 0x00c0, 0x7e08, 0x2001, 0x0000, 0x1078, + 0x3ef1, 0x6018, 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x0040, + 0x7e08, 0x2001, 0x0002, 0x1078, 0x3f05, 0x1078, 0x578f, 0x601f, + 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x53e6, 0x1078, + 0x5888, 0x0c7e, 0x6118, 0x2160, 0x2009, 0x0001, 0x1078, 0x50ff, + 0x0c7f, 0x0078, 0x7e0e, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, + 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x7e08, 0xa686, + 0x0004, 0x0040, 0x7e08, 0x2001, 0x0004, 0x0078, 0x7e06, 0x2001, + 0x8800, 0x2004, 0xa086, 0x0003, 0x00c0, 0x7de8, 0x1078, 0x31f8, + 0x2001, 0x0006, 0x1078, 0x7e0f, 0x6618, 0x0d7e, 0x2668, 0x6e04, + 0x0d7f, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x7e08, + 0x2001, 0x0006, 0x0078, 0x7e06, 0x2001, 0x0004, 0x0078, 0x7e06, + 0x2001, 0x0006, 0x1078, 0x7e0f, 0x0078, 0x7e08, 0x1078, 0x3f2c, + 0x1078, 0x578f, 0x1078, 0x690e, 0x1078, 0x5888, 0x007c, 0x017e, + 0x0d7e, 0x6118, 0x2168, 0x6900, 0xd184, 0x0040, 0x7e2a, 0x6104, + 0xa18e, 0x000a, 0x00c0, 0x7e22, 0x699c, 0xd1a4, 0x00c0, 0x7e22, + 0x2001, 0x0007, 0x1078, 0x3f05, 0x2001, 0x0000, 0x1078, 0x3ef1, + 0x1078, 0x24e5, 0x0d7f, 0x017f, 0x007c, 0x0d7e, 0x6618, 0x2668, + 0x6804, 0xa084, 0xff00, 0x8007, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, + 0x12d2, 0xa1b6, 0x0015, 0x00c0, 0x7e41, 0x1079, 0x7e48, 0x0078, + 0x7e47, 0xa1b6, 0x0016, 0x10c0, 0x12d2, 0x1079, 0x7e89, 0x007c, + 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x7e54, + 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x0f7e, 0x2079, 0x8851, 0x7804, + 0x0f7f, 0xd0ac, 0x00c0, 0x7e70, 0x2001, 0x0000, 0x1078, 0x3ef1, + 0x2001, 0x0002, 0x1078, 0x3f05, 0x601f, 0x0001, 0x6003, 0x0001, + 0x6007, 0x0002, 0x1078, 0x53e6, 0x1078, 0x5888, 0x0078, 0x7e88, + 0x2011, 0x8d83, 0x2204, 0x8211, 0x220c, 0x1078, 0x2245, 0x00c0, + 0x7e88, 0x0c7e, 0x1078, 0x3f8e, 0x0040, 0x7e83, 0x0c7f, 0x1078, + 0x690e, 0x0078, 0x7e88, 0x1078, 0x3d31, 0x0c7f, 0x1078, 0x690e, + 0x007c, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, + 0x7e95, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x1078, 0x6e76, 0x00c0, + 0x7ea1, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x53e6, 0x0078, + 0x7ea3, 0x1078, 0x690e, 0x007c, 0x6004, 0xa08a, 0x0040, 0x10c8, + 0x12d2, 0x1078, 0x578f, 0x1078, 0x79a8, 0x1078, 0x5888, 0x007c, + 0xa182, 0x0040, 0x0079, 0x7eb4, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, + 0x7ec9, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, + 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, 0x1078, + 0x12d2, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e, 0x027e, 0x6106, + 0x2071, 0x8d80, 0x7444, 0xa4a4, 0xff00, 0x0040, 0x7f3e, 0xa486, + 0x2000, 0x0040, 0x7ef3, 0xa486, 0x0400, 0x0040, 0x7ef3, 0xa486, + 0x1000, 0x0040, 0x7ee5, 0x0078, 0x7ef9, 0x2069, 0x8b24, 0x6a00, + 0xd284, 0x0040, 0x7fab, 0x1078, 0x5253, 0x0040, 0x7fd6, 0xc2cd, + 0x6a02, 0x0078, 0x7ef9, 0x2009, 0x0001, 0x2011, 0x0200, 0x1078, + 0x5243, 0x1078, 0x132b, 0x1040, 0x12d2, 0x6003, 0x0007, 0x2d00, + 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, + 0x685e, 0x6008, 0x68b2, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, + 0x694a, 0x017e, 0xa084, 0xff00, 0x6846, 0x684f, 0x0000, 0x6857, + 0x0036, 0x1078, 0x4376, 0x017f, 0xa486, 0x2000, 0x00c0, 0x7f26, + 0x2019, 0x0017, 0x1078, 0x8683, 0x0078, 0x7f98, 0xa486, 0x0400, + 0x00c0, 0x7f30, 0x2019, 0x0002, 0x1078, 0x8644, 0x0078, 0x7f98, + 0xa486, 0x0200, 0x00c0, 0x7f36, 0x1078, 0x8631, 0xa486, 0x1000, + 0x00c0, 0x7f3c, 0x1078, 0x8670, 0x0078, 0x7f98, 0x2069, 0x8b24, + 0x6a00, 0xd284, 0x0040, 0x7fee, 0xa284, 0x0300, 0x00c0, 0x7fe6, + 0x6804, 0xa005, 0x0040, 0x7fd6, 0x2d78, 0x6003, 0x0007, 0x1078, + 0x1310, 0x0040, 0x7f9f, 0x7800, 0xd08c, 0x00c0, 0x7f5a, 0x7804, + 0x8001, 0x7806, 0x6013, 0x0000, 0x6803, 0x0000, 0x6837, 0x0116, + 0x683b, 0x0000, 0x6008, 0x68b2, 0x2c00, 0x684a, 0x6018, 0x2078, + 0x78a0, 0x8007, 0x7130, 0x6986, 0x6846, 0x6853, 0x003d, 0x7244, + 0xa294, 0x0003, 0xa286, 0x0002, 0x00c0, 0x7f7a, 0x684f, 0x0040, + 0x0078, 0x7f84, 0xa286, 0x0001, 0x00c0, 0x7f82, 0x684f, 0x0080, + 0x0078, 0x7f84, 0x684f, 0x0000, 0x20a9, 0x000a, 0x2001, 0x8d90, + 0xad90, 0x0015, 0x200c, 0x810f, 0x2112, 0x8000, 0x8210, 0x00f0, + 0x7f8a, 0x200c, 0x6982, 0x8000, 0x200c, 0x697e, 0x1078, 0x4376, + 0x027f, 0x047f, 0x157f, 0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x6013, + 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x5399, 0x1078, + 0x5888, 0x0078, 0x7f98, 0x2069, 0x8d92, 0x2d04, 0xa084, 0xff00, + 0xa086, 0x1200, 0x00c0, 0x7fca, 0x2069, 0x8d80, 0x686c, 0xa084, + 0x00ff, 0x017e, 0x6110, 0xa18c, 0x0700, 0xa10d, 0x6112, 0x017f, + 0x6003, 0x0001, 0x6007, 0x0043, 0x1078, 0x5399, 0x1078, 0x5888, + 0x0078, 0x7f98, 0x6013, 0x0200, 0x6003, 0x0001, 0x6007, 0x0041, + 0x1078, 0x5399, 0x1078, 0x5888, 0x0078, 0x7f98, 0x6013, 0x0300, + 0x0078, 0x7fdc, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, + 0x1078, 0x5399, 0x1078, 0x5888, 0x0078, 0x7f98, 0x6013, 0x0500, + 0x0078, 0x7fdc, 0x6013, 0x0600, 0x0078, 0x7fab, 0x6013, 0x0200, + 0x0078, 0x7fab, 0xa186, 0x0013, 0x00c0, 0x8004, 0x6004, 0xa08a, + 0x0040, 0x1048, 0x12d2, 0xa08a, 0x0053, 0x10c8, 0x12d2, 0xa082, + 0x0040, 0x2008, 0x0079, 0x806b, 0xa186, 0x0047, 0x00c0, 0x8026, + 0x6004, 0xa086, 0x0041, 0x0040, 0x8034, 0x2001, 0x0109, 0x2004, + 0xd084, 0x0040, 0x8034, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, + 0x027e, 0x1078, 0x5273, 0x027f, 0x017f, 0x007f, 0x127f, 0x6000, + 0xa086, 0x0002, 0x00c0, 0x8034, 0x0078, 0x80ac, 0xa186, 0x0027, + 0x0040, 0x802e, 0xa186, 0x0014, 0x10c0, 0x12d2, 0x6004, 0xa082, + 0x0040, 0x2008, 0x0079, 0x8037, 0x1078, 0x6950, 0x007c, 0x804a, + 0x804c, 0x804c, 0x804a, 0x804a, 0x804a, 0x804a, 0x804a, 0x804a, + 0x804a, 0x804a, 0x804a, 0x804a, 0x804a, 0x804a, 0x804a, 0x804a, + 0x804a, 0x804a, 0x1078, 0x12d2, 0x1078, 0x578f, 0x1078, 0x5888, + 0x037e, 0x0d7e, 0x6010, 0xa06d, 0x0040, 0x8068, 0xad84, 0xf000, + 0x0040, 0x8068, 0x2019, 0x0004, 0x1078, 0x86aa, 0x6013, 0x0000, + 0x6014, 0xa005, 0x00c0, 0x8066, 0x6017, 0x0014, 0x6003, 0x0007, + 0x0d7f, 0x037f, 0x007c, 0x807e, 0x809d, 0x8087, 0x80a6, 0x807e, + 0x807e, 0x807e, 0x807e, 0x807e, 0x807e, 0x807e, 0x807e, 0x807e, + 0x807e, 0x807e, 0x807e, 0x807e, 0x807e, 0x807e, 0x1078, 0x12d2, + 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x1078, + 0x578f, 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4, 0x0040, 0x8098, + 0x6003, 0x0007, 0x2009, 0x0043, 0x1078, 0x6939, 0x0078, 0x809a, + 0x6003, 0x0002, 0x1078, 0x5888, 0x007c, 0x1078, 0x578f, 0x1078, + 0x5219, 0x1078, 0x690e, 0x1078, 0x5888, 0x007c, 0x1078, 0x578f, + 0x2009, 0x0041, 0x0078, 0x819b, 0xa182, 0x0040, 0x0079, 0x80b0, + 0x80c3, 0x80c5, 0x80c3, 0x80c3, 0x80c3, 0x80c3, 0x80c3, 0x80c6, + 0x80c3, 0x80c3, 0x80c3, 0x80c3, 0x80c3, 0x80c3, 0x80c3, 0x80c3, + 0x80c3, 0x80c3, 0x80c3, 0x1078, 0x12d2, 0x007c, 0x6003, 0x0004, + 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x1594, + 0x007c, 0xa182, 0x0040, 0x0079, 0x80d5, 0x80e8, 0x80e8, 0x80e8, + 0x80e8, 0x80e8, 0x80e8, 0x80e8, 0x80e8, 0x80e8, 0x80ea, 0x810d, + 0x80e8, 0x80e8, 0x80e8, 0x80e8, 0x810d, 0x80e8, 0x80e8, 0x80e8, + 0x1078, 0x12d2, 0x1078, 0x5837, 0x1078, 0x5948, 0x6010, 0x0d7e, + 0x2068, 0x684c, 0xd0fc, 0x0040, 0x8100, 0xa08c, 0x0003, 0xa18e, + 0x0002, 0x0040, 0x8106, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x819b, + 0x6003, 0x0007, 0x1078, 0x5219, 0x0d7f, 0x007c, 0x1078, 0x5219, + 0x1078, 0x690e, 0x0d7f, 0x0078, 0x8105, 0x037e, 0x1078, 0x5837, + 0x1078, 0x5948, 0x6010, 0x0d7e, 0x2068, 0x2019, 0x0004, 0x1078, + 0x86aa, 0x1078, 0x79a8, 0x6017, 0x0028, 0x0d7f, 0x037f, 0x007c, + 0xa186, 0x0013, 0x00c0, 0x812e, 0x6004, 0xa086, 0x0042, 0x10c0, + 0x12d2, 0x1078, 0x578f, 0x1078, 0x5888, 0x007c, 0xa186, 0x0027, + 0x0040, 0x8136, 0xa186, 0x0014, 0x00c0, 0x8146, 0x6004, 0xa086, + 0x0042, 0x10c0, 0x12d2, 0x2001, 0x0007, 0x1078, 0x3f2c, 0x1078, + 0x578f, 0x1078, 0x79a8, 0x1078, 0x5888, 0x007c, 0xa182, 0x0040, + 0x0079, 0x814a, 0x815d, 0x815d, 0x815d, 0x815d, 0x815d, 0x815d, + 0x815d, 0x815f, 0x816b, 0x815d, 0x815d, 0x815d, 0x815d, 0x815d, + 0x815d, 0x815d, 0x815d, 0x815d, 0x815d, 0x1078, 0x12d2, 0x037e, + 0x047e, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x1594, + 0x047f, 0x037f, 0x007c, 0x6010, 0x0d7e, 0x2068, 0x6810, 0x6a14, + 0xa20d, 0x00c0, 0x8182, 0x684c, 0xd0fc, 0x0040, 0x817c, 0x2009, + 0x0041, 0x0d7f, 0x0078, 0x819b, 0x6003, 0x0007, 0x1078, 0x5219, + 0x0d7f, 0x007c, 0x6003, 0x0006, 0x1078, 0x818a, 0x1078, 0x521b, + 0x0d7f, 0x007c, 0xd2fc, 0x0040, 0x8196, 0x8002, 0x8000, 0x8212, + 0xa291, 0x0000, 0x2009, 0x0009, 0x0078, 0x8198, 0x2009, 0x0015, + 0x6a6a, 0x6866, 0x007c, 0xa182, 0x0040, 0x0079, 0x819f, 0x81b2, + 0x81b4, 0x81c0, 0x81cc, 0x81b2, 0x81b2, 0x81b2, 0x81db, 0x81b2, + 0x81b2, 0x81b2, 0x81b2, 0x81b2, 0x81b2, 0x81b2, 0x81b2, 0x81b2, + 0x81b2, 0x81b2, 0x1078, 0x12d2, 0x6003, 0x0001, 0x6106, 0x1078, + 0x5399, 0x127e, 0x2091, 0x8000, 0x1078, 0x5888, 0x127f, 0x007c, + 0x6003, 0x0001, 0x6106, 0x1078, 0x5399, 0x127e, 0x2091, 0x8000, + 0x1078, 0x5888, 0x127f, 0x007c, 0x6003, 0x0003, 0x6106, 0x2c10, + 0x1078, 0x1b07, 0x127e, 0x2091, 0x8000, 0x1078, 0x5405, 0x1078, + 0x5948, 0x127f, 0x007c, 0xa016, 0x1078, 0x1594, 0x007c, 0x127e, + 0x2091, 0x8000, 0x037e, 0x0d7e, 0xa182, 0x0040, 0x1079, 0x81ec, + 0x0d7f, 0x037f, 0x127f, 0x007c, 0x81fc, 0x81fe, 0x8213, 0x8232, + 0x81fc, 0x81fc, 0x81fc, 0x824a, 0x81fc, 0x81fc, 0x81fc, 0x81fc, + 0x81fc, 0x81fc, 0x81fc, 0x81fc, 0x1078, 0x12d2, 0x6010, 0x2068, + 0x684c, 0xd0fc, 0x0040, 0x8228, 0xa09c, 0x0003, 0xa39e, 0x0003, + 0x0040, 0x8228, 0x6003, 0x0001, 0x6106, 0x1078, 0x5399, 0x1078, + 0x5888, 0x0078, 0x824d, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, + 0x8228, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040, 0x8228, 0x6003, + 0x0001, 0x6106, 0x1078, 0x5399, 0x1078, 0x5888, 0x0078, 0x824d, + 0x6013, 0x0000, 0x6017, 0x0000, 0x2019, 0x0004, 0x1078, 0x86aa, + 0x0078, 0x824d, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x8228, + 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040, 0x8228, 0x6003, 0x0003, + 0x6106, 0x2c10, 0x1078, 0x1b07, 0x1078, 0x5405, 0x1078, 0x5948, + 0x0078, 0x824d, 0xa016, 0x1078, 0x1594, 0x007c, 0x1078, 0x578f, + 0x6110, 0x81ff, 0x0040, 0x825d, 0x0d7e, 0x2168, 0x037e, 0x2019, + 0x0029, 0x1078, 0x86aa, 0x037f, 0x0d7f, 0x1078, 0x79a8, 0x1078, + 0x5888, 0x007c, 0x1078, 0x5837, 0x6110, 0x81ff, 0x0040, 0x8271, + 0x0d7e, 0x2168, 0x037e, 0x2019, 0x0029, 0x1078, 0x86aa, 0x037f, + 0x0d7f, 0x1078, 0x79a8, 0x1078, 0x5948, 0x007c, 0xa182, 0x0085, + 0x0079, 0x827a, 0x8281, 0x8281, 0x8281, 0x8283, 0x8281, 0x8281, + 0x8281, 0x1078, 0x12d2, 0x027e, 0x0e7e, 0x1078, 0x8727, 0x0040, + 0x828d, 0x1078, 0x690e, 0x0078, 0x82a9, 0x2071, 0x8d80, 0x7224, + 0x6212, 0x7220, 0x1078, 0x8575, 0x0040, 0x829a, 0x6007, 0x0086, + 0x0078, 0x82a3, 0x6007, 0x0087, 0x7224, 0xa296, 0xffff, 0x00c0, + 0x82a3, 0x6007, 0x0086, 0x6003, 0x0001, 0x1078, 0x5399, 0x1078, + 0x5888, 0x0e7f, 0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x82bd, + 0x6004, 0xa08a, 0x0085, 0x1048, 0x12d2, 0xa08a, 0x008c, 0x10c8, + 0x12d2, 0xa082, 0x0085, 0x0079, 0x82d4, 0xa186, 0x0027, 0x0040, + 0x82c9, 0xa186, 0x0014, 0x0040, 0x82c9, 0x1078, 0x6950, 0x0078, + 0x82d3, 0x2001, 0x0007, 0x1078, 0x3f2c, 0x1078, 0x578f, 0x1078, + 0x79a8, 0x1078, 0x5888, 0x007c, 0x82db, 0x82dd, 0x82dd, 0x82db, + 0x82db, 0x82db, 0x82db, 0x1078, 0x12d2, 0x1078, 0x578f, 0x1078, + 0x690e, 0x1078, 0x5888, 0x007c, 0xa182, 0x0085, 0x1048, 0x12d2, + 0xa182, 0x008c, 0x10c8, 0x12d2, 0xa182, 0x0085, 0x0079, 0x82f0, + 0x82f7, 0x82f7, 0x82f7, 0x82f9, 0x82f7, 0x82f7, 0x82f7, 0x1078, + 0x12d2, 0x007c, 0xa186, 0x0013, 0x0040, 0x830a, 0xa186, 0x0014, + 0x0040, 0x830a, 0xa186, 0x0027, 0x0040, 0x830a, 0x1078, 0x6950, + 0x0078, 0x8310, 0x1078, 0x578f, 0x1078, 0x79a8, 0x1078, 0x5888, + 0x007c, 0x037e, 0x2019, 0x000b, 0x1078, 0x831c, 0x601f, 0x0006, + 0x6003, 0x0007, 0x037f, 0x007c, 0x127e, 0x037e, 0x087e, 0x2091, + 0x8000, 0x2c40, 0x1078, 0x6614, 0x00c0, 0x834b, 0x1078, 0x66be, + 0x00c0, 0x834b, 0x6000, 0xa086, 0x0000, 0x0040, 0x834b, 0x601c, + 0xa086, 0x0007, 0x0040, 0x834b, 0x0d7e, 0x6000, 0xa086, 0x0004, + 0x00c0, 0x833e, 0x601f, 0x0007, 0x1078, 0x16af, 0x6010, 0x2068, + 0x1078, 0x77ed, 0x0040, 0x8346, 0x1078, 0x86aa, 0x0d7f, 0x6013, 0x0000, 0x601f, 0x0007, 0x087f, 0x037f, 0x127f, 0x007c, 0x0f7e, - 0x0c7e, 0x037e, 0x157e, 0x2079, 0x7c80, 0x7838, 0xa08c, 0x00ff, - 0x783c, 0x1078, 0x207f, 0x00c0, 0x734e, 0x017e, 0x0c7e, 0x1078, - 0x384c, 0x00c0, 0x734e, 0x2011, 0x7c90, 0xac98, 0x000a, 0x20a9, - 0x0004, 0x1078, 0x6280, 0x00c0, 0x734e, 0x017f, 0x027f, 0x027e, - 0x017e, 0x2019, 0x0029, 0x1078, 0x5ba2, 0x1078, 0x4a7e, 0x1078, - 0x49c1, 0x017f, 0x1078, 0x747b, 0x1078, 0x3a36, 0x017f, 0x1078, - 0x3637, 0x6612, 0x6516, 0xa006, 0x0078, 0x7350, 0x0c7f, 0x017f, - 0x157f, 0x037f, 0x0c7f, 0x0f7f, 0x007c, 0x0c7e, 0x0d7e, 0x017e, - 0x2009, 0x771e, 0x2104, 0xa086, 0x0074, 0x00c0, 0x73ac, 0x2069, - 0x7c8e, 0x690c, 0xa182, 0x0100, 0x0048, 0x739c, 0x6908, 0xa184, - 0x8000, 0x0040, 0x73a8, 0xa184, 0x0800, 0x0040, 0x73a8, 0x6910, - 0xa18a, 0x0001, 0x0048, 0x73a0, 0x6914, 0x2069, 0x7cae, 0x6904, - 0x81ff, 0x00c0, 0x7394, 0x690c, 0xa182, 0x0100, 0x0048, 0x739c, - 0x6908, 0x81ff, 0x00c0, 0x7398, 0x6910, 0xa18a, 0x0001, 0x0048, - 0x73a0, 0x6918, 0xa18a, 0x0001, 0x0048, 0x73a8, 0x0078, 0x73b2, - 0x6013, 0x0100, 0x0078, 0x73ae, 0x6013, 0x0300, 0x0078, 0x73ae, - 0x6013, 0x0500, 0x0078, 0x73ae, 0x6013, 0x0700, 0x0078, 0x73ae, - 0x6013, 0x0900, 0x0078, 0x73ae, 0x6013, 0x0b00, 0x0078, 0x73ae, - 0x6013, 0x0f00, 0x0078, 0x73ae, 0x6013, 0x2d00, 0xa085, 0x0001, - 0x0078, 0x73b3, 0xa006, 0x017f, 0x0d7f, 0x0c7f, 0x007c, 0x0c7e, - 0x0d7e, 0x027e, 0x037e, 0x157e, 0x6218, 0x2268, 0x6b04, 0xa394, - 0x00ff, 0xa286, 0x0006, 0x0040, 0x73db, 0xa286, 0x0004, 0x0040, - 0x73db, 0xa394, 0xff00, 0x8217, 0xa286, 0x0006, 0x0040, 0x73db, - 0xa286, 0x0004, 0x0040, 0x73db, 0x0c7e, 0x2d60, 0x1078, 0x385e, - 0x0c7f, 0x0078, 0x740e, 0x2011, 0x7c96, 0xad98, 0x000a, 0x20a9, - 0x0004, 0x1078, 0x6280, 0x00c0, 0x740f, 0x2011, 0x7c9a, 0xad98, - 0x0006, 0x20a9, 0x0004, 0x1078, 0x6280, 0x00c0, 0x740f, 0x047e, - 0x017e, 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0x7752, - 0x210c, 0xd1a4, 0x0040, 0x7403, 0x2009, 0x0029, 0x1078, 0x7641, - 0x6800, 0xc0e5, 0x6802, 0x2019, 0x0029, 0x1078, 0x4a7e, 0x1078, - 0x49c1, 0x2c08, 0x1078, 0x747b, 0x017f, 0x047f, 0xa006, 0x157f, - 0x037f, 0x027f, 0x0d7f, 0x0c7f, 0x007c, 0x0d7e, 0x2069, 0x7c8e, - 0x6800, 0xa086, 0x0800, 0x0040, 0x7421, 0x6013, 0x0000, 0x0078, - 0x7422, 0xa006, 0x0d7f, 0x007c, 0x0c7e, 0x0f7e, 0x017e, 0x027e, - 0x037e, 0x157e, 0x2079, 0x7c8c, 0x7930, 0x7834, 0x1078, 0x207f, - 0x00c0, 0x7448, 0x1078, 0x384c, 0x00c0, 0x7448, 0x2011, 0x7c90, - 0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x6280, 0x00c0, 0x7448, - 0x2011, 0x7c94, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078, 0x6280, - 0x157f, 0x037f, 0x027f, 0x017f, 0x0f7f, 0x0c7f, 0x007c, 0x0c7e, - 0x007e, 0x017e, 0x027e, 0x037e, 0x157e, 0x2011, 0x7c83, 0x2204, - 0x8211, 0x220c, 0x1078, 0x207f, 0x00c0, 0x7474, 0x1078, 0x384c, - 0x00c0, 0x7474, 0x2011, 0x7c96, 0xac98, 0x000a, 0x20a9, 0x0004, - 0x1078, 0x6280, 0x00c0, 0x7474, 0x2011, 0x7c9a, 0xac98, 0x0006, - 0x20a9, 0x0004, 0x1078, 0x6280, 0x157f, 0x037f, 0x027f, 0x017f, - 0x007f, 0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x057e, - 0x047e, 0x027e, 0x127e, 0x2091, 0x8000, 0x2029, 0x793f, 0x252c, - 0x2021, 0x7945, 0x2424, 0x2061, 0x7e00, 0x2071, 0x7700, 0x7644, - 0x7060, 0x8001, 0xa602, 0x00c8, 0x74e0, 0x2100, 0xac06, 0x0040, - 0x74d6, 0x1078, 0x7659, 0x0040, 0x74d6, 0x671c, 0xa786, 0x0001, - 0x0040, 0x74f5, 0xa786, 0x0007, 0x0040, 0x74d6, 0x2500, 0xac06, - 0x0040, 0x74d6, 0x2400, 0xac06, 0x0040, 0x74d6, 0x1078, 0x766d, - 0x00c0, 0x74d6, 0x0d7e, 0x6000, 0xa086, 0x0004, 0x00c0, 0x74bc, - 0x017e, 0x1078, 0x166e, 0x017f, 0x6010, 0x2068, 0x1078, 0x6a58, - 0x0040, 0x74d3, 0xa786, 0x0003, 0x00c0, 0x74e9, 0x6837, 0x0103, - 0x6b4a, 0x6847, 0x0000, 0x017e, 0x1078, 0x6c54, 0x1078, 0x3b92, - 0x017f, 0x1078, 0x6ba9, 0x0d7f, 0x1078, 0x6bb6, 0xace0, 0x0008, - 0x2001, 0x7715, 0x2004, 0xac02, 0x00c8, 0x74e0, 0x0078, 0x748d, - 0x127f, 0x027f, 0x047f, 0x057f, 0x067f, 0x077f, 0x0c7f, 0x0e7f, - 0x007c, 0xa786, 0x0006, 0x00c0, 0x74c6, 0xa386, 0x0005, 0x0040, - 0x74d6, 0x1078, 0x75fd, 0x0078, 0x74d3, 0x1078, 0x766d, 0x00c0, - 0x74d6, 0xa180, 0x0001, 0x2004, 0xa086, 0x0018, 0x00c0, 0x74d6, - 0x6000, 0xa086, 0x0002, 0x00c0, 0x74d6, 0x1078, 0x6bcf, 0x0040, - 0x7511, 0x1078, 0x6be3, 0x00c0, 0x74d6, 0x1078, 0x5f6d, 0x0078, - 0x7513, 0x1078, 0x22d7, 0x1078, 0x6bb6, 0x0078, 0x74d6, 0x0c7e, - 0x0e7e, 0x017e, 0x2c08, 0x2170, 0x1078, 0x7614, 0x017f, 0x0040, - 0x7526, 0x601c, 0xa084, 0x000f, 0x1079, 0x7529, 0x0e7f, 0x0c7f, - 0x007c, 0x7531, 0x7531, 0x7531, 0x7531, 0x7531, 0x7531, 0x7533, - 0x7531, 0xa006, 0x007c, 0x047e, 0x017e, 0x7018, 0xa080, 0x0028, - 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, 0x2009, 0x0020, 0x1078, - 0x7641, 0x017f, 0x047f, 0x037e, 0x2019, 0x0002, 0x1078, 0x72e6, - 0x037f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0001, 0x1078, 0x37e0, - 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019, 0x7705, - 0x2011, 0x7c96, 0x1078, 0x6280, 0x037f, 0x027f, 0x017f, 0x157f, - 0xa005, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x027e, - 0x127e, 0x2091, 0x8000, 0x2061, 0x7e00, 0x2079, 0x0001, 0x8fff, - 0x0040, 0x75bd, 0x2071, 0x7700, 0x7644, 0x7060, 0x8001, 0xa602, - 0x00c8, 0x75bd, 0x88ff, 0x0040, 0x7583, 0x2800, 0xac06, 0x00c0, - 0x75b3, 0x2079, 0x0000, 0x1078, 0x7659, 0x0040, 0x75b3, 0x2400, - 0xac06, 0x0040, 0x75b3, 0x671c, 0xa786, 0x0006, 0x00c0, 0x75b3, - 0xa786, 0x0007, 0x0040, 0x75b3, 0x88ff, 0x00c0, 0x759b, 0x6018, - 0xa206, 0x00c0, 0x75b3, 0x0d7e, 0x6000, 0xa086, 0x0004, 0x00c0, - 0x75a3, 0x1078, 0x166e, 0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, - 0x75ad, 0x047e, 0x1078, 0x75fd, 0x047f, 0x0d7f, 0x1078, 0x6bb6, - 0x88ff, 0x00c0, 0x75c6, 0xace0, 0x0008, 0x2001, 0x7715, 0x2004, - 0xac02, 0x00c8, 0x75bd, 0x0078, 0x756f, 0xa006, 0x127f, 0x027f, - 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0xa8c5, 0x0001, - 0x0078, 0x75be, 0x087e, 0x2041, 0x0000, 0x2c20, 0x2019, 0x0002, - 0x6218, 0x1078, 0x5a2d, 0x1078, 0x5ace, 0x1078, 0x7562, 0x087f, - 0x007c, 0x027e, 0x047e, 0x087e, 0x0c7e, 0x157e, 0x2c20, 0x20a9, - 0x007f, 0x2009, 0x0000, 0x017e, 0x037e, 0x1078, 0x384c, 0x00c0, - 0x75f2, 0x2c10, 0x2041, 0x0000, 0x1078, 0x5a2d, 0x1078, 0x5ace, - 0x1078, 0x7562, 0x037f, 0x017f, 0x8108, 0x00f0, 0x75e3, 0x157f, - 0x0c7f, 0x087f, 0x047f, 0x027f, 0x007c, 0x017e, 0x0f7e, 0x8dff, - 0x0040, 0x7611, 0x6800, 0xa07d, 0x0040, 0x760e, 0x6803, 0x0000, - 0x6b52, 0x1078, 0x3b92, 0x2f68, 0x0078, 0x7602, 0x6b52, 0x1078, - 0x3b92, 0x0f7f, 0x017f, 0x007c, 0x0e7e, 0x047e, 0x037e, 0x2061, - 0x7e00, 0x2071, 0x7700, 0x7444, 0x7060, 0x8001, 0xa402, 0x00c8, - 0x763c, 0x2100, 0xac06, 0x0040, 0x762e, 0x6000, 0xa086, 0x0000, - 0x0040, 0x762e, 0x6008, 0xa206, 0x0040, 0x7638, 0xace0, 0x0008, - 0x2001, 0x7715, 0x2004, 0xac02, 0x00c8, 0x763c, 0x0078, 0x7619, - 0xa085, 0x0001, 0x0078, 0x763d, 0xa006, 0x037f, 0x047f, 0x0e7f, - 0x007c, 0x0d7e, 0x007e, 0x1078, 0x1327, 0x007f, 0x1040, 0x12cd, - 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x685b, 0x0000, - 0x685e, 0x6956, 0x6c46, 0x684f, 0x0000, 0x1078, 0x3b92, 0x0d7f, - 0x007c, 0x6700, 0xa786, 0x0000, 0x0040, 0x766c, 0xa786, 0x0001, - 0x0040, 0x766c, 0xa786, 0x000a, 0x0040, 0x766c, 0xa786, 0x0009, - 0x0040, 0x766c, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x6018, 0x2070, - 0x70a0, 0xa206, 0x0e7f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, - 0x8000, 0x2071, 0x7740, 0xd5a4, 0x0040, 0x7681, 0x7034, 0x8000, - 0x7036, 0xd5b4, 0x0040, 0x7687, 0x7030, 0x8000, 0x7032, 0xd5ac, - 0x0040, 0x768e, 0x2071, 0x774a, 0x1078, 0x76bd, 0x0e7f, 0x007f, + 0x0c7e, 0x037e, 0x157e, 0x2079, 0x8d80, 0x7938, 0x783c, 0x1078, + 0x2245, 0x00c0, 0x839d, 0x017e, 0x0c7e, 0x1078, 0x3f8e, 0x00c0, + 0x839d, 0x2011, 0x8d90, 0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, + 0x6f0c, 0x00c0, 0x839d, 0x017f, 0x027f, 0x027e, 0x017e, 0x2019, + 0x0029, 0x1078, 0x6799, 0x1078, 0x54f0, 0x087e, 0x2041, 0x0000, + 0x1078, 0x5419, 0x087f, 0x017f, 0x087e, 0x2041, 0x0000, 0x1078, + 0x84d2, 0x087f, 0x1078, 0x418b, 0x027e, 0x6204, 0xa294, 0xff00, + 0x8217, 0xa286, 0x0006, 0x0040, 0x8391, 0xa286, 0x0004, 0x00c0, + 0x8394, 0x62a0, 0x1078, 0x2566, 0x027f, 0x017f, 0x1078, 0x3d31, + 0x6612, 0x6516, 0xa006, 0x0078, 0x839f, 0x0c7f, 0x017f, 0x157f, + 0x037f, 0x0c7f, 0x0f7f, 0x007c, 0x0c7e, 0x0d7e, 0x017e, 0x2009, + 0x881f, 0x2104, 0xa086, 0x0074, 0x00c0, 0x83fb, 0x2069, 0x8d8e, + 0x690c, 0xa182, 0x0100, 0x0048, 0x83eb, 0x6908, 0xa184, 0x8000, + 0x0040, 0x83f7, 0xa184, 0x0800, 0x0040, 0x83f7, 0x6910, 0xa18a, + 0x0001, 0x0048, 0x83ef, 0x6914, 0x2069, 0x8dae, 0x6904, 0x81ff, + 0x00c0, 0x83e3, 0x690c, 0xa182, 0x0100, 0x0048, 0x83eb, 0x6908, + 0x81ff, 0x00c0, 0x83e7, 0x6910, 0xa18a, 0x0001, 0x0048, 0x83ef, + 0x6918, 0xa18a, 0x0001, 0x0048, 0x83f7, 0x0078, 0x8401, 0x6013, + 0x0100, 0x0078, 0x83fd, 0x6013, 0x0300, 0x0078, 0x83fd, 0x6013, + 0x0500, 0x0078, 0x83fd, 0x6013, 0x0700, 0x0078, 0x83fd, 0x6013, + 0x0900, 0x0078, 0x83fd, 0x6013, 0x0b00, 0x0078, 0x83fd, 0x6013, + 0x0f00, 0x0078, 0x83fd, 0x6013, 0x2d00, 0xa085, 0x0001, 0x0078, + 0x8402, 0xa006, 0x017f, 0x0d7f, 0x0c7f, 0x007c, 0x0c7e, 0x0d7e, + 0x027e, 0x037e, 0x157e, 0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff, + 0xa286, 0x0006, 0x0040, 0x842a, 0xa286, 0x0004, 0x0040, 0x842a, + 0xa394, 0xff00, 0x8217, 0xa286, 0x0006, 0x0040, 0x842a, 0xa286, + 0x0004, 0x0040, 0x842a, 0x0c7e, 0x2d60, 0x1078, 0x3fa0, 0x0c7f, + 0x0078, 0x8465, 0x2011, 0x8d96, 0xad98, 0x000a, 0x20a9, 0x0004, + 0x1078, 0x6f0c, 0x00c0, 0x8466, 0x2011, 0x8d9a, 0xad98, 0x0006, + 0x20a9, 0x0004, 0x1078, 0x6f0c, 0x00c0, 0x8466, 0x047e, 0x017e, + 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0x8852, 0x210c, + 0xd1a4, 0x0040, 0x8452, 0x2009, 0x0029, 0x1078, 0x86f5, 0x6800, + 0xc0e5, 0x6802, 0x2019, 0x0029, 0x1078, 0x54f0, 0x087e, 0x2041, + 0x0000, 0x1078, 0x5419, 0x2c08, 0x1078, 0x84d2, 0x087f, 0x2001, + 0x0007, 0x1078, 0x3f2c, 0x017f, 0x047f, 0xa006, 0x157f, 0x037f, + 0x027f, 0x0d7f, 0x0c7f, 0x007c, 0x0d7e, 0x2069, 0x8d8e, 0x6800, + 0xa086, 0x0800, 0x0040, 0x8478, 0x6013, 0x0000, 0x0078, 0x8479, + 0xa006, 0x0d7f, 0x007c, 0x0c7e, 0x0f7e, 0x017e, 0x027e, 0x037e, + 0x157e, 0x2079, 0x8d8c, 0x7930, 0x7834, 0x1078, 0x2245, 0x00c0, + 0x849f, 0x1078, 0x3f8e, 0x00c0, 0x849f, 0x2011, 0x8d90, 0xac98, + 0x000a, 0x20a9, 0x0004, 0x1078, 0x6f0c, 0x00c0, 0x849f, 0x2011, + 0x8d94, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078, 0x6f0c, 0x157f, + 0x037f, 0x027f, 0x017f, 0x0f7f, 0x0c7f, 0x007c, 0x0c7e, 0x007e, + 0x017e, 0x027e, 0x037e, 0x157e, 0x2011, 0x8d83, 0x2204, 0x8211, + 0x220c, 0x1078, 0x2245, 0x00c0, 0x84cb, 0x1078, 0x3f8e, 0x00c0, + 0x84cb, 0x2011, 0x8d96, 0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, + 0x6f0c, 0x00c0, 0x84cb, 0x2011, 0x8d9a, 0xac98, 0x0006, 0x20a9, + 0x0004, 0x1078, 0x6f0c, 0x157f, 0x037f, 0x027f, 0x017f, 0x007f, + 0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x057e, 0x047e, + 0x027e, 0x127e, 0x2091, 0x8000, 0x2029, 0x8aab, 0x252c, 0x2021, + 0x8ab1, 0x2424, 0x2061, 0x8f00, 0x2071, 0x8800, 0x7644, 0x7060, + 0x8001, 0xa602, 0x00c8, 0x853e, 0x2100, 0xac06, 0x0040, 0x8534, + 0x1078, 0x870c, 0x0040, 0x8534, 0x671c, 0xa786, 0x0001, 0x0040, + 0x8553, 0xa786, 0x0007, 0x0040, 0x8534, 0x2500, 0xac06, 0x0040, + 0x8534, 0x2400, 0xac06, 0x0040, 0x8534, 0x1078, 0x8720, 0x00c0, + 0x8534, 0x88ff, 0x0040, 0x8510, 0x6020, 0xa906, 0x00c0, 0x8534, + 0x0d7e, 0x6000, 0xa086, 0x0004, 0x00c0, 0x851a, 0x017e, 0x1078, + 0x16af, 0x017f, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, 0x8531, + 0xa786, 0x0003, 0x00c0, 0x8547, 0x6837, 0x0103, 0x6b4a, 0x6847, + 0x0000, 0x017e, 0x1078, 0x7a46, 0x1078, 0x4376, 0x017f, 0x1078, + 0x799b, 0x0d7f, 0x1078, 0x79a8, 0xace0, 0x000c, 0x2001, 0x8815, + 0x2004, 0xac02, 0x00c8, 0x853e, 0x0078, 0x84e4, 0x127f, 0x027f, + 0x047f, 0x057f, 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x007c, 0xa786, + 0x0006, 0x00c0, 0x8524, 0xa386, 0x0005, 0x0040, 0x8534, 0x1078, + 0x86aa, 0x0078, 0x8531, 0x1078, 0x8720, 0x00c0, 0x8534, 0xa180, + 0x0001, 0x2004, 0xa086, 0x0018, 0x00c0, 0x8534, 0x6000, 0xa086, + 0x0002, 0x00c0, 0x8534, 0x1078, 0x79c1, 0x0040, 0x856f, 0x1078, + 0x79d5, 0x00c0, 0x8534, 0x1078, 0x6bc7, 0x0078, 0x8571, 0x1078, + 0x24e5, 0x1078, 0x79a8, 0x0078, 0x8534, 0x0c7e, 0x0e7e, 0x017e, + 0x2c08, 0x2170, 0x1078, 0x86c1, 0x017f, 0x0040, 0x8584, 0x601c, + 0xa084, 0x000f, 0x1079, 0x8587, 0x0e7f, 0x0c7f, 0x007c, 0x858f, + 0x858f, 0x858f, 0x858f, 0x858f, 0x858f, 0x8591, 0x858f, 0xa006, + 0x007c, 0x047e, 0x017e, 0x7018, 0xa080, 0x0028, 0x2024, 0xa4a4, + 0x00ff, 0x8427, 0x2c00, 0x2009, 0x0020, 0x1078, 0x86f5, 0x017f, + 0x047f, 0x037e, 0x2019, 0x0002, 0x1078, 0x831c, 0x037f, 0xa085, + 0x0001, 0x007c, 0x2001, 0x0001, 0x1078, 0x3ef1, 0x157e, 0x017e, + 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019, 0x8805, 0x2011, 0x8d96, + 0x1078, 0x6f0c, 0x037f, 0x027f, 0x017f, 0x157f, 0xa005, 0x007c, + 0x0f7e, 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x027e, 0x127e, 0x2091, + 0x8000, 0x2061, 0x8f00, 0x2079, 0x0001, 0x8fff, 0x0040, 0x8624, + 0x2071, 0x8800, 0x7644, 0x7060, 0x8001, 0xa602, 0x00c8, 0x8624, + 0x88ff, 0x0040, 0x85e1, 0x2800, 0xac06, 0x00c0, 0x861a, 0x2079, + 0x0000, 0x1078, 0x870c, 0x0040, 0x861a, 0x2400, 0xac06, 0x0040, + 0x861a, 0x671c, 0xa786, 0x0006, 0x00c0, 0x861a, 0xa786, 0x0007, + 0x0040, 0x861a, 0x88ff, 0x00c0, 0x8600, 0x6018, 0xa206, 0x00c0, + 0x861a, 0x85ff, 0x0040, 0x8600, 0x6020, 0xa106, 0x00c0, 0x861a, + 0x0d7e, 0x6000, 0xa086, 0x0004, 0x00c0, 0x860a, 0x601f, 0x0007, + 0x1078, 0x16af, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, 0x8614, + 0x047e, 0x1078, 0x86aa, 0x047f, 0x0d7f, 0x1078, 0x79a8, 0x88ff, + 0x00c0, 0x862d, 0xace0, 0x000c, 0x2001, 0x8815, 0x2004, 0xac02, + 0x00c8, 0x8624, 0x0078, 0x85cd, 0xa006, 0x127f, 0x027f, 0x067f, + 0x077f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0xa8c5, 0x0001, 0x0078, + 0x8625, 0x087e, 0x057e, 0x2041, 0x0000, 0x2029, 0x0001, 0x2c20, + 0x2019, 0x0002, 0x6218, 0x1078, 0x6614, 0x1078, 0x66be, 0x1078, + 0x85c0, 0x057f, 0x087f, 0x007c, 0x027e, 0x047e, 0x057e, 0x087e, + 0x0c7e, 0x157e, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009, 0x0000, + 0x017e, 0x037e, 0x1078, 0x3f8e, 0x00c0, 0x8664, 0x2c10, 0x2041, + 0x0000, 0x2508, 0x057e, 0x2029, 0x0001, 0x1078, 0x6614, 0x1078, + 0x66be, 0x1078, 0x85c0, 0x057f, 0x037f, 0x017f, 0x8108, 0x00f0, + 0x8650, 0x157f, 0x0c7f, 0x087f, 0x057f, 0x047f, 0x027f, 0x007c, + 0x087e, 0x057e, 0x6218, 0x2041, 0x0000, 0x2029, 0x0001, 0x2019, + 0x0048, 0x1078, 0x6614, 0x1078, 0x66be, 0x2c20, 0x1078, 0x85c0, + 0x057f, 0x087f, 0x007c, 0x027e, 0x047e, 0x057e, 0x087e, 0x0c7e, + 0x157e, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x037e, + 0x1078, 0x3f8e, 0x00c0, 0x869e, 0x2c10, 0x2041, 0x0000, 0x2828, + 0x1078, 0x6614, 0x1078, 0x66be, 0x1078, 0x85c0, 0x037f, 0x017f, + 0x8108, 0x00f0, 0x868e, 0x157f, 0x0c7f, 0x087f, 0x057f, 0x047f, + 0x027f, 0x007c, 0x017e, 0x0f7e, 0x8dff, 0x0040, 0x86be, 0x6800, + 0xa07d, 0x0040, 0x86bb, 0x6803, 0x0000, 0x6b52, 0x1078, 0x4376, + 0x2f68, 0x0078, 0x86af, 0x6b52, 0x1078, 0x4376, 0x0f7f, 0x017f, + 0x007c, 0x0e7e, 0x047e, 0x037e, 0x2061, 0x8f00, 0x2071, 0x8800, + 0x7444, 0x7060, 0x8001, 0xa402, 0x00c8, 0x86f0, 0x2100, 0xac06, + 0x0040, 0x86e2, 0x6000, 0xa086, 0x0000, 0x0040, 0x86e2, 0x6008, + 0xa206, 0x00c0, 0x86e2, 0x6018, 0xa1a0, 0x0006, 0x2424, 0xa406, + 0x0040, 0x86ec, 0xace0, 0x000c, 0x2001, 0x8815, 0x2004, 0xac02, + 0x00c8, 0x86f0, 0x0078, 0x86c6, 0xa085, 0x0001, 0x0078, 0x86f1, + 0xa006, 0x037f, 0x047f, 0x0e7f, 0x007c, 0x0d7e, 0x007e, 0x1078, + 0x132b, 0x007f, 0x1040, 0x12d2, 0x6837, 0x010d, 0x685e, 0x6956, + 0x6c46, 0x684f, 0x0000, 0xa006, 0x68b2, 0x6802, 0x683a, 0x685a, + 0x1078, 0x4376, 0x0d7f, 0x007c, 0x6700, 0xa786, 0x0000, 0x0040, + 0x871f, 0xa786, 0x0001, 0x0040, 0x871f, 0xa786, 0x000a, 0x0040, + 0x871f, 0xa786, 0x0009, 0x0040, 0x871f, 0xa085, 0x0001, 0x007c, + 0x0e7e, 0x6018, 0x2070, 0x70a0, 0xa206, 0x0e7f, 0x007c, 0x0e7e, + 0x6018, 0x2070, 0x7000, 0xd0ec, 0x0e7f, 0x007c, 0x127e, 0x007e, + 0x0e7e, 0x2091, 0x8000, 0x2071, 0x8840, 0xd5a4, 0x0040, 0x873b, + 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, 0x8741, 0x7030, 0x8000, + 0x7032, 0xd5ac, 0x0040, 0x8748, 0x2071, 0x884a, 0x1078, 0x8777, + 0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, + 0x8000, 0x2071, 0x8840, 0xd5a4, 0x0040, 0x8759, 0x7034, 0x8000, + 0x7036, 0xd5b4, 0x0040, 0x875f, 0x7030, 0x8000, 0x7032, 0xd5ac, + 0x0040, 0x8766, 0x2071, 0x884a, 0x1078, 0x8777, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071, - 0x7740, 0xd5a4, 0x0040, 0x769f, 0x7034, 0x8000, 0x7036, 0xd5b4, - 0x0040, 0x76a5, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0040, 0x76ac, - 0x2071, 0x774a, 0x1078, 0x76bd, 0x0e7f, 0x007f, 0x127f, 0x007c, - 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x7742, 0x1078, - 0x76bd, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x2e04, 0x8000, 0x2072, - 0x00c8, 0x76c6, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x007c, 0x0e7e, - 0x2071, 0x7740, 0x1078, 0x76bd, 0x0e7f, 0x007c, 0x0e7e, 0x2071, - 0x7744, 0x1078, 0x76bd, 0x0e7f, 0x007c, 0x0001, 0x0002, 0x0004, - 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, - 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x687d + 0x8842, 0x1078, 0x8777, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x2e04, + 0x8000, 0x2072, 0x00c8, 0x8780, 0x8e70, 0x2e04, 0x8000, 0x2072, + 0x007c, 0x0e7e, 0x2071, 0x8840, 0x1078, 0x8777, 0x0e7f, 0x007c, + 0x0e7e, 0x2071, 0x8844, 0x1078, 0x8777, 0x0e7f, 0x007c, 0x0001, + 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, + 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x6f37 }; -/* - * Firmware Version 2.00.16 (09:36 Jun 29, 1999) - */ unsigned short risc_code2200[] = { - 0x0470, 0x0000, 0x0000, 0x81bd, 0x0000, 0x0002, 0x0000, 0x0010, - 0x0027, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939, + 0x0470, 0x0000, 0x0000, 0x7a68, 0x0000, 0x0002, 0x0000, 0x0028, + 0x0007, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939, 0x3920, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3232, 0x3030, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, - 0x322e, 0x3030, 0x2e31, 0x3620, 0x2020, 0x2020, 0x2400, 0x20c1, - 0x0005, 0x2001, 0x017f, 0x2003, 0x0000, 0x20c9, 0x96ff, 0x2091, - 0x2000, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x2490, - 0x2051, 0x9200, 0x2a70, 0x2029, 0xb100, 0x2031, 0xffff, 0x2039, - 0xb0f5, 0x2021, 0x0200, 0x0804, 0x136b, 0x20a1, 0x91bd, 0xa00e, - 0x20a9, 0x0743, 0x41a4, 0x3400, 0x755e, 0x7662, 0x775a, 0x7466, - 0x746a, 0x20a1, 0x9900, 0x7160, 0x810d, 0x810d, 0x810d, 0x810d, + 0x322e, 0x3030, 0x2e34, 0x3020, 0x2020, 0x2020, 0x2400, 0x20c1, + 0x0005, 0x2001, 0x017f, 0x2003, 0x0000, 0x20c9, 0x8fff, 0x2091, + 0x2000, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x236e, + 0x2051, 0x8b00, 0x2a70, 0x2029, 0xaa00, 0x2031, 0xffff, 0x2039, + 0xa9f5, 0x2021, 0x0200, 0x0804, 0x137d, 0x20a1, 0x8a68, 0xa00e, + 0x20a9, 0x0798, 0x41a4, 0x3400, 0x755e, 0x7662, 0x775a, 0x7466, + 0x746a, 0x20a1, 0x9200, 0x7160, 0x810d, 0x810d, 0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, 0x0009, 0xa112, 0xa00e, 0x21a8, 0x41a4, 0x3400, 0x8211, 0x1dd8, 0x7160, 0x3400, 0xa102, 0x0120, 0x0218, - 0x20a8, 0xa00e, 0x41a4, 0x3800, 0xd08c, 0x01d8, 0x2009, 0x9200, + 0x20a8, 0xa00e, 0x41a4, 0x3800, 0xd08c, 0x01d8, 0x2009, 0x8b00, 0x810d, 0x810d, 0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, 0x0001, 0xa112, 0x20a1, 0x1000, 0xa00e, 0x21a8, 0x41a4, 0x8211, 0x1de0, - 0x2009, 0x9200, 0x3400, 0xa102, 0x0120, 0x0218, 0x20a8, 0xa00e, - 0x41a4, 0x080c, 0x1322, 0x080c, 0x14b6, 0x080c, 0x1649, 0x080c, - 0x1c81, 0x080c, 0x41d4, 0x080c, 0x7494, 0x080c, 0x1439, 0x080c, - 0x2819, 0x080c, 0x4e42, 0x080c, 0x4757, 0x080c, 0x5874, 0x080c, - 0x56c0, 0x080c, 0x2138, 0x080c, 0x5ed0, 0x080c, 0x532f, 0x080c, - 0x206a, 0x080c, 0x210e, 0x2091, 0x3009, 0x7823, 0x0000, 0x1004, - 0x10c7, 0x7820, 0xa086, 0x0002, 0x1150, 0x7823, 0x4000, 0x0e04, - 0x10bf, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, - 0x7003, 0x0000, 0x2a70, 0x7000, 0xa08e, 0x0003, 0x1168, 0x080c, - 0x36d4, 0x080c, 0x2840, 0x080c, 0x4e90, 0x080c, 0x493b, 0x080c, - 0x58b1, 0x080c, 0x56d8, 0x0c70, 0x000b, 0x0c88, 0x10e8, 0x10e9, - 0x11b8, 0x10e6, 0x123f, 0x131f, 0x1320, 0x1321, 0x080c, 0x13fe, - 0x0005, 0x0126, 0x00f6, 0x2091, 0x8000, 0x080c, 0x4dc5, 0x0150, - 0x080c, 0x4deb, 0x11f8, 0x2079, 0x0100, 0x7828, 0xa085, 0x1800, - 0x782a, 0x00c0, 0x080c, 0x4d10, 0x7088, 0xa086, 0x0026, 0x1904, - 0x119d, 0x2079, 0x0100, 0x7827, 0xffff, 0x782b, 0x1c2b, 0x2011, - 0x4ce2, 0x080c, 0x5731, 0x2011, 0x8030, 0x2019, 0x0000, 0x7087, - 0x0000, 0x00a8, 0x080c, 0x3a6a, 0x2079, 0x0100, 0x7844, 0xa005, - 0x1904, 0x119d, 0x2011, 0x40af, 0x080c, 0x5731, 0x780f, 0x03ff, + 0x2009, 0x8b00, 0x3400, 0xa102, 0x0120, 0x0218, 0x20a8, 0xa00e, + 0x41a4, 0x080c, 0x1334, 0x080c, 0x14c2, 0x080c, 0x165b, 0x080c, + 0x1bc1, 0x080c, 0x410c, 0x080c, 0x6cba, 0x080c, 0x144b, 0x080c, + 0x273d, 0x080c, 0x4d5e, 0x080c, 0x45ef, 0x080c, 0x559c, 0x080c, + 0x2029, 0x080c, 0x577b, 0x080c, 0x5212, 0x080c, 0x1f59, 0x080c, + 0x1ffd, 0x2091, 0x3009, 0x7823, 0x0000, 0x1004, 0x10c5, 0x7820, + 0xa086, 0x0002, 0x1150, 0x7823, 0x4000, 0x0e04, 0x10bd, 0x781b, + 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, 0x7003, 0x0000, + 0x2a70, 0x7000, 0xa08e, 0x0003, 0x1158, 0x080c, 0x3653, 0x080c, + 0x2764, 0x080c, 0x4dac, 0x080c, 0x4788, 0x080c, 0x55b4, 0x0c80, + 0x000b, 0x0c98, 0x10e4, 0x10e5, 0x11c0, 0x10e2, 0x1251, 0x1331, + 0x1332, 0x1333, 0x080c, 0x1410, 0x0005, 0x0126, 0x00f6, 0x2091, + 0x8000, 0x080c, 0x4c42, 0x0150, 0x080c, 0x4c68, 0x1518, 0x2079, + 0x0100, 0x7828, 0xa085, 0x1800, 0x782a, 0x00e0, 0x080c, 0x4b8b, + 0x7088, 0xa086, 0x0027, 0x1904, 0x11a5, 0x2079, 0x0100, 0x7827, + 0xffff, 0x782b, 0x1e2b, 0x2011, 0x4b5d, 0x080c, 0x560d, 0x2011, + 0x3fe7, 0x080c, 0x560d, 0x2011, 0x8030, 0x2019, 0x0000, 0x7087, + 0x0000, 0x00a8, 0x080c, 0x399f, 0x2079, 0x0100, 0x7844, 0xa005, + 0x1904, 0x11a5, 0x2011, 0x3fe7, 0x080c, 0x560d, 0x780f, 0x00ff, 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011, 0x8010, 0x73c4, 0x080c, - 0x3698, 0x080c, 0x706b, 0x2011, 0x0004, 0x080c, 0x82f3, 0x080c, - 0x46a8, 0x080c, 0x4dc5, 0x0158, 0x080c, 0x41bd, 0x0140, 0x7087, - 0x0001, 0x70bf, 0x0000, 0x080c, 0x3bfd, 0x0804, 0x119d, 0x70d3, - 0x0000, 0x70cf, 0x0000, 0x706f, 0x0000, 0x7073, 0x0000, 0x080c, - 0x11a0, 0x72c8, 0x080c, 0x4dc5, 0x1160, 0x2011, 0x0000, 0x2001, - 0x0204, 0x2004, 0x2019, 0x94c8, 0x201a, 0x704f, 0xffff, 0x7053, - 0x00ef, 0x2079, 0x9251, 0x7804, 0xd0ac, 0x0108, 0xc295, 0x72ca, - 0x080c, 0x4dc5, 0x0118, 0xa296, 0x0004, 0x0500, 0x2011, 0x0001, - 0x080c, 0x82f3, 0x080c, 0x854a, 0x7097, 0x0000, 0x709b, 0xffff, - 0x7003, 0x0002, 0x00fe, 0x080c, 0x251c, 0x2011, 0x0005, 0x080c, - 0x718f, 0x080c, 0x6462, 0x080c, 0x4dc5, 0x0130, 0x00c6, 0x2061, - 0x0100, 0x60e3, 0x0008, 0x00ce, 0x012e, 0x00c8, 0x080c, 0x854a, + 0x3617, 0x7238, 0xc284, 0x723a, 0x2001, 0x8b0c, 0x200c, 0xc1ac, + 0x2102, 0x080c, 0x683e, 0x2011, 0x0004, 0x080c, 0x7b94, 0x080c, + 0x4581, 0x080c, 0x4c42, 0x0158, 0x080c, 0x40f5, 0x0140, 0x7087, + 0x0001, 0x70bf, 0x0000, 0x080c, 0x3b32, 0x0804, 0x11a5, 0x70d3, + 0x0000, 0x70cf, 0x0000, 0x706f, 0x0000, 0x080c, 0x11a8, 0x72c8, + 0x080c, 0x4c42, 0x1170, 0x2011, 0x0000, 0x2001, 0x0204, 0x2004, + 0x2019, 0x8d8d, 0x201a, 0x704f, 0xffff, 0x7053, 0x00ef, 0x7073, + 0x0000, 0x2079, 0x8b51, 0x7804, 0xd0ac, 0x0108, 0xc295, 0x72ca, + 0x080c, 0x4c42, 0x0118, 0xa296, 0x0004, 0x0500, 0x2011, 0x0001, + 0x080c, 0x7b94, 0x080c, 0x7deb, 0x7097, 0x0000, 0x709b, 0xffff, + 0x7003, 0x0002, 0x00fe, 0x080c, 0x23fa, 0x2011, 0x0005, 0x080c, + 0x695c, 0x080c, 0x5d10, 0x080c, 0x4c42, 0x0130, 0x00c6, 0x2061, + 0x0100, 0x60e3, 0x0008, 0x00ce, 0x012e, 0x00c8, 0x080c, 0x7deb, 0x7097, 0x0000, 0x709b, 0xffff, 0x7003, 0x0002, 0x2011, 0x0005, - 0x080c, 0x718f, 0x080c, 0x6462, 0x080c, 0x4dc5, 0x0130, 0x00c6, + 0x080c, 0x695c, 0x080c, 0x5d10, 0x080c, 0x4c42, 0x0130, 0x00c6, 0x2061, 0x0100, 0x60e3, 0x0008, 0x00ce, 0x00fe, 0x012e, 0x0005, - 0x00c6, 0x080c, 0x4dc5, 0x1118, 0x20a9, 0x0100, 0x0010, 0x20a9, - 0x0082, 0x080c, 0x4dc5, 0x1118, 0x2009, 0x0000, 0x0010, 0x2009, - 0x007e, 0x080c, 0x441f, 0x8108, 0x1f04, 0x11b1, 0x00ce, 0x0005, + 0x00c6, 0x080c, 0x4c42, 0x1118, 0x20a9, 0x0100, 0x0010, 0x20a9, + 0x0082, 0x080c, 0x4c42, 0x1118, 0x2009, 0x0000, 0x0010, 0x2009, + 0x007e, 0x080c, 0x42f5, 0x8108, 0x1f04, 0x11b9, 0x00ce, 0x0005, 0x0126, 0x2091, 0x8000, 0x7098, 0xa086, 0xffff, 0x0130, 0x080c, - 0x251c, 0x080c, 0x6462, 0x0804, 0x123d, 0x70c8, 0xd0ac, 0x1110, - 0xd09c, 0x0558, 0xd084, 0x0548, 0x0006, 0x70c8, 0xa084, 0x0030, - 0x000e, 0x1138, 0x00f6, 0x2079, 0x0100, 0x790c, 0xc1b5, 0x790e, - 0x00fe, 0xd08c, 0x01d0, 0x70cc, 0xa086, 0xffff, 0x0190, 0x080c, - 0x25fd, 0x080c, 0x6462, 0x70c8, 0xd094, 0x1904, 0x123d, 0x2011, - 0x0001, 0x2019, 0x0000, 0x080c, 0x2631, 0x080c, 0x6462, 0x0804, - 0x123d, 0x70d0, 0xa005, 0x1904, 0x123d, 0x7094, 0xa005, 0x1904, - 0x123d, 0x70c8, 0xd0a4, 0x0110, 0xd0b4, 0x05f8, 0x2001, 0x9252, - 0x2004, 0xd0ac, 0x01c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x2009, - 0x0000, 0x0016, 0x080c, 0x4434, 0x1118, 0x6000, 0xd0ec, 0x1138, - 0x001e, 0x8108, 0x1f04, 0x1209, 0x00ce, 0x015e, 0x0020, 0x001e, - 0x00ce, 0x015e, 0x0410, 0x00f6, 0x2079, 0x0100, 0x780c, 0xc0b5, - 0x780e, 0x00fe, 0x7003, 0x0003, 0x709b, 0xffff, 0xa006, 0x080c, - 0x23ba, 0x080c, 0x370a, 0x2001, 0x94e6, 0x2004, 0xa086, 0x0005, - 0x1120, 0x2011, 0x0000, 0x080c, 0x718f, 0x2011, 0x0000, 0x080c, - 0x7199, 0x080c, 0x6462, 0x080c, 0x651c, 0x012e, 0x0005, 0x0016, - 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0x00f7, - 0x080c, 0x4186, 0x7940, 0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4, - 0x0110, 0x7827, 0x0040, 0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, - 0x0036, 0x0156, 0x7954, 0xd1ac, 0x1904, 0x12a5, 0x080c, 0x4dd7, - 0x0158, 0x080c, 0x4deb, 0x1128, 0x2001, 0x94d7, 0x2003, 0x0000, - 0x0070, 0x080c, 0x4dcd, 0x0dc0, 0x2001, 0x94d7, 0x2003, 0xaaaa, - 0x2001, 0x94d8, 0x2003, 0x0001, 0x080c, 0x4d10, 0x0058, 0x080c, - 0x4dc5, 0x0140, 0x2009, 0x00f8, 0x080c, 0x4186, 0x7843, 0x0090, - 0x7843, 0x0010, 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, - 0x4dc5, 0x0138, 0x7824, 0xd0ac, 0x1904, 0x130d, 0x1f04, 0x1284, - 0x0070, 0x7824, 0x080c, 0x4de1, 0x0118, 0xd0ac, 0x1904, 0x130d, - 0xa084, 0x1800, 0x0d98, 0x7003, 0x0001, 0x0804, 0x130d, 0x2001, - 0x0001, 0x080c, 0x23ba, 0x0804, 0x1318, 0x7850, 0xa084, 0x0180, - 0x7852, 0x782f, 0x0020, 0x20a9, 0x0050, 0x1d04, 0x12ad, 0x2091, - 0x6000, 0x1f04, 0x12ad, 0x7850, 0xa084, 0x0180, 0xa085, 0x0400, - 0x7852, 0x782f, 0x0000, 0x080c, 0x4dd7, 0x0158, 0x080c, 0x4deb, - 0x1128, 0x2001, 0x94d7, 0x2003, 0x0000, 0x0070, 0x080c, 0x4dcd, - 0x0dc0, 0x2001, 0x94d7, 0x2003, 0xaaaa, 0x2001, 0x94d8, 0x2003, - 0x0001, 0x080c, 0x4d10, 0x0020, 0x2009, 0x00f8, 0x080c, 0x4186, - 0x20a9, 0x000e, 0xe000, 0x1f04, 0x12da, 0x7850, 0xa084, 0x0180, - 0xa085, 0x1400, 0x7852, 0x080c, 0x4dc5, 0x0120, 0x7843, 0x0090, - 0x7843, 0x0010, 0x2019, 0x61a8, 0x7820, 0xd09c, 0x1130, 0x080c, - 0x4dc5, 0x0130, 0x7824, 0xd0ac, 0x11c0, 0x8319, 0x1da8, 0x0080, - 0x7827, 0x1800, 0xe000, 0xe000, 0x7824, 0x080c, 0x4de1, 0x0110, - 0xd0ac, 0x1158, 0xa084, 0x1800, 0x0d80, 0x7003, 0x0001, 0x0028, - 0x2001, 0x0001, 0x080c, 0x23ba, 0x0028, 0x7827, 0x0048, 0x7828, - 0xc09d, 0x782a, 0x7850, 0xa084, 0x0180, 0xa085, 0x0400, 0x7852, - 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, 0x001e, 0x0005, 0x0005, - 0x0005, 0x0005, 0x2a70, 0x2001, 0x94d7, 0x2003, 0x0000, 0x7087, - 0x0000, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0218, 0x704f, - 0xffff, 0x0010, 0x704f, 0x0000, 0x7057, 0xffff, 0x706f, 0x0000, - 0x7073, 0x0000, 0x080c, 0x854a, 0x2061, 0x94c7, 0x6003, 0x0909, - 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013, 0x00ff, - 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0, 0x2061, 0x94cf, - 0x6003, 0x8800, 0x6007, 0x0000, 0x600b, 0x0000, 0x600f, 0x0200, - 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001, 0x601f, 0x0000, - 0x2061, 0x94df, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, - 0x600f, 0x2020, 0x0005, 0x04a0, 0x2011, 0x0000, 0x81ff, 0x0570, - 0xa186, 0x0001, 0x1148, 0x2031, 0x8fff, 0x2039, 0xa501, 0x2021, - 0x0100, 0x2029, 0xa500, 0x00e8, 0xa186, 0x0002, 0x1118, 0x2011, - 0x0000, 0x00b8, 0xa186, 0x0005, 0x1118, 0x2011, 0x0001, 0x0088, - 0xa186, 0x0009, 0x1118, 0x2011, 0x0002, 0x0058, 0xa186, 0x000a, - 0x1118, 0x2011, 0x0002, 0x0028, 0xa186, 0x0055, 0x1110, 0x2011, - 0x0003, 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0, 0x0804, 0x104d, - 0xa00e, 0x2011, 0x0003, 0x2019, 0x13a7, 0x0804, 0x13f8, 0x2019, - 0xaaaa, 0x2061, 0xffff, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c04, - 0xa306, 0x2262, 0x1110, 0xc1b5, 0xc1a5, 0x2011, 0x0000, 0x2019, - 0x13ba, 0x04f0, 0x2019, 0xaaaa, 0x2061, 0xffff, 0x2c14, 0x2362, - 0xe000, 0xe000, 0x2c1c, 0x2061, 0x7fff, 0xe000, 0xe000, 0x2c04, - 0x2061, 0xffff, 0x2262, 0xa306, 0x0110, 0xc18d, 0x0008, 0xc185, - 0x2011, 0x0002, 0x2019, 0x13d5, 0x0418, 0x2061, 0xffff, 0x2019, - 0xaaaa, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c04, 0x2262, 0xa306, - 0x1180, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c1c, 0x2061, 0x7fff, - 0x2c04, 0x2061, 0xffff, 0x2262, 0xa306, 0x1110, 0xc195, 0x0008, - 0xc19d, 0x2011, 0x0001, 0x2019, 0x13f6, 0x0010, 0x0804, 0x136c, - 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0, 0x0837, 0x2091, 0x8000, - 0x0e04, 0x1400, 0x0006, 0x0016, 0x2079, 0x0000, 0x7818, 0xd084, - 0x1de8, 0x001e, 0x792e, 0x000e, 0x782a, 0x000e, 0x7826, 0x3900, - 0x783a, 0x7823, 0x8002, 0x781b, 0x0001, 0x2091, 0x5000, 0x0156, - 0x0146, 0x20a9, 0x0010, 0x20a1, 0x95e6, 0x2091, 0x2000, 0x40a1, - 0x20a9, 0x0010, 0x2091, 0x2200, 0x40a1, 0x20a9, 0x0010, 0x2091, - 0x2400, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2600, 0x40a1, 0x014e, - 0x015e, 0x2079, 0x9200, 0x7803, 0x0005, 0x2091, 0x4080, 0x0cf8, - 0x0005, 0x2071, 0x9200, 0x715c, 0x712e, 0x2021, 0x0001, 0xa190, - 0x0030, 0xa298, 0x0030, 0x0240, 0x7060, 0xa302, 0x1228, 0x220a, - 0x2208, 0x2310, 0x8420, 0x0ca8, 0x3800, 0xd08c, 0x0148, 0x7060, - 0xa086, 0x9200, 0x0128, 0x7063, 0x9200, 0x2011, 0x1000, 0x0c48, - 0x200b, 0x0000, 0x74aa, 0x74ae, 0x70df, 0x0010, 0x0005, 0x00e6, - 0x0126, 0x2091, 0x8000, 0x2071, 0x9200, 0x70ac, 0x0016, 0x2008, - 0x70dc, 0xa16a, 0x2100, 0x001e, 0x0268, 0x8001, 0x70ae, 0x702c, - 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x012e, - 0x00ee, 0x0005, 0xa06e, 0x0cd8, 0x00e6, 0x2071, 0x9200, 0x0126, - 0x2091, 0x8000, 0x70ac, 0x8001, 0x0260, 0x70ae, 0x702c, 0x2068, - 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x012e, 0x00ee, - 0x0005, 0xa06e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, - 0x9200, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70ac, 0x8000, 0x70ae, - 0x012e, 0x00ee, 0x0005, 0x8dff, 0x0138, 0x6804, 0x6807, 0x0000, - 0x0006, 0x0c49, 0x00de, 0x0cb8, 0x0005, 0x00e6, 0x2071, 0x9200, - 0x70ac, 0xa08a, 0x0010, 0xa00d, 0x00ee, 0x0005, 0x00e6, 0x2071, - 0x9508, 0x7007, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000, 0x2071, - 0x0000, 0x7010, 0xa085, 0x8004, 0x7012, 0x00ee, 0x0005, 0x00e6, - 0x2270, 0x700b, 0x0000, 0x2071, 0x9508, 0x7018, 0xa088, 0x9511, - 0x220a, 0x8000, 0xa084, 0x0007, 0x701a, 0x7004, 0xa005, 0x1128, - 0x00f6, 0x2079, 0x0010, 0x0081, 0x00fe, 0x00ee, 0x0005, 0x00e6, - 0x2071, 0x9508, 0x7004, 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010, - 0x0019, 0x00fe, 0x00ee, 0x0005, 0x7000, 0x0002, 0x14f3, 0x1557, - 0x1574, 0x1574, 0x1f79, 0x7018, 0x711c, 0xa106, 0x1118, 0x7007, - 0x0000, 0x0005, 0x00d6, 0xa180, 0x9511, 0x2004, 0x700a, 0x2068, - 0x8108, 0xa18c, 0x0007, 0x711e, 0x7803, 0x0026, 0x6824, 0x7832, - 0x6828, 0x7836, 0x682c, 0x783a, 0x6830, 0x783e, 0x6810, 0x700e, - 0x680c, 0x7016, 0x6804, 0x00de, 0xd084, 0x0120, 0x7007, 0x0001, - 0x0029, 0x0005, 0x7007, 0x0002, 0x00b1, 0x0005, 0x0016, 0x0026, - 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x1210, 0x2110, 0xa006, - 0x700e, 0x7212, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803, 0x0041, - 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x0136, 0x0146, 0x0156, - 0x7014, 0x2098, 0x20a1, 0x0014, 0x7803, 0x0026, 0x710c, 0x2011, - 0x0040, 0xa182, 0x0040, 0x1210, 0x2110, 0xa006, 0x700e, 0x22a8, - 0x53a6, 0x8203, 0x7822, 0x7803, 0x0020, 0x3300, 0x7016, 0x7803, - 0x0001, 0x015e, 0x014e, 0x013e, 0x002e, 0x001e, 0x0005, 0x0136, - 0x0146, 0x0156, 0x2099, 0x930e, 0x20a1, 0x0018, 0x20a9, 0x0008, - 0x53a3, 0x7803, 0x0020, 0x0126, 0x2091, 0x8000, 0x7803, 0x0041, - 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x700b, 0x9309, 0x012e, - 0x015e, 0x014e, 0x013e, 0x0005, 0x0136, 0x0146, 0x0156, 0x2001, - 0x933d, 0x209c, 0x20a1, 0x0014, 0x7803, 0x0026, 0x2001, 0x933e, - 0x20ac, 0x53a6, 0x2099, 0x933f, 0x20a1, 0x0018, 0x20a9, 0x0008, - 0x53a3, 0x7803, 0x0020, 0x0126, 0x2091, 0x8000, 0x7803, 0x0001, - 0x7007, 0x0004, 0x7000, 0xc08c, 0x7002, 0x700b, 0x933a, 0x012e, - 0x015e, 0x014e, 0x013e, 0x0005, 0x0016, 0x00e6, 0x2071, 0x9508, - 0x00f6, 0x2079, 0x0010, 0x7904, 0x7803, 0x0002, 0xd1fc, 0x0120, - 0xa18c, 0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, - 0x14ec, 0x15b8, 0x15e2, 0x1608, 0x1638, 0x1f96, 0x15b7, 0x0cf8, - 0xa18c, 0x0700, 0x1508, 0x0136, 0x0146, 0x0156, 0x7014, 0x20a0, - 0x2099, 0x0014, 0x7803, 0x0040, 0x7010, 0x20a8, 0x53a5, 0x3400, - 0x7016, 0x015e, 0x014e, 0x013e, 0x700c, 0xa005, 0x0530, 0x080c, - 0x151e, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007, - 0x0000, 0x080c, 0x14ec, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, - 0x0200, 0x0ca8, 0xa18c, 0x0700, 0x1130, 0x700c, 0xa005, 0x0168, - 0x080c, 0x1533, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200, - 0x7007, 0x0000, 0x080c, 0x14ec, 0x0005, 0x00d6, 0x7008, 0x2068, - 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, 0x682e, 0x783c, 0x6832, - 0x680b, 0x0100, 0x00de, 0x7007, 0x0000, 0x080c, 0x14ec, 0x0005, - 0xa18c, 0x0700, 0x1540, 0x0136, 0x0146, 0x0156, 0x2001, 0x930c, - 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, - 0x20a9, 0x0020, 0x53a5, 0x2001, 0x930e, 0x2004, 0xd0bc, 0x0148, - 0x2001, 0x9317, 0x2004, 0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020, - 0x53a5, 0x015e, 0x014e, 0x013e, 0x7007, 0x0000, 0x080c, 0x4f27, - 0x080c, 0x14ec, 0x0005, 0x2011, 0x8003, 0x080c, 0x3698, 0x0cf8, - 0xa18c, 0x0700, 0x1148, 0x2001, 0x933c, 0x2003, 0x0100, 0x7007, - 0x0000, 0x080c, 0x14ec, 0x0005, 0x2011, 0x8004, 0x080c, 0x3698, - 0x0cf8, 0x0126, 0x2091, 0x2200, 0x2079, 0x0030, 0x2071, 0x9519, - 0x7003, 0x0000, 0x700f, 0x9520, 0x7013, 0x9520, 0x780f, 0x00f0, - 0x012e, 0x0005, 0x6934, 0xa184, 0x0007, 0x0002, 0x1666, 0x16ab, - 0x1666, 0x1666, 0x166a, 0x1693, 0x167a, 0x1671, 0xa085, 0x0001, - 0x0804, 0x16c5, 0xa186, 0x0024, 0x05f0, 0xa186, 0x002c, 0x05d8, - 0x0ca8, 0x684c, 0xd0bc, 0x0d90, 0x6860, 0x682e, 0x685c, 0x682a, - 0x6858, 0x04c8, 0xa18c, 0x00ff, 0xa186, 0x001e, 0x1d38, 0x684c, - 0xd0bc, 0x0d20, 0x6860, 0x682e, 0x685c, 0x682a, 0x6804, 0x681a, - 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x1f59, 0x2005, - 0x6832, 0x6858, 0x0440, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x1970, - 0x684c, 0xd0ac, 0x0958, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, - 0xa084, 0x000f, 0xa080, 0x1f59, 0x2005, 0x6832, 0xa006, 0x682e, - 0x682a, 0x6858, 0x0080, 0x684c, 0xd0ac, 0x0904, 0x1666, 0xa006, - 0x682e, 0x682a, 0x6858, 0xa18c, 0x000f, 0xa188, 0x1f59, 0x210d, - 0x6932, 0x2d08, 0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, - 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x0005, 0x20e1, 0x0007, - 0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, 0x82ff, 0x0178, 0xa280, - 0x0004, 0x00d6, 0x206c, 0x684c, 0xd0dc, 0x1120, 0x080c, 0x165a, - 0x190c, 0x13fe, 0x6808, 0x8000, 0x680a, 0x00de, 0x0126, 0x0046, - 0x0036, 0x0026, 0x2091, 0x2200, 0x002e, 0x003e, 0x004e, 0x7000, - 0xa005, 0x0178, 0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a, - 0x8108, 0xa182, 0x953b, 0x0210, 0x2009, 0x9520, 0x710e, 0x012e, - 0x0005, 0x7206, 0x2001, 0x16f7, 0x0006, 0x2260, 0x0804, 0x17e8, - 0x0126, 0x0026, 0x0036, 0x00c6, 0x0006, 0x2091, 0x2200, 0x000e, - 0x004e, 0x003e, 0x002e, 0x00d6, 0x00c6, 0x2460, 0x6110, 0x2168, - 0x6a62, 0x6b5e, 0xa005, 0x05b8, 0x6808, 0xa005, 0x0904, 0x177c, - 0x7000, 0xa005, 0x1108, 0x0430, 0x700c, 0x7110, 0xa106, 0x1904, - 0x1784, 0x7004, 0xa406, 0x11f0, 0x2001, 0x0005, 0x2004, 0xd08c, - 0x0130, 0x0046, 0x080c, 0x1942, 0x004e, 0x2460, 0x0c28, 0x2001, - 0x0207, 0x2004, 0xd09c, 0x1d80, 0x7804, 0xa084, 0x6000, 0x0120, - 0xa086, 0x6000, 0x0108, 0x0c40, 0x7803, 0x0004, 0x7003, 0x0000, - 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004, 0x15f0, 0x2009, 0x0048, - 0x080c, 0x7518, 0x04c8, 0x6808, 0xa005, 0x0570, 0x7000, 0xa005, - 0x0558, 0x700c, 0x7110, 0xa106, 0x1118, 0x7004, 0xa406, 0x1520, - 0x2001, 0x0005, 0x2004, 0xd08c, 0x0130, 0x0046, 0x080c, 0x1942, - 0x004e, 0x2460, 0x0c40, 0x2001, 0x0207, 0x2004, 0xd09c, 0x1d80, - 0x2001, 0x0005, 0x2004, 0xd08c, 0x1d80, 0x7804, 0xa084, 0x6000, - 0x0118, 0xa086, 0x6000, 0x1d20, 0x7818, 0x6812, 0x781c, 0x6816, - 0x7803, 0x0004, 0x7003, 0x0000, 0x6100, 0xa18e, 0x0004, 0x1120, - 0x2009, 0x0048, 0x080c, 0x7518, 0x00ce, 0x00de, 0x012e, 0x0005, - 0x00f6, 0x00e6, 0x0026, 0x0036, 0x0046, 0x080c, 0x1c26, 0x0026, - 0x2071, 0x9519, 0x7000, 0xa086, 0x0000, 0x0580, 0x7004, 0xac06, + 0x23fa, 0x080c, 0x5d10, 0x0804, 0x124f, 0x70c8, 0xd0ac, 0x1110, + 0xd09c, 0x0520, 0xd084, 0x0510, 0x0006, 0x2001, 0x0103, 0x2003, + 0x00ff, 0x000e, 0xd08c, 0x01d0, 0x70cc, 0xa086, 0xffff, 0x0190, + 0x080c, 0x24f4, 0x080c, 0x5d10, 0x70c8, 0xd094, 0x1904, 0x124f, + 0x2011, 0x0001, 0x2019, 0x0000, 0x080c, 0x2528, 0x080c, 0x5d10, + 0x0804, 0x124f, 0x70d0, 0xa005, 0x1904, 0x124f, 0x7094, 0xa005, + 0x1904, 0x124f, 0x70c8, 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x124f, + 0x2001, 0x8b52, 0x2004, 0xd0ac, 0x01c0, 0x0156, 0x00c6, 0x20a9, + 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x430a, 0x1118, 0x6000, + 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x120b, 0x00ce, 0x015e, + 0x0020, 0x001e, 0x00ce, 0x015e, 0x0490, 0x0006, 0x2001, 0x0103, + 0x2003, 0x00ff, 0x000e, 0x7003, 0x0003, 0x709b, 0xffff, 0xa006, + 0x080c, 0x2298, 0x080c, 0x3689, 0x00f6, 0x2079, 0x0100, 0x080c, + 0x4c68, 0x0150, 0x080c, 0x4c42, 0x7828, 0x0118, 0xa084, 0xe1ff, + 0x0010, 0xa084, 0xffdf, 0x782a, 0x00fe, 0x2001, 0x8dab, 0x2004, + 0xa086, 0x0005, 0x1120, 0x2011, 0x0000, 0x080c, 0x695c, 0x2011, + 0x0000, 0x080c, 0x6966, 0x080c, 0x5d10, 0x080c, 0x5dc2, 0x012e, + 0x0005, 0x0016, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, + 0x2009, 0x00f7, 0x080c, 0x40be, 0x7940, 0xa18c, 0x0010, 0x7942, + 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040, 0xd19c, 0x0110, 0x7827, + 0x0008, 0x0006, 0x0036, 0x0156, 0x7954, 0xd1ac, 0x1904, 0x12b7, + 0x080c, 0x4c54, 0x0158, 0x080c, 0x4c68, 0x1128, 0x2001, 0x8d9c, + 0x2003, 0x0000, 0x0070, 0x080c, 0x4c4a, 0x0dc0, 0x2001, 0x8d9c, + 0x2003, 0xaaaa, 0x2001, 0x8d9d, 0x2003, 0x0001, 0x080c, 0x4b8b, + 0x0058, 0x080c, 0x4c42, 0x0140, 0x2009, 0x00f8, 0x080c, 0x40be, + 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x09c4, 0x7820, 0xd09c, + 0x1138, 0x080c, 0x4c42, 0x0138, 0x7824, 0xd0ac, 0x1904, 0x131f, + 0x1f04, 0x1296, 0x0070, 0x7824, 0x080c, 0x4c5e, 0x0118, 0xd0ac, + 0x1904, 0x131f, 0xa084, 0x1800, 0x0d98, 0x7003, 0x0001, 0x0804, + 0x131f, 0x2001, 0x0001, 0x080c, 0x2298, 0x0804, 0x132a, 0x7850, + 0xa084, 0x0180, 0x7852, 0x782f, 0x0020, 0x20a9, 0x0050, 0x1d04, + 0x12bf, 0x2091, 0x6000, 0x1f04, 0x12bf, 0x7850, 0xa084, 0x0180, + 0xa085, 0x0400, 0x7852, 0x782f, 0x0000, 0x080c, 0x4c54, 0x0158, + 0x080c, 0x4c68, 0x1128, 0x2001, 0x8d9c, 0x2003, 0x0000, 0x0070, + 0x080c, 0x4c4a, 0x0dc0, 0x2001, 0x8d9c, 0x2003, 0xaaaa, 0x2001, + 0x8d9d, 0x2003, 0x0001, 0x080c, 0x4b8b, 0x0020, 0x2009, 0x00f8, + 0x080c, 0x40be, 0x20a9, 0x000e, 0xe000, 0x1f04, 0x12ec, 0x7850, + 0xa084, 0x0180, 0xa085, 0x1400, 0x7852, 0x080c, 0x4c42, 0x0120, + 0x7843, 0x0090, 0x7843, 0x0010, 0x2019, 0x61a8, 0x7820, 0xd09c, + 0x1130, 0x080c, 0x4c42, 0x0130, 0x7824, 0xd0ac, 0x11c0, 0x8319, + 0x1da8, 0x0080, 0x7827, 0x1800, 0xe000, 0xe000, 0x7824, 0x080c, + 0x4c5e, 0x0110, 0xd0ac, 0x1158, 0xa084, 0x1800, 0x0d80, 0x7003, + 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x2298, 0x0028, 0x7827, + 0x0048, 0x7828, 0xc09d, 0x782a, 0x7850, 0xa084, 0x0180, 0xa085, + 0x0400, 0x7852, 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, 0x001e, + 0x0005, 0x0005, 0x0005, 0x0005, 0x2a70, 0x2001, 0x8d9c, 0x2003, + 0x0000, 0x7087, 0x0000, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, + 0x0218, 0x704f, 0xffff, 0x0010, 0x704f, 0x0000, 0x7057, 0xffff, + 0x706f, 0x0000, 0x7073, 0x0000, 0x080c, 0x7deb, 0x2061, 0x8d8c, + 0x6003, 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200, + 0x6013, 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0, + 0x2061, 0x8d94, 0x6003, 0x8800, 0x6007, 0x0000, 0x600b, 0x0000, + 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001, + 0x601f, 0x0000, 0x2061, 0x8da4, 0x6003, 0x514c, 0x6007, 0x4f47, + 0x600b, 0x4943, 0x600f, 0x2020, 0x0005, 0x04a0, 0x2011, 0x0000, + 0x81ff, 0x0570, 0xa186, 0x0001, 0x1148, 0x2031, 0x8fff, 0x2039, + 0x9e01, 0x2021, 0x0100, 0x2029, 0x9e00, 0x00e8, 0xa186, 0x0002, + 0x1118, 0x2011, 0x0000, 0x00b8, 0xa186, 0x0005, 0x1118, 0x2011, + 0x0001, 0x0088, 0xa186, 0x0009, 0x1118, 0x2011, 0x0002, 0x0058, + 0xa186, 0x000a, 0x1118, 0x2011, 0x0002, 0x0028, 0xa186, 0x0055, + 0x1110, 0x2011, 0x0003, 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0, + 0x0804, 0x104d, 0xa00e, 0x2011, 0x0003, 0x2019, 0x13b9, 0x0804, + 0x140a, 0x2019, 0xaaaa, 0x2061, 0xffff, 0x2c14, 0x2362, 0xe000, + 0xe000, 0x2c04, 0xa306, 0x2262, 0x1110, 0xc1b5, 0xc1a5, 0x2011, + 0x0000, 0x2019, 0x13cc, 0x04f0, 0x2019, 0xaaaa, 0x2061, 0xffff, + 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c1c, 0x2061, 0x7fff, 0xe000, + 0xe000, 0x2c04, 0x2061, 0xffff, 0x2262, 0xa306, 0x0110, 0xc18d, + 0x0008, 0xc185, 0x2011, 0x0002, 0x2019, 0x13e7, 0x0418, 0x2061, + 0xffff, 0x2019, 0xaaaa, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c04, + 0x2262, 0xa306, 0x1180, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c1c, + 0x2061, 0x7fff, 0x2c04, 0x2061, 0xffff, 0x2262, 0xa306, 0x1110, + 0xc195, 0x0008, 0xc19d, 0x2011, 0x0001, 0x2019, 0x1408, 0x0010, + 0x0804, 0x137e, 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0, 0x0837, + 0x2091, 0x8000, 0x0e04, 0x1412, 0x0006, 0x0016, 0x2079, 0x0000, + 0x7818, 0xd084, 0x1de8, 0x001e, 0x792e, 0x000e, 0x782a, 0x000e, + 0x7826, 0x3900, 0x783a, 0x7823, 0x8002, 0x781b, 0x0001, 0x2091, + 0x5000, 0x0156, 0x0146, 0x20a9, 0x0010, 0x20a1, 0x8eaa, 0x2091, + 0x2000, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2200, 0x40a1, 0x20a9, + 0x0010, 0x2091, 0x2400, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2600, + 0x40a1, 0x014e, 0x015e, 0x2079, 0x8b00, 0x7803, 0x0005, 0x2091, + 0x4080, 0x0cf8, 0x0005, 0x2071, 0x8b00, 0x715c, 0x712e, 0x2021, + 0x0001, 0xa190, 0x0030, 0xa298, 0x0030, 0x0240, 0x7060, 0xa302, + 0x1228, 0x220a, 0x2208, 0x2310, 0x8420, 0x0ca8, 0x3800, 0xd08c, + 0x0148, 0x7060, 0xa086, 0x8b00, 0x0128, 0x7063, 0x8b00, 0x2011, + 0x1000, 0x0c48, 0x200b, 0x0000, 0x74aa, 0x74ae, 0x0005, 0x00e6, + 0x0126, 0x2091, 0x8000, 0x2071, 0x8b00, 0x70ac, 0xa0ea, 0x0010, + 0x0268, 0x8001, 0x70ae, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, + 0x0000, 0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e, 0x0cd8, + 0x00e6, 0x2071, 0x8b00, 0x0126, 0x2091, 0x8000, 0x70ac, 0x8001, + 0x0260, 0x70ae, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, + 0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e, 0x0cd8, 0x00e6, + 0x0126, 0x2091, 0x8000, 0x2071, 0x8b00, 0x702c, 0x206a, 0x2d00, + 0x702e, 0x70ac, 0x8000, 0x70ae, 0x012e, 0x00ee, 0x0005, 0x8dff, + 0x0138, 0x6804, 0x6807, 0x0000, 0x0006, 0x0c49, 0x00de, 0x0cb8, + 0x0005, 0x00e6, 0x2071, 0x8b00, 0x70ac, 0xa08a, 0x0010, 0xa00d, + 0x00ee, 0x0005, 0x00e6, 0x2071, 0x8dcd, 0x7007, 0x0000, 0x701b, + 0x0000, 0x701f, 0x0000, 0x2071, 0x0000, 0x7010, 0xa085, 0x8004, + 0x7012, 0x00ee, 0x0005, 0x00e6, 0x2270, 0x700b, 0x0000, 0x2071, + 0x8dcd, 0x7018, 0xa088, 0x8dd6, 0x220a, 0x8000, 0xa084, 0x0007, + 0x701a, 0x7004, 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010, 0x0081, + 0x00fe, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x8dcd, 0x7004, 0xa005, + 0x1128, 0x00f6, 0x2079, 0x0010, 0x0019, 0x00fe, 0x00ee, 0x0005, + 0x7000, 0x0002, 0x14fe, 0x1562, 0x157f, 0x157f, 0x7018, 0x711c, + 0xa106, 0x1118, 0x7007, 0x0000, 0x0005, 0x00d6, 0xa180, 0x8dd6, + 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007, 0x711e, 0x7803, + 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c, 0x783a, 0x6830, + 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804, 0x00de, 0xd084, + 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007, 0x0002, 0x00b1, + 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, + 0x1210, 0x2110, 0xa006, 0x700e, 0x7212, 0x8203, 0x7822, 0x7803, + 0x0020, 0x7803, 0x0041, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, + 0x0136, 0x0146, 0x0156, 0x7014, 0x2098, 0x20a1, 0x0014, 0x7803, + 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x1210, 0x2110, + 0xa006, 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803, 0x0020, + 0x3300, 0x7016, 0x7803, 0x0001, 0x015e, 0x014e, 0x013e, 0x002e, + 0x001e, 0x0005, 0x0136, 0x0146, 0x0156, 0x2099, 0x8bf9, 0x20a1, + 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126, 0x2091, + 0x8000, 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, + 0x700b, 0x8bf4, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005, 0x0136, + 0x0146, 0x0156, 0x2001, 0x8c28, 0x209c, 0x20a1, 0x0014, 0x7803, + 0x0026, 0x2001, 0x8c29, 0x20ac, 0x53a6, 0x2099, 0x8c2a, 0x20a1, + 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126, 0x2091, + 0x8000, 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c, 0x7002, + 0x700b, 0x8c25, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005, 0x0016, + 0x00e6, 0x2071, 0x8dcd, 0x00f6, 0x2079, 0x0010, 0x7904, 0x7803, + 0x0002, 0xd1fc, 0x0120, 0xa18c, 0x0700, 0x7004, 0x0023, 0x00fe, + 0x00ee, 0x001e, 0x0005, 0x14f8, 0x15c2, 0x15f0, 0x161a, 0x164a, + 0x15c1, 0x0cf8, 0xa18c, 0x0700, 0x1528, 0x0136, 0x0146, 0x0156, + 0x7014, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x7010, 0x20a8, + 0x53a5, 0x3400, 0x7016, 0x015e, 0x014e, 0x013e, 0x700c, 0xa005, + 0x0570, 0x7830, 0x7832, 0x7834, 0x7836, 0x080c, 0x1529, 0x0005, + 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007, 0x0000, 0x080c, + 0x14f8, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200, 0x0ca8, + 0xa18c, 0x0700, 0x1150, 0x700c, 0xa005, 0x0188, 0x7830, 0x7832, + 0x7834, 0x7836, 0x080c, 0x153e, 0x0005, 0x7008, 0xa080, 0x0002, + 0x2003, 0x0200, 0x7007, 0x0000, 0x080c, 0x14f8, 0x0005, 0x00d6, + 0x7008, 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, 0x682e, + 0x783c, 0x6832, 0x680b, 0x0100, 0x00de, 0x7007, 0x0000, 0x080c, + 0x14f8, 0x0005, 0xa18c, 0x0700, 0x1540, 0x0136, 0x0146, 0x0156, + 0x2001, 0x8bf7, 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099, 0x0014, + 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001, 0x8bf9, 0x2004, + 0xd0bc, 0x0148, 0x2001, 0x8c02, 0x2004, 0xa080, 0x000d, 0x20a0, + 0x20a9, 0x0020, 0x53a5, 0x015e, 0x014e, 0x013e, 0x7007, 0x0000, + 0x080c, 0x4e43, 0x080c, 0x14f8, 0x0005, 0x2011, 0x8003, 0x080c, + 0x3617, 0x0cf8, 0xa18c, 0x0700, 0x1148, 0x2001, 0x8c27, 0x2003, + 0x0100, 0x7007, 0x0000, 0x080c, 0x14f8, 0x0005, 0x2011, 0x8004, + 0x080c, 0x3617, 0x0cf8, 0x0126, 0x2091, 0x2200, 0x2079, 0x0030, + 0x2071, 0x8dde, 0x7003, 0x0000, 0x700f, 0x8de4, 0x7013, 0x8de4, + 0x780f, 0x00f6, 0x012e, 0x0005, 0x6934, 0xa184, 0x0007, 0x0002, + 0x1678, 0x16b6, 0x1678, 0x1678, 0x1678, 0x169e, 0x1685, 0x167c, + 0xa085, 0x0001, 0x0804, 0x16d0, 0x684c, 0xd0bc, 0x0dc8, 0x6860, + 0x682e, 0x685c, 0x682a, 0x6858, 0x04c8, 0xa18c, 0x00ff, 0xa186, + 0x001e, 0x1d70, 0x684c, 0xd0bc, 0x0d58, 0x6860, 0x682e, 0x685c, + 0x682a, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, + 0xa080, 0x1e76, 0x2005, 0x6832, 0x6858, 0x0440, 0xa18c, 0x00ff, + 0xa186, 0x0015, 0x19a8, 0x684c, 0xd0ac, 0x0990, 0x6804, 0x681a, + 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x1e76, 0x2005, + 0x6832, 0xa006, 0x682e, 0x682a, 0x6858, 0x0080, 0x684c, 0xd0ac, + 0x0904, 0x1678, 0xa006, 0x682e, 0x682a, 0x6858, 0xa18c, 0x000f, + 0xa188, 0x1e76, 0x210d, 0x6932, 0x2d08, 0x691a, 0x6826, 0x684c, + 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, + 0x0005, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, + 0x82ff, 0x0178, 0xa280, 0x0004, 0x00d6, 0x206c, 0x684c, 0xd0dc, + 0x1120, 0x080c, 0x166c, 0x190c, 0x1410, 0x6808, 0x8000, 0x680a, + 0x00de, 0x0126, 0x0046, 0x0036, 0x0026, 0x2091, 0x2200, 0x002e, + 0x003e, 0x004e, 0x7000, 0xa005, 0x01d0, 0x710c, 0x220a, 0x8108, + 0x230a, 0x8108, 0x240a, 0x8108, 0xa182, 0x8dff, 0x0210, 0x2009, + 0x8de4, 0x710e, 0x7010, 0xa102, 0xa082, 0x0009, 0x0118, 0xa080, + 0x001b, 0x1118, 0x2009, 0x0138, 0x200a, 0x012e, 0x0005, 0x7206, + 0x2001, 0x170d, 0x0006, 0x2260, 0x0804, 0x180c, 0x0126, 0x0026, + 0x0036, 0x00c6, 0x0006, 0x2091, 0x2200, 0x000e, 0x004e, 0x003e, + 0x002e, 0x00d6, 0x00c6, 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e, + 0xa005, 0x05b8, 0x6808, 0xa005, 0x0904, 0x1792, 0x7000, 0xa005, + 0x1108, 0x0430, 0x700c, 0x7110, 0xa106, 0x1904, 0x179a, 0x7004, + 0xa406, 0x11f0, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0130, 0x0046, + 0x080c, 0x18ee, 0x004e, 0x2460, 0x0c28, 0x2001, 0x0207, 0x2004, + 0xd09c, 0x1d80, 0x7804, 0xa084, 0x6000, 0x0120, 0xa086, 0x6000, + 0x0108, 0x0c40, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, + 0x6100, 0xa18e, 0x0004, 0x15f0, 0x2009, 0x0048, 0x080c, 0x6d3f, + 0x04c8, 0x6808, 0xa005, 0x0570, 0x7000, 0xa005, 0x0558, 0x700c, + 0x7110, 0xa106, 0x1118, 0x7004, 0xa406, 0x1520, 0x2001, 0x0005, + 0x2004, 0xd08c, 0x0130, 0x0046, 0x080c, 0x18ee, 0x004e, 0x2460, + 0x0c40, 0x2001, 0x0207, 0x2004, 0xd09c, 0x1d80, 0x2001, 0x0005, + 0x2004, 0xd08c, 0x1d80, 0x7804, 0xa084, 0x6000, 0x0118, 0xa086, + 0x6000, 0x1d20, 0x7818, 0x6812, 0x781c, 0x6816, 0x7803, 0x0004, + 0x7003, 0x0000, 0x6100, 0xa18e, 0x0004, 0x1120, 0x2009, 0x0048, + 0x080c, 0x6d3f, 0x00ce, 0x00de, 0x012e, 0x0005, 0x00f6, 0x00e6, + 0x0026, 0x0036, 0x0046, 0x0056, 0x080c, 0x1b5e, 0x0026, 0x0056, + 0x2071, 0x8dde, 0x7000, 0xa086, 0x0000, 0x0580, 0x7004, 0xac06, 0x11f8, 0x2079, 0x0030, 0x7000, 0xa086, 0x0003, 0x01c8, 0x7804, 0xd0fc, 0x1198, 0x2001, 0x0207, 0x2004, 0xd09c, 0x1dc0, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x1de8, 0x7803, 0x0002, 0x7803, 0x0009, - 0x7003, 0x0003, 0x7007, 0x0000, 0x0018, 0x080c, 0x1942, 0x08d0, - 0x0156, 0x20a9, 0x0009, 0x2009, 0x9520, 0x2104, 0xac06, 0x1108, - 0x200a, 0xa188, 0x0003, 0x1f04, 0x17bd, 0x015e, 0x002e, 0x2001, - 0x015d, 0x201c, 0x831a, 0x2302, 0x2001, 0x0138, 0x2202, 0x004e, - 0x003e, 0x002e, 0x00ee, 0x00fe, 0x0005, 0x700c, 0x7110, 0xa106, - 0x0904, 0x182c, 0x2104, 0x7006, 0x2060, 0x8108, 0x211c, 0x8108, - 0x2124, 0x8108, 0xa182, 0x953b, 0x0210, 0x2009, 0x9520, 0x7112, - 0x8cff, 0x05a0, 0x6010, 0x2068, 0x2d58, 0x6828, 0xa406, 0x1598, - 0x682c, 0xa306, 0x1580, 0x684c, 0xd0f4, 0x1540, 0x6850, 0xd0f4, - 0x1130, 0x7803, 0x0004, 0x6810, 0x781a, 0x6814, 0x781e, 0x6824, - 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f, - 0x6834, 0xa08c, 0x00ff, 0xa186, 0x0024, 0x0118, 0xa186, 0x002c, - 0x1120, 0x2009, 0x0011, 0x00d9, 0x0038, 0x2009, 0x0011, 0x00b9, - 0x0118, 0x2009, 0x0001, 0x0099, 0x2d58, 0x0005, 0x7803, 0x0004, - 0x080c, 0x1be2, 0x0cd0, 0x601c, 0xa086, 0x0008, 0x1108, 0x0858, - 0x080c, 0x1fa7, 0x1d98, 0x0838, 0x7003, 0x0000, 0x0005, 0x8aff, - 0x0904, 0x191c, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x11b8, 0xd0f4, - 0x1538, 0x00d6, 0x2805, 0xac68, 0x2900, 0x0002, 0x18b6, 0x1867, - 0x1867, 0x18b6, 0x18b9, 0x18ae, 0x18b6, 0x1867, 0x18b6, 0x1878, - 0x1878, 0x18b6, 0x18b9, 0x18b6, 0x18a6, 0x1878, 0x7803, 0x0004, - 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x00d6, 0xd99c, - 0x0904, 0x1909, 0x2805, 0xac68, 0x6f08, 0x6e0c, 0x0804, 0x1909, - 0xc0f4, 0x6852, 0x6b6c, 0x6a70, 0x00d6, 0x0804, 0x1910, 0x2d10, - 0x00de, 0x00d6, 0x6834, 0x2268, 0xa084, 0x00ff, 0xa096, 0x0024, - 0x0904, 0x18e9, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0804, 0x1909, - 0x2d10, 0x00de, 0x00d6, 0x6834, 0x2268, 0xa084, 0x00ff, 0xa096, - 0x002c, 0x0904, 0x18c6, 0x7b0c, 0xd3bc, 0x01c0, 0x7004, 0x00e6, - 0x2070, 0x701c, 0x00ee, 0xa086, 0x0008, 0x1180, 0x7b08, 0xa39c, - 0x0fff, 0x2d20, 0x7a1c, 0x82ff, 0x1120, 0x7818, 0xa302, 0x0208, - 0x7b18, 0xa016, 0x7a1e, 0x7b1a, 0x2468, 0x0010, 0x6b10, 0x6a14, - 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0804, 0x1909, 0x00de, 0x00d6, - 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x1140, 0x00de, 0x080c, - 0x1f1b, 0x1904, 0x182f, 0xa00e, 0x0804, 0x191c, 0x00de, 0x080c, - 0x13fe, 0x2d10, 0x00de, 0x00d6, 0x6834, 0x2268, 0xa084, 0x00ff, - 0xa096, 0x0024, 0x0530, 0xa096, 0x002c, 0x1d80, 0x6b10, 0xa3a6, - 0xffff, 0x1130, 0x2d10, 0x00de, 0x00d6, 0x080c, 0x59f4, 0x2268, - 0x2d10, 0x00de, 0x00d6, 0x7314, 0x685c, 0xa086, 0x0001, 0x1120, - 0x6868, 0xa005, 0x0108, 0x2018, 0x2268, 0x2011, 0x0000, 0x6d00, - 0x6c04, 0x6f08, 0x6e0c, 0x780f, 0x00f0, 0xe000, 0xe000, 0xe000, - 0x0400, 0x6b08, 0xa3a6, 0xffff, 0x1130, 0x2d10, 0x00de, 0x00d6, - 0x080c, 0x59f4, 0x2268, 0x2d10, 0x00de, 0x00d6, 0x7314, 0x685c, - 0xa086, 0x0001, 0x1120, 0x6868, 0xa005, 0x0108, 0x2018, 0x2268, - 0x2011, 0x0000, 0x6d00, 0x6c04, 0x780f, 0x00f0, 0xe000, 0xe000, - 0xe000, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, - 0x7000, 0x8000, 0x7002, 0x00de, 0x6828, 0xa300, 0x682a, 0x682c, - 0xa201, 0x682e, 0x080c, 0x1f1b, 0x0005, 0x080c, 0x13fe, 0x7803, - 0x0004, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068, 0x7003, 0x0000, - 0x080c, 0x1c02, 0x080c, 0x82ee, 0x0170, 0x6808, 0x8001, 0x680a, - 0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff, 0x682f, 0xffff, - 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x80f6, 0x0804, 0x1b4b, - 0x080c, 0x13fe, 0x0126, 0x2091, 0x2200, 0x0006, 0x0016, 0x2b68, - 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x1978, - 0xa184, 0x0003, 0xa086, 0x0003, 0x0d58, 0x7000, 0x0002, 0x195f, - 0x1961, 0x1aa6, 0x1b20, 0x1b3a, 0x195f, 0x195f, 0x195f, 0x080c, - 0x13fe, 0x8001, 0x7002, 0xa184, 0x0880, 0x1904, 0x19a8, 0x6834, - 0xa084, 0x00ff, 0xa086, 0x0024, 0x0130, 0x6834, 0xa084, 0x00ff, - 0xa086, 0x002c, 0x1518, 0x6864, 0x8000, 0x6866, 0xd19c, 0x0140, - 0x7004, 0x2060, 0x2009, 0x0102, 0x080c, 0x7518, 0x0804, 0x1a64, - 0x8aff, 0x0130, 0x2009, 0x0001, 0x080c, 0x182f, 0x0804, 0x1b4b, - 0x7004, 0x2060, 0x2009, 0x0106, 0x080c, 0x7518, 0x7007, 0x0000, - 0x7803, 0x0009, 0x7003, 0x0003, 0x0804, 0x1b4b, 0xd19c, 0x1904, - 0x1a49, 0x8aff, 0x0904, 0x1a49, 0x2009, 0x0001, 0x080c, 0x182f, - 0x0904, 0x1b4b, 0x2009, 0x0001, 0x080c, 0x182f, 0x0804, 0x1b4b, - 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, 0x1904, 0x1a18, 0x6834, - 0xa084, 0x00ff, 0xa086, 0x0024, 0x0130, 0x6834, 0xa084, 0x00ff, - 0xa086, 0x002c, 0x1138, 0xd19c, 0x0128, 0x6864, 0x8000, 0x6866, - 0x0804, 0x1978, 0x0026, 0x0036, 0x7c20, 0x7d24, 0x7e30, 0x7f34, - 0x7818, 0x6812, 0x781c, 0x6816, 0x2001, 0x0201, 0x2004, 0xa005, - 0x0140, 0x7808, 0xd0ec, 0x1128, 0x7803, 0x0009, 0x7003, 0x0004, - 0x0070, 0x6834, 0xa084, 0x00ff, 0xa086, 0x0024, 0x0140, 0x6834, - 0xa084, 0x00ff, 0xa086, 0x002c, 0x0110, 0x080c, 0x1b4f, 0x6b28, - 0x6a2c, 0x2400, 0x686e, 0xa31a, 0x2500, 0x6872, 0xa213, 0x6b2a, - 0x6a2e, 0x003e, 0x002e, 0x6e1e, 0x6f22, 0x080c, 0x1f31, 0x2a00, - 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852, - 0x6808, 0x8001, 0x680a, 0x1148, 0x684c, 0xd0e4, 0x0130, 0x7004, - 0x2060, 0x2009, 0x0048, 0x080c, 0x7518, 0x7000, 0xa086, 0x0004, - 0x0904, 0x1b4b, 0x7003, 0x0000, 0x080c, 0x17d5, 0x0804, 0x1b4b, - 0x0056, 0x7d0c, 0xd5bc, 0x1110, 0x080c, 0x9171, 0x005e, 0x080c, - 0x1c02, 0x7004, 0x7007, 0x0000, 0x2060, 0x601c, 0xa086, 0x0009, - 0x1198, 0x790c, 0x0016, 0x2009, 0x0106, 0x080c, 0x7518, 0x001e, - 0xd0ec, 0x1118, 0x2009, 0x0009, 0x0010, 0x2009, 0x0019, 0x7902, - 0x7003, 0x0003, 0x0804, 0x1b4b, 0x682b, 0xffff, 0x682f, 0xffff, - 0x6808, 0x8001, 0x680a, 0x697c, 0x791a, 0x6980, 0x791e, 0x0804, - 0x1b4b, 0x7818, 0x6812, 0x7a1c, 0x6a16, 0xd19c, 0x0118, 0xa205, - 0x1904, 0x19a8, 0x684c, 0xc0f5, 0x684e, 0x7814, 0xa005, 0x1180, - 0x7003, 0x0000, 0x6808, 0x8001, 0x680a, 0x1130, 0x7004, 0x2060, - 0x2009, 0x0048, 0x080c, 0x7518, 0x080c, 0x17d5, 0x0804, 0x1b4b, - 0x7818, 0x6812, 0x781c, 0x6816, 0x7814, 0x7908, 0xa18c, 0x0fff, - 0xa188, 0x0007, 0x8114, 0x8214, 0x8214, 0xa10a, 0x8104, 0x8004, - 0x8004, 0xa20a, 0x810b, 0x810b, 0x810b, 0x080c, 0x1c40, 0x7803, - 0x0004, 0x780f, 0xffff, 0x7803, 0x0001, 0x7804, 0xd0fc, 0x0de8, - 0x7803, 0x0002, 0x7803, 0x0004, 0x780f, 0x00f0, 0x7004, 0x7007, - 0x0000, 0x2060, 0x2009, 0x0048, 0x080c, 0x7518, 0x080c, 0x1c62, - 0x0958, 0x7908, 0xd1ec, 0x1118, 0x2009, 0x0009, 0x0010, 0x2009, - 0x0019, 0x7902, 0x7003, 0x0003, 0x0804, 0x1b4b, 0x8001, 0x7002, - 0xd194, 0x0178, 0x7804, 0xd0fc, 0x1904, 0x194a, 0xd09c, 0x11a8, - 0x8aff, 0x0904, 0x1b4b, 0x2009, 0x0001, 0x080c, 0x182f, 0x0804, - 0x1b4b, 0xa184, 0x0888, 0x1148, 0x8aff, 0x0904, 0x1b4b, 0x2009, - 0x0001, 0x080c, 0x182f, 0x0804, 0x1b4b, 0x7803, 0x0004, 0x7003, - 0x0000, 0xd1bc, 0x1904, 0x1b0d, 0x0026, 0x0036, 0x7c20, 0x7d24, - 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816, 0x2001, 0x0201, - 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128, 0x7803, 0x0009, - 0x7003, 0x0004, 0x0020, 0x0016, 0x080c, 0x1b4f, 0x001e, 0x6b28, - 0x6a2c, 0x080c, 0x1f31, 0x00d6, 0x2805, 0xac68, 0x6034, 0xd09c, - 0x1128, 0x6808, 0xa31a, 0x680c, 0xa213, 0x0020, 0x6810, 0xa31a, - 0x6814, 0xa213, 0x00de, 0xd194, 0x0904, 0x19e9, 0x2a00, 0x6826, - 0x2c00, 0x681a, 0x2800, 0x6832, 0x6808, 0x8001, 0x680a, 0x6b2a, - 0x6a2e, 0x003e, 0x002e, 0x0804, 0x1a64, 0x0056, 0x7d0c, 0x080c, - 0x9171, 0x005e, 0x080c, 0x1c02, 0x682b, 0xffff, 0x682f, 0xffff, - 0x6808, 0x8001, 0x680a, 0x697c, 0x791a, 0x6980, 0x791e, 0x0458, - 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, 0x0180, 0x6808, - 0x8001, 0x680a, 0x1160, 0x7004, 0x2060, 0x2009, 0x0048, 0x601c, - 0xa086, 0x0009, 0x1110, 0x080c, 0x13fe, 0x080c, 0x7518, 0x080c, - 0x17d5, 0x0088, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, - 0x6010, 0xa005, 0x0da0, 0x2068, 0x6808, 0x8000, 0x680a, 0x6c28, - 0x6b2c, 0x080c, 0x17e8, 0x001e, 0x000e, 0x012e, 0x0005, 0x700c, - 0x7110, 0xa106, 0x0904, 0x1bd6, 0x7004, 0x0016, 0x210c, 0xa106, - 0x001e, 0x0904, 0x1bd6, 0x00d6, 0x00c6, 0x216c, 0x2d00, 0xa005, - 0x0904, 0x1bd4, 0x6810, 0x2068, 0x6834, 0xa084, 0x00ff, 0xa086, - 0x0024, 0x0904, 0x1bd4, 0x6834, 0xa084, 0x00ff, 0xa086, 0x002c, - 0x0904, 0x1bd4, 0x6850, 0xd0fc, 0x0558, 0x8108, 0x2104, 0x6b2c, - 0xa306, 0x1904, 0x1bd4, 0x8108, 0x2104, 0x6a28, 0xa206, 0x1904, - 0x1bd4, 0x6850, 0xc0fc, 0xc0f5, 0x6852, 0x686c, 0x7822, 0x6870, - 0x7826, 0x681c, 0x7832, 0x6820, 0x7836, 0x6818, 0x2060, 0x6034, - 0xd09c, 0x0150, 0x6830, 0x2005, 0x00d6, 0xac68, 0x6808, 0x783a, - 0x680c, 0x783e, 0x00de, 0x0490, 0xa006, 0x783a, 0x783e, 0x0470, - 0x8108, 0x2104, 0xa005, 0x1580, 0x8108, 0x2104, 0xa005, 0x1560, - 0x6850, 0xc0f5, 0x6852, 0x6830, 0x2005, 0x6918, 0xa160, 0x6834, - 0xd09c, 0x1170, 0x6008, 0x7822, 0x686e, 0x600c, 0x7826, 0x6872, - 0x6000, 0x7832, 0x6004, 0x7836, 0xa006, 0x783a, 0x783e, 0x0070, - 0x6010, 0x7822, 0x686e, 0x6014, 0x7826, 0x6872, 0x6000, 0x7832, - 0x6004, 0x7836, 0x6008, 0x783a, 0x600c, 0x783e, 0x6810, 0x781a, - 0x6814, 0x781e, 0x7803, 0x0011, 0x00ce, 0x00de, 0x0005, 0x2011, - 0x0201, 0x2009, 0x003c, 0x2204, 0xa005, 0x1118, 0x8109, 0x1dd8, - 0x0005, 0x0005, 0x0ca1, 0x01e0, 0x7908, 0xd1ec, 0x1160, 0x080c, - 0x1c62, 0x0148, 0x7803, 0x0009, 0x7904, 0xd1fc, 0x0de8, 0x7803, - 0x0006, 0x0c29, 0x0168, 0x780c, 0xd0a4, 0x1150, 0x7007, 0x0000, - 0x080c, 0x1c62, 0x0130, 0x7803, 0x0019, 0x7003, 0x0003, 0x0008, - 0x0009, 0x0005, 0x00c6, 0x0411, 0x20e1, 0x9028, 0x700c, 0x7110, - 0xa106, 0x0190, 0x2104, 0xa005, 0x0130, 0x2060, 0x6010, 0x2060, - 0x6008, 0x8001, 0x600a, 0xa188, 0x0003, 0xa182, 0x953b, 0x0210, - 0x2009, 0x9520, 0x7112, 0x0c50, 0x2001, 0x015d, 0x200c, 0x810a, - 0x2102, 0x2001, 0x0138, 0x2202, 0x00ce, 0x0005, 0x2001, 0x0138, - 0x2014, 0x2003, 0x0000, 0x2021, 0xb015, 0x2001, 0x0141, 0x201c, - 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0xa39c, 0x0048, 0x1138, - 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70, 0x0005, - 0x3c00, 0x0006, 0x00e6, 0x2071, 0x0200, 0x7808, 0xa084, 0xf000, - 0xa10d, 0x08e1, 0x20e1, 0x7000, 0x7324, 0x7420, 0x7028, 0x7028, - 0x7426, 0x7037, 0x0001, 0x810f, 0x712e, 0x702f, 0x0100, 0x7037, - 0x0008, 0x7326, 0x7422, 0x2001, 0x0138, 0x2202, 0x00ee, 0x000e, + 0x7003, 0x0003, 0x7007, 0x0000, 0x0018, 0x080c, 0x18ee, 0x08d0, + 0x0156, 0x20a9, 0x0009, 0x2009, 0x8de4, 0x2104, 0xac06, 0x1108, + 0x200a, 0xa188, 0x0003, 0x1f04, 0x17d5, 0x015e, 0x005e, 0x002e, + 0x2001, 0x015d, 0x201c, 0x831a, 0x2302, 0x2001, 0x0160, 0x2502, + 0x2001, 0x0138, 0x2202, 0x005e, 0x004e, 0x003e, 0x002e, 0x00ee, + 0x00fe, 0x0005, 0x700c, 0x7110, 0xa106, 0x0904, 0x1841, 0x2104, + 0x7006, 0x2060, 0x8108, 0x211c, 0x8108, 0x2124, 0x8108, 0xa182, + 0x8dff, 0x0210, 0x2009, 0x8de4, 0x7112, 0x700c, 0xa106, 0x1120, + 0x2001, 0x0138, 0x2003, 0x0008, 0x8cff, 0x0538, 0x6010, 0x2068, + 0x2d58, 0x6828, 0xa406, 0x1520, 0x682c, 0xa306, 0x1508, 0x684c, + 0xd0f4, 0x11d8, 0x6850, 0xd0f4, 0x1130, 0x7803, 0x0004, 0x6810, + 0x781a, 0x6814, 0x781e, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, + 0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009, 0x0011, 0x00a9, 0x0118, + 0x2009, 0x0001, 0x0089, 0x2d58, 0x0005, 0x080c, 0x1b10, 0x0ce0, + 0x601c, 0xa086, 0x0008, 0x1108, 0x08d0, 0x080c, 0x1e96, 0x1da8, + 0x08b0, 0x7003, 0x0000, 0x0005, 0x8aff, 0x0904, 0x18c8, 0xa03e, + 0x2730, 0x6850, 0xd0fc, 0x11b8, 0xd0f4, 0x1538, 0x00d6, 0x2805, + 0xac68, 0x2900, 0x0002, 0x18b2, 0x187c, 0x187c, 0x18b2, 0x18b2, + 0x18ab, 0x18b2, 0x187c, 0x18b2, 0x1881, 0x1881, 0x18b2, 0x18b2, + 0x18b2, 0x18a3, 0x1881, 0x7803, 0x0004, 0xc0fc, 0x6852, 0x6b6c, + 0x6a70, 0x6d1c, 0x6c20, 0x00d6, 0xd99c, 0x0904, 0x18b5, 0x2805, + 0xac68, 0x6f08, 0x6e0c, 0x0804, 0x18b5, 0xc0f4, 0x6852, 0x6b6c, + 0x6a70, 0x00d6, 0x0804, 0x18bc, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, + 0x04a0, 0x7b0c, 0xd3bc, 0x01c0, 0x7004, 0x00e6, 0x2070, 0x701c, + 0x00ee, 0xa086, 0x0008, 0x1180, 0x7b08, 0xa39c, 0x0fff, 0x2d20, + 0x7a1c, 0x82ff, 0x1120, 0x7818, 0xa302, 0x0208, 0x7b18, 0xa016, + 0x7a1e, 0x7b1a, 0x2468, 0x0010, 0x6b10, 0x6a14, 0x6d00, 0x6c04, + 0x6f08, 0x6e0c, 0x0090, 0x00de, 0x00d6, 0x6834, 0xa084, 0x00ff, + 0xa086, 0x001e, 0x1138, 0x00de, 0x080c, 0x1e38, 0x1904, 0x1844, + 0xa00e, 0x00b0, 0x00de, 0x080c, 0x1410, 0x7b22, 0x7a26, 0x7d32, + 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x00de, + 0x6828, 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x080c, 0x1e38, + 0x0005, 0x080c, 0x1410, 0x7803, 0x0004, 0x7004, 0x2060, 0x00d6, + 0x6010, 0x2068, 0x7003, 0x0000, 0x080c, 0x1b30, 0x080c, 0x7b8f, + 0x0170, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, + 0x682b, 0xffff, 0x682f, 0xffff, 0x6850, 0xc0bd, 0x6852, 0x00de, + 0x080c, 0x795f, 0x0804, 0x1a87, 0x080c, 0x1410, 0x0126, 0x2091, + 0x2200, 0x0006, 0x0016, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, + 0x0002, 0xa184, 0x0700, 0x1978, 0xa184, 0x0003, 0xa086, 0x0003, + 0x0d58, 0x7000, 0x0002, 0x190b, 0x190d, 0x19e8, 0x1a62, 0x1a76, + 0x190b, 0x190b, 0x190b, 0x080c, 0x1410, 0x8001, 0x7002, 0xa184, + 0x0880, 0x1190, 0xd19c, 0x1904, 0x198b, 0x8aff, 0x0904, 0x198b, + 0x2009, 0x0001, 0x080c, 0x1844, 0x0904, 0x1a87, 0x2009, 0x0001, + 0x080c, 0x1844, 0x0804, 0x1a87, 0x7803, 0x0004, 0x7003, 0x0000, + 0xd1bc, 0x1904, 0x1975, 0x0026, 0x0036, 0x7c20, 0x7d24, 0x7e30, + 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816, 0x2001, 0x0201, 0x2004, + 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128, 0x7803, 0x0009, 0x7003, + 0x0004, 0x0010, 0x080c, 0x1a8b, 0x6b28, 0x6a2c, 0x2400, 0x686e, + 0xa31a, 0x2500, 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x003e, 0x002e, + 0x6e1e, 0x6f22, 0x080c, 0x1e4e, 0x2a00, 0x6826, 0x2c00, 0x681a, + 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852, 0x6808, 0x8001, 0x680a, + 0x1148, 0x684c, 0xd0e4, 0x0130, 0x7004, 0x2060, 0x2009, 0x0048, + 0x080c, 0x6d3f, 0x7000, 0xa086, 0x0004, 0x0904, 0x1a87, 0x7003, + 0x0000, 0x080c, 0x17f2, 0x0804, 0x1a87, 0x0056, 0x7d0c, 0xd5bc, + 0x1110, 0x080c, 0x8a1c, 0x005e, 0x080c, 0x1b30, 0x682b, 0xffff, + 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x791a, 0x6980, + 0x791e, 0x0804, 0x1a87, 0x7818, 0x6812, 0x7a1c, 0x6a16, 0xd19c, + 0x0118, 0xa205, 0x1904, 0x1924, 0x684c, 0xc0f5, 0x684e, 0x7814, + 0xa005, 0x1180, 0x7003, 0x0000, 0x6808, 0x8001, 0x680a, 0x1130, + 0x7004, 0x2060, 0x2009, 0x0048, 0x080c, 0x6d3f, 0x080c, 0x17f2, + 0x0804, 0x1a87, 0x7818, 0x6812, 0x781c, 0x6816, 0x7814, 0x7908, + 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214, 0x8214, 0xa10a, + 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b, 0x810b, 0x080c, + 0x1b7d, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803, 0x0001, 0x7804, + 0xd0fc, 0x0de8, 0x7803, 0x0002, 0x7803, 0x0004, 0x780f, 0x00f6, + 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, 0x0048, 0x080c, 0x6d3f, + 0x080c, 0x1ba2, 0x0958, 0x7908, 0xd1ec, 0x1118, 0x2009, 0x0009, + 0x0010, 0x2009, 0x0019, 0x7902, 0x7003, 0x0003, 0x0804, 0x1a87, + 0x8001, 0x7002, 0xd194, 0x0178, 0x7804, 0xd0fc, 0x1904, 0x18f6, + 0xd09c, 0x11a8, 0x8aff, 0x0904, 0x1a87, 0x2009, 0x0001, 0x080c, + 0x1844, 0x0804, 0x1a87, 0xa184, 0x0888, 0x1148, 0x8aff, 0x0904, + 0x1a87, 0x2009, 0x0001, 0x080c, 0x1844, 0x0804, 0x1a87, 0x7803, + 0x0004, 0x7003, 0x0000, 0xd1bc, 0x1904, 0x1a4f, 0x0026, 0x0036, + 0x7c20, 0x7d24, 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816, + 0x2001, 0x0201, 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128, + 0x7803, 0x0009, 0x7003, 0x0004, 0x0020, 0x0016, 0x080c, 0x1a8b, + 0x001e, 0x6b28, 0x6a2c, 0x080c, 0x1e4e, 0x00d6, 0x2805, 0xac68, + 0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c, 0xa213, 0x0020, + 0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0xd194, 0x0904, 0x1946, + 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6808, 0x8001, + 0x680a, 0x6b2a, 0x6a2e, 0x003e, 0x002e, 0x0804, 0x19a6, 0x0056, + 0x7d0c, 0x080c, 0x8a1c, 0x005e, 0x080c, 0x1b30, 0x682b, 0xffff, + 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x791a, 0x6980, + 0x791e, 0x0428, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, + 0x0150, 0x6808, 0x8001, 0x680a, 0x1130, 0x7004, 0x2060, 0x2009, + 0x0048, 0x080c, 0x6d3f, 0x080c, 0x17f2, 0x0088, 0x7803, 0x0004, + 0x7003, 0x0000, 0x7004, 0x2060, 0x6010, 0xa005, 0x0da0, 0x2068, + 0x6808, 0x8000, 0x680a, 0x6c28, 0x6b2c, 0x080c, 0x180c, 0x001e, + 0x000e, 0x012e, 0x0005, 0x700c, 0x7110, 0xa106, 0x0904, 0x1b04, + 0x7004, 0x0016, 0x210c, 0xa106, 0x001e, 0x0904, 0x1b04, 0x00d6, + 0x00c6, 0x216c, 0x2d00, 0xa005, 0x0904, 0x1b02, 0x6810, 0x2068, + 0x6850, 0xd0fc, 0x0558, 0x8108, 0x2104, 0x6b2c, 0xa306, 0x1904, + 0x1b02, 0x8108, 0x2104, 0x6a28, 0xa206, 0x1904, 0x1b02, 0x6850, + 0xc0fc, 0xc0f5, 0x6852, 0x686c, 0x7822, 0x6870, 0x7826, 0x681c, + 0x7832, 0x6820, 0x7836, 0x6818, 0x2060, 0x6034, 0xd09c, 0x0150, + 0x6830, 0x2005, 0x00d6, 0xac68, 0x6808, 0x783a, 0x680c, 0x783e, + 0x00de, 0x0490, 0xa006, 0x783a, 0x783e, 0x0470, 0x8108, 0x2104, + 0xa005, 0x1580, 0x8108, 0x2104, 0xa005, 0x1560, 0x6850, 0xc0f5, + 0x6852, 0x6830, 0x2005, 0x6918, 0xa160, 0x6834, 0xd09c, 0x1170, + 0x6008, 0x7822, 0x686e, 0x600c, 0x7826, 0x6872, 0x6000, 0x7832, + 0x6004, 0x7836, 0xa006, 0x783a, 0x783e, 0x0070, 0x6010, 0x7822, + 0x686e, 0x6014, 0x7826, 0x6872, 0x6000, 0x7832, 0x6004, 0x7836, + 0x6008, 0x783a, 0x600c, 0x783e, 0x6810, 0x781a, 0x6814, 0x781e, + 0x7803, 0x0011, 0x00ce, 0x00de, 0x0005, 0x2011, 0x0201, 0x2009, + 0x003c, 0x2204, 0xa005, 0x1118, 0x8109, 0x1dd8, 0x0005, 0x0005, + 0x0ca1, 0x01e0, 0x7908, 0xd1ec, 0x1160, 0x080c, 0x1ba2, 0x0148, + 0x7803, 0x0009, 0x7904, 0xd1fc, 0x0de8, 0x7803, 0x0006, 0x0c29, + 0x0168, 0x780c, 0xd0a4, 0x1150, 0x7007, 0x0000, 0x080c, 0x1ba2, + 0x0130, 0x7803, 0x0019, 0x7003, 0x0003, 0x0008, 0x0009, 0x0005, + 0x00c6, 0x0461, 0x20e1, 0x9028, 0x700c, 0x7110, 0xa106, 0x01c8, + 0x2104, 0xa005, 0x0130, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001, + 0x600a, 0xa188, 0x0003, 0xa182, 0x8dff, 0x0210, 0x2009, 0x8de4, + 0x7112, 0x700c, 0xa106, 0x1d40, 0x2001, 0x0138, 0x2003, 0x0008, + 0x0c18, 0x2001, 0x015d, 0x200c, 0x810a, 0x2102, 0x2001, 0x0160, + 0x2502, 0x2001, 0x0138, 0x2202, 0x00ce, 0x0005, 0x2001, 0x0138, + 0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000, + 0x2021, 0xb015, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001, + 0x0109, 0x201c, 0xa39c, 0x0048, 0x1138, 0x2001, 0x0111, 0x201c, + 0x83ff, 0x1110, 0x8421, 0x1d70, 0x0005, 0x3c00, 0x0006, 0x00e6, + 0x2071, 0x0200, 0x7808, 0xa084, 0xf000, 0xa10d, 0x08b9, 0x20e1, + 0x7000, 0x7324, 0x7420, 0x7028, 0x7028, 0x7426, 0x7037, 0x0001, + 0x810f, 0x712e, 0x702f, 0x0100, 0x7037, 0x0008, 0x7326, 0x7422, + 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x00ee, 0x000e, 0x20e0, 0x0005, 0x3c00, 0x0006, 0x7908, 0xa18c, 0x0fff, 0xa182, 0x0009, 0x0218, 0xa085, 0x0001, 0x0088, 0x2001, 0x020a, 0x81ff, 0x0130, 0x20e1, 0x6000, 0x200c, 0x200c, 0x200c, 0x200c, 0x20e1, 0x7000, 0x200c, 0x200c, 0x7003, 0x0000, 0xa006, 0x000e, 0x20e0, - 0x0005, 0x00e6, 0x2071, 0x953b, 0x7003, 0x0000, 0x00ee, 0x0005, - 0x00d6, 0xa280, 0x0004, 0x206c, 0x694c, 0xd1dc, 0x1904, 0x1d0d, - 0x6934, 0xa184, 0x0007, 0x0002, 0x1c9c, 0x1cf8, 0x1c9c, 0x1c9e, - 0x1c9c, 0x1cdf, 0x1cbe, 0x1cad, 0x080c, 0x13fe, 0x2100, 0xa084, - 0x00ff, 0xa086, 0x0013, 0x0904, 0x1cf8, 0x2100, 0xa084, 0x00ff, - 0xa086, 0x001b, 0x0904, 0x1cf8, 0x0c78, 0x684c, 0xd0b4, 0x0904, - 0x1e15, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, - 0x680a, 0x6880, 0x680e, 0x6958, 0x0804, 0x1d00, 0x6834, 0xa084, - 0x00ff, 0xa086, 0x001e, 0x19c0, 0x684c, 0xd0b4, 0x0904, 0x1e15, - 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, - 0x6880, 0x680e, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, - 0x000f, 0xa080, 0x1f59, 0x2005, 0x6832, 0x6958, 0x0450, 0xa18c, - 0x00ff, 0xa186, 0x0015, 0x1548, 0x684c, 0xd0b4, 0x0904, 0x1e15, - 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, - 0x1f59, 0x2005, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0088, - 0x684c, 0xd0b4, 0x0904, 0x191d, 0x6958, 0xa006, 0x682e, 0x682a, - 0x2d00, 0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x1f59, 0x2005, - 0x6832, 0x6926, 0x684c, 0xc0dd, 0x684e, 0x00de, 0x0005, 0x00f6, - 0x2079, 0x0020, 0x7804, 0xd0fc, 0x190c, 0x1e3b, 0x00e6, 0x00d6, - 0x2071, 0x953b, 0x7000, 0xa005, 0x1904, 0x1d81, 0x00c6, 0x7206, - 0xa280, 0x0004, 0x205c, 0x7004, 0x2068, 0x7803, 0x0004, 0x6818, - 0x00d6, 0x2068, 0x686c, 0x7812, 0x6890, 0x00f6, 0x20e1, 0x9040, - 0x2079, 0x0200, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x00fe, - 0x00de, 0x2b68, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, - 0x6034, 0xa0cc, 0x000f, 0x6908, 0xa184, 0x0007, 0x0128, 0x0016, - 0x2009, 0x0008, 0xa102, 0x001e, 0xa108, 0x791a, 0x7116, 0x701e, - 0x680c, 0xa081, 0x0000, 0x781e, 0x701a, 0xa006, 0x700e, 0x7012, - 0x7004, 0x692c, 0x6814, 0xa106, 0x1120, 0x6928, 0x6810, 0xa106, - 0x0158, 0x0036, 0x0046, 0x6b14, 0x6c10, 0x080c, 0x1fa7, 0x004e, - 0x003e, 0x0110, 0x00ce, 0x00a8, 0x8aff, 0x1120, 0x00ce, 0xa085, - 0x0001, 0x0078, 0x0126, 0x2091, 0x8000, 0x2079, 0x0020, 0x2009, - 0x0001, 0x0059, 0x0118, 0x2009, 0x0001, 0x0039, 0x012e, 0x00ce, - 0xa006, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x0076, 0x0066, 0x0056, - 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x1e0e, 0x700c, 0x7214, - 0xa23a, 0x7010, 0x7218, 0xa203, 0x0a04, 0x1e0d, 0xa705, 0x0904, - 0x1e0d, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x11a8, 0x00d6, 0x2805, - 0xac68, 0x2900, 0x0002, 0x1ddc, 0x1dc1, 0x1dc1, 0x1ddc, 0x1ddc, - 0x1dd5, 0x1ddc, 0x1dc1, 0x1ddc, 0x1dc6, 0x1dc6, 0x1ddc, 0x1ddc, - 0x1ddc, 0x1dcd, 0x1dc6, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, - 0x6c20, 0xd99c, 0x05c8, 0x00d6, 0x2805, 0xac68, 0x6f08, 0x6e0c, - 0x0490, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0468, 0x6b10, 0x6a14, - 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0430, 0x00de, 0x00d6, 0x6834, - 0xa084, 0x00ff, 0xa086, 0x001e, 0x1138, 0x00de, 0x080c, 0x1f1b, - 0x1904, 0x1d8b, 0xa00e, 0x0490, 0x2d10, 0x00de, 0x00d6, 0x6834, - 0xa084, 0x00ff, 0xa086, 0x0013, 0x2268, 0x09d8, 0x2d10, 0x00de, - 0x00d6, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001b, 0x2268, 0x09b0, - 0x00de, 0x080c, 0x13fe, 0x00de, 0x7b22, 0x7a26, 0x7d32, 0x7c36, - 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x6828, 0xa300, - 0x682a, 0x682c, 0xa201, 0x682e, 0x700c, 0xa300, 0x700e, 0x7010, - 0xa201, 0x7012, 0x080c, 0x1f1b, 0x0008, 0xa006, 0x002e, 0x003e, - 0x004e, 0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x13fe, 0x2001, - 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, - 0x0000, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068, 0x080c, 0x82ee, - 0x0118, 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x80f6, 0x20e1, - 0x9040, 0x080c, 0x7366, 0x2011, 0x0000, 0x080c, 0x7199, 0x080c, - 0x651c, 0x0804, 0x1ef0, 0x0126, 0x2091, 0x2400, 0x0006, 0x0016, - 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x2079, 0x0020, 0x2071, 0x953b, - 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, - 0x1930, 0x7000, 0x0002, 0x1ef0, 0x1e57, 0x1ec3, 0x1eee, 0x8001, - 0x7002, 0xd19c, 0x1170, 0x8aff, 0x0540, 0x2009, 0x0001, 0x080c, - 0x1d85, 0x0904, 0x1ef0, 0x2009, 0x0001, 0x080c, 0x1d85, 0x0804, - 0x1ef0, 0x7803, 0x0004, 0xd194, 0x0148, 0x6850, 0xc0fc, 0x6852, - 0x8aff, 0x1148, 0x684c, 0xc0f5, 0x684e, 0x0028, 0x080c, 0x1f31, - 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, - 0x6832, 0x7003, 0x0000, 0x0804, 0x1ef0, 0x711c, 0x81ff, 0x0190, - 0x7918, 0x7922, 0x7827, 0x0000, 0x7803, 0x0001, 0x7000, 0x8000, - 0x7002, 0x700c, 0xa100, 0x700e, 0x7010, 0xa081, 0x0000, 0x7012, - 0x0804, 0x1ef0, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006, - 0x2079, 0x0100, 0x7a14, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, - 0x7820, 0xd0bc, 0x1de8, 0x79c8, 0x000e, 0xa102, 0x001e, 0x0006, - 0x0016, 0x79c4, 0x000e, 0xa102, 0x78c6, 0x000e, 0x78ca, 0xa284, - 0x0004, 0xa085, 0x0012, 0x7816, 0x002e, 0x00fe, 0x7803, 0x0008, - 0x7003, 0x0000, 0x0468, 0x8001, 0x7002, 0xd194, 0x0168, 0x7804, - 0xd0fc, 0x1904, 0x1e4b, 0xd19c, 0x11f8, 0x8aff, 0x0508, 0x2009, - 0x0001, 0x080c, 0x1d85, 0x00e0, 0x0026, 0x0036, 0x6b28, 0x6a2c, - 0x080c, 0x1f31, 0x00d6, 0x2805, 0xac68, 0x6034, 0xd09c, 0x1128, - 0x6808, 0xa31a, 0x680c, 0xa213, 0x0020, 0x6810, 0xa31a, 0x6814, - 0xa213, 0x00de, 0x0804, 0x1e76, 0x0804, 0x1e76, 0x080c, 0x13fe, - 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x001e, 0x000e, 0x012e, 0x0005, - 0x00f6, 0x00e6, 0x2071, 0x953b, 0x7000, 0xa086, 0x0000, 0x01c0, - 0x2079, 0x0020, 0x20e1, 0x9040, 0x7804, 0xd0fc, 0x0dd8, 0x080c, - 0x1e3b, 0x7000, 0xa086, 0x0000, 0x1da8, 0x7803, 0x0004, 0x7804, - 0xd0ac, 0x1de8, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, - 0x00ee, 0x00fe, 0x0005, 0x8840, 0x2805, 0xa005, 0x1170, 0x6004, - 0xa005, 0x0168, 0x681a, 0x2060, 0x6034, 0xa084, 0x000f, 0xa080, - 0x1f59, 0x2045, 0x88ff, 0x090c, 0x13fe, 0x8a51, 0x0005, 0x2050, - 0x0005, 0x8a50, 0x8841, 0x2805, 0xa005, 0x1190, 0x2c00, 0xad06, - 0x0120, 0x6000, 0xa005, 0x1108, 0x2d00, 0x2060, 0x681a, 0x6034, - 0xa084, 0x000f, 0xa080, 0x1f69, 0x2045, 0x88ff, 0x090c, 0x13fe, - 0x0005, 0x0000, 0x0011, 0x0015, 0x0019, 0x001d, 0x0021, 0x0025, - 0x0029, 0x0000, 0x000f, 0x0015, 0x001b, 0x0021, 0x0027, 0x0000, - 0x0000, 0x0000, 0x1f4e, 0x1f4a, 0x1f4e, 0x1f4e, 0x1f58, 0x0000, - 0x1f4e, 0x0000, 0x1f55, 0x1f52, 0x1f55, 0x1f55, 0x0000, 0x1f58, - 0x1f55, 0x0000, 0x1f50, 0x1f50, 0x0000, 0x1f50, 0x1f58, 0x0000, - 0x1f50, 0x0000, 0x1f56, 0x1f56, 0x0000, 0x1f56, 0x0000, 0x1f58, - 0x1f56, 0x0136, 0x0146, 0x0156, 0x2099, 0x9359, 0x20a1, 0x0018, - 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126, 0x2091, 0x8000, - 0x7803, 0x0041, 0x7007, 0x0005, 0x7000, 0xc094, 0x7002, 0x700b, - 0x9354, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005, 0x2099, 0x0014, - 0x7803, 0x0040, 0x2001, 0x9359, 0x2004, 0x2010, 0x080c, 0x59a7, - 0x080c, 0x5949, 0x7007, 0x0000, 0x080c, 0x14ec, 0x0005, 0x00a6, - 0x0096, 0x0086, 0x6858, 0xa055, 0x0904, 0x2036, 0x2d60, 0x6034, - 0xa0cc, 0x000f, 0xa9c0, 0x1f59, 0xa986, 0x0007, 0x0130, 0xa986, - 0x000e, 0x0118, 0xa986, 0x000f, 0x1120, 0x605c, 0xa422, 0x6060, - 0xa31a, 0x2805, 0xa045, 0x1140, 0x0310, 0x0804, 0x2036, 0x6004, - 0xa065, 0x0904, 0x2036, 0x0c18, 0x2805, 0xa005, 0x01a8, 0xac68, - 0xd99c, 0x1128, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0020, 0x6810, - 0xa422, 0x6814, 0xa31b, 0x0620, 0x2300, 0xa405, 0x0150, 0x8a51, - 0x0904, 0x2036, 0x8840, 0x0c40, 0x6004, 0xa065, 0x0904, 0x2036, - 0x0830, 0x8a51, 0x0904, 0x2036, 0x8840, 0x2805, 0xa005, 0x1158, - 0x6004, 0xa065, 0x0904, 0x2036, 0x6034, 0xa0cc, 0x000f, 0xa9c0, - 0x1f59, 0x2805, 0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852, 0x0458, - 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x00d6, 0x2b68, 0x6c6e, - 0x6b72, 0x00de, 0xd99c, 0x1168, 0x6908, 0x2400, 0xa122, 0x690c, - 0x2300, 0xa11b, 0x0a0c, 0x13fe, 0x6800, 0xa420, 0x6804, 0xa319, - 0x0060, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, 0x0a0c, - 0x13fe, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, 0x6b22, - 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832, 0x2a00, - 0x6826, 0x000e, 0x000e, 0x000e, 0xa006, 0x0028, 0x008e, 0x009e, - 0x00ae, 0xa085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004, 0xa084, - 0x0007, 0x0002, 0x204a, 0x204b, 0x204e, 0x2051, 0x2056, 0x2059, - 0x205e, 0x2063, 0x0005, 0x080c, 0x1e3b, 0x0005, 0x080c, 0x1942, - 0x0005, 0x080c, 0x1942, 0x080c, 0x1e3b, 0x0005, 0x080c, 0x159c, - 0x0005, 0x080c, 0x1e3b, 0x080c, 0x159c, 0x0005, 0x080c, 0x1942, - 0x080c, 0x159c, 0x0005, 0x080c, 0x1942, 0x080c, 0x1e3b, 0x080c, - 0x159c, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, - 0x9780, 0x2069, 0x9200, 0x2009, 0x0004, 0x7912, 0x7817, 0x0004, - 0x080c, 0x23e6, 0x781b, 0x0002, 0x783b, 0x001f, 0x20e1, 0x8700, - 0x012e, 0x0005, 0x0126, 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, - 0x210b, 0xa084, 0x0007, 0x0002, 0x20a6, 0x2094, 0x2097, 0x209a, - 0x209f, 0x20a1, 0x20a3, 0x20a5, 0x080c, 0x5338, 0x0078, 0x080c, - 0x536c, 0x0060, 0x080c, 0x5338, 0x080c, 0x536c, 0x0038, 0x0041, - 0x0028, 0x0031, 0x0018, 0x0021, 0x0008, 0x0011, 0x012e, 0x0005, - 0x0006, 0x0016, 0x0026, 0x7930, 0xa184, 0x0003, 0x0118, 0x20e1, - 0x9040, 0x00b8, 0xa184, 0x0030, 0x0150, 0x6a00, 0xa286, 0x0003, - 0x1108, 0x0010, 0x080c, 0x4105, 0x20e1, 0x9010, 0x0050, 0xa184, - 0x00c0, 0x0110, 0x080c, 0x13fe, 0xa184, 0x0300, 0x0110, 0x20e1, - 0x9020, 0x7932, 0x002e, 0x001e, 0x000e, 0x0005, 0x0016, 0x00e6, - 0x00f6, 0x2071, 0x9200, 0x7128, 0x2001, 0x94ca, 0x2102, 0x2001, - 0x94d2, 0x2102, 0xa182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, - 0xa182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0xa182, 0x02c1, - 0x1218, 0x2009, 0x0006, 0x00a0, 0xa182, 0x0349, 0x1218, 0x2009, - 0x0005, 0x0070, 0xa182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, - 0xa182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, - 0x2079, 0x0200, 0x7912, 0x7817, 0x0004, 0x080c, 0x23e6, 0x00fe, - 0x00ee, 0x001e, 0x0005, 0x7938, 0x080c, 0x13fe, 0x0126, 0x2091, - 0x2400, 0x2061, 0x0100, 0x2071, 0x9200, 0x6024, 0x6026, 0x080c, - 0x2425, 0x6050, 0xa084, 0xfe7f, 0x6052, 0x2009, 0x00ef, 0x6132, - 0x6136, 0x080c, 0x2435, 0x60e7, 0x0000, 0x61ea, 0x60e3, 0x0008, - 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, - 0x6007, 0x0c9f, 0x600f, 0x03ff, 0x602b, 0x002f, 0x012e, 0x0005, - 0x2001, 0x9230, 0x2003, 0x0000, 0x2001, 0x922f, 0x2003, 0x0001, - 0x0005, 0x0126, 0x2091, 0x2400, 0x0006, 0x0016, 0x0026, 0x6124, - 0x0066, 0x2031, 0x9232, 0x2634, 0xa6b4, 0x0028, 0x006e, 0x11c0, - 0x6020, 0xd0bc, 0x01a8, 0xd1bc, 0x0198, 0x783c, 0xa005, 0x0180, - 0x00e6, 0x0006, 0x2070, 0x701c, 0xa086, 0x0009, 0x000e, 0x00ee, - 0x1138, 0x00e6, 0x783c, 0x2070, 0x7008, 0xd0fc, 0x00ee, 0x1130, - 0xa184, 0x1c2c, 0x1118, 0xa184, 0x0007, 0x002a, 0xa195, 0x0004, - 0xa284, 0x0007, 0x0002, 0x2195, 0x217b, 0x217e, 0x2181, 0x2186, - 0x2188, 0x218c, 0x2190, 0x080c, 0x5ee3, 0x00b8, 0x080c, 0x5fbe, - 0x00a0, 0x080c, 0x5fbe, 0x080c, 0x5ee3, 0x0078, 0x0099, 0x0068, - 0x080c, 0x5ee3, 0x0079, 0x0048, 0x080c, 0x5fbe, 0x0059, 0x0028, - 0x080c, 0x5fbe, 0x080c, 0x5ee3, 0x0029, 0x002e, 0x001e, 0x000e, - 0x012e, 0x0005, 0xd19c, 0x1904, 0x238f, 0x080c, 0x4dc5, 0x01a0, - 0x080c, 0x4deb, 0x15c0, 0x6024, 0xa084, 0x1800, 0x1108, 0x0498, - 0x2001, 0x94d7, 0x2003, 0xaaaa, 0x2001, 0x94d8, 0x2003, 0x0001, - 0x080c, 0x4d10, 0x0804, 0x238f, 0xd1ac, 0x1528, 0x6024, 0xd0dc, - 0x1130, 0xd0e4, 0x1148, 0xd0d4, 0x1180, 0x0804, 0x238f, 0x2001, - 0x94d8, 0x2003, 0x0000, 0x0068, 0xa085, 0x0001, 0x080c, 0x4e05, - 0x2001, 0x94d8, 0x2003, 0x0002, 0x0020, 0x2001, 0x94d8, 0x2003, - 0x0003, 0x0016, 0x2001, 0x9200, 0x2003, 0x0001, 0x080c, 0x4d10, - 0x001e, 0x0804, 0x238f, 0x6220, 0xd1bc, 0x0568, 0xd2bc, 0x0558, - 0x783c, 0xa005, 0x0540, 0x00e6, 0x2070, 0x7008, 0xd0fc, 0x00ee, - 0x0510, 0x6028, 0xc0bc, 0x602a, 0x0026, 0x0036, 0x6288, 0x638c, - 0x608b, 0xbc91, 0x608f, 0xffff, 0x6043, 0x0001, 0xe000, 0xe000, - 0x6027, 0x0080, 0x6017, 0x0000, 0x6043, 0x0000, 0x628a, 0x638e, - 0x003e, 0x002e, 0x0016, 0x2001, 0x9295, 0x200c, 0xc184, 0x2102, - 0x001e, 0x0804, 0x23b6, 0xd1ac, 0x0904, 0x22d7, 0x080c, 0x4dc5, - 0x1550, 0x6027, 0x0020, 0x0006, 0x0026, 0x0036, 0x2001, 0x94d8, - 0x080c, 0x4de1, 0x11d8, 0x2011, 0x9225, 0x2204, 0xa005, 0x1140, - 0x8000, 0x2012, 0x2011, 0x8036, 0x2019, 0x0001, 0x080c, 0x3698, - 0x2001, 0x94d8, 0x2003, 0x0001, 0x2001, 0x9200, 0x2003, 0x0001, - 0x080c, 0x4d10, 0x003e, 0x002e, 0x000e, 0x0005, 0x003e, 0x002e, - 0x000e, 0x080c, 0x4ca5, 0x0016, 0x0046, 0x00c6, 0x644c, 0xa486, - 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a, 0x6043, 0x0090, 0x6043, - 0x0010, 0x74c6, 0xa48c, 0xff00, 0xa196, 0xff00, 0x01e8, 0x7050, - 0xa084, 0x00ff, 0x810f, 0xa116, 0x01b8, 0x7130, 0xd18c, 0x11a0, - 0x2011, 0x9252, 0x2214, 0xd2ec, 0x0118, 0xc18d, 0x7132, 0x0060, - 0x6240, 0xa294, 0x0010, 0x0904, 0x22ad, 0x6248, 0xa294, 0xff00, - 0xa296, 0xff00, 0x1904, 0x22ad, 0x70bc, 0xa005, 0x1138, 0x0036, - 0x73c4, 0x2011, 0x8013, 0x080c, 0x3698, 0x003e, 0x7130, 0xc185, - 0x7132, 0x2011, 0x9252, 0x220c, 0xd1a4, 0x01d0, 0x0016, 0x2009, - 0x0001, 0x2011, 0x0100, 0x080c, 0x585b, 0x2019, 0x000e, 0x080c, - 0x9071, 0xa484, 0x00ff, 0xa080, 0x2719, 0x200d, 0xa18c, 0xff00, - 0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x080c, 0x90d7, 0x001e, - 0xd1ac, 0x1128, 0x2019, 0x0004, 0x080c, 0x264b, 0x0070, 0x0156, - 0x20a9, 0x007f, 0x2009, 0x0000, 0x080c, 0x4434, 0x1110, 0x080c, - 0x41e0, 0x8108, 0x1f04, 0x22a4, 0x015e, 0x00ce, 0x004e, 0x2011, - 0x0003, 0x080c, 0x718f, 0x2011, 0x0002, 0x080c, 0x7199, 0x080c, - 0x708d, 0x080c, 0x57a1, 0x0036, 0x2019, 0x0000, 0x080c, 0x7110, - 0x003e, 0x60e3, 0x0000, 0x001e, 0x2001, 0x9200, 0x2014, 0xa296, - 0x0004, 0x1128, 0xd19c, 0x1118, 0x6228, 0xc29d, 0x622a, 0x2003, - 0x0001, 0x2001, 0x9222, 0x2003, 0x0000, 0x6027, 0x0020, 0xd194, - 0x0904, 0x238f, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x2340, 0x080c, - 0x57a1, 0x080c, 0x6f1e, 0x6027, 0x0004, 0x00f6, 0x2019, 0x94ee, - 0x2304, 0xa07d, 0x0570, 0x7804, 0xa086, 0x0032, 0x1550, 0x00d6, - 0x00c6, 0x00e6, 0x2069, 0x0140, 0x618c, 0x6288, 0x7818, 0x608e, - 0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x1df0, - 0x6043, 0x0000, 0x6803, 0x1000, 0x6803, 0x0000, 0x618e, 0x628a, - 0x080c, 0x6389, 0x080c, 0x6462, 0x7810, 0x2070, 0x7037, 0x0103, - 0x2f60, 0x080c, 0x74f2, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, - 0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, - 0x0120, 0x6803, 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, 0x2061, - 0x94e5, 0x6028, 0xa09a, 0x0002, 0x1238, 0x8000, 0x602a, 0x00ce, - 0x080c, 0x6f11, 0x0804, 0x238e, 0x2019, 0x94ee, 0x2304, 0xa065, - 0x0120, 0x2009, 0x0027, 0x080c, 0x7518, 0x00ce, 0x0804, 0x238e, - 0xd2bc, 0x0904, 0x238e, 0x080c, 0x57ae, 0x6017, 0x0010, 0x6027, - 0x0004, 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0120, - 0x6803, 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, 0x2061, 0x94e5, - 0x6044, 0xa09a, 0x0002, 0x12e0, 0x8000, 0x6046, 0x603c, 0x00ce, - 0xa005, 0x0560, 0x2009, 0x07d0, 0x080c, 0x57a6, 0xa080, 0x0007, - 0x2004, 0xa086, 0x0006, 0x1118, 0x6017, 0x0012, 0x00f8, 0xa080, - 0x0007, 0x2004, 0xa086, 0x0009, 0x0db8, 0x6017, 0x0016, 0x00b0, - 0x0036, 0x2019, 0x0001, 0x080c, 0x7110, 0x003e, 0x2019, 0x94f4, - 0x2304, 0xa065, 0x0150, 0x2009, 0x004f, 0x601c, 0xa086, 0x0009, - 0x1110, 0x2009, 0x0105, 0x080c, 0x7518, 0x00ce, 0x001e, 0xd19c, - 0x0528, 0x0016, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, - 0x718f, 0x2011, 0x0002, 0x080c, 0x7199, 0x080c, 0x708d, 0x080c, - 0x57a1, 0x0036, 0x2019, 0x0000, 0x080c, 0x7110, 0x003e, 0x60e3, - 0x0000, 0x080c, 0x918b, 0x080c, 0x91a6, 0x2001, 0x9200, 0x2003, - 0x0004, 0x6027, 0x0008, 0x080c, 0x123f, 0x001e, 0xa18c, 0xffd0, - 0x6126, 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0126, - 0x2091, 0x8000, 0x2071, 0x9200, 0x71bc, 0x70be, 0xa116, 0x01b8, - 0x81ff, 0x0128, 0x2011, 0x8011, 0x080c, 0x3698, 0x0080, 0x2011, - 0x8012, 0x080c, 0x3698, 0x0036, 0x00c6, 0x080c, 0x2480, 0x2061, - 0x0100, 0x2019, 0x0028, 0x080c, 0x264b, 0x00ce, 0x003e, 0x012e, - 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x00c6, 0x00f6, - 0x0006, 0x0026, 0x2061, 0x0100, 0xa190, 0x23f9, 0x2205, 0x60f2, - 0x2011, 0x2406, 0x2205, 0x60ee, 0x002e, 0x000e, 0x00fe, 0x00ce, - 0x0005, 0x0840, 0x0840, 0x0840, 0x0580, 0x0420, 0x0348, 0x02c0, - 0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x0140, 0x00f8, - 0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c, 0x00ff, 0x2130, 0xa094, - 0xff00, 0x1110, 0x81ff, 0x0118, 0x080c, 0x550c, 0x0038, 0xa080, - 0x2719, 0x200d, 0xa18c, 0xff00, 0x810f, 0xa006, 0x0005, 0xa080, - 0x2719, 0x200d, 0xa18c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, - 0x2001, 0x9214, 0x2003, 0x00ef, 0x20a9, 0x0010, 0xa006, 0x6852, - 0x6856, 0x1f04, 0x2430, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, - 0x2069, 0x0140, 0x2001, 0x9214, 0x2102, 0x8114, 0x8214, 0x8214, - 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0xa006, 0x82ff, 0x1128, - 0xa184, 0x000f, 0xa080, 0x91ac, 0x2005, 0x6856, 0x8211, 0x1f04, - 0x2445, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x9200, - 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, - 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, - 0xa116, 0x0180, 0xa112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, - 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x2475, - 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, - 0x2001, 0x9252, 0x2004, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0xa006, - 0x0046, 0x2020, 0x2009, 0x002e, 0x080c, 0x90d7, 0x004e, 0x0005, - 0x24b0, 0x24b4, 0x24b8, 0x24be, 0x24c4, 0x24ca, 0x24d0, 0x24d8, - 0x24df, 0x24e4, 0x24e9, 0x24f0, 0x24f7, 0x24fe, 0x2505, 0x250e, - 0x2517, 0x2517, 0x2517, 0x2517, 0x2517, 0x2517, 0x2517, 0x2517, - 0x2517, 0x2517, 0x2517, 0x2517, 0x2517, 0x2517, 0x2517, 0x2517, - 0x0106, 0x0006, 0x0804, 0x2519, 0x0106, 0x0006, 0x0804, 0x2519, - 0x0106, 0x0006, 0x080c, 0x2141, 0x0804, 0x2519, 0x0106, 0x0006, - 0x080c, 0x2141, 0x0804, 0x2519, 0x0106, 0x0006, 0x080c, 0x203c, - 0x0804, 0x2519, 0x0106, 0x0006, 0x080c, 0x203c, 0x0804, 0x2519, - 0x0106, 0x0006, 0x080c, 0x2141, 0x080c, 0x203c, 0x0804, 0x2519, - 0x0106, 0x0006, 0x080c, 0x2141, 0x080c, 0x203c, 0x04d0, 0x0106, - 0x0006, 0x080c, 0x2082, 0x04a8, 0x0106, 0x0006, 0x080c, 0x2082, - 0x0480, 0x0106, 0x0006, 0x080c, 0x2141, 0x080c, 0x2082, 0x0448, - 0x0106, 0x0006, 0x080c, 0x2141, 0x080c, 0x2082, 0x0410, 0x0106, - 0x0006, 0x080c, 0x203c, 0x080c, 0x2082, 0x00d8, 0x0106, 0x0006, - 0x080c, 0x203c, 0x080c, 0x2082, 0x00a0, 0x0106, 0x0006, 0x080c, - 0x2141, 0x080c, 0x203c, 0x080c, 0x2082, 0x0058, 0x0106, 0x0006, - 0x080c, 0x2141, 0x080c, 0x203c, 0x080c, 0x2082, 0x0010, 0xe000, - 0x0cf0, 0x000e, 0x010e, 0x000d, 0x00c6, 0x0026, 0x2041, 0x007e, - 0x70c8, 0xd09c, 0x0110, 0x2041, 0x007f, 0xd094, 0x2001, 0x9214, - 0x203c, 0x15d8, 0x7284, 0x82ff, 0x05c0, 0x0036, 0x7398, 0xa38e, - 0xffff, 0x1110, 0x2019, 0x0001, 0x8314, 0xa2e0, 0x98c0, 0x2c04, - 0xa38c, 0x0001, 0x0120, 0xa084, 0xff00, 0x8007, 0x0010, 0xa084, - 0x00ff, 0xa70e, 0x01c8, 0xa08e, 0x00ff, 0x01d0, 0x2009, 0x0000, - 0x080c, 0x240b, 0x080c, 0x4400, 0x1188, 0x6004, 0xa084, 0x00ff, - 0xa086, 0x0006, 0x1120, 0x080c, 0x25b1, 0x0140, 0x0028, 0x080c, - 0x26ad, 0x080c, 0x25d7, 0x0110, 0x8318, 0x08b0, 0x739a, 0x0010, - 0x709b, 0xffff, 0x003e, 0x0804, 0x25ae, 0xa780, 0x2719, 0x203d, - 0xa7bc, 0xff00, 0x873f, 0x7098, 0xa096, 0xffff, 0x0128, 0xa812, - 0x12c8, 0x709b, 0xffff, 0x04b8, 0x2009, 0x0000, 0x70c8, 0xd09c, - 0x0120, 0xd094, 0x0110, 0x2009, 0x007e, 0x2001, 0x94d7, 0x2004, - 0xa005, 0x0120, 0x2009, 0x007e, 0x2041, 0x007f, 0x2100, 0xa802, - 0x20a8, 0x0020, 0x2008, 0x2810, 0xa202, 0x20a8, 0x2700, 0x0156, - 0x0016, 0xa106, 0x0180, 0x080c, 0x4400, 0x11a8, 0x6004, 0xa084, - 0x00ff, 0xa086, 0x0006, 0x1118, 0x00a1, 0x0168, 0x0020, 0x080c, - 0x26ad, 0x04a9, 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x258e, - 0x709b, 0xffff, 0x0018, 0x001e, 0x015e, 0x719a, 0x002e, 0x00ce, - 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x080c, 0x749c, - 0x01c8, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, - 0x43d1, 0x2001, 0x0000, 0x080c, 0x43e3, 0x0126, 0x2091, 0x8000, - 0x7094, 0x8000, 0x7096, 0x012e, 0x2009, 0x0004, 0x080c, 0x7518, - 0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, - 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x080c, 0x749c, 0x01c8, 0x2d00, - 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x43d1, 0x2001, - 0x0002, 0x080c, 0x43e3, 0x0126, 0x2091, 0x8000, 0x7094, 0x8000, - 0x7096, 0x012e, 0x2009, 0x0002, 0x080c, 0x7518, 0xa085, 0x0001, - 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x0026, 0x2009, - 0x0080, 0x080c, 0x4400, 0x1120, 0x0031, 0x0110, 0x70cf, 0xffff, - 0x002e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, - 0x080c, 0x749c, 0x01c8, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, - 0x0000, 0x080c, 0x43d1, 0x2001, 0x0002, 0x080c, 0x43e3, 0x0126, - 0x2091, 0x8000, 0x70d0, 0x8000, 0x70d2, 0x012e, 0x2009, 0x0002, - 0x080c, 0x7518, 0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, - 0x0005, 0x00c6, 0x00d6, 0x2009, 0x007f, 0x080c, 0x4400, 0x1180, - 0x2c68, 0x080c, 0x749c, 0x0160, 0x2d00, 0x601a, 0x6312, 0x601f, - 0x0001, 0x620a, 0x2009, 0x0022, 0x080c, 0x7518, 0xa085, 0x0001, - 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, - 0x080c, 0x6133, 0x080c, 0x60dc, 0x080c, 0x7a8c, 0x20a9, 0x007f, - 0x2009, 0x0000, 0x0016, 0x080c, 0x4434, 0x1120, 0x080c, 0x460d, - 0x080c, 0x41e0, 0x001e, 0x8108, 0x1f04, 0x265a, 0x002e, 0x003e, - 0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0026, - 0x0016, 0x6218, 0x2270, 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, - 0x6127, 0x0086, 0x2041, 0x0000, 0x080c, 0x606d, 0x2c08, 0x080c, - 0x8ee4, 0x008e, 0x001e, 0x2e60, 0x080c, 0x460d, 0x6210, 0x6314, - 0x080c, 0x41e0, 0x6212, 0x6316, 0x001e, 0x002e, 0x003e, 0x00ce, - 0x00ee, 0x0005, 0x00e6, 0x0006, 0x6018, 0xa080, 0x0028, 0x2004, - 0xa086, 0x0080, 0x0150, 0x2071, 0x9200, 0x7094, 0xa005, 0x0110, - 0x8001, 0x7096, 0x000e, 0x00ee, 0x0005, 0x2071, 0x9200, 0x70d0, - 0xa005, 0x0dc0, 0x8001, 0x70d2, 0x0ca8, 0x6000, 0xc08c, 0x6002, - 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x0156, - 0x2178, 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0098, 0x2001, 0x9252, + 0x0005, 0x00e6, 0x2071, 0x8dff, 0x7003, 0x0000, 0x00ee, 0x0005, + 0x00d6, 0xa280, 0x0004, 0x206c, 0x694c, 0xd1dc, 0x1904, 0x1c3e, + 0x6934, 0xa184, 0x0007, 0x0002, 0x1bdc, 0x1c29, 0x1bdc, 0x1bdc, + 0x1bdc, 0x1c10, 0x1bef, 0x1bde, 0x080c, 0x1410, 0x684c, 0xd0b4, + 0x0904, 0x1d32, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, + 0x687c, 0x680a, 0x6880, 0x680e, 0x6958, 0x0804, 0x1c31, 0x6834, + 0xa084, 0x00ff, 0xa086, 0x001e, 0x1d38, 0x684c, 0xd0b4, 0x0904, + 0x1d32, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, + 0x680a, 0x6880, 0x680e, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, + 0xa084, 0x000f, 0xa080, 0x1e76, 0x2005, 0x6832, 0x6958, 0x0450, + 0xa18c, 0x00ff, 0xa186, 0x0015, 0x1548, 0x684c, 0xd0b4, 0x0904, + 0x1d32, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, + 0xa080, 0x1e76, 0x2005, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, + 0x0088, 0x684c, 0xd0b4, 0x0904, 0x18c9, 0x6958, 0xa006, 0x682e, + 0x682a, 0x2d00, 0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x1e76, + 0x2005, 0x6832, 0x6926, 0x684c, 0xc0dd, 0x684e, 0x00de, 0x0005, + 0x00f6, 0x2079, 0x0020, 0x7804, 0xd0fc, 0x190c, 0x1d58, 0x00e6, + 0x00d6, 0x2071, 0x8dff, 0x7000, 0xa005, 0x1904, 0x1cb2, 0x00c6, + 0x7206, 0xa280, 0x0004, 0x205c, 0x7004, 0x2068, 0x7803, 0x0004, + 0x6818, 0x00d6, 0x2068, 0x686c, 0x7812, 0x6890, 0x00f6, 0x20e1, + 0x9040, 0x2079, 0x0200, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, + 0x00fe, 0x00de, 0x2b68, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, + 0x2040, 0x6034, 0xa0cc, 0x000f, 0x6908, 0xa184, 0x0007, 0x0128, + 0x0016, 0x2009, 0x0008, 0xa102, 0x001e, 0xa108, 0x791a, 0x7116, + 0x701e, 0x680c, 0xa081, 0x0000, 0x781e, 0x701a, 0xa006, 0x700e, + 0x7012, 0x7004, 0x692c, 0x6814, 0xa106, 0x1120, 0x6928, 0x6810, + 0xa106, 0x0158, 0x0036, 0x0046, 0x6b14, 0x6c10, 0x080c, 0x1e96, + 0x004e, 0x003e, 0x0110, 0x00ce, 0x00a8, 0x8aff, 0x1120, 0x00ce, + 0xa085, 0x0001, 0x0078, 0x0126, 0x2091, 0x8000, 0x2079, 0x0020, + 0x2009, 0x0001, 0x0059, 0x0118, 0x2009, 0x0001, 0x0039, 0x012e, + 0x00ce, 0xa006, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x0076, 0x0066, + 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x1d2b, 0x700c, + 0x7214, 0xa23a, 0x7010, 0x7218, 0xa203, 0x0a04, 0x1d2a, 0xa705, + 0x0904, 0x1d2a, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x11a8, 0x00d6, + 0x2805, 0xac68, 0x2900, 0x0002, 0x1d0d, 0x1cf2, 0x1cf2, 0x1d0d, + 0x1d0d, 0x1d06, 0x1d0d, 0x1cf2, 0x1d0d, 0x1cf7, 0x1cf7, 0x1d0d, + 0x1d0d, 0x1d0d, 0x1cfe, 0x1cf7, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, + 0x6d1c, 0x6c20, 0xd99c, 0x0528, 0x00d6, 0x2805, 0xac68, 0x6f08, + 0x6e0c, 0x00f0, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x00c8, 0x6b10, + 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0090, 0x00de, 0x00d6, + 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x1138, 0x00de, 0x080c, + 0x1e38, 0x1904, 0x1cbc, 0xa00e, 0x00f0, 0x00de, 0x080c, 0x1410, + 0x00de, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, + 0x7000, 0x8000, 0x7002, 0x6828, 0xa300, 0x682a, 0x682c, 0xa201, + 0x682e, 0x700c, 0xa300, 0x700e, 0x7010, 0xa201, 0x7012, 0x080c, + 0x1e38, 0x0008, 0xa006, 0x002e, 0x003e, 0x004e, 0x005e, 0x006e, + 0x007e, 0x0005, 0x080c, 0x1410, 0x2001, 0x0105, 0x2003, 0x0010, + 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, + 0x00d6, 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0118, 0x6850, 0xc0bd, + 0x6852, 0x00de, 0x080c, 0x795f, 0x20e1, 0x9040, 0x080c, 0x6b33, + 0x2011, 0x0000, 0x080c, 0x6966, 0x080c, 0x5dc2, 0x0804, 0x1e0d, + 0x0126, 0x2091, 0x2400, 0x0006, 0x0016, 0x00f6, 0x00e6, 0x00d6, + 0x00c6, 0x2079, 0x0020, 0x2071, 0x8dff, 0x2b68, 0x6818, 0x2060, + 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x1930, 0x7000, 0x0002, + 0x1e0d, 0x1d74, 0x1de0, 0x1e0b, 0x8001, 0x7002, 0xd19c, 0x1170, + 0x8aff, 0x0540, 0x2009, 0x0001, 0x080c, 0x1cb6, 0x0904, 0x1e0d, + 0x2009, 0x0001, 0x080c, 0x1cb6, 0x0804, 0x1e0d, 0x7803, 0x0004, + 0xd194, 0x0148, 0x6850, 0xc0fc, 0x6852, 0x8aff, 0x1148, 0x684c, + 0xc0f5, 0x684e, 0x0028, 0x080c, 0x1e4e, 0x6850, 0xc0fd, 0x6852, + 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000, + 0x0804, 0x1e0d, 0x711c, 0x81ff, 0x0190, 0x7918, 0x7922, 0x7827, + 0x0000, 0x7803, 0x0001, 0x7000, 0x8000, 0x7002, 0x700c, 0xa100, + 0x700e, 0x7010, 0xa081, 0x0000, 0x7012, 0x0804, 0x1e0d, 0x00f6, + 0x0026, 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100, 0x7a14, + 0xa284, 0x0184, 0xa085, 0x0012, 0x7816, 0x7820, 0xd0bc, 0x1de8, + 0x79c8, 0x000e, 0xa102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e, + 0xa102, 0x78c6, 0x000e, 0x78ca, 0xa284, 0x0184, 0xa085, 0x0012, + 0x7816, 0x002e, 0x00fe, 0x7803, 0x0008, 0x7003, 0x0000, 0x0468, + 0x8001, 0x7002, 0xd194, 0x0168, 0x7804, 0xd0fc, 0x1904, 0x1d68, + 0xd19c, 0x11f8, 0x8aff, 0x0508, 0x2009, 0x0001, 0x080c, 0x1cb6, + 0x00e0, 0x0026, 0x0036, 0x6b28, 0x6a2c, 0x080c, 0x1e4e, 0x00d6, + 0x2805, 0xac68, 0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c, + 0xa213, 0x0020, 0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0x0804, + 0x1d93, 0x0804, 0x1d93, 0x080c, 0x1410, 0x00ce, 0x00de, 0x00ee, + 0x00fe, 0x001e, 0x000e, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071, + 0x8dff, 0x7000, 0xa086, 0x0000, 0x01c0, 0x2079, 0x0020, 0x20e1, + 0x9040, 0x7804, 0xd0fc, 0x0dd8, 0x080c, 0x1d58, 0x7000, 0xa086, + 0x0000, 0x1da8, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x1de8, 0x20e1, + 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, + 0x8840, 0x2805, 0xa005, 0x1170, 0x6004, 0xa005, 0x0168, 0x681a, + 0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x1e76, 0x2045, 0x88ff, + 0x090c, 0x1410, 0x8a51, 0x0005, 0x2050, 0x0005, 0x8a50, 0x8841, + 0x2805, 0xa005, 0x1190, 0x2c00, 0xad06, 0x0120, 0x6000, 0xa005, + 0x1108, 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080, + 0x1e86, 0x2045, 0x88ff, 0x090c, 0x1410, 0x0005, 0x0000, 0x0011, + 0x0015, 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f, + 0x0015, 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x1e6b, + 0x1e67, 0x0000, 0x0000, 0x1e75, 0x0000, 0x1e6b, 0x0000, 0x1e72, + 0x1e6f, 0x0000, 0x0000, 0x0000, 0x1e75, 0x1e72, 0x0000, 0x1e6d, + 0x1e6d, 0x0000, 0x0000, 0x1e75, 0x0000, 0x1e6d, 0x0000, 0x1e73, + 0x1e73, 0x0000, 0x0000, 0x0000, 0x1e75, 0x1e73, 0x00a6, 0x0096, + 0x0086, 0x6858, 0xa055, 0x0904, 0x1f25, 0x2d60, 0x6034, 0xa0cc, + 0x000f, 0xa9c0, 0x1e76, 0xa986, 0x0007, 0x0130, 0xa986, 0x000e, + 0x0118, 0xa986, 0x000f, 0x1120, 0x605c, 0xa422, 0x6060, 0xa31a, + 0x2805, 0xa045, 0x1140, 0x0310, 0x0804, 0x1f25, 0x6004, 0xa065, + 0x0904, 0x1f25, 0x0c18, 0x2805, 0xa005, 0x01a8, 0xac68, 0xd99c, + 0x1128, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0020, 0x6810, 0xa422, + 0x6814, 0xa31b, 0x0620, 0x2300, 0xa405, 0x0150, 0x8a51, 0x0904, + 0x1f25, 0x8840, 0x0c40, 0x6004, 0xa065, 0x0904, 0x1f25, 0x0830, + 0x8a51, 0x0904, 0x1f25, 0x8840, 0x2805, 0xa005, 0x1158, 0x6004, + 0xa065, 0x0904, 0x1f25, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x1e76, + 0x2805, 0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852, 0x0458, 0x8422, + 0x8420, 0x831a, 0xa399, 0x0000, 0x00d6, 0x2b68, 0x6c6e, 0x6b72, + 0x00de, 0xd99c, 0x1168, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, + 0xa11b, 0x0a0c, 0x1410, 0x6800, 0xa420, 0x6804, 0xa319, 0x0060, + 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, 0x0a0c, 0x1410, + 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, 0x6b22, 0x6850, + 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832, 0x2a00, 0x6826, + 0x000e, 0x000e, 0x000e, 0xa006, 0x0028, 0x008e, 0x009e, 0x00ae, + 0xa085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004, 0xa084, 0x0007, + 0x0002, 0x1f39, 0x1f3a, 0x1f3d, 0x1f40, 0x1f45, 0x1f48, 0x1f4d, + 0x1f52, 0x0005, 0x080c, 0x1d58, 0x0005, 0x080c, 0x18ee, 0x0005, + 0x080c, 0x18ee, 0x080c, 0x1d58, 0x0005, 0x080c, 0x15a7, 0x0005, + 0x080c, 0x1d58, 0x080c, 0x15a7, 0x0005, 0x080c, 0x18ee, 0x080c, + 0x15a7, 0x0005, 0x080c, 0x18ee, 0x080c, 0x1d58, 0x080c, 0x15a7, + 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x9080, + 0x2069, 0x8b00, 0x2009, 0x0004, 0x7912, 0x7817, 0x0004, 0x080c, + 0x22c4, 0x781b, 0x0002, 0x783b, 0x001f, 0x20e1, 0x8700, 0x012e, + 0x0005, 0x0126, 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x1ffa, + 0xa084, 0x0007, 0x0002, 0x1f95, 0x1f83, 0x1f86, 0x1f89, 0x1f8e, + 0x1f90, 0x1f92, 0x1f94, 0x080c, 0x521b, 0x0078, 0x080c, 0x5242, + 0x0060, 0x080c, 0x521b, 0x080c, 0x5242, 0x0038, 0x0041, 0x0028, + 0x0031, 0x0018, 0x0021, 0x0008, 0x0011, 0x012e, 0x0005, 0x0006, + 0x0016, 0x0026, 0x7930, 0xa184, 0x0003, 0x0118, 0x20e1, 0x9040, + 0x00b8, 0xa184, 0x0030, 0x0150, 0x6a00, 0xa286, 0x0003, 0x1108, + 0x0010, 0x080c, 0x403d, 0x20e1, 0x9010, 0x0050, 0xa184, 0x00c0, + 0x0110, 0x080c, 0x1410, 0xa184, 0x0300, 0x0110, 0x20e1, 0x9020, + 0x7932, 0x002e, 0x001e, 0x000e, 0x0005, 0x0016, 0x00e6, 0x00f6, + 0x2071, 0x8b00, 0x7128, 0x2001, 0x8d8f, 0x2102, 0x2001, 0x8d97, + 0x2102, 0xa182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, 0xa182, + 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0xa182, 0x02c1, 0x1218, + 0x2009, 0x0006, 0x00a0, 0xa182, 0x0349, 0x1218, 0x2009, 0x0005, + 0x0070, 0xa182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, 0xa182, + 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, 0x2079, + 0x0200, 0x7912, 0x7817, 0x0004, 0x080c, 0x22c4, 0x00fe, 0x00ee, + 0x001e, 0x0005, 0x7938, 0x080c, 0x1410, 0x0126, 0x2091, 0x2400, + 0x2061, 0x0100, 0x2071, 0x8b00, 0x6024, 0x6026, 0x6053, 0x0030, + 0x080c, 0x2303, 0x6050, 0xa084, 0xfe7f, 0x6052, 0x2009, 0x00ef, + 0x6132, 0x6136, 0x080c, 0x2313, 0x60e7, 0x0000, 0x61ea, 0x60e3, + 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, + 0x0000, 0x6007, 0x0e9f, 0x600f, 0x00ff, 0x602b, 0x002f, 0x012e, + 0x0005, 0x2001, 0x8b30, 0x2003, 0x0000, 0x2001, 0x8b2f, 0x2003, + 0x0001, 0x0005, 0x0126, 0x2091, 0x2400, 0x0006, 0x0016, 0x0026, + 0x6124, 0xa184, 0x1e2c, 0x1118, 0xa184, 0x0007, 0x002a, 0xa195, + 0x0004, 0xa284, 0x0007, 0x0002, 0x2066, 0x204c, 0x204f, 0x2052, + 0x2057, 0x2059, 0x205d, 0x2061, 0x080c, 0x578e, 0x00b8, 0x080c, + 0x5869, 0x00a0, 0x080c, 0x5869, 0x080c, 0x578e, 0x0078, 0x0099, + 0x0068, 0x080c, 0x578e, 0x0079, 0x0048, 0x080c, 0x5869, 0x0059, + 0x0028, 0x080c, 0x5869, 0x080c, 0x578e, 0x0029, 0x002e, 0x001e, + 0x000e, 0x012e, 0x0005, 0xd19c, 0x1904, 0x226d, 0x080c, 0x4c42, + 0x0560, 0x7000, 0xa086, 0x0003, 0x0198, 0x6024, 0xa084, 0x1800, + 0x0178, 0x080c, 0x4c68, 0x0118, 0x080c, 0x4c54, 0x1148, 0x6027, + 0x0020, 0x6043, 0x0000, 0x2001, 0x8d9c, 0x2003, 0xaaaa, 0x0458, + 0x080c, 0x4c68, 0x1904, 0x20cf, 0x6024, 0xa084, 0x1800, 0x1108, + 0x04f0, 0x2001, 0x8d9c, 0x2003, 0xaaaa, 0x2001, 0x8d9d, 0x2003, + 0x0001, 0x080c, 0x4b8b, 0x0804, 0x226d, 0xd1ac, 0x1580, 0x6024, + 0xd0dc, 0x1188, 0xd0e4, 0x11a0, 0xd0d4, 0x11d8, 0xd0cc, 0x0148, + 0x7088, 0xa086, 0x0027, 0x1128, 0x6028, 0xc0cc, 0x602a, 0x080c, + 0x4b52, 0x0804, 0x226d, 0x2001, 0x8d9d, 0x2003, 0x0000, 0x0068, + 0xa085, 0x0001, 0x080c, 0x4c82, 0x2001, 0x8d9d, 0x2003, 0x0002, + 0x0020, 0x080c, 0x4d10, 0x0804, 0x226d, 0x0016, 0x2001, 0x8b00, + 0x2003, 0x0001, 0x080c, 0x4b8b, 0x001e, 0x0804, 0x226d, 0xd1ac, + 0x0904, 0x21b5, 0x080c, 0x4c42, 0x1550, 0x6027, 0x0020, 0x0006, + 0x0026, 0x0036, 0x2001, 0x8d9d, 0x080c, 0x4c5e, 0x11d8, 0x2011, + 0x8b25, 0x2204, 0xa005, 0x1140, 0x8000, 0x2012, 0x2011, 0x8036, + 0x2019, 0x0001, 0x080c, 0x3617, 0x2001, 0x8d9d, 0x2003, 0x0001, + 0x2001, 0x8b00, 0x2003, 0x0001, 0x080c, 0x4b8b, 0x003e, 0x002e, + 0x000e, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x4b06, 0x0016, + 0x0046, 0x00c6, 0x644c, 0xa486, 0xf0f0, 0x1138, 0x2061, 0x0100, + 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74c6, 0xa48c, 0xff00, + 0x7034, 0xd084, 0x0178, 0xa186, 0xf800, 0x1160, 0x7038, 0xd084, + 0x1148, 0xc085, 0x703a, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c, + 0x3617, 0x003e, 0xa196, 0xff00, 0x01e8, 0x7050, 0xa084, 0x00ff, + 0x810f, 0xa116, 0x01b8, 0x7130, 0xd18c, 0x11a0, 0x2011, 0x8b52, + 0x2214, 0xd2ec, 0x0118, 0xc18d, 0x7132, 0x0060, 0x6240, 0xa294, + 0x0010, 0x0904, 0x218b, 0x6248, 0xa294, 0xff00, 0xa296, 0xff00, + 0x1904, 0x218b, 0x7034, 0xd08c, 0x1140, 0x2001, 0x8b0c, 0x200c, + 0xd1ac, 0x1904, 0x218b, 0xc1ad, 0x2102, 0x0036, 0x73c4, 0x2011, + 0x8013, 0x080c, 0x3617, 0x003e, 0x7130, 0xc185, 0x7132, 0x2011, + 0x8b52, 0x220c, 0xd1a4, 0x01d0, 0x0016, 0x2009, 0x0001, 0x2011, + 0x0100, 0x080c, 0x5734, 0x2019, 0x000e, 0x080c, 0x891c, 0xa484, + 0x00ff, 0xa080, 0x263d, 0x200d, 0xa18c, 0xff00, 0x810f, 0x8127, + 0xa006, 0x2009, 0x000e, 0x080c, 0x8982, 0x001e, 0xd1ac, 0x1128, + 0x2019, 0x0004, 0x080c, 0x2542, 0x0070, 0x0156, 0x20a9, 0x007f, + 0x2009, 0x0000, 0x080c, 0x430a, 0x1110, 0x080c, 0x4118, 0x8108, + 0x1f04, 0x2182, 0x015e, 0x00ce, 0x004e, 0x2011, 0x0003, 0x080c, + 0x695c, 0x2011, 0x0002, 0x080c, 0x6966, 0x080c, 0x6862, 0x080c, + 0x567a, 0x0036, 0x2019, 0x0000, 0x080c, 0x68e5, 0x003e, 0x60e3, + 0x0000, 0x001e, 0x2001, 0x8b00, 0x2014, 0xa296, 0x0004, 0x1128, + 0xd19c, 0x1118, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, + 0x8b22, 0x2003, 0x0000, 0x6027, 0x0020, 0xd194, 0x0904, 0x226d, + 0x0016, 0x6220, 0xd2b4, 0x0904, 0x221e, 0x080c, 0x567a, 0x080c, + 0x66f7, 0x6027, 0x0004, 0x00f6, 0x2019, 0x8db3, 0x2304, 0xa07d, + 0x0570, 0x7804, 0xa086, 0x0032, 0x1550, 0x00d6, 0x00c6, 0x00e6, + 0x2069, 0x0140, 0x618c, 0x6288, 0x7818, 0x608e, 0x7808, 0x608a, + 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x1df0, 0x6043, 0x0000, + 0x6803, 0x1000, 0x6803, 0x0000, 0x618e, 0x628a, 0x080c, 0x5c37, + 0x080c, 0x5d10, 0x7810, 0x2070, 0x7037, 0x0103, 0x2f60, 0x080c, + 0x6d18, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x0005, 0x00fe, + 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0120, 0x6803, + 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, 0x2061, 0x8daa, 0x6028, + 0xa09a, 0x0002, 0x1238, 0x8000, 0x602a, 0x00ce, 0x080c, 0x66ea, + 0x0804, 0x226c, 0x2019, 0x8db3, 0x2304, 0xa065, 0x0120, 0x2009, + 0x0027, 0x080c, 0x6d3f, 0x00ce, 0x0804, 0x226c, 0xd2bc, 0x0904, + 0x226c, 0x080c, 0x5687, 0x6014, 0xa084, 0x0184, 0xa085, 0x0010, + 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, + 0x4000, 0x0120, 0x6803, 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, + 0x2061, 0x8daa, 0x6044, 0xa09a, 0x0002, 0x12f0, 0x8000, 0x6046, + 0x603c, 0x00ce, 0xa005, 0x0540, 0x2009, 0x07d0, 0x080c, 0x567f, + 0xa080, 0x0007, 0x2004, 0xa086, 0x0006, 0x1138, 0x6114, 0xa18c, + 0x0184, 0xa18d, 0x0012, 0x6116, 0x00b8, 0x6114, 0xa18c, 0x0184, + 0xa18d, 0x0016, 0x6116, 0x0080, 0x0036, 0x2019, 0x0001, 0x080c, + 0x68e5, 0x003e, 0x2019, 0x8db9, 0x2304, 0xa065, 0x0120, 0x2009, + 0x004f, 0x080c, 0x6d3f, 0x00ce, 0x001e, 0xd19c, 0x0528, 0x0016, + 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, 0x695c, 0x2011, + 0x0002, 0x080c, 0x6966, 0x080c, 0x6862, 0x080c, 0x567a, 0x0036, + 0x2019, 0x0000, 0x080c, 0x68e5, 0x003e, 0x60e3, 0x0000, 0x080c, + 0x8a36, 0x080c, 0x8a51, 0x2001, 0x8b00, 0x2003, 0x0004, 0x6027, + 0x0008, 0x080c, 0x1251, 0x001e, 0xa18c, 0xffd0, 0x6126, 0x0005, + 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, + 0x2071, 0x8b00, 0x71bc, 0x70be, 0xa116, 0x01b8, 0x81ff, 0x0128, + 0x2011, 0x8011, 0x080c, 0x3617, 0x0080, 0x2011, 0x8012, 0x080c, + 0x3617, 0x0036, 0x00c6, 0x080c, 0x235e, 0x2061, 0x0100, 0x2019, + 0x0028, 0x080c, 0x2542, 0x00ce, 0x003e, 0x012e, 0x00fe, 0x00ee, + 0x002e, 0x001e, 0x000e, 0x0005, 0x00c6, 0x00f6, 0x0006, 0x0026, + 0x2061, 0x0100, 0xa190, 0x22d7, 0x2205, 0x60f2, 0x2011, 0x22e4, + 0x2205, 0x60ee, 0x002e, 0x000e, 0x00fe, 0x00ce, 0x0005, 0x0840, + 0x0840, 0x0840, 0x0580, 0x0420, 0x0348, 0x02c0, 0x0258, 0x0210, + 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x0140, 0x00f8, 0x00d0, 0x00b0, + 0x00a0, 0x2028, 0xa18c, 0x00ff, 0x2130, 0xa094, 0xff00, 0x1110, + 0x81ff, 0x0118, 0x080c, 0x53f4, 0x0038, 0xa080, 0x263d, 0x200d, + 0xa18c, 0xff00, 0x810f, 0xa006, 0x0005, 0xa080, 0x263d, 0x200d, + 0xa18c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, 0x8b14, + 0x2003, 0x00ef, 0x20a9, 0x0010, 0xa006, 0x6852, 0x6856, 0x1f04, + 0x230e, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, + 0x2001, 0x8b14, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, + 0x0010, 0x6853, 0x0000, 0xa006, 0x82ff, 0x1128, 0xa184, 0x000f, + 0xa080, 0x8a57, 0x2005, 0x6856, 0x8211, 0x1f04, 0x2323, 0x002e, + 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x8b00, 0x6030, 0x0110, + 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6, + 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0xa116, 0x0180, + 0xa112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402, 0x0018, + 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x2353, 0x680f, 0x0000, + 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x2001, 0x8b52, 0x2004, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020, - 0x2009, 0x002d, 0x080c, 0x90d7, 0x004e, 0x20a9, 0x00ff, 0x2011, - 0x0000, 0x0026, 0xa288, 0x936e, 0x210c, 0x81ff, 0x0508, 0x8fff, - 0x0559, 0x2019, 0x0029, 0x080c, 0x6127, 0x0086, 0x2041, 0x0000, - 0x080c, 0x606d, 0x00c6, 0x0026, 0x2160, 0x6204, 0xa294, 0x00ff, - 0x2001, 0x0004, 0x8007, 0xa215, 0x6206, 0x002e, 0x00ce, 0x0016, - 0x2c08, 0x080c, 0x8ee4, 0x001e, 0x008e, 0x2160, 0x080c, 0x460d, - 0x002e, 0x8210, 0x1f04, 0x26d1, 0x015e, 0x001e, 0x002e, 0x003e, - 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x2001, - 0x9252, 0x2004, 0xd0c4, 0x0148, 0xd0a4, 0x0138, 0xa006, 0x2220, - 0x8427, 0x2009, 0x0029, 0x080c, 0x90d7, 0x001e, 0x002e, 0x004e, - 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, - 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, - 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, - 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, - 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, - 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, - 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, - 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, - 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, - 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, - 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, - 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, - 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, - 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, - 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, - 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, - 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, - 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, - 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, - 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, - 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, - 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, - 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, - 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, - 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, - 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, - 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, - 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x2009, 0x002e, 0x080c, 0x8982, 0x004e, 0x0005, 0x238e, 0x2392, + 0x2396, 0x239c, 0x23a2, 0x23a8, 0x23ae, 0x23b6, 0x23bd, 0x23c2, + 0x23c7, 0x23ce, 0x23d5, 0x23dc, 0x23e3, 0x23ec, 0x23f5, 0x23f5, + 0x23f5, 0x23f5, 0x23f5, 0x23f5, 0x23f5, 0x23f5, 0x23f5, 0x23f5, + 0x23f5, 0x23f5, 0x23f5, 0x23f5, 0x23f5, 0x23f5, 0x0106, 0x0006, + 0x0804, 0x23f7, 0x0106, 0x0006, 0x0804, 0x23f7, 0x0106, 0x0006, + 0x080c, 0x2032, 0x0804, 0x23f7, 0x0106, 0x0006, 0x080c, 0x2032, + 0x0804, 0x23f7, 0x0106, 0x0006, 0x080c, 0x1f2b, 0x0804, 0x23f7, + 0x0106, 0x0006, 0x080c, 0x1f2b, 0x0804, 0x23f7, 0x0106, 0x0006, + 0x080c, 0x2032, 0x080c, 0x1f2b, 0x0804, 0x23f7, 0x0106, 0x0006, + 0x080c, 0x2032, 0x080c, 0x1f2b, 0x04d0, 0x0106, 0x0006, 0x080c, + 0x1f71, 0x04a8, 0x0106, 0x0006, 0x080c, 0x1f71, 0x0480, 0x0106, + 0x0006, 0x080c, 0x2032, 0x080c, 0x1f71, 0x0448, 0x0106, 0x0006, + 0x080c, 0x2032, 0x080c, 0x1f71, 0x0410, 0x0106, 0x0006, 0x080c, + 0x1f2b, 0x080c, 0x1f71, 0x00d8, 0x0106, 0x0006, 0x080c, 0x1f2b, + 0x080c, 0x1f71, 0x00a0, 0x0106, 0x0006, 0x080c, 0x2032, 0x080c, + 0x1f2b, 0x080c, 0x1f71, 0x0058, 0x0106, 0x0006, 0x080c, 0x2032, + 0x080c, 0x1f2b, 0x080c, 0x1f71, 0x0010, 0xe000, 0x0cf0, 0x000e, + 0x010e, 0x000d, 0x00c6, 0x0026, 0x2041, 0x007e, 0x70c8, 0xd09c, + 0x0110, 0x2041, 0x007f, 0xd094, 0x2001, 0x8b14, 0x203c, 0x1904, + 0x2454, 0x7284, 0xd284, 0x0904, 0x2454, 0xd28c, 0x1904, 0x2454, + 0x0036, 0x7398, 0xa38e, 0xffff, 0x1110, 0x2019, 0x0001, 0x8314, + 0xa2e0, 0x91c0, 0x2c04, 0xa38c, 0x0001, 0x0120, 0xa084, 0xff00, + 0x8007, 0x0010, 0xa084, 0x00ff, 0xa70e, 0x0528, 0xa08e, 0x00ff, + 0x1160, 0x2011, 0x8b52, 0x2214, 0xd2ec, 0x1508, 0x7284, 0xc28d, + 0x7286, 0x709b, 0xffff, 0x003e, 0x00f8, 0x2009, 0x0000, 0x080c, + 0x22e9, 0x080c, 0x42d6, 0x1188, 0x6004, 0xa084, 0x00ff, 0xa086, + 0x0006, 0x1120, 0x080c, 0x24a8, 0x0140, 0x0028, 0x080c, 0x25a4, + 0x080c, 0x24ce, 0x0110, 0x8318, 0x0850, 0x739a, 0x0010, 0x709b, + 0xffff, 0x003e, 0x0804, 0x24a5, 0xa780, 0x263d, 0x203d, 0xa7bc, + 0xff00, 0x873f, 0x7098, 0xa096, 0xffff, 0x0128, 0xa812, 0x12c8, + 0x709b, 0xffff, 0x04f8, 0x2009, 0x0000, 0x70c8, 0xd09c, 0x0120, + 0xd094, 0x0110, 0x2009, 0x007e, 0x2001, 0x8d9c, 0x2004, 0xa005, + 0x0120, 0x2009, 0x007e, 0x2041, 0x007f, 0x2100, 0xa802, 0x20a8, + 0x0020, 0x2008, 0x2810, 0xa202, 0x20a8, 0x2700, 0x0156, 0x0016, + 0xa106, 0x01c0, 0x080c, 0x42d6, 0x11e8, 0x6004, 0xa084, 0x00ff, + 0xa086, 0x0006, 0x1120, 0x080c, 0x2610, 0x0160, 0x0020, 0x7284, + 0xd28c, 0x0120, 0x0038, 0x00a1, 0x0168, 0x0020, 0x080c, 0x25a4, + 0x04a9, 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x247d, 0x709b, + 0xffff, 0x0018, 0x001e, 0x015e, 0x719a, 0x002e, 0x00ce, 0x0005, + 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x080c, 0x6cc2, 0x01c8, + 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x42a7, + 0x2001, 0x0000, 0x080c, 0x42b9, 0x0126, 0x2091, 0x8000, 0x7094, + 0x8000, 0x7096, 0x012e, 0x2009, 0x0004, 0x080c, 0x6d3f, 0xa085, + 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076, + 0x00d6, 0x00c6, 0x2c68, 0x080c, 0x6cc2, 0x01c8, 0x2d00, 0x601a, + 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x42a7, 0x2001, 0x0002, + 0x080c, 0x42b9, 0x0126, 0x2091, 0x8000, 0x7094, 0x8000, 0x7096, + 0x012e, 0x2009, 0x0002, 0x080c, 0x6d3f, 0xa085, 0x0001, 0x00ce, + 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x0026, 0x2009, 0x0080, + 0x080c, 0x42d6, 0x1120, 0x0031, 0x0110, 0x70cf, 0xffff, 0x002e, + 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x080c, + 0x6cc2, 0x01c8, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, + 0x080c, 0x42a7, 0x2001, 0x0002, 0x080c, 0x42b9, 0x0126, 0x2091, + 0x8000, 0x70d0, 0x8000, 0x70d2, 0x012e, 0x2009, 0x0002, 0x080c, + 0x6d3f, 0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, + 0x00c6, 0x00d6, 0x2009, 0x007f, 0x080c, 0x42d6, 0x1180, 0x2c68, + 0x080c, 0x6cc2, 0x0160, 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, + 0x620a, 0x2009, 0x0022, 0x080c, 0x6d3f, 0xa085, 0x0001, 0x00de, + 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x080c, + 0x59e1, 0x080c, 0x598b, 0x080c, 0x72cc, 0x20a9, 0x007f, 0x2009, + 0x0000, 0x0016, 0x080c, 0x430a, 0x1120, 0x080c, 0x44e6, 0x080c, + 0x4118, 0x001e, 0x8108, 0x1f04, 0x2551, 0x002e, 0x003e, 0x006e, + 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, + 0x6218, 0x2270, 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x59d5, + 0x0086, 0x2041, 0x0000, 0x080c, 0x5911, 0x2c08, 0x080c, 0x878f, + 0x008e, 0x001e, 0x2e60, 0x080c, 0x44e6, 0x6210, 0x6314, 0x080c, + 0x4118, 0x6212, 0x6316, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, + 0x0005, 0x00e6, 0x0006, 0x6018, 0xa080, 0x0028, 0x2004, 0xa086, + 0x0080, 0x0150, 0x2071, 0x8b00, 0x7094, 0xa005, 0x0110, 0x8001, + 0x7096, 0x000e, 0x00ee, 0x0005, 0x2071, 0x8b00, 0x70d0, 0xa005, + 0x0dc0, 0x8001, 0x70d2, 0x0ca8, 0x6000, 0xc08c, 0x6002, 0x0005, + 0x00f6, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, + 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0098, 0x2001, 0x8b52, 0x2004, + 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020, 0x2009, + 0x002d, 0x080c, 0x8982, 0x004e, 0x20a9, 0x00ff, 0x2011, 0x0000, + 0x0026, 0xa288, 0x8c34, 0x210c, 0x81ff, 0x0508, 0x8fff, 0x0559, + 0x2019, 0x0029, 0x080c, 0x59d5, 0x0086, 0x2041, 0x0000, 0x080c, + 0x5911, 0x00c6, 0x0026, 0x2160, 0x6204, 0xa294, 0x00ff, 0x2001, + 0x0004, 0x8007, 0xa215, 0x6206, 0x002e, 0x00ce, 0x0016, 0x2c08, + 0x080c, 0x878f, 0x001e, 0x008e, 0x2160, 0x080c, 0x44e6, 0x002e, + 0x8210, 0x1f04, 0x25c8, 0x015e, 0x001e, 0x002e, 0x003e, 0x00ce, + 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x2001, 0x8b52, + 0x2004, 0xd0c4, 0x0148, 0xd0a4, 0x0138, 0xa006, 0x2220, 0x8427, + 0x2009, 0x0029, 0x080c, 0x8982, 0x001e, 0x002e, 0x004e, 0x0005, + 0x0016, 0x0026, 0x0036, 0x00c6, 0x7284, 0x82ff, 0x01f8, 0xa290, + 0x8b52, 0x2214, 0xd2ac, 0x11d0, 0x2100, 0x080c, 0x22fd, 0x81ff, + 0x01b8, 0x2019, 0x0001, 0x8314, 0xa2e0, 0x91c0, 0x2c04, 0xd384, + 0x0120, 0xa084, 0xff00, 0x8007, 0x0010, 0xa084, 0x00ff, 0xa116, + 0x0138, 0xa096, 0x00ff, 0x0110, 0x8318, 0x0c68, 0xa085, 0x0001, + 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x7eef, 0x7de8, 0x7ce4, + 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5, + 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb, + 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba, + 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae, + 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, + 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, 0x6690, + 0x658f, 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, 0x607a, + 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, 0x806e, + 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965, + 0x5863, 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, 0x5353, + 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49, + 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, 0x8036, + 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, 0x462c, + 0x452b, 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, 0x401f, + 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08, + 0x8004, 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, 0x3600, + 0x8000, 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, 0x8000, + 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000, + 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, 0x2600, + 0x2500, 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, 0x2000, + 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00, + 0x8000, 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x1800, 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, 0x1300, + 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00, + 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, 0x0700, + 0x8000, 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, 0x0300, + 0x8000, 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, - 0x8000, 0x2071, 0x9296, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, - 0x703a, 0x703e, 0x7033, 0x92a6, 0x7037, 0x92a6, 0x7007, 0x0001, - 0x2061, 0x92e6, 0x6003, 0x0002, 0x0005, 0x1004, 0x283f, 0x0e04, - 0x283f, 0x2071, 0x9296, 0x2b78, 0x7818, 0xd084, 0x1140, 0x2a60, - 0x7820, 0xa08e, 0x0069, 0x1904, 0x2924, 0x0804, 0x28bd, 0x0005, - 0x2071, 0x9296, 0x7004, 0x0002, 0x2848, 0x2849, 0x2852, 0x2863, - 0x0005, 0x1004, 0x2851, 0x0e04, 0x2851, 0x2b78, 0x7818, 0xd084, - 0x01e8, 0x0005, 0x2b78, 0x2061, 0x92e6, 0x6008, 0xa08e, 0x0100, - 0x0128, 0xa086, 0x0200, 0x0904, 0x291e, 0x0005, 0x7014, 0x2068, - 0x2a60, 0x7018, 0x0807, 0x7010, 0x2068, 0x6834, 0xa086, 0x0103, - 0x0108, 0x0005, 0x2a60, 0x2b78, 0x7018, 0x0807, 0x2a60, 0x7820, - 0xa08a, 0x0040, 0x1210, 0x61bc, 0x0042, 0x2100, 0xa08a, 0x003f, - 0x1a04, 0x291b, 0x61bc, 0x0804, 0x28bd, 0x28ff, 0x292a, 0x2932, - 0x2936, 0x293e, 0x2944, 0x2948, 0x2951, 0x2954, 0x295e, 0x2961, - 0x291b, 0x291b, 0x291b, 0x2964, 0x291b, 0x2973, 0x298a, 0x29a1, - 0x2a18, 0x2a1d, 0x2a46, 0x2a97, 0x2aa8, 0x2ac6, 0x2af2, 0x2afc, - 0x2b09, 0x2b1c, 0x2b3c, 0x2b45, 0x2b7b, 0x2b81, 0x291b, 0x2ba4, - 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x2ba8, 0x2bae, 0x291b, - 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x2bb6, - 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x2bc3, 0x2bc9, 0x291b, - 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x0002, 0x2bdb, 0x2c2e, - 0x2c88, 0x2c98, 0x291b, 0x2cb2, 0x309c, 0x291b, 0x291b, 0x291b, - 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x295e, 0x2961, - 0x291b, 0x291b, 0x309e, 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, - 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x30a2, 0x31e7, - 0x31fb, 0x3215, 0x3276, 0x32c7, 0x32d2, 0x3309, 0x3318, 0x3327, - 0x3336, 0x335e, 0x33a8, 0x340a, 0x3417, 0x3501, 0x35f6, 0x361f, - 0x3716, 0x3732, 0x373e, 0x3777, 0x381e, 0x3878, 0x38ff, 0x3908, - 0x390b, 0x3920, 0x393b, 0x39ab, 0x3a5b, 0x713c, 0x0000, 0x2021, - 0x4000, 0x080c, 0x3675, 0x0126, 0x2091, 0x8000, 0x0e04, 0x290b, - 0x7818, 0xd084, 0x0110, 0x012e, 0x0cb0, 0x7c22, 0x7926, 0x7a2a, - 0x7b2e, 0x781b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x2091, - 0x5000, 0x012e, 0x0005, 0x2021, 0x4001, 0x0c18, 0x2021, 0x4002, - 0x0c00, 0x2021, 0x4003, 0x08e8, 0x2021, 0x4005, 0x08d0, 0x2021, - 0x4006, 0x08b8, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, - 0x0804, 0x3682, 0x7823, 0x0004, 0x7824, 0x0807, 0xa02e, 0x2520, - 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0804, 0x3685, 0x7924, 0x7828, - 0x2114, 0x200a, 0x0804, 0x28ff, 0x7924, 0x2114, 0x0804, 0x28ff, - 0x2099, 0x0009, 0x20a1, 0x0009, 0x20a9, 0x0007, 0x53a3, 0x0804, - 0x28ff, 0x7824, 0x2060, 0x0090, 0x2009, 0x0002, 0x2011, 0x0000, - 0x2019, 0x0010, 0x783b, 0x0027, 0x0804, 0x28ff, 0x7d38, 0x7c3c, - 0x0858, 0x7d38, 0x7c3c, 0x08a0, 0x2061, 0x1000, 0xe10c, 0xa006, - 0x2c15, 0xa200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0xa005, 0x0904, - 0x28ff, 0x0804, 0x2921, 0x2069, 0x9251, 0x7824, 0x7930, 0xa11a, - 0x1a04, 0x2927, 0x8019, 0x0904, 0x2927, 0x684a, 0x6942, 0x782c, - 0x6852, 0x7828, 0x6856, 0xa006, 0x685a, 0x685e, 0x080c, 0x4e5d, - 0x0804, 0x28ff, 0x2069, 0x9251, 0x7824, 0x7934, 0xa11a, 0x1a04, - 0x2927, 0x8019, 0x0904, 0x2927, 0x684e, 0x6946, 0x782c, 0x6862, - 0x7828, 0x6866, 0xa006, 0x686a, 0x686e, 0x080c, 0x47d8, 0x0804, - 0x28ff, 0xa02e, 0x2520, 0x81ff, 0x1904, 0x2924, 0x7924, 0x7b28, - 0x7a2c, 0x20a9, 0x0005, 0x20a1, 0x929d, 0x41a1, 0x080c, 0x3641, - 0x0904, 0x2924, 0x2009, 0x0023, 0x080c, 0x3682, 0x701b, 0x29b9, - 0x0005, 0x6834, 0x2008, 0xa084, 0x00ff, 0xa096, 0x0011, 0x0120, - 0xa096, 0x0019, 0x1904, 0x2924, 0x810f, 0xa18c, 0x00ff, 0x0904, - 0x2924, 0x710e, 0x700c, 0x8001, 0x0528, 0x700e, 0x080c, 0x3641, - 0x0904, 0x2924, 0x2009, 0x0023, 0x2061, 0x92e6, 0x6224, 0x6328, - 0x642c, 0x6530, 0xa290, 0x0046, 0xa399, 0x0000, 0xa4a1, 0x0000, - 0xa5a9, 0x0000, 0x080c, 0x3682, 0x701b, 0x29e7, 0x0005, 0x6834, - 0xa084, 0x00ff, 0xa096, 0x0002, 0x0120, 0xa096, 0x000a, 0x1904, - 0x2924, 0x08c0, 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x080c, - 0x4337, 0x1128, 0x7007, 0x0003, 0x701b, 0x2a01, 0x0005, 0x080c, - 0x492c, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0x929d, - 0x530a, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, - 0x0000, 0xad80, 0x000d, 0x2009, 0x0023, 0x012e, 0x0804, 0x3685, - 0x61a4, 0x7824, 0x60a6, 0x0804, 0x28ff, 0x2091, 0x8000, 0x7823, - 0x4000, 0x7827, 0x4953, 0x782b, 0x5020, 0x782f, 0x2020, 0x2009, - 0x017f, 0x2104, 0x7832, 0x3f00, 0x7836, 0x2061, 0x0100, 0x6200, - 0x2061, 0x0200, 0x603c, 0x8007, 0xa205, 0x783a, 0x2009, 0x04fd, - 0x2104, 0x783e, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, - 0x2071, 0x0010, 0x20c1, 0x00f0, 0x0804, 0x0427, 0x81ff, 0x1904, - 0x2924, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4434, 0x1904, - 0x2927, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0210, 0x0804, - 0x2927, 0x7c28, 0x7d2c, 0x080c, 0x45d4, 0xd28c, 0x1118, 0x080c, - 0x457f, 0x0010, 0x080c, 0x45ad, 0x1518, 0x2061, 0x9900, 0x0126, - 0x2091, 0x8000, 0x6000, 0xa086, 0x0000, 0x0148, 0x6010, 0xa06d, - 0x0130, 0x683c, 0xa406, 0x1118, 0x6840, 0xa506, 0x0150, 0x012e, - 0xace0, 0x000c, 0x2001, 0x9216, 0x2004, 0xac02, 0x1a04, 0x2924, - 0x0c30, 0x080c, 0x80f6, 0x012e, 0x0904, 0x2924, 0x0804, 0x28ff, - 0xa00e, 0x2001, 0x0005, 0x080c, 0x492c, 0x0126, 0x2091, 0x8000, - 0x080c, 0x852d, 0x080c, 0x4809, 0x012e, 0x0804, 0x28ff, 0x81ff, - 0x1904, 0x2924, 0x080c, 0x3656, 0x0904, 0x2927, 0x080c, 0x44d4, - 0x0904, 0x2924, 0x080c, 0x45e0, 0x0904, 0x2924, 0x0804, 0x28ff, - 0x81ff, 0x1904, 0x2924, 0x080c, 0x3666, 0x0904, 0x2927, 0x080c, - 0x4644, 0x0904, 0x2924, 0x2019, 0x0005, 0x080c, 0x45fb, 0x0904, - 0x2924, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2927, 0x8003, 0x800b, - 0x810b, 0xa108, 0x080c, 0x573d, 0x0804, 0x28ff, 0x0126, 0x2091, - 0x8000, 0x81ff, 0x1508, 0x2029, 0x00ff, 0x644c, 0x2400, 0xa506, - 0x01b0, 0x2508, 0x080c, 0x4434, 0x1190, 0x080c, 0x4644, 0x01a0, - 0x2019, 0x0004, 0x080c, 0x45fb, 0x0178, 0x7824, 0xa08a, 0x1000, - 0x1270, 0x8003, 0x800b, 0x810b, 0xa108, 0x080c, 0x573d, 0x8529, - 0x1e28, 0x012e, 0x0804, 0x28ff, 0x012e, 0x0804, 0x2924, 0x012e, - 0x0804, 0x2927, 0x080c, 0x3656, 0x0904, 0x2927, 0x080c, 0x453a, - 0x080c, 0x45d4, 0x0804, 0x28ff, 0x81ff, 0x1904, 0x2924, 0x080c, - 0x3656, 0x0904, 0x2927, 0x080c, 0x452b, 0x080c, 0x45d4, 0x0804, - 0x28ff, 0x81ff, 0x1904, 0x2924, 0x080c, 0x3656, 0x0904, 0x2927, - 0x080c, 0x45af, 0x0904, 0x2924, 0x080c, 0x4373, 0x080c, 0x4578, - 0x080c, 0x45d4, 0x0804, 0x28ff, 0x080c, 0x3656, 0x0904, 0x2927, - 0x080c, 0x44d4, 0x0904, 0x2924, 0x62a0, 0x2019, 0x0005, 0x00c6, - 0x080c, 0x460d, 0x2061, 0x0000, 0x080c, 0x6127, 0x0086, 0x2041, - 0x0000, 0x080c, 0x606d, 0x2c08, 0x080c, 0x8ee4, 0x008e, 0x00ce, - 0x080c, 0x45d4, 0x0804, 0x28ff, 0x080c, 0x3656, 0x0904, 0x2927, - 0x080c, 0x45d4, 0x2208, 0x0804, 0x28ff, 0x0156, 0x00d6, 0x00e6, - 0x2069, 0x9328, 0x6810, 0x6914, 0xa10a, 0x1210, 0x2009, 0x0000, - 0x6816, 0x2011, 0x0000, 0x2019, 0x0000, 0x20a9, 0x007e, 0x2069, - 0x936e, 0x2d04, 0xa075, 0x0130, 0x704c, 0x0071, 0xa210, 0x7080, - 0x0059, 0xa318, 0x8d68, 0x1f04, 0x2b59, 0x2300, 0xa218, 0x00ee, - 0x00de, 0x015e, 0x0804, 0x28ff, 0x00f6, 0x0016, 0xa07d, 0x0140, - 0x2001, 0x0000, 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0, - 0x001e, 0x00fe, 0x0005, 0x2069, 0x9328, 0x6910, 0x62a8, 0x0804, - 0x28ff, 0x81ff, 0x1904, 0x2924, 0x614c, 0xa190, 0x2719, 0x2215, - 0xa294, 0x00ff, 0x636c, 0x83ff, 0x0108, 0x6270, 0x67c8, 0xd79c, - 0x0118, 0x2031, 0x0001, 0x0060, 0xd7ac, 0x0118, 0x2031, 0x0003, - 0x0038, 0xd7a4, 0x0118, 0x2031, 0x0002, 0x0010, 0x2031, 0x0000, - 0x7e3a, 0x7f3e, 0x0804, 0x28ff, 0x613c, 0x6240, 0x0804, 0x28ff, - 0x080c, 0x3666, 0x0904, 0x2927, 0x0804, 0x28ff, 0x080c, 0x3666, - 0x0904, 0x2927, 0x6244, 0x6338, 0x0804, 0x28ff, 0x613c, 0x6240, - 0x7824, 0x603e, 0x7b28, 0x6342, 0x2069, 0x9251, 0x831f, 0xa305, - 0x6816, 0x0804, 0x28ff, 0x080c, 0x3666, 0x0904, 0x2927, 0x0804, - 0x28ff, 0x080c, 0x3666, 0x0904, 0x2927, 0x7828, 0xa00d, 0x0904, - 0x2927, 0x782c, 0xa005, 0x0904, 0x2927, 0x6244, 0x6146, 0x6338, - 0x603a, 0x0804, 0x28ff, 0x2001, 0x9200, 0x2004, 0xa086, 0x0003, - 0x1904, 0x2924, 0x00c6, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, - 0x00ff, 0xa196, 0x00ff, 0x1130, 0x2001, 0x9214, 0x2004, 0xa085, - 0xff00, 0x0078, 0xa182, 0x007f, 0x1698, 0xa188, 0x2719, 0x210d, - 0xa18c, 0x00ff, 0x2001, 0x9214, 0x2004, 0xa116, 0x0548, 0x810f, - 0xa105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0x749c, 0x000e, - 0x01e0, 0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, 0x080c, 0x3641, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0x8b81, 0x7003, + 0x0002, 0xa006, 0x7012, 0x7016, 0x703a, 0x703e, 0x7033, 0x8b91, + 0x7037, 0x8b91, 0x7007, 0x0001, 0x2061, 0x8bd1, 0x6003, 0x0002, + 0x0005, 0x1004, 0x2763, 0x0e04, 0x2763, 0x2071, 0x8b81, 0x2b78, + 0x7818, 0xd084, 0x1140, 0x2a60, 0x7820, 0xa08e, 0x0069, 0x1904, + 0x2848, 0x0804, 0x27e1, 0x0005, 0x2071, 0x8b81, 0x7004, 0x0002, + 0x276c, 0x276d, 0x2776, 0x2787, 0x0005, 0x1004, 0x2775, 0x0e04, + 0x2775, 0x2b78, 0x7818, 0xd084, 0x01e8, 0x0005, 0x2b78, 0x2061, + 0x8bd1, 0x6008, 0xa08e, 0x0100, 0x0128, 0xa086, 0x0200, 0x0904, + 0x2842, 0x0005, 0x7014, 0x2068, 0x2a60, 0x7018, 0x0807, 0x7010, + 0x2068, 0x6834, 0xa086, 0x0103, 0x0108, 0x0005, 0x2a60, 0x2b78, + 0x7018, 0x0807, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x1210, 0x61bc, + 0x0042, 0x2100, 0xa08a, 0x003f, 0x1a04, 0x283f, 0x61bc, 0x0804, + 0x27e1, 0x2823, 0x284e, 0x2856, 0x285a, 0x2862, 0x2868, 0x286c, + 0x2875, 0x2878, 0x2882, 0x2885, 0x283f, 0x283f, 0x283f, 0x2888, + 0x283f, 0x2897, 0x28ae, 0x28c5, 0x293c, 0x2941, 0x296a, 0x29bb, + 0x29cc, 0x29ea, 0x2a21, 0x2a2b, 0x2a38, 0x2a4b, 0x2a6b, 0x2a74, + 0x2aaa, 0x2ab0, 0x283f, 0x2ad3, 0x283f, 0x283f, 0x283f, 0x283f, + 0x283f, 0x2ad7, 0x2ae1, 0x283f, 0x283f, 0x283f, 0x283f, 0x283f, + 0x283f, 0x283f, 0x283f, 0x2ae9, 0x283f, 0x283f, 0x283f, 0x283f, + 0x283f, 0x2af6, 0x2afe, 0x283f, 0x283f, 0x283f, 0x283f, 0x283f, + 0x283f, 0x0002, 0x2b10, 0x2b63, 0x2bbd, 0x2bcd, 0x283f, 0x2be7, + 0x2ff7, 0x393f, 0x283f, 0x283f, 0x283f, 0x283f, 0x283f, 0x283f, + 0x283f, 0x283f, 0x2882, 0x2885, 0x283f, 0x283f, 0x2ff9, 0x283f, + 0x283f, 0x283f, 0x283f, 0x283f, 0x283f, 0x283f, 0x283f, 0x283f, + 0x283f, 0x283f, 0x2ffd, 0x314a, 0x315e, 0x3178, 0x31d9, 0x322a, + 0x3235, 0x326c, 0x327b, 0x328a, 0x3299, 0x32c1, 0x330b, 0x336d, + 0x337a, 0x3474, 0x356e, 0x3597, 0x3695, 0x36b1, 0x36bd, 0x36f6, + 0x378d, 0x283f, 0x283f, 0x283f, 0x283f, 0x37f5, 0x3810, 0x3880, + 0x3930, 0x713c, 0x0000, 0x2021, 0x4000, 0x080c, 0x35f4, 0x0126, + 0x2091, 0x8000, 0x0e04, 0x282f, 0x7818, 0xd084, 0x0110, 0x012e, + 0x0cb0, 0x7c22, 0x7926, 0x7a2a, 0x7b2e, 0x781b, 0x0001, 0x2091, + 0x4080, 0x7007, 0x0001, 0x2091, 0x5000, 0x012e, 0x0005, 0x2021, + 0x4001, 0x0c18, 0x2021, 0x4002, 0x0c00, 0x2021, 0x4003, 0x08e8, + 0x2021, 0x4005, 0x08d0, 0x2021, 0x4006, 0x08b8, 0xa02e, 0x2520, + 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0804, 0x3601, 0x7823, 0x0004, + 0x7824, 0x0807, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, + 0x0804, 0x3604, 0x7924, 0x7828, 0x2114, 0x200a, 0x0804, 0x2823, + 0x7924, 0x2114, 0x0804, 0x2823, 0x2099, 0x0009, 0x20a1, 0x0009, + 0x20a9, 0x0007, 0x53a3, 0x0804, 0x2823, 0x7824, 0x2060, 0x0090, + 0x2009, 0x0002, 0x2011, 0x0000, 0x2019, 0x0028, 0x783b, 0x0007, + 0x0804, 0x2823, 0x7d38, 0x7c3c, 0x0858, 0x7d38, 0x7c3c, 0x08a0, + 0x2061, 0x1000, 0xe10c, 0xa006, 0x2c15, 0xa200, 0x8c60, 0x8109, + 0x1dd8, 0x2010, 0xa005, 0x0904, 0x2823, 0x0804, 0x2845, 0x2069, + 0x8b51, 0x7824, 0x7930, 0xa11a, 0x1a04, 0x284b, 0x8019, 0x0904, + 0x284b, 0x684a, 0x6942, 0x782c, 0x6852, 0x7828, 0x6856, 0xa006, + 0x685a, 0x685e, 0x080c, 0x4d79, 0x0804, 0x2823, 0x2069, 0x8b51, + 0x7824, 0x7934, 0xa11a, 0x1a04, 0x284b, 0x8019, 0x0904, 0x284b, + 0x684e, 0x6946, 0x782c, 0x6862, 0x7828, 0x6866, 0xa006, 0x686a, + 0x686e, 0x080c, 0x4670, 0x0804, 0x2823, 0xa02e, 0x2520, 0x81ff, + 0x1904, 0x2848, 0x7924, 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1, + 0x8b88, 0x41a1, 0x080c, 0x35c0, 0x0904, 0x2848, 0x2009, 0x0023, + 0x080c, 0x3601, 0x701b, 0x28dd, 0x0005, 0x6834, 0x2008, 0xa084, + 0x00ff, 0xa096, 0x0011, 0x0120, 0xa096, 0x0019, 0x1904, 0x2848, + 0x810f, 0xa18c, 0x00ff, 0x0904, 0x2848, 0x710e, 0x700c, 0x8001, + 0x0528, 0x700e, 0x080c, 0x35c0, 0x0904, 0x2848, 0x2009, 0x0023, + 0x2061, 0x8bd1, 0x6224, 0x6328, 0x642c, 0x6530, 0xa290, 0x0046, + 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x080c, 0x3601, + 0x701b, 0x290b, 0x0005, 0x6834, 0xa084, 0x00ff, 0xa096, 0x0002, + 0x0120, 0xa096, 0x000a, 0x1904, 0x2848, 0x08c0, 0x7010, 0x2068, + 0x6838, 0xc0fd, 0x683a, 0x080c, 0x420d, 0x1128, 0x7007, 0x0003, + 0x701b, 0x2925, 0x0005, 0x080c, 0x4773, 0x0126, 0x2091, 0x8000, + 0x20a9, 0x0005, 0x2099, 0x8b88, 0x530a, 0x2100, 0xa210, 0xa399, + 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0xad80, 0x000d, 0x2009, + 0x0023, 0x012e, 0x0804, 0x3604, 0x61a4, 0x7824, 0x60a6, 0x0804, + 0x2823, 0x2091, 0x8000, 0x7823, 0x4000, 0x7827, 0x4953, 0x782b, + 0x5020, 0x782f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7832, 0x3f00, + 0x7836, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, + 0xa205, 0x783a, 0x2009, 0x04fd, 0x2104, 0x783e, 0x781b, 0x0001, + 0x2091, 0x5000, 0x2091, 0x4080, 0x2071, 0x0010, 0x20c1, 0x00f0, + 0x0804, 0x0427, 0x81ff, 0x1904, 0x2848, 0x7924, 0x810f, 0xa18c, + 0x00ff, 0x080c, 0x430a, 0x1904, 0x284b, 0x7e38, 0xa684, 0x3fff, + 0xa082, 0x4000, 0x0210, 0x0804, 0x284b, 0x7c28, 0x7d2c, 0x080c, + 0x44ad, 0xd28c, 0x1118, 0x080c, 0x4458, 0x0010, 0x080c, 0x4486, + 0x1518, 0x2061, 0x9200, 0x0126, 0x2091, 0x8000, 0x6000, 0xa086, + 0x0000, 0x0148, 0x6010, 0xa06d, 0x0130, 0x683c, 0xa406, 0x1118, + 0x6840, 0xa506, 0x0150, 0x012e, 0xace0, 0x000c, 0x2001, 0x8b16, + 0x2004, 0xac02, 0x1a04, 0x2848, 0x0c30, 0x080c, 0x795f, 0x012e, + 0x0904, 0x2848, 0x0804, 0x2823, 0xa00e, 0x2001, 0x0005, 0x080c, + 0x4773, 0x0126, 0x2091, 0x8000, 0x080c, 0x7dce, 0x080c, 0x46a1, + 0x012e, 0x0804, 0x2823, 0x81ff, 0x1904, 0x2848, 0x080c, 0x35d5, + 0x0904, 0x284b, 0x080c, 0x43ad, 0x0904, 0x2848, 0x080c, 0x44b9, + 0x0904, 0x2848, 0x0804, 0x2823, 0x81ff, 0x1904, 0x2848, 0x080c, + 0x35e5, 0x0904, 0x284b, 0x080c, 0x451d, 0x0904, 0x2848, 0x2019, + 0x0005, 0x080c, 0x44d4, 0x0904, 0x2848, 0x7828, 0xa08a, 0x1000, + 0x1a04, 0x284b, 0x8003, 0x800b, 0x810b, 0xa108, 0x080c, 0x5619, + 0x0804, 0x2823, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118, 0x2009, + 0x0001, 0x0448, 0x2029, 0x00ff, 0x644c, 0x2400, 0xa506, 0x01f0, + 0x2508, 0x080c, 0x430a, 0x11d0, 0x080c, 0x451d, 0x1128, 0x2009, + 0x0002, 0x62ac, 0x2518, 0x00b8, 0x2019, 0x0004, 0x080c, 0x44d4, + 0x1118, 0x2009, 0x0006, 0x0078, 0x7824, 0xa08a, 0x1000, 0x1270, + 0x8003, 0x800b, 0x810b, 0xa108, 0x080c, 0x5619, 0x8529, 0x1ae8, + 0x012e, 0x0804, 0x2823, 0x012e, 0x0804, 0x2848, 0x012e, 0x0804, + 0x284b, 0x080c, 0x35d5, 0x0904, 0x284b, 0x080c, 0x4413, 0x080c, + 0x44ad, 0x0804, 0x2823, 0x81ff, 0x1904, 0x2848, 0x080c, 0x35d5, + 0x0904, 0x284b, 0x080c, 0x4404, 0x080c, 0x44ad, 0x0804, 0x2823, + 0x81ff, 0x1904, 0x2848, 0x080c, 0x35d5, 0x0904, 0x284b, 0x080c, + 0x4488, 0x0904, 0x2848, 0x080c, 0x4249, 0x080c, 0x4451, 0x080c, + 0x44ad, 0x0804, 0x2823, 0x080c, 0x35d5, 0x0904, 0x284b, 0x080c, + 0x43ad, 0x0904, 0x2848, 0x62a0, 0x2019, 0x0005, 0x00c6, 0x080c, + 0x44e6, 0x2061, 0x0000, 0x080c, 0x59d5, 0x0086, 0x2041, 0x0000, + 0x080c, 0x5911, 0x2c08, 0x080c, 0x878f, 0x008e, 0x00ce, 0x080c, + 0x44ad, 0x0804, 0x2823, 0x080c, 0x35d5, 0x0904, 0x284b, 0x080c, + 0x44ad, 0x2208, 0x0804, 0x2823, 0x0156, 0x00d6, 0x00e6, 0x2069, + 0x8c13, 0x6810, 0x6914, 0xa10a, 0x1210, 0x2009, 0x0000, 0x6816, + 0x2011, 0x0000, 0x2019, 0x0000, 0x20a9, 0x007e, 0x2069, 0x8c34, + 0x2d04, 0xa075, 0x0130, 0x704c, 0x0071, 0xa210, 0x7080, 0x0059, + 0xa318, 0x8d68, 0x1f04, 0x2a88, 0x2300, 0xa218, 0x00ee, 0x00de, + 0x015e, 0x0804, 0x2823, 0x00f6, 0x0016, 0xa07d, 0x0140, 0x2001, + 0x0000, 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, + 0x00fe, 0x0005, 0x2069, 0x8c13, 0x6910, 0x62a8, 0x0804, 0x2823, + 0x81ff, 0x1904, 0x2848, 0x614c, 0xa190, 0x263d, 0x2215, 0xa294, + 0x00ff, 0x636c, 0x83ff, 0x0108, 0x6270, 0x67c8, 0xd79c, 0x0118, + 0x2031, 0x0001, 0x0060, 0xd7ac, 0x0118, 0x2031, 0x0003, 0x0038, + 0xd7a4, 0x0118, 0x2031, 0x0002, 0x0010, 0x2031, 0x0000, 0x7e3a, + 0x7f3e, 0x0804, 0x2823, 0x613c, 0x6240, 0x0804, 0x2823, 0x0126, + 0x2091, 0x8000, 0x6134, 0xa006, 0x2010, 0x2018, 0x012e, 0x0804, + 0x2823, 0x080c, 0x35e5, 0x0904, 0x284b, 0x6244, 0x6338, 0x0804, + 0x2823, 0x613c, 0x6240, 0x7824, 0x603e, 0x7b28, 0x6342, 0x2069, + 0x8b51, 0x831f, 0xa305, 0x6816, 0x0804, 0x2823, 0x0126, 0x2091, + 0x8000, 0x7824, 0x6036, 0x012e, 0x0804, 0x2823, 0x080c, 0x35e5, + 0x0904, 0x284b, 0x7828, 0xa00d, 0x0904, 0x284b, 0x782c, 0xa005, + 0x0904, 0x284b, 0x6244, 0x6146, 0x6338, 0x603a, 0x0804, 0x2823, + 0x2001, 0x8b00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2848, 0x00c6, + 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff, + 0x1130, 0x2001, 0x8b14, 0x2004, 0xa085, 0xff00, 0x0078, 0xa182, + 0x007f, 0x1698, 0xa188, 0x263d, 0x210d, 0xa18c, 0x00ff, 0x2001, + 0x8b14, 0x2004, 0xa116, 0x0548, 0x810f, 0xa105, 0x0126, 0x2091, + 0x8000, 0x0006, 0x080c, 0x6cc2, 0x000e, 0x01e0, 0x601a, 0x600b, + 0xbc09, 0x601f, 0x0001, 0x080c, 0x35c0, 0x01d0, 0x6837, 0x0000, + 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x701b, + 0x2bb6, 0x2d00, 0x6012, 0x2009, 0x0032, 0x080c, 0x6d3f, 0x012e, + 0x00ce, 0x0005, 0x00ce, 0x0804, 0x2848, 0x00ce, 0x0804, 0x284b, + 0x080c, 0x6d18, 0x0cb8, 0x2001, 0x8b00, 0x2004, 0xa086, 0x0003, + 0x1904, 0x2848, 0x00c6, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, + 0x00ff, 0xa196, 0x00ff, 0x1130, 0x2001, 0x8b14, 0x2004, 0xa085, + 0xff00, 0x0078, 0xa182, 0x007f, 0x1698, 0xa188, 0x263d, 0x210d, + 0xa18c, 0x00ff, 0x2001, 0x8b14, 0x2004, 0xa116, 0x0548, 0x810f, + 0xa105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0x6cc2, 0x000e, + 0x01e0, 0x601a, 0x600b, 0xbc05, 0x601f, 0x0001, 0x080c, 0x35c0, 0x01d0, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, - 0xc0fd, 0x683a, 0x701b, 0x2c81, 0x2d00, 0x6012, 0x2009, 0x0032, - 0x080c, 0x7518, 0x012e, 0x00ce, 0x0005, 0x00ce, 0x0804, 0x2924, - 0x00ce, 0x0804, 0x2927, 0x080c, 0x74f2, 0x0cb8, 0x2001, 0x9200, - 0x2004, 0xa086, 0x0003, 0x1904, 0x2924, 0x00c6, 0x2061, 0x0100, - 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff, 0x1130, 0x2001, - 0x9214, 0x2004, 0xa085, 0xff00, 0x0078, 0xa182, 0x007f, 0x1698, - 0xa188, 0x2719, 0x210d, 0xa18c, 0x00ff, 0x2001, 0x9214, 0x2004, - 0xa116, 0x0548, 0x810f, 0xa105, 0x0126, 0x2091, 0x8000, 0x0006, - 0x080c, 0x749c, 0x000e, 0x01e0, 0x601a, 0x600b, 0xbc05, 0x601f, - 0x0001, 0x080c, 0x3641, 0x01d0, 0x6837, 0x0000, 0x7007, 0x0003, - 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x701b, 0x2c81, 0x2d00, - 0x6012, 0x2009, 0x0032, 0x080c, 0x7518, 0x012e, 0x00ce, 0x0005, - 0x00ce, 0x0804, 0x2924, 0x00ce, 0x0804, 0x2927, 0x080c, 0x74f2, - 0x0cb8, 0x6830, 0xa086, 0x0100, 0x0904, 0x2924, 0x0804, 0x28ff, - 0x2061, 0x9566, 0x0126, 0x2091, 0x8000, 0x6000, 0xd084, 0x0128, - 0x6104, 0x6208, 0x012e, 0x0804, 0x28ff, 0x012e, 0x0804, 0x2927, - 0x81ff, 0x1904, 0x2924, 0x080c, 0x4dc5, 0x0904, 0x2924, 0x0126, - 0x2091, 0x8000, 0x6244, 0x6064, 0xa202, 0x0248, 0xa085, 0x0001, - 0x080c, 0x2455, 0x080c, 0x3bfd, 0x012e, 0x0804, 0x28ff, 0x012e, - 0x0804, 0x2927, 0x0126, 0x2091, 0x8000, 0x7824, 0xa084, 0x0007, - 0x0002, 0x2cc4, 0x2ccd, 0x2cd4, 0x2cc1, 0x2cc1, 0x2cc1, 0x2cc1, - 0x2cc1, 0x012e, 0x0804, 0x2927, 0x2009, 0x0114, 0x2104, 0xa085, - 0x0800, 0x200a, 0x080c, 0x2e1e, 0x0070, 0x2009, 0x010b, 0x200b, - 0x0010, 0x080c, 0x2e1e, 0x0038, 0x81ff, 0x0128, 0x012e, 0x2021, - 0x400b, 0x0804, 0x2901, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, - 0x00d6, 0x00e6, 0x00f6, 0x2009, 0x0101, 0x210c, 0x0016, 0x2001, - 0x0138, 0x200c, 0x2003, 0x0001, 0x0016, 0x2001, 0x007a, 0x2034, - 0x2001, 0x007b, 0x202c, 0xa006, 0x2048, 0x2050, 0x2058, 0x080c, - 0x302f, 0x080c, 0x2f99, 0xa03e, 0x2720, 0x00f6, 0x00e6, 0x00c6, - 0x2d60, 0x2071, 0x953b, 0x2079, 0x0020, 0x2011, 0x0001, 0x080c, - 0x2f45, 0x080c, 0x2f45, 0x00ce, 0x00ee, 0x00fe, 0x080c, 0x2ea6, - 0x080c, 0x2f6d, 0x080c, 0x2eea, 0x080c, 0x2e65, 0x080c, 0x2e96, - 0x00f6, 0x2079, 0x0100, 0x7824, 0xd094, 0x01d8, 0x7817, 0x0010, - 0x2079, 0x0140, 0x2001, 0x0109, 0x2004, 0xd0ac, 0x11a8, 0x7804, - 0xd0dc, 0x0dc0, 0x2079, 0x0100, 0x7827, 0x0086, 0x7817, 0x0032, - 0x7824, 0xd0ac, 0x1148, 0xd0bc, 0x0dd8, 0x7827, 0x0080, 0xa026, - 0x7c16, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x2e06, 0x00fe, - 0x0804, 0x2dd0, 0x00fe, 0x1d04, 0x2d55, 0x2091, 0x6000, 0x8420, - 0xa486, 0x0064, 0x1150, 0x8948, 0x2001, 0x007a, 0x2602, 0x2001, - 0x007b, 0x2502, 0x080c, 0x2e06, 0x0088, 0x87ff, 0x0140, 0x2001, - 0x0201, 0x2004, 0xa005, 0x1904, 0x2d10, 0x8739, 0x0038, 0x2001, - 0x9519, 0x2004, 0xa086, 0x0000, 0x1904, 0x2d10, 0x2001, 0x0033, - 0x2003, 0x00f0, 0x8631, 0x1208, 0x8529, 0x2500, 0xa605, 0x0904, - 0x2dd0, 0x7824, 0xd0bc, 0x0128, 0x2900, 0xaa05, 0xab05, 0x1904, - 0x2dd0, 0x6033, 0x000d, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824, - 0xd0ac, 0x1148, 0x2001, 0x9519, 0x2003, 0x0003, 0x2001, 0x0030, - 0x2003, 0x0009, 0x0040, 0x6027, 0x0001, 0x2001, 0x0075, 0x2004, - 0xa005, 0x0108, 0x6026, 0x2c00, 0x601a, 0x20e1, 0x9040, 0x2d00, - 0x681a, 0x6833, 0x000d, 0x7824, 0xd0a4, 0x1180, 0x6827, 0x0000, - 0x00c6, 0x20a9, 0x0008, 0x2061, 0x0020, 0x6003, 0x0008, 0x2001, - 0x0203, 0x2004, 0x1f04, 0x2da5, 0x00ce, 0x0040, 0x6827, 0x0001, - 0x2001, 0x0074, 0x2004, 0xa005, 0x0108, 0x6826, 0x00f6, 0x00c6, - 0x2079, 0x0100, 0x2061, 0x0020, 0x7827, 0x0002, 0x2001, 0x0072, - 0x2004, 0xa084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x0073, 0x2004, - 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x2cfd, - 0x2061, 0x0100, 0x6027, 0x0002, 0x20e1, 0x9028, 0x6050, 0xa084, - 0xf7ef, 0x6052, 0x602f, 0x0000, 0x001e, 0x61e2, 0x001e, 0x6106, - 0x7824, 0xa084, 0x0003, 0xa086, 0x0002, 0x0148, 0x602c, 0xc0ac, - 0x602e, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x2908, - 0x2a10, 0x2b18, 0x2b00, 0xaa05, 0xa905, 0x00fe, 0x00ee, 0x00de, - 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804, - 0x28ff, 0x012e, 0x2021, 0x400c, 0x0804, 0x2901, 0x2001, 0x0105, - 0x2003, 0x0010, 0x2001, 0x0030, 0x2003, 0x0004, 0x2001, 0x0020, - 0x2003, 0x0004, 0x2001, 0x9519, 0x2003, 0x0000, 0x2001, 0x953b, - 0x2003, 0x0000, 0x20e1, 0xf000, 0xa026, 0x0005, 0x00f6, 0x2079, - 0x0100, 0x7850, 0xa084, 0x0990, 0x7852, 0x782c, 0xa085, 0x0020, - 0x782e, 0x20a9, 0x0008, 0x1d04, 0x2e2b, 0x2091, 0x6000, 0x1f04, - 0x2e2b, 0x7850, 0xa085, 0x0400, 0x7852, 0x784b, 0xf7f7, 0x7843, - 0x0090, 0x7843, 0x0010, 0x20a9, 0x000e, 0xe000, 0x1f04, 0x2e3d, + 0xc0fd, 0x683a, 0x701b, 0x2bb6, 0x2d00, 0x6012, 0x2009, 0x0032, + 0x080c, 0x6d3f, 0x012e, 0x00ce, 0x0005, 0x00ce, 0x0804, 0x2848, + 0x00ce, 0x0804, 0x284b, 0x080c, 0x6d18, 0x0cb8, 0x6830, 0xa086, + 0x0100, 0x0904, 0x2848, 0x0804, 0x2823, 0x2061, 0x8e2a, 0x0126, + 0x2091, 0x8000, 0x6000, 0xd084, 0x0128, 0x6104, 0x6208, 0x012e, + 0x0804, 0x2823, 0x012e, 0x0804, 0x284b, 0x81ff, 0x1904, 0x2848, + 0x080c, 0x4c42, 0x0904, 0x2848, 0x0126, 0x2091, 0x8000, 0x6244, + 0x6064, 0xa202, 0x0248, 0xa085, 0x0001, 0x080c, 0x2333, 0x080c, + 0x3b32, 0x012e, 0x0804, 0x2823, 0x012e, 0x0804, 0x284b, 0x0126, + 0x2091, 0x8000, 0x7824, 0xa084, 0x0007, 0x0002, 0x2bf9, 0x2c02, + 0x2c09, 0x2bf6, 0x2bf6, 0x2bf6, 0x2bf6, 0x2bf6, 0x012e, 0x0804, + 0x284b, 0x2009, 0x0114, 0x2104, 0xa085, 0x0800, 0x200a, 0x080c, + 0x2d63, 0x0070, 0x2009, 0x010b, 0x200b, 0x0010, 0x080c, 0x2d63, + 0x0038, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x2825, + 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, + 0x2009, 0x0101, 0x210c, 0x0016, 0x2001, 0x0138, 0x200c, 0x2003, + 0x0001, 0x0016, 0x2001, 0x007a, 0x2034, 0x2001, 0x007b, 0x202c, + 0xa006, 0x2048, 0x2050, 0x2058, 0x080c, 0x2f8a, 0x080c, 0x2ef4, + 0xa03e, 0x2720, 0x00f6, 0x00e6, 0x00c6, 0x2d60, 0x2071, 0x8dff, + 0x2079, 0x0020, 0x2011, 0x0001, 0x080c, 0x2ea0, 0x080c, 0x2ea0, + 0x00ce, 0x00ee, 0x00fe, 0x080c, 0x2dfa, 0x080c, 0x2ec8, 0x080c, + 0x2e45, 0x080c, 0x2db9, 0x080c, 0x2dea, 0x00f6, 0x2079, 0x0100, + 0x7824, 0xd094, 0x0530, 0x7814, 0xa084, 0x0184, 0xa085, 0x0010, + 0x7816, 0x2079, 0x0140, 0x080c, 0x2d41, 0x1110, 0x00fe, 0x0430, + 0x7804, 0xd0dc, 0x0dc0, 0x2079, 0x0100, 0x7827, 0x0086, 0x7814, + 0xa084, 0x0184, 0xa085, 0x0032, 0x7816, 0x080c, 0x2d41, 0x1110, + 0x00fe, 0x00a0, 0x7824, 0xd0bc, 0x0dc0, 0x7827, 0x0080, 0xa026, + 0x7c16, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x2d4b, 0x00fe, + 0x0804, 0x2d0b, 0x00fe, 0x080c, 0x2d41, 0x1150, 0x8948, 0x2001, + 0x007a, 0x2602, 0x2001, 0x007b, 0x2502, 0x080c, 0x2d4b, 0x0088, + 0x87ff, 0x0140, 0x2001, 0x0201, 0x2004, 0xa005, 0x1904, 0x2c45, + 0x8739, 0x0038, 0x2001, 0x8dde, 0x2004, 0xa086, 0x0000, 0x1904, + 0x2c45, 0x2001, 0x0033, 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, + 0x2500, 0xa605, 0x0904, 0x2d0b, 0x7824, 0xd0bc, 0x0128, 0x2900, + 0xaa05, 0xab05, 0x1904, 0x2d0b, 0x6033, 0x000d, 0x2001, 0x0030, + 0x2003, 0x0004, 0x7824, 0xd0ac, 0x1148, 0x2001, 0x8dde, 0x2003, + 0x0003, 0x2001, 0x0030, 0x2003, 0x0009, 0x0040, 0x6027, 0x0001, + 0x2001, 0x0075, 0x2004, 0xa005, 0x0108, 0x6026, 0x2c00, 0x601a, + 0x20e1, 0x9040, 0x2d00, 0x681a, 0x6833, 0x000d, 0x7824, 0xd0a4, + 0x1180, 0x6827, 0x0000, 0x00c6, 0x20a9, 0x0008, 0x2061, 0x0020, + 0x6003, 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x2ce0, 0x00ce, + 0x0040, 0x6827, 0x0001, 0x2001, 0x0074, 0x2004, 0xa005, 0x0108, + 0x6826, 0x00f6, 0x00c6, 0x2079, 0x0100, 0x2061, 0x0020, 0x7827, + 0x0002, 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x601a, 0x0006, + 0x2001, 0x0073, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, + 0x00fe, 0x0804, 0x2c32, 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, + 0x61e2, 0x001e, 0x6106, 0x7824, 0xa084, 0x0003, 0xa086, 0x0002, + 0x0188, 0x20e1, 0x9028, 0x6050, 0xa084, 0xf7ef, 0x6052, 0x602f, + 0x0000, 0x602c, 0xc0ac, 0x602e, 0x604b, 0xf7f7, 0x6043, 0x0090, + 0x6043, 0x0010, 0x2908, 0x2a10, 0x2b18, 0x2b00, 0xaa05, 0xa905, + 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, + 0x1118, 0x012e, 0x0804, 0x2823, 0x012e, 0x2021, 0x400c, 0x0804, + 0x2825, 0xa085, 0x0001, 0x1d04, 0x2d4a, 0x2091, 0x6000, 0x8420, + 0xa486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, + 0x0030, 0x2003, 0x0004, 0x2001, 0x0020, 0x2003, 0x0004, 0x2001, + 0x8dde, 0x2003, 0x0000, 0x2001, 0x8dff, 0x2003, 0x0000, 0x20e1, + 0xf000, 0xa026, 0x0005, 0x00f6, 0x2079, 0x0100, 0x7850, 0xa084, + 0x0990, 0x7852, 0x782c, 0xa085, 0x0020, 0x782e, 0x20a9, 0x0008, + 0x1d04, 0x2d70, 0x2091, 0x6000, 0x1f04, 0x2d70, 0x7850, 0xa085, + 0x0400, 0x7852, 0x2001, 0x0009, 0x2004, 0xa084, 0x0003, 0xa086, + 0x0001, 0x1118, 0x782c, 0xc0ac, 0x782e, 0x784b, 0xf7f7, 0x7843, + 0x0090, 0x7843, 0x0010, 0x20a9, 0x000e, 0xe000, 0x1f04, 0x2d8d, 0x7850, 0xa085, 0x1400, 0x7852, 0x2019, 0x61a8, 0x7854, 0xe000, 0xe000, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, 0x0048, 0x7850, 0xa085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, 0x01f4, 0xe000, - 0xe000, 0x8319, 0x1de0, 0x2001, 0x0140, 0x2003, 0x0100, 0x7843, - 0x0000, 0x2003, 0x0000, 0x00fe, 0x0005, 0x7824, 0xd0ac, 0x11c8, - 0x00f6, 0x00e6, 0x2071, 0x9519, 0x2079, 0x0030, 0x2001, 0x0201, - 0x2004, 0xa005, 0x0160, 0x7000, 0xa086, 0x0000, 0x1140, 0x0051, - 0xd0bc, 0x0108, 0x8738, 0x7003, 0x0003, 0x7803, 0x0019, 0x00ee, - 0x00fe, 0x0005, 0x780c, 0xa08c, 0x0070, 0x0178, 0x2009, 0x007a, - 0x260a, 0x2009, 0x007b, 0x250a, 0xd0b4, 0x0108, 0x8a50, 0xd0ac, - 0x0108, 0x8948, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6, 0x2079, - 0x0200, 0x781c, 0xd084, 0x0140, 0x20e1, 0x0007, 0x20e1, 0x2000, - 0x2001, 0x020a, 0x2004, 0x0ca8, 0x00fe, 0x0005, 0x00e6, 0x2071, - 0x0100, 0x2009, 0x9214, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, - 0x719e, 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, - 0xa080, 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, - 0xa006, 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, - 0x95d5, 0x7027, 0x0080, 0x7017, 0x0032, 0x080c, 0x2f6d, 0x7024, - 0xd0ac, 0x1120, 0xd0bc, 0x0dc8, 0x7027, 0x0080, 0x00f6, 0x00e6, - 0x2071, 0x9519, 0x2079, 0x0030, 0x2011, 0x0011, 0x080c, 0x2f45, - 0x2011, 0x0001, 0x080c, 0x2f45, 0x00ee, 0x00fe, 0x7017, 0x0000, - 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x9519, 0x2079, 0x0030, - 0x7904, 0xd1fc, 0x0904, 0x2f42, 0x7803, 0x0002, 0xa026, 0xd19c, - 0x1904, 0x2f3e, 0x7000, 0x0002, 0x2f42, 0x2f00, 0x2f24, 0x2f3e, - 0xd1bc, 0x1150, 0xd1dc, 0x1150, 0x8001, 0x7002, 0x2011, 0x0001, - 0x04e1, 0x05c0, 0x04d1, 0x04b0, 0x780f, 0x0000, 0x7820, 0x7924, - 0x7803, 0x0004, 0x7822, 0x7926, 0x2001, 0x0201, 0x200c, 0x81ff, - 0x0de8, 0x080c, 0x2e82, 0x2009, 0x0001, 0x7808, 0xd0ec, 0x0110, - 0x2009, 0x0011, 0x7902, 0x00f0, 0x8001, 0x7002, 0xa184, 0x0880, - 0x1138, 0x7804, 0xd0fc, 0x1940, 0x2011, 0x0001, 0x00b1, 0x0090, - 0x6030, 0xa092, 0x0004, 0xa086, 0x0009, 0x1120, 0x6000, 0x601a, - 0x2011, 0x0025, 0x6232, 0xd1dc, 0x1988, 0x0870, 0x7803, 0x0004, - 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x6024, 0xa005, 0x0520, - 0x8001, 0x6026, 0x6018, 0x6130, 0xa140, 0x2804, 0x7832, 0x8840, - 0x2804, 0x7836, 0x8840, 0x2804, 0x7822, 0x8840, 0x2804, 0x7826, - 0x8840, 0x7a02, 0x7000, 0x8000, 0x7002, 0x6018, 0xa802, 0xa08a, - 0x0029, 0x1138, 0x6018, 0xa080, 0x0001, 0x2004, 0x601a, 0x2001, - 0x000d, 0x6032, 0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6, 0x00c6, - 0x2071, 0x953b, 0x2079, 0x0020, 0x7904, 0xd1fc, 0x01f0, 0x7803, - 0x0002, 0x2d60, 0xa026, 0x7000, 0x0002, 0x2f95, 0x2f80, 0x2f8c, - 0x8001, 0x7002, 0xd19c, 0x1188, 0x2011, 0x0001, 0x080c, 0x2f45, - 0x0160, 0x080c, 0x2f45, 0x0048, 0x8001, 0x7002, 0x7804, 0xd0fc, - 0x1d30, 0x2011, 0x0001, 0x080c, 0x2f45, 0x00ce, 0x00ee, 0x00fe, - 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x601b, 0x0004, - 0x2061, 0x0100, 0x60cf, 0x0400, 0x6004, 0xc0ac, 0xa085, 0x0200, - 0x6006, 0x2001, 0x0074, 0x2004, 0xa005, 0x01f8, 0x2038, 0x2001, - 0x0076, 0x2024, 0x2001, 0x0077, 0x201c, 0x080c, 0x3089, 0x6833, - 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220, 0x2138, - 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080, 0x000d, - 0x04a1, 0x1d90, 0x2d00, 0x681a, 0x0088, 0x080c, 0x3089, 0x6833, - 0x000d, 0x2070, 0x6827, 0x0001, 0x2d00, 0x681a, 0x2001, 0x0076, - 0x2004, 0x2072, 0x2001, 0x0077, 0x2004, 0x7006, 0x2061, 0x0020, - 0x2079, 0x0100, 0x6013, 0x0400, 0x20e1, 0x9040, 0x2001, 0x0072, - 0x2004, 0xa084, 0xfff8, 0x700a, 0x601a, 0x0006, 0x2001, 0x0073, - 0x2004, 0x700e, 0x601e, 0x78c6, 0x000e, 0x78ca, 0xa006, 0x603a, - 0x603e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0010, - 0x20a0, 0x2099, 0x0014, 0x7003, 0x0026, 0x7432, 0x7336, 0xa006, - 0x703a, 0x703e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7122, 0x7003, - 0x0041, 0x7004, 0xd0fc, 0x0de8, 0x7003, 0x0002, 0x7003, 0x0040, - 0x53a5, 0x7430, 0x7334, 0x87ff, 0x0180, 0x00c6, 0x00d6, 0x2d60, - 0x00c6, 0x080c, 0x3641, 0x00ce, 0x6018, 0x2070, 0x2d00, 0x7006, - 0x601a, 0x00de, 0x00ce, 0xa085, 0x0001, 0x00ee, 0x0005, 0x00e6, - 0x2001, 0x0075, 0x2004, 0xa005, 0x0508, 0x2038, 0x2001, 0x0078, - 0x2024, 0x2001, 0x0079, 0x201c, 0x080c, 0x3089, 0x2d60, 0x6833, - 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220, 0x2138, - 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080, 0x000d, - 0x080c, 0x2ffd, 0x1d88, 0x2d00, 0x681a, 0x00d8, 0x0491, 0x2d60, - 0x6033, 0x000d, 0x2070, 0x6027, 0x0001, 0x2c00, 0x601a, 0x2001, - 0x0078, 0x2004, 0x2072, 0x2001, 0x0079, 0x2004, 0x7006, 0x2001, - 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x2001, 0x0073, 0x2004, - 0x700e, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824, 0xd0ac, 0x1178, - 0x2001, 0x0101, 0x200c, 0xc1ed, 0x2102, 0x6027, 0x0000, 0x2001, - 0x9519, 0x2003, 0x0003, 0x2001, 0x0030, 0x2003, 0x0009, 0x00ee, - 0x0005, 0x080c, 0x147c, 0x0178, 0xa006, 0x6802, 0x7010, 0xa005, - 0x1120, 0x2d00, 0x7012, 0x7016, 0x0020, 0x7014, 0x6802, 0x2d00, - 0x7016, 0xad80, 0x000d, 0x0005, 0x0804, 0x28ff, 0x7d38, 0x7c3c, - 0x0804, 0x29a3, 0x080c, 0x3641, 0x0904, 0x2924, 0x080c, 0x4dc5, - 0x0110, 0x080c, 0x41c5, 0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c, - 0x7d38, 0x080c, 0x3682, 0x701b, 0x30b6, 0x0005, 0xade8, 0x000d, - 0x6800, 0xa005, 0x0904, 0x2927, 0x6804, 0xd0ac, 0x0118, 0xd0a4, - 0x0904, 0x2927, 0xd094, 0x00c6, 0x2061, 0x0100, 0x6104, 0xa18d, - 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, 0x2061, 0x0100, 0x6104, - 0x0118, 0xa18d, 0x0010, 0x0010, 0xa18c, 0xffef, 0x6106, 0x00ce, - 0x2009, 0x0100, 0x210c, 0xa18a, 0x0002, 0x0268, 0xd084, 0x0158, - 0x6a28, 0xa28a, 0x007f, 0x1a04, 0x2927, 0xa288, 0x2719, 0x210d, - 0xa18c, 0x00ff, 0x6156, 0xd0dc, 0x0130, 0x6828, 0xa08a, 0x007f, - 0x1a04, 0x2927, 0x604e, 0x6808, 0xa08a, 0x0100, 0x0a04, 0x2927, - 0xa08a, 0x0841, 0x1a04, 0x2927, 0xa084, 0x0007, 0x1904, 0x2927, - 0x680c, 0xa005, 0x0904, 0x2927, 0x6810, 0xa005, 0x0904, 0x2927, - 0x6848, 0x6940, 0xa10a, 0x1a04, 0x2927, 0x8001, 0x0904, 0x2927, - 0x684c, 0x6944, 0xa10a, 0x1a04, 0x2927, 0x8001, 0x0904, 0x2927, - 0x6804, 0xd0fc, 0x01f8, 0x080c, 0x3641, 0x0904, 0x2924, 0x2009, - 0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0xa290, 0x0038, 0xa399, - 0x0000, 0x080c, 0x3682, 0x701b, 0x312e, 0x0005, 0xade8, 0x000d, - 0x20a9, 0x0014, 0x2d98, 0x2069, 0x926d, 0x2da0, 0x53a3, 0x7010, - 0xa0e8, 0x000d, 0x20a9, 0x001c, 0x2d98, 0x2069, 0x9251, 0x2da0, - 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084, 0x00ff, - 0x6042, 0x080c, 0x4e5d, 0x080c, 0x4780, 0x080c, 0x47d8, 0x6000, - 0xa086, 0x0000, 0x1904, 0x31e5, 0x6808, 0x602a, 0x080c, 0x20ce, - 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, - 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, - 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, - 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x080c, 0x57bc, - 0x6904, 0xd1fc, 0x0520, 0x00c6, 0x2009, 0x0000, 0x20a9, 0x0001, - 0x6b70, 0xd384, 0x01c8, 0x0020, 0x839d, 0x12b0, 0x3508, 0x8109, - 0x080c, 0x532a, 0x6878, 0x6016, 0x6874, 0x2008, 0xa084, 0xff00, - 0x8007, 0x600a, 0xa184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, - 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, 0x3184, 0x00ce, 0x2069, - 0x9251, 0x2001, 0x94d7, 0x6a80, 0xa294, 0x0030, 0xa28e, 0x0000, - 0x0178, 0xa28e, 0x0010, 0x0118, 0xa28e, 0x0020, 0x0148, 0x2003, - 0xaaaa, 0x2001, 0x0204, 0x2004, 0x2009, 0x94c8, 0x200a, 0x0008, - 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, - 0x00ce, 0x080c, 0x4dc5, 0x0128, 0x080c, 0x3912, 0x0110, 0x080c, - 0x2455, 0x60c0, 0xa005, 0x01a8, 0x6003, 0x0001, 0x2091, 0x301d, - 0x080c, 0x4dc5, 0x1158, 0x2011, 0x4ce2, 0x080c, 0x5731, 0x2001, - 0x94d8, 0x2003, 0x0000, 0x080c, 0x4d10, 0x0038, 0x080c, 0x4105, - 0x0020, 0x6003, 0x0004, 0x2091, 0x301d, 0x0804, 0x28ff, 0x6000, - 0xa086, 0x0000, 0x0904, 0x2924, 0x2069, 0x9251, 0x7830, 0x6842, - 0x7834, 0x6846, 0x2d00, 0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c, - 0x7d38, 0x0804, 0x3685, 0x81ff, 0x1904, 0x2924, 0x080c, 0x4dc5, - 0x1158, 0x2001, 0x94d8, 0x2003, 0x0001, 0x2001, 0x9200, 0x2003, - 0x0001, 0x080c, 0x4d10, 0x0038, 0xa006, 0x080c, 0x2455, 0x080c, - 0x41c5, 0x080c, 0x4105, 0x0804, 0x28ff, 0x81ff, 0x1904, 0x2924, - 0x080c, 0x4dc5, 0x1110, 0x0804, 0x2924, 0x6184, 0x81ff, 0x0198, - 0x703f, 0x0000, 0x2001, 0x98c0, 0x2009, 0x0040, 0x7a2c, 0x7b28, - 0x7c3c, 0x7d38, 0x0126, 0x2091, 0x8000, 0x080c, 0x3685, 0x701b, - 0x28fd, 0x012e, 0x0005, 0x703f, 0x0001, 0x00d6, 0x2069, 0x98c0, - 0x20a9, 0x0040, 0x20a1, 0x98c0, 0x2019, 0xffff, 0x43a4, 0x654c, - 0xa588, 0x2719, 0x210d, 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, - 0x0002, 0x2100, 0xa506, 0x01a8, 0x080c, 0x4434, 0x1190, 0x6014, - 0x821c, 0x0238, 0xa398, 0x98c0, 0xa085, 0xff00, 0x8007, 0x201a, - 0x0038, 0xa398, 0x98c0, 0x2324, 0xa4a4, 0xff00, 0xa405, 0x201a, - 0x8210, 0x8108, 0xa182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, - 0x2d0c, 0xa105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0x98c0, - 0x2099, 0x98c0, 0x080c, 0x4166, 0x0804, 0x3222, 0x080c, 0x3666, - 0x0904, 0x2927, 0x00c6, 0x080c, 0x3641, 0x00ce, 0x0904, 0x2924, - 0x080c, 0x4dc5, 0x0500, 0x2001, 0x9252, 0x2004, 0xd0b4, 0x01d8, - 0x6000, 0xd08c, 0x11c0, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, - 0x1190, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x8476, - 0x0904, 0x2924, 0x7007, 0x0003, 0x701b, 0x329f, 0x0005, 0x080c, - 0x3666, 0x0904, 0x2927, 0x20a9, 0x002d, 0x2c98, 0xade8, 0x0002, - 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, 0x0006, 0x2098, 0xad80, - 0x0006, 0x20a0, 0x080c, 0x4166, 0x20a9, 0x0004, 0xac80, 0x000a, - 0x2098, 0xad80, 0x000a, 0x20a0, 0x080c, 0x4166, 0x2d00, 0x2009, - 0x002f, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3685, 0x81ff, - 0x1904, 0x2924, 0x080c, 0x3656, 0x0904, 0x2927, 0x080c, 0x45e9, - 0x0804, 0x28ff, 0x81ff, 0x1904, 0x2924, 0x7828, 0xa08a, 0x1000, - 0x1a04, 0x2927, 0x080c, 0x3666, 0x0904, 0x2927, 0x080c, 0x4644, - 0x0904, 0x2924, 0x2019, 0x0004, 0x080c, 0x45fb, 0x7924, 0x810f, - 0x7a28, 0x0011, 0x0804, 0x28ff, 0xa186, 0x00ff, 0x0110, 0x0071, - 0x0060, 0x2029, 0x007e, 0x2061, 0x9200, 0x644c, 0x2400, 0xa506, - 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x4434, - 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108, 0x080c, 0x573d, - 0x0005, 0x81ff, 0x1904, 0x2924, 0x080c, 0x3656, 0x0904, 0x2927, - 0x080c, 0x44d4, 0x0904, 0x2924, 0x080c, 0x45f2, 0x0804, 0x28ff, - 0x81ff, 0x1904, 0x2924, 0x080c, 0x3656, 0x0904, 0x2927, 0x080c, - 0x44d4, 0x0904, 0x2924, 0x080c, 0x45e0, 0x0804, 0x28ff, 0x6100, - 0x2001, 0x94d8, 0x2014, 0xa282, 0x0003, 0x1210, 0x0804, 0x28ff, - 0x2011, 0x0000, 0x0804, 0x28ff, 0x0804, 0x28ff, 0x080c, 0x3666, - 0x0904, 0x2927, 0x6004, 0xa086, 0x0707, 0x0904, 0x2927, 0x2001, - 0x9200, 0x2004, 0xa086, 0x0003, 0x1904, 0x2924, 0x00d6, 0xace8, - 0x000a, 0x7924, 0xd184, 0x0110, 0xace8, 0x0006, 0x680c, 0x8007, - 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f, 0x6a00, 0x8217, - 0x00de, 0x6100, 0xa18c, 0x0200, 0x0804, 0x28ff, 0x7824, 0xa09c, - 0x00ff, 0xa39a, 0x0003, 0x1a04, 0x2924, 0x624c, 0xa294, 0x00ff, - 0xa084, 0xff00, 0x8007, 0xa206, 0x1150, 0x2001, 0x9240, 0x2009, - 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3685, 0x81ff, - 0x1904, 0x2924, 0x080c, 0x3666, 0x0904, 0x2927, 0x6004, 0xa084, - 0x00ff, 0xa086, 0x0006, 0x1904, 0x2924, 0x00c6, 0x080c, 0x3641, - 0x00ce, 0x0904, 0x2924, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, - 0x080c, 0x8428, 0x0904, 0x2924, 0x7007, 0x0003, 0x701b, 0x3399, - 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2924, 0xad80, 0x000e, - 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3685, - 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff, 0x0118, 0x81ff, 0x1904, - 0x2924, 0x080c, 0x4dc5, 0x0128, 0xa006, 0x080c, 0x2455, 0x080c, - 0x41c5, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2927, 0x7924, 0xa18c, - 0xff00, 0x810f, 0xa186, 0x00ff, 0x0138, 0xa182, 0x007f, 0x1a04, - 0x2927, 0x2100, 0x080c, 0x241f, 0x0026, 0x00c6, 0x0126, 0x2091, - 0x8000, 0x2061, 0x94f8, 0x601b, 0x0000, 0x601f, 0x0000, 0x080c, - 0x4dc5, 0x1158, 0x2001, 0x94d8, 0x2003, 0x0001, 0x2001, 0x9200, - 0x2003, 0x0001, 0x080c, 0x4d10, 0x00a0, 0x2061, 0x0100, 0x2001, - 0x9214, 0x2004, 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, 0x6043, - 0x0090, 0x6043, 0x0010, 0x2009, 0x001e, 0x2011, 0x412a, 0x080c, - 0x57b3, 0x7924, 0xa18c, 0xff00, 0x810f, 0x080c, 0x4dc5, 0x1110, - 0x2009, 0x00ff, 0x7a28, 0x080c, 0x32ec, 0x012e, 0x00ce, 0x002e, - 0x0804, 0x28ff, 0x7924, 0xa18c, 0xff00, 0x810f, 0x00c6, 0x080c, - 0x4400, 0x2c08, 0x00ce, 0x1904, 0x2927, 0x0804, 0x28ff, 0x81ff, - 0x1904, 0x2924, 0x60c8, 0xd0ac, 0x1118, 0xd09c, 0x0904, 0x2924, - 0x080c, 0x3641, 0x0904, 0x2924, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, - 0x7d38, 0x080c, 0x3682, 0x701b, 0x342e, 0x0005, 0x2009, 0x0080, - 0x080c, 0x4434, 0x1130, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, - 0x0120, 0x2021, 0x400a, 0x0804, 0x2901, 0x00d6, 0xade8, 0x000d, - 0x6900, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, - 0x0100, 0x0904, 0x34a1, 0xa0be, 0x0112, 0x0904, 0x34a1, 0xa0be, - 0x0113, 0x0904, 0x34a1, 0xa0be, 0x0114, 0x0904, 0x34a1, 0xa0be, - 0x0117, 0x0904, 0x34a1, 0xa0be, 0x011a, 0x0904, 0x34a1, 0xa0be, - 0x0121, 0x05b0, 0xa0be, 0x0131, 0x0598, 0xa0be, 0x0171, 0x05c8, - 0xa0be, 0x0173, 0x05b0, 0xa0be, 0x01a1, 0x1120, 0x6830, 0x8007, - 0x6832, 0x04a0, 0xa0be, 0x0212, 0x0540, 0xa0be, 0x0213, 0x0528, - 0xa0be, 0x0214, 0x01b0, 0xa0be, 0x0217, 0x0168, 0xa0be, 0x021a, - 0x1120, 0x6838, 0x8007, 0x683a, 0x00e0, 0xa0be, 0x0300, 0x01c8, - 0x00de, 0x0804, 0x2927, 0xad80, 0x0010, 0x20a9, 0x0007, 0x080c, - 0x34dd, 0xad80, 0x000e, 0x20a9, 0x0001, 0x080c, 0x34dd, 0x0048, - 0xad80, 0x000c, 0x080c, 0x34eb, 0x0048, 0xad80, 0x000e, 0x080c, - 0x34eb, 0xad80, 0x000c, 0x20a9, 0x0001, 0x04b9, 0x00c6, 0x080c, - 0x3641, 0x0540, 0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119, 0x6853, - 0x0000, 0x684f, 0x0020, 0x685b, 0x0001, 0x810b, 0x697e, 0x6883, - 0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996, 0x689b, 0x0000, - 0x00ce, 0x00de, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, - 0x0000, 0x080c, 0x8442, 0x0904, 0x2924, 0x7007, 0x0003, 0x701b, - 0x34d6, 0x0005, 0x00ce, 0x00de, 0x0804, 0x2924, 0x6820, 0xa086, - 0x8001, 0x0904, 0x2924, 0x0804, 0x28ff, 0x0016, 0x2008, 0x2044, - 0x8000, 0x204c, 0x8000, 0x290a, 0x8108, 0x280a, 0x8108, 0x1f04, - 0x34df, 0x001e, 0x0005, 0x0016, 0x00a6, 0x00b6, 0x2008, 0x2044, - 0x8000, 0x204c, 0x8000, 0x2054, 0x8000, 0x205c, 0x2b0a, 0x8108, - 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a, 0x00be, 0x00ae, 0x001e, - 0x0005, 0x81ff, 0x1904, 0x2924, 0x7924, 0x2140, 0xa18c, 0xff00, - 0x810f, 0x60c8, 0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x2927, - 0xa182, 0x00ff, 0x1a04, 0x2927, 0x7a2c, 0x7b28, 0x606c, 0xa306, - 0x1140, 0x6070, 0xa24e, 0x0904, 0x2927, 0xa9cc, 0xff00, 0x0904, - 0x2927, 0x00c6, 0x080c, 0x359b, 0x2c68, 0x00ce, 0x01c0, 0xa0c6, - 0x4000, 0x1108, 0x0088, 0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, - 0xa0c6, 0x4008, 0x1118, 0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, - 0x1108, 0x0010, 0x2001, 0x4006, 0x2020, 0x0804, 0x2901, 0x2d00, - 0x7022, 0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0x749c, - 0x05b8, 0x2d00, 0x601a, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, - 0x3641, 0x00ce, 0x2b70, 0x1140, 0x080c, 0x74f2, 0x00ee, 0x00ce, - 0x00be, 0x001e, 0x0804, 0x2924, 0x6837, 0x0000, 0x683b, 0x0000, - 0x2d00, 0x6012, 0x6833, 0x0000, 0x6838, 0xc0fd, 0xd88c, 0x0108, - 0xc0f5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x266c, 0x012e, - 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x43d1, 0x2001, 0x0002, - 0x080c, 0x43e3, 0x2009, 0x0002, 0x080c, 0x7518, 0xa085, 0x0001, - 0x00ee, 0x00ce, 0x00be, 0x001e, 0x0904, 0x2924, 0x7007, 0x0003, - 0x701b, 0x358b, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2924, - 0x7020, 0x2060, 0x2009, 0x0000, 0x080c, 0x46a5, 0x1110, 0x2009, - 0x0001, 0x0804, 0x28ff, 0x00e6, 0x00d6, 0x2029, 0x0000, 0x2001, - 0x9232, 0x2004, 0xd0ac, 0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff, - 0x2071, 0x936e, 0x0030, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, - 0x93ee, 0x2e04, 0xa005, 0x1130, 0x2100, 0xa406, 0x1548, 0x2428, + 0xe000, 0x8319, 0x1de0, 0x2001, 0x0140, 0x2003, 0x0100, 0x7827, + 0x0020, 0x7843, 0x0000, 0x2003, 0x0000, 0x7827, 0x0048, 0x00fe, + 0x0005, 0x7824, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071, 0x8dde, + 0x2079, 0x0030, 0x2001, 0x0201, 0x2004, 0xa005, 0x0160, 0x7000, + 0xa086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738, 0x7003, + 0x0003, 0x7803, 0x0019, 0x00ee, 0x00fe, 0x0005, 0x780c, 0xa08c, + 0x0070, 0x0178, 0x2009, 0x007a, 0x260a, 0x2009, 0x007b, 0x250a, + 0xd0b4, 0x0108, 0x8a50, 0xd0ac, 0x0108, 0x8948, 0xd0a4, 0x0108, + 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, 0x0140, + 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, 0x0ca8, + 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, 0x2009, 0x8b14, 0x210c, + 0x716e, 0x7063, 0x0100, 0x7166, 0x719e, 0x706b, 0x0000, 0x7073, + 0x0809, 0x7077, 0x0008, 0x7078, 0xa080, 0x0100, 0x707a, 0x7080, + 0x8000, 0x7082, 0x7087, 0xaaaa, 0xa006, 0x708a, 0x708e, 0x707e, + 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5, 0x7027, 0x0080, 0x7014, + 0xa084, 0x0184, 0xa085, 0x0032, 0x7016, 0x080c, 0x2ec8, 0x080c, + 0x2d41, 0x1110, 0x8421, 0x0028, 0x7024, 0xd0bc, 0x0db0, 0x7027, + 0x0080, 0x00f6, 0x00e6, 0x2071, 0x8dde, 0x2079, 0x0030, 0x2011, + 0x0011, 0x080c, 0x2ea0, 0x2011, 0x0001, 0x080c, 0x2ea0, 0x00ee, + 0x00fe, 0x7017, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, + 0x8dde, 0x2079, 0x0030, 0x7904, 0xd1fc, 0x0904, 0x2e9d, 0x7803, + 0x0002, 0xa026, 0xd19c, 0x1904, 0x2e99, 0x7000, 0x0002, 0x2e9d, + 0x2e5b, 0x2e7f, 0x2e99, 0xd1bc, 0x1150, 0xd1dc, 0x1150, 0x8001, + 0x7002, 0x2011, 0x0001, 0x04e1, 0x05c0, 0x04d1, 0x04b0, 0x780f, + 0x0000, 0x7820, 0x7924, 0x7803, 0x0004, 0x7822, 0x7926, 0x2001, + 0x0201, 0x200c, 0x81ff, 0x0de8, 0x080c, 0x2dd6, 0x2009, 0x0001, + 0x7808, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x7902, 0x00f0, 0x8001, + 0x7002, 0xa184, 0x0880, 0x1138, 0x7804, 0xd0fc, 0x1940, 0x2011, + 0x0001, 0x00b1, 0x0090, 0x6030, 0xa092, 0x0004, 0xa086, 0x0009, + 0x1120, 0x6000, 0x601a, 0x2011, 0x0025, 0x6232, 0xd1dc, 0x1988, + 0x0870, 0x7803, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, + 0x6024, 0xa005, 0x0520, 0x8001, 0x6026, 0x6018, 0x6130, 0xa140, + 0x2804, 0x7832, 0x8840, 0x2804, 0x7836, 0x8840, 0x2804, 0x7822, + 0x8840, 0x2804, 0x7826, 0x8840, 0x7a02, 0x7000, 0x8000, 0x7002, + 0x6018, 0xa802, 0xa08a, 0x0029, 0x1138, 0x6018, 0xa080, 0x0001, + 0x2004, 0x601a, 0x2001, 0x000d, 0x6032, 0xa085, 0x0001, 0x0005, + 0x00f6, 0x00e6, 0x00c6, 0x2071, 0x8dff, 0x2079, 0x0020, 0x7904, + 0xd1fc, 0x01f0, 0x7803, 0x0002, 0x2d60, 0xa026, 0x7000, 0x0002, + 0x2ef0, 0x2edb, 0x2ee7, 0x8001, 0x7002, 0xd19c, 0x1188, 0x2011, + 0x0001, 0x080c, 0x2ea0, 0x0160, 0x080c, 0x2ea0, 0x0048, 0x8001, + 0x7002, 0x7804, 0xd0fc, 0x1d30, 0x2011, 0x0001, 0x080c, 0x2ea0, + 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, + 0x0200, 0x601b, 0x0004, 0x2061, 0x0100, 0x60cf, 0x0400, 0x6004, + 0xc0ac, 0xa085, 0x0200, 0x6006, 0x2001, 0x0074, 0x2004, 0xa005, + 0x01f8, 0x2038, 0x2001, 0x0076, 0x2024, 0x2001, 0x0077, 0x201c, + 0x080c, 0x2fe4, 0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, + 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, + 0x6818, 0xa080, 0x000d, 0x04a1, 0x1d90, 0x2d00, 0x681a, 0x0088, + 0x080c, 0x2fe4, 0x6833, 0x000d, 0x2070, 0x6827, 0x0001, 0x2d00, + 0x681a, 0x2001, 0x0076, 0x2004, 0x2072, 0x2001, 0x0077, 0x2004, + 0x7006, 0x2061, 0x0020, 0x2079, 0x0100, 0x6013, 0x0400, 0x20e1, + 0x9040, 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x601a, + 0x0006, 0x2001, 0x0073, 0x2004, 0x700e, 0x601e, 0x78c6, 0x000e, + 0x78ca, 0xa006, 0x603a, 0x603e, 0x00ce, 0x00ee, 0x00fe, 0x0005, + 0x00e6, 0x2071, 0x0010, 0x20a0, 0x2099, 0x0014, 0x7003, 0x0026, + 0x7432, 0x7336, 0xa006, 0x703a, 0x703e, 0x810b, 0x810b, 0x21a8, + 0x810b, 0x7122, 0x7003, 0x0041, 0x7004, 0xd0fc, 0x0de8, 0x7003, + 0x0002, 0x7003, 0x0040, 0x53a5, 0x7430, 0x7334, 0x87ff, 0x0180, + 0x00c6, 0x00d6, 0x2d60, 0x00c6, 0x080c, 0x35c0, 0x00ce, 0x6018, + 0x2070, 0x2d00, 0x7006, 0x601a, 0x00de, 0x00ce, 0xa085, 0x0001, + 0x00ee, 0x0005, 0x00e6, 0x2001, 0x0075, 0x2004, 0xa005, 0x0508, + 0x2038, 0x2001, 0x0078, 0x2024, 0x2001, 0x0079, 0x201c, 0x080c, + 0x2fe4, 0x2d60, 0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, + 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, + 0x6818, 0xa080, 0x000d, 0x080c, 0x2f58, 0x1d88, 0x2d00, 0x681a, + 0x00d8, 0x0491, 0x2d60, 0x6033, 0x000d, 0x2070, 0x6027, 0x0001, + 0x2c00, 0x601a, 0x2001, 0x0078, 0x2004, 0x2072, 0x2001, 0x0079, + 0x2004, 0x7006, 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, + 0x2001, 0x0073, 0x2004, 0x700e, 0x2001, 0x0030, 0x2003, 0x0004, + 0x7824, 0xd0ac, 0x1178, 0x2001, 0x0101, 0x200c, 0xc1ed, 0x2102, + 0x6027, 0x0000, 0x2001, 0x8dde, 0x2003, 0x0003, 0x2001, 0x0030, + 0x2003, 0x0009, 0x00ee, 0x0005, 0x080c, 0x1488, 0x0178, 0xa006, + 0x6802, 0x7010, 0xa005, 0x1120, 0x2d00, 0x7012, 0x7016, 0x0020, + 0x7014, 0x6802, 0x2d00, 0x7016, 0xad80, 0x000d, 0x0005, 0x0804, + 0x2823, 0x7d38, 0x7c3c, 0x0804, 0x28c7, 0x080c, 0x35c0, 0x0904, + 0x2848, 0x080c, 0x4c42, 0x0110, 0x080c, 0x40fd, 0x2009, 0x001c, + 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3601, 0x701b, 0x3011, + 0x0005, 0xade8, 0x000d, 0x6800, 0xa005, 0x0904, 0x284b, 0x6804, + 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x284b, 0xd094, 0x00c6, 0x2061, + 0x0100, 0x6104, 0x0138, 0x6200, 0xa292, 0x0005, 0x0218, 0xa18c, + 0xffdf, 0x0010, 0xa18d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, + 0x2061, 0x0100, 0x6104, 0x0118, 0xa18d, 0x0010, 0x0010, 0xa18c, + 0xffef, 0x6106, 0x00ce, 0x2009, 0x0100, 0x210c, 0xa18a, 0x0002, + 0x0268, 0xd084, 0x0158, 0x6a28, 0xa28a, 0x007f, 0x1a04, 0x284b, + 0xa288, 0x263d, 0x210d, 0xa18c, 0x00ff, 0x6156, 0xd0dc, 0x0130, + 0x6828, 0xa08a, 0x007f, 0x1a04, 0x284b, 0x604e, 0x6808, 0xa08a, + 0x0100, 0x0a04, 0x284b, 0xa08a, 0x0841, 0x1a04, 0x284b, 0xa084, + 0x0007, 0x1904, 0x284b, 0x680c, 0xa005, 0x0904, 0x284b, 0x6810, + 0xa005, 0x0904, 0x284b, 0x6848, 0x6940, 0xa10a, 0x1a04, 0x284b, + 0x8001, 0x0904, 0x284b, 0x684c, 0x6944, 0xa10a, 0x1a04, 0x284b, + 0x8001, 0x0904, 0x284b, 0x6804, 0xd0fc, 0x01f8, 0x080c, 0x35c0, + 0x0904, 0x2848, 0x2009, 0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, + 0xa290, 0x0038, 0xa399, 0x0000, 0x080c, 0x3601, 0x701b, 0x3091, + 0x0005, 0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069, 0x8b6d, + 0x2da0, 0x53a3, 0x7010, 0xa0e8, 0x000d, 0x20a9, 0x001c, 0x2d98, + 0x2069, 0x8b51, 0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e, + 0x8007, 0xa084, 0x00ff, 0x6042, 0x080c, 0x4d79, 0x080c, 0x4618, + 0x080c, 0x4670, 0x6000, 0xa086, 0x0000, 0x1904, 0x3148, 0x6808, + 0x602a, 0x080c, 0x1fbd, 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, + 0x810f, 0x8217, 0x831f, 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, + 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, + 0x8217, 0x831f, 0x0010, 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, + 0x6312, 0x080c, 0x5695, 0x6904, 0xd1fc, 0x0520, 0x00c6, 0x2009, + 0x0000, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020, 0x839d, + 0x12b0, 0x3508, 0x8109, 0x080c, 0x520d, 0x6878, 0x6016, 0x6874, + 0x2008, 0xa084, 0xff00, 0x8007, 0x600a, 0xa184, 0x00ff, 0x6006, + 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, + 0x30e7, 0x00ce, 0x2069, 0x8b51, 0x2001, 0x8d9c, 0x6a80, 0xa294, + 0x0030, 0xa28e, 0x0000, 0x0178, 0xa28e, 0x0010, 0x0118, 0xa28e, + 0x0020, 0x0148, 0x2003, 0xaaaa, 0x2001, 0x0204, 0x2004, 0x2009, + 0x8d8d, 0x200a, 0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, + 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x4c42, 0x0128, 0x080c, + 0x37e7, 0x0110, 0x080c, 0x2333, 0x60c0, 0xa005, 0x01a8, 0x6003, + 0x0001, 0x2091, 0x301d, 0x080c, 0x4c42, 0x1158, 0x2011, 0x4b5d, + 0x080c, 0x560d, 0x2001, 0x8d9d, 0x2003, 0x0000, 0x080c, 0x4b8b, + 0x0038, 0x080c, 0x403d, 0x0020, 0x6003, 0x0004, 0x2091, 0x301d, + 0x0804, 0x2823, 0x6000, 0xa086, 0x0000, 0x0904, 0x2848, 0x2069, + 0x8b51, 0x7830, 0x6842, 0x7834, 0x6846, 0x2d00, 0x2009, 0x001c, + 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3604, 0x81ff, 0x1904, + 0x2848, 0x080c, 0x4c42, 0x1158, 0x2001, 0x8d9d, 0x2003, 0x0001, + 0x2001, 0x8b00, 0x2003, 0x0001, 0x080c, 0x4b8b, 0x0038, 0xa006, + 0x080c, 0x2333, 0x080c, 0x40fd, 0x080c, 0x403d, 0x0804, 0x2823, + 0x81ff, 0x1904, 0x2848, 0x080c, 0x4c42, 0x1110, 0x0804, 0x2848, + 0x6184, 0x81ff, 0x0198, 0x703f, 0x0000, 0x2001, 0x91c0, 0x2009, + 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0126, 0x2091, 0x8000, + 0x080c, 0x3604, 0x701b, 0x2821, 0x012e, 0x0005, 0x703f, 0x0001, + 0x00d6, 0x2069, 0x91c0, 0x20a9, 0x0040, 0x20a1, 0x91c0, 0x2019, + 0xffff, 0x43a4, 0x654c, 0xa588, 0x263d, 0x210d, 0xa18c, 0x00ff, + 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100, 0xa506, 0x01a8, 0x080c, + 0x430a, 0x1190, 0x6014, 0x821c, 0x0238, 0xa398, 0x91c0, 0xa085, + 0xff00, 0x8007, 0x201a, 0x0038, 0xa398, 0x91c0, 0x2324, 0xa4a4, + 0xff00, 0xa405, 0x201a, 0x8210, 0x8108, 0xa182, 0x0080, 0x1208, + 0x0c18, 0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a, 0x00de, 0x20a9, + 0x0040, 0x20a1, 0x91c0, 0x2099, 0x91c0, 0x080c, 0x409e, 0x0804, + 0x3185, 0x080c, 0x35e5, 0x0904, 0x284b, 0x00c6, 0x080c, 0x35c0, + 0x00ce, 0x0904, 0x2848, 0x080c, 0x4c42, 0x0500, 0x2001, 0x8b52, + 0x2004, 0xd0b4, 0x01d8, 0x6000, 0xd08c, 0x11c0, 0x6004, 0xa084, + 0x00ff, 0xa086, 0x0006, 0x1190, 0x6837, 0x0000, 0x6838, 0xc0fd, + 0x683a, 0x080c, 0x7d17, 0x0904, 0x2848, 0x7007, 0x0003, 0x701b, + 0x3202, 0x0005, 0x080c, 0x35e5, 0x0904, 0x284b, 0x20a9, 0x002b, + 0x2c98, 0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, + 0x0006, 0x2098, 0xad80, 0x0006, 0x20a0, 0x080c, 0x409e, 0x20a9, + 0x0004, 0xac80, 0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, 0x080c, + 0x409e, 0x2d00, 0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, + 0x0804, 0x3604, 0x81ff, 0x1904, 0x2848, 0x080c, 0x35d5, 0x0904, + 0x284b, 0x080c, 0x44c2, 0x0804, 0x2823, 0x81ff, 0x1904, 0x2848, + 0x7828, 0xa08a, 0x1000, 0x1a04, 0x284b, 0x080c, 0x35e5, 0x0904, + 0x284b, 0x080c, 0x451d, 0x0904, 0x2848, 0x2019, 0x0004, 0x080c, + 0x44d4, 0x7924, 0x810f, 0x7a28, 0x0011, 0x0804, 0x2823, 0xa186, + 0x00ff, 0x0110, 0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0x8b00, + 0x644c, 0x2400, 0xa506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, + 0x0005, 0x080c, 0x430a, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, + 0xa108, 0x080c, 0x5619, 0x0005, 0x81ff, 0x1904, 0x2848, 0x080c, + 0x35d5, 0x0904, 0x284b, 0x080c, 0x43ad, 0x0904, 0x2848, 0x080c, + 0x44cb, 0x0804, 0x2823, 0x81ff, 0x1904, 0x2848, 0x080c, 0x35d5, + 0x0904, 0x284b, 0x080c, 0x43ad, 0x0904, 0x2848, 0x080c, 0x44b9, + 0x0804, 0x2823, 0x6100, 0x2001, 0x8d9d, 0x2014, 0xa282, 0x0003, + 0x1210, 0x0804, 0x2823, 0x2011, 0x0000, 0x0804, 0x2823, 0x0804, + 0x2823, 0x080c, 0x35e5, 0x0904, 0x284b, 0x6004, 0xa086, 0x0707, + 0x0904, 0x284b, 0x2001, 0x8b00, 0x2004, 0xa086, 0x0003, 0x1904, + 0x2848, 0x00d6, 0xace8, 0x000a, 0x7924, 0xd184, 0x0110, 0xace8, + 0x0006, 0x680c, 0x8007, 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, + 0x831f, 0x6a00, 0x8217, 0x00de, 0x6100, 0xa18c, 0x0200, 0x0804, + 0x2823, 0x7824, 0xa09c, 0x00ff, 0xa39a, 0x0003, 0x1a04, 0x2848, + 0x624c, 0xa294, 0x00ff, 0xa084, 0xff00, 0x8007, 0xa206, 0x1150, + 0x2001, 0x8b40, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, + 0x0804, 0x3604, 0x81ff, 0x1904, 0x2848, 0x080c, 0x35e5, 0x0904, + 0x284b, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1904, 0x2848, + 0x00c6, 0x080c, 0x35c0, 0x00ce, 0x0904, 0x2848, 0x6837, 0x0000, + 0x6838, 0xc0fd, 0x683a, 0x080c, 0x7cc9, 0x0904, 0x2848, 0x7007, + 0x0003, 0x701b, 0x32fc, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, + 0x2848, 0xad80, 0x000e, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, + 0x7d38, 0x0804, 0x3604, 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff, + 0x0118, 0x81ff, 0x1904, 0x2848, 0x080c, 0x4c42, 0x0128, 0xa006, + 0x080c, 0x2333, 0x080c, 0x40fd, 0x7828, 0xa08a, 0x1000, 0x1a04, + 0x284b, 0x7924, 0xa18c, 0xff00, 0x810f, 0xa186, 0x00ff, 0x0138, + 0xa182, 0x007f, 0x1a04, 0x284b, 0x2100, 0x080c, 0x22fd, 0x0026, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, 0x8dbd, 0x601b, 0x0000, + 0x601f, 0x0000, 0x080c, 0x4c42, 0x1158, 0x2001, 0x8d9d, 0x2003, + 0x0001, 0x2001, 0x8b00, 0x2003, 0x0001, 0x080c, 0x4b8b, 0x00a0, + 0x2061, 0x0100, 0x2001, 0x8b14, 0x2004, 0xa084, 0x00ff, 0x810f, + 0xa105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x001e, + 0x2011, 0x4062, 0x080c, 0x568c, 0x7924, 0xa18c, 0xff00, 0x810f, + 0x080c, 0x4c42, 0x1110, 0x2009, 0x00ff, 0x7a28, 0x080c, 0x324f, + 0x012e, 0x00ce, 0x002e, 0x0804, 0x2823, 0x7924, 0xa18c, 0xff00, + 0x810f, 0x00c6, 0x080c, 0x42d6, 0x2c08, 0x00ce, 0x1904, 0x284b, + 0x0804, 0x2823, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x2848, + 0x60c8, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, + 0x2848, 0x080c, 0x35c0, 0x1120, 0x2009, 0x0002, 0x0804, 0x2848, + 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3601, 0x701b, + 0x339a, 0x0005, 0x2009, 0x0080, 0x080c, 0x430a, 0x1130, 0x6004, + 0xa084, 0x00ff, 0xa086, 0x0006, 0x0120, 0x2021, 0x400a, 0x0804, + 0x2825, 0x00d6, 0xade8, 0x000d, 0x6900, 0x6a08, 0x6b0c, 0x6c10, + 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0904, 0x340d, 0xa0be, + 0x0112, 0x0904, 0x340d, 0xa0be, 0x0113, 0x0904, 0x340d, 0xa0be, + 0x0114, 0x0904, 0x340d, 0xa0be, 0x0117, 0x0904, 0x340d, 0xa0be, + 0x011a, 0x0904, 0x340d, 0xa0be, 0x0121, 0x05b0, 0xa0be, 0x0131, + 0x0598, 0xa0be, 0x0171, 0x05c8, 0xa0be, 0x0173, 0x05b0, 0xa0be, + 0x01a1, 0x1120, 0x6830, 0x8007, 0x6832, 0x04a0, 0xa0be, 0x0212, + 0x0540, 0xa0be, 0x0213, 0x0528, 0xa0be, 0x0214, 0x01b0, 0xa0be, + 0x0217, 0x0168, 0xa0be, 0x021a, 0x1120, 0x6838, 0x8007, 0x683a, + 0x00e0, 0xa0be, 0x0300, 0x01c8, 0x00de, 0x0804, 0x284b, 0xad80, + 0x0010, 0x20a9, 0x0007, 0x080c, 0x3450, 0xad80, 0x000e, 0x20a9, + 0x0001, 0x080c, 0x3450, 0x0048, 0xad80, 0x000c, 0x080c, 0x345e, + 0x0048, 0xad80, 0x000e, 0x080c, 0x345e, 0xad80, 0x000c, 0x20a9, + 0x0001, 0x04f1, 0x00c6, 0x080c, 0x35c0, 0x0558, 0x6838, 0xc0fd, + 0x683a, 0x6837, 0x0119, 0x6853, 0x0000, 0x684f, 0x0020, 0x685b, + 0x0001, 0x810b, 0x697e, 0x6883, 0x0000, 0x6a86, 0x6b8a, 0x6c8e, + 0x6d92, 0x6996, 0x689b, 0x0000, 0x00ce, 0x00de, 0x6837, 0x0000, + 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x080c, 0x7ce3, 0x1120, + 0x2009, 0x0003, 0x0804, 0x2848, 0x7007, 0x0003, 0x701b, 0x3447, + 0x0005, 0x00ce, 0x00de, 0x2009, 0x0002, 0x0804, 0x2848, 0x6820, + 0xa086, 0x8001, 0x1904, 0x2823, 0x2009, 0x0004, 0x0804, 0x2848, + 0x0016, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108, + 0x280a, 0x8108, 0x1f04, 0x3452, 0x001e, 0x0005, 0x0016, 0x00a6, + 0x00b6, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x2054, 0x8000, + 0x205c, 0x2b0a, 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a, + 0x00be, 0x00ae, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, + 0x0804, 0x2848, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0x60c8, + 0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x284b, 0xa182, 0x00ff, + 0x1a04, 0x284b, 0x7a2c, 0x7b28, 0x606c, 0xa306, 0x1140, 0x6070, + 0xa24e, 0x0904, 0x284b, 0xa9cc, 0xff00, 0x0904, 0x284b, 0x00c6, + 0x080c, 0x3513, 0x2c68, 0x00ce, 0x01c0, 0xa0c6, 0x4000, 0x1108, + 0x0088, 0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008, + 0x1118, 0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010, + 0x2001, 0x4006, 0x2020, 0x0804, 0x2825, 0x2d00, 0x7022, 0x0016, + 0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0x6cc2, 0x05a0, 0x2d00, + 0x601a, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x35c0, 0x00ce, + 0x2b70, 0x1150, 0x080c, 0x6d18, 0x00ee, 0x00ce, 0x00be, 0x001e, + 0x2009, 0x0002, 0x0804, 0x2848, 0x6837, 0x0000, 0x2d00, 0x6012, + 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x0126, 0x2091, 0x8000, + 0x080c, 0x2563, 0x012e, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, + 0x42a7, 0x2001, 0x0002, 0x080c, 0x42b9, 0x2009, 0x0002, 0x080c, + 0x6d3f, 0xa085, 0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x1120, + 0x2009, 0x0003, 0x0804, 0x2848, 0x7007, 0x0003, 0x701b, 0x3501, + 0x0005, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0904, 0x2848, + 0x7020, 0x2060, 0x2009, 0x0000, 0x080c, 0x457e, 0x1110, 0x2009, + 0x0001, 0x0804, 0x2823, 0x00e6, 0x00d6, 0x2029, 0x0000, 0x2001, + 0x8b32, 0x2004, 0xd0ac, 0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff, + 0x2071, 0x8c34, 0x0030, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, + 0x8cb4, 0x2e04, 0xa005, 0x1130, 0x2100, 0xa406, 0x1548, 0x2428, 0xc5fd, 0x0430, 0x2068, 0x6f10, 0x2700, 0xa306, 0x11b0, 0x6e14, 0x2600, 0xa206, 0x1190, 0x2400, 0xa106, 0x1160, 0x2d60, 0xd884, 0x0540, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1510, 0x2001, 0x4000, 0x0400, 0x2001, 0x4007, 0x00e8, 0x2400, 0xa106, 0x1140, 0x6e14, 0x87ff, 0x1110, 0x86ff, 0x09d0, 0x2001, 0x4008, 0x0090, - 0x8420, 0x8e70, 0x1f04, 0x35b1, 0x85ff, 0x1130, 0x2001, 0x4009, - 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, 0x4400, 0x1dd0, 0x6312, + 0x8420, 0x8e70, 0x1f04, 0x3529, 0x85ff, 0x1130, 0x2001, 0x4009, + 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, 0x42d6, 0x1dd0, 0x6312, 0x6216, 0xa006, 0xa005, 0x00de, 0x00ee, 0x0005, 0x81ff, 0x1904, - 0x2924, 0x080c, 0x3641, 0x0904, 0x2924, 0x6837, 0x0000, 0x6838, - 0xc0fd, 0x683a, 0x7824, 0xa005, 0x0904, 0x2927, 0xa096, 0x00ff, - 0x0120, 0xa092, 0x0004, 0x1a04, 0x2927, 0x2010, 0x2d18, 0x080c, - 0x2631, 0x0904, 0x2924, 0x7007, 0x0003, 0x701b, 0x3618, 0x0005, - 0x6830, 0xa086, 0x0100, 0x0904, 0x2924, 0x0804, 0x28ff, 0x7924, + 0x2848, 0x080c, 0x35c0, 0x0904, 0x2848, 0x6837, 0x0000, 0x6838, + 0xc0fd, 0x683a, 0x7824, 0xa005, 0x0904, 0x284b, 0xa096, 0x00ff, + 0x0120, 0xa092, 0x0004, 0x1a04, 0x284b, 0x2010, 0x2d18, 0x080c, + 0x2528, 0x0904, 0x2848, 0x7007, 0x0003, 0x701b, 0x3590, 0x0005, + 0x6830, 0xa086, 0x0100, 0x0904, 0x2848, 0x0804, 0x2823, 0x7924, 0xa18c, 0xff00, 0x810f, 0x60c8, 0xd0ac, 0x1120, 0xa182, 0x0080, - 0x0a04, 0x2927, 0xa182, 0x00ff, 0x1a04, 0x2927, 0x0126, 0x2091, - 0x8000, 0x080c, 0x831a, 0x1150, 0xa190, 0x936e, 0x2204, 0xa065, - 0x0128, 0x080c, 0x41e0, 0x012e, 0x0804, 0x28ff, 0x012e, 0x0804, - 0x2924, 0x080c, 0x147c, 0x0188, 0xa006, 0x6802, 0x7010, 0xa005, - 0x1120, 0x2d00, 0x7012, 0x7016, 0x0030, 0x7014, 0x6802, 0x2060, - 0x2d00, 0x6006, 0x7016, 0xad80, 0x000d, 0x0005, 0x7924, 0x810f, - 0xa18c, 0x00ff, 0x080c, 0x4434, 0x1130, 0x7e28, 0xa684, 0x3fff, - 0xa082, 0x4000, 0x0208, 0xa066, 0x8cff, 0x0005, 0x7e24, 0x860f, - 0xa18c, 0x00ff, 0x080c, 0x4434, 0x1128, 0xa6b4, 0x00ff, 0xa682, - 0x4000, 0x0208, 0xa066, 0x8cff, 0x0005, 0x0016, 0x7110, 0x81ff, - 0x0128, 0x2168, 0x6904, 0x080c, 0x1493, 0x0cc8, 0x7112, 0x7116, - 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, - 0x92e6, 0x6606, 0x6112, 0x600e, 0x6226, 0x632a, 0x642e, 0x6532, - 0x2c10, 0x080c, 0x14c7, 0x7007, 0x0002, 0x701b, 0x28ff, 0x0005, - 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x92a4, - 0x2004, 0xa005, 0x1168, 0x0e04, 0x36b0, 0x7818, 0xd084, 0x1140, - 0x7a22, 0x7b26, 0x7c2a, 0x781b, 0x0001, 0x2091, 0x4080, 0x0408, - 0x0016, 0x00c6, 0x00e6, 0x2071, 0x9296, 0x7138, 0xa182, 0x0010, - 0x0218, 0x7030, 0x2060, 0x0078, 0x7030, 0xa0e0, 0x0004, 0xac82, - 0x92e6, 0x0210, 0x2061, 0x92a6, 0x2c00, 0x7032, 0x81ff, 0x1108, - 0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce, - 0x001e, 0x012e, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x9296, 0x7038, - 0xa005, 0x0570, 0x0126, 0x2091, 0x8000, 0x0e04, 0x3707, 0x00f6, - 0x2079, 0x0000, 0x7818, 0xd084, 0x1508, 0x00c6, 0x7034, 0x2060, - 0x2c04, 0x7822, 0x6004, 0x7826, 0x6008, 0x782a, 0x781b, 0x0001, - 0x2091, 0x4080, 0x7038, 0x8001, 0x703a, 0xa005, 0x1130, 0x7033, - 0x92a6, 0x7037, 0x92a6, 0x00ce, 0x0048, 0xac80, 0x0004, 0xa0fa, - 0x92e6, 0x0210, 0x2001, 0x92a6, 0x7036, 0x00ce, 0x00fe, 0x012e, - 0x00ee, 0x0005, 0x0026, 0x2001, 0x9252, 0x2004, 0xd0c4, 0x0120, - 0x2011, 0x8014, 0x080c, 0x3698, 0x002e, 0x0005, 0x81ff, 0x1904, - 0x2924, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d, 0x6032, 0x080c, - 0x4dc5, 0x1158, 0x2001, 0x94d8, 0x2003, 0x0001, 0x2001, 0x9200, - 0x2003, 0x0001, 0x080c, 0x4d10, 0x0010, 0x080c, 0x4105, 0x012e, - 0x0804, 0x28ff, 0x7824, 0x2008, 0xa18c, 0xfffd, 0x1128, 0x61d4, - 0xa10d, 0x61d6, 0x0804, 0x28ff, 0x0804, 0x2927, 0x81ff, 0x1904, - 0x2924, 0x6000, 0xa086, 0x0003, 0x1904, 0x2924, 0x2001, 0x9252, - 0x2004, 0xd0a4, 0x1904, 0x2924, 0x080c, 0x3666, 0x0904, 0x2927, - 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1120, 0x7828, 0xa005, - 0x0904, 0x28ff, 0x00c6, 0x080c, 0x3641, 0x00ce, 0x0904, 0x2924, - 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, - 0x84d7, 0x0904, 0x2924, 0x7007, 0x0003, 0x701b, 0x3770, 0x0005, - 0x6830, 0xa086, 0x0100, 0x0904, 0x2924, 0x0804, 0x28ff, 0x2001, - 0x9200, 0x2004, 0xa086, 0x0003, 0x1904, 0x2924, 0x7f24, 0x7a2c, - 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3641, 0x0904, 0x2924, 0x2009, - 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80, - 0x0005, 0x7026, 0x20a0, 0x080c, 0x4434, 0x15e0, 0x6004, 0xa0c4, - 0x00ff, 0xa8c6, 0x0006, 0x0150, 0xa0c4, 0xff00, 0xa8c6, 0x0600, - 0x0128, 0xa084, 0x00ff, 0xa082, 0x0006, 0x1660, 0xd784, 0x0150, - 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x080c, - 0x34eb, 0x0048, 0xac80, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, - 0x53a3, 0x080c, 0x34eb, 0xa186, 0x007e, 0x0178, 0xa186, 0x0080, - 0x0160, 0x6004, 0xa084, 0x00ff, 0xa0c2, 0x0006, 0x1210, 0xc1fd, - 0x0020, 0x080c, 0x46a5, 0x1108, 0xc1fd, 0x21a2, 0xc1fc, 0x94a0, - 0xa6b0, 0x0005, 0x8108, 0x2001, 0x9232, 0x2004, 0xd0ac, 0x0118, - 0xa186, 0x0100, 0x0040, 0xd78c, 0x0120, 0xa186, 0x0100, 0x0148, - 0x0018, 0xa186, 0x007e, 0x0128, 0xa686, 0x0028, 0x0150, 0x0804, - 0x3793, 0x86ff, 0x1120, 0x7120, 0x810b, 0x0804, 0x28ff, 0x702f, - 0x0001, 0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0x92e6, - 0x6007, 0x0000, 0x6612, 0x7024, 0x600e, 0x6226, 0x632a, 0x642e, - 0x6532, 0x2c10, 0x080c, 0x14c7, 0x7007, 0x0002, 0x701b, 0x3809, - 0x0005, 0x702c, 0xa005, 0x1170, 0x711c, 0x7024, 0x20a0, 0x7728, - 0x2031, 0x0000, 0x2061, 0x92e6, 0x6224, 0x6328, 0x642c, 0x6530, - 0x0804, 0x3793, 0x7120, 0x810b, 0x0804, 0x28ff, 0x2029, 0x007e, - 0x7924, 0x7a28, 0x7b2c, 0x7c38, 0xa184, 0xff00, 0x8007, 0xa0e2, - 0x0020, 0x0a04, 0x2927, 0xa502, 0x0a04, 0x2927, 0xa184, 0x00ff, - 0xa0e2, 0x0020, 0x0a04, 0x2927, 0xa502, 0x0a04, 0x2927, 0xa284, - 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2927, 0xa502, 0x0a04, - 0x2927, 0xa284, 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x2927, 0xa502, - 0x0a04, 0x2927, 0xa384, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, - 0x2927, 0xa502, 0x0a04, 0x2927, 0xa384, 0x00ff, 0xa0e2, 0x0020, - 0x0a04, 0x2927, 0xa502, 0x0a04, 0x2927, 0xa484, 0xff00, 0x8007, - 0xa0e2, 0x0020, 0x0a04, 0x2927, 0xa502, 0x0a04, 0x2927, 0xa484, - 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x2927, 0xa502, 0x0a04, 0x2927, - 0x2061, 0x94df, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x28ff, - 0x080c, 0x3641, 0x0904, 0x2924, 0x2009, 0x0015, 0x7a2c, 0x7b28, - 0x7c3c, 0x7d38, 0x080c, 0x3682, 0x701b, 0x3887, 0x0005, 0xade8, - 0x000d, 0x6800, 0xa005, 0x0904, 0x2927, 0x6804, 0x2008, 0xa18c, - 0xfff8, 0x1904, 0x2927, 0x680c, 0xa005, 0x0904, 0x2927, 0xa082, - 0xff01, 0x1a04, 0x2927, 0x6810, 0xa082, 0x005c, 0x0a04, 0x2927, - 0x6824, 0x2008, 0xa082, 0x0008, 0x0a04, 0x2927, 0xa182, 0x0400, - 0x1a04, 0x2927, 0x080c, 0x5a84, 0x6944, 0x6820, 0xa102, 0x0a04, - 0x2927, 0x6828, 0x6944, 0x810c, 0xa102, 0x0a04, 0x2927, 0x6840, - 0xa082, 0x000f, 0x1a04, 0x2927, 0x00d6, 0x080c, 0x145f, 0x0904, - 0x2924, 0x2d00, 0x00de, 0x684e, 0x00d6, 0x6848, 0xa005, 0x0148, - 0x2008, 0x2069, 0x9200, 0x68dc, 0xa108, 0x68a8, 0xa102, 0x1208, - 0x69de, 0x00de, 0x20a9, 0x0015, 0x2d98, 0x2069, 0x9281, 0x2da0, - 0x53a3, 0x080c, 0x5957, 0x0904, 0x2924, 0x080c, 0x5885, 0x1904, - 0x2924, 0x00c6, 0x2061, 0x0100, 0x6104, 0xa18d, 0x8000, 0x6106, - 0x610c, 0xa18d, 0x0100, 0x610e, 0x2061, 0x0140, 0x610c, 0xa18d, - 0x0100, 0x6902, 0x6b10, 0x2061, 0x9519, 0x6316, 0x080c, 0x4716, - 0x2001, 0x9295, 0x2003, 0x0000, 0x00ce, 0x0804, 0x28ff, 0xe000, - 0xe000, 0xe000, 0xe000, 0xe000, 0xe000, 0xe000, 0x0804, 0x28ff, - 0x7824, 0x0804, 0x28ff, 0x7824, 0x00e6, 0x2071, 0x9281, 0x00ee, - 0x0804, 0x28ff, 0x0006, 0x2001, 0x9252, 0x2004, 0xd0cc, 0x000e, - 0x0005, 0x0006, 0x2001, 0x9271, 0x2004, 0xd0bc, 0x000e, 0x0005, - 0x6164, 0x7a24, 0x6300, 0x82ff, 0x1118, 0x7926, 0x0804, 0x28ff, - 0x83ff, 0x1904, 0x2927, 0x2001, 0xfff0, 0xa200, 0x1a04, 0x2927, - 0x2019, 0xffff, 0x6068, 0xa302, 0xa200, 0x0a04, 0x2927, 0x7926, - 0x6266, 0x0804, 0x28ff, 0x2001, 0x9200, 0x2004, 0xa086, 0x0003, - 0x1904, 0x2924, 0x7c28, 0x7d24, 0x7e38, 0x7f2c, 0x080c, 0x3641, - 0x0904, 0x2924, 0x2009, 0x0000, 0x2019, 0x0000, 0x7023, 0x0000, - 0x702f, 0x0000, 0xad80, 0x0003, 0x7026, 0x20a0, 0xa1e0, 0x936e, - 0x2c64, 0x8cff, 0x01b8, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, - 0x0130, 0x6004, 0xa084, 0xff00, 0xa086, 0x0600, 0x1158, 0x6014, - 0x20a2, 0x94a0, 0x6010, 0x8007, 0xa105, 0x8007, 0x20a2, 0x94a0, - 0xa398, 0x0002, 0x8108, 0xa182, 0x00ff, 0x0120, 0xa386, 0x002a, - 0x0148, 0x08e0, 0x83ff, 0x1120, 0x7120, 0x810c, 0x0804, 0x28ff, - 0x702f, 0x0001, 0x711e, 0x7020, 0xa300, 0x7022, 0x2061, 0x92e6, - 0x6007, 0x0000, 0x6312, 0x7024, 0x600e, 0x6426, 0x652a, 0x662e, - 0x6732, 0x2c10, 0x080c, 0x14c7, 0x7007, 0x0002, 0x701b, 0x3999, - 0x0005, 0x702c, 0xa005, 0x1158, 0x711c, 0x7024, 0x20a0, 0x2019, - 0x0000, 0x6424, 0x6528, 0x662c, 0x6730, 0x0804, 0x3956, 0x7120, - 0x810c, 0x0804, 0x28ff, 0x81ff, 0x1904, 0x2924, 0x60c8, 0xd0ac, - 0x1118, 0xd09c, 0x0904, 0x2924, 0x080c, 0x3641, 0x0904, 0x2924, - 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3682, 0x701b, - 0x39c2, 0x0005, 0x00d6, 0xade8, 0x000d, 0x6828, 0xa0be, 0x7000, - 0x0148, 0xa0be, 0x7100, 0x0130, 0xa0be, 0x7200, 0x0118, 0x00de, - 0x0804, 0x2927, 0x6820, 0x6924, 0x080c, 0x240b, 0x1500, 0x080c, - 0x4400, 0x11e8, 0x7122, 0x6612, 0x6516, 0x6e18, 0x00c6, 0x080c, - 0x3641, 0x01a8, 0x080c, 0x3641, 0x0190, 0x00ce, 0x00de, 0x6837, - 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x080c, 0x845c, - 0x0904, 0x2924, 0x7007, 0x0003, 0x701b, 0x39fa, 0x0005, 0x00de, - 0x0804, 0x2924, 0x7120, 0x080c, 0x441f, 0x6820, 0xa086, 0x8001, - 0x0904, 0x2924, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002, 0x0006, - 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x4166, 0x000e, 0xade8, - 0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0x92e6, 0x6007, - 0x0000, 0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x1108, 0x0018, 0xa7c6, - 0x7100, 0x1140, 0xa6c2, 0x0004, 0x0a04, 0x2927, 0x2009, 0x0004, - 0x0804, 0x3685, 0xa7c6, 0x7200, 0x1904, 0x2927, 0xa6c2, 0x0054, - 0x0a04, 0x2927, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a, 0x642e, - 0x6532, 0x2c10, 0x080c, 0x14c7, 0x7007, 0x0002, 0x701b, 0x3a41, - 0x0005, 0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004, 0xa080, - 0x0002, 0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x4166, - 0x000e, 0x2009, 0x002a, 0x2061, 0x92e6, 0x6224, 0x6328, 0x642c, - 0x6530, 0x0804, 0x3685, 0x81ff, 0x1904, 0x2924, 0x080c, 0x3656, - 0x0904, 0x2927, 0x080c, 0x44d4, 0x0904, 0x2924, 0x080c, 0x4604, - 0x0804, 0x28ff, 0x0126, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, - 0x9200, 0x6044, 0xd0a4, 0x11b0, 0xd084, 0x0118, 0x080c, 0x3bd7, - 0x0068, 0xd08c, 0x0118, 0x080c, 0x3af8, 0x0040, 0xd094, 0x0118, - 0x080c, 0x3ad0, 0x0018, 0xd09c, 0x0108, 0x0061, 0x00ee, 0x00ce, - 0x012e, 0x0005, 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, - 0x001e, 0x0ca0, 0x624c, 0xa286, 0xf0f0, 0x1150, 0x6048, 0xa086, - 0xf0f0, 0x0130, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0478, - 0xa294, 0xff00, 0xa296, 0xf700, 0x0160, 0x6240, 0xa295, 0x0100, - 0x6242, 0xa294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x4186, - 0x00f0, 0x6040, 0xa084, 0x0010, 0xa085, 0x0040, 0x6042, 0x6043, - 0x0000, 0x7077, 0x0000, 0x7093, 0x0001, 0x70b3, 0x0000, 0x70cb, - 0x0000, 0x2009, 0x98c0, 0x200b, 0x0000, 0x7087, 0x0000, 0x707b, - 0x000f, 0x2009, 0x000f, 0x2011, 0x40a8, 0x080c, 0x57b3, 0x0005, - 0x0156, 0x7078, 0xa005, 0x1510, 0x2011, 0x40a8, 0x080c, 0x5731, - 0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9, 0x00c8, - 0x6044, 0xd08c, 0x1168, 0x1f04, 0x3ae0, 0x6242, 0x708b, 0x0000, - 0x6040, 0xa094, 0x0010, 0xa285, 0x0080, 0x6042, 0x6242, 0x0030, - 0x6242, 0x708b, 0x0000, 0x707f, 0x0000, 0x0000, 0x015e, 0x0005, - 0x707c, 0xa08a, 0x0003, 0x1210, 0x0023, 0x0010, 0x080c, 0x13fe, - 0x0005, 0x3b04, 0x3b54, 0x3bd6, 0x00f6, 0x707f, 0x0001, 0x20e1, - 0xa000, 0xe000, 0x20e1, 0x8700, 0x080c, 0x20ce, 0x20e1, 0x9080, - 0x20e1, 0x4000, 0x2079, 0x9700, 0x207b, 0x2200, 0x7807, 0x00ef, - 0x780b, 0x0000, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, - 0x781b, 0x0000, 0x781f, 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, - 0x782b, 0x0000, 0x782f, 0x0000, 0x2079, 0x970c, 0x207b, 0x1101, - 0x7807, 0x0000, 0x2099, 0x9205, 0x20a1, 0x970e, 0x20a9, 0x0004, - 0x53a3, 0x2079, 0x9712, 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, - 0x9700, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, - 0x600f, 0x0000, 0x080c, 0x40ec, 0x00fe, 0x7083, 0x0000, 0x6043, - 0x0008, 0x6043, 0x0000, 0x0005, 0x00d6, 0x7080, 0x7083, 0x0000, - 0xa025, 0x0904, 0x3bbe, 0x6020, 0xd0b4, 0x1904, 0x3bbc, 0x7190, - 0x81ff, 0x0904, 0x3ba6, 0xa486, 0x000c, 0x1904, 0x3bb1, 0xa480, - 0x0018, 0x8004, 0x20a8, 0x2011, 0x9780, 0x2019, 0x9700, 0x220c, - 0x2304, 0xa106, 0x1188, 0x8210, 0x8318, 0x1f04, 0x3b6f, 0x6043, - 0x0004, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x707f, - 0x0002, 0x708b, 0x0002, 0x04c0, 0x2069, 0x9780, 0x6930, 0xa18e, - 0x1101, 0x1538, 0x6834, 0xa005, 0x1520, 0x6900, 0xa18c, 0x00ff, - 0x1118, 0x6804, 0xa005, 0x0190, 0x2011, 0x978e, 0x2019, 0x9205, - 0x20a9, 0x0004, 0x220c, 0x2304, 0xa102, 0x0230, 0x1190, 0x8210, - 0x8318, 0x1f04, 0x3b9a, 0x0068, 0x7093, 0x0000, 0x20e1, 0x9080, - 0x20e1, 0x4000, 0x2099, 0x9780, 0x20a1, 0x020b, 0x20a9, 0x0014, - 0x53a6, 0x6043, 0x0008, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x1120, - 0x60c3, 0x000c, 0x080c, 0x40ec, 0x00de, 0x0005, 0x6040, 0xa085, - 0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8, 0x60c3, 0x000c, 0x2011, - 0x94ef, 0x2013, 0x0000, 0x7083, 0x0000, 0x20e1, 0x9080, 0x60a3, - 0x0056, 0x60a7, 0x9575, 0x080c, 0x6f15, 0x0c30, 0x0005, 0x7088, - 0xa08a, 0x001d, 0x1210, 0x0023, 0x0010, 0x080c, 0x13fe, 0x0005, - 0x3c0a, 0x3c19, 0x3c43, 0x3c58, 0x3c7e, 0x3ca6, 0x3ccc, 0x3cfd, - 0x3d23, 0x3d4b, 0x3d86, 0x3dae, 0x3dca, 0x3de0, 0x3e00, 0x3e13, - 0x3e1b, 0x3e45, 0x3e6b, 0x3e93, 0x3eb9, 0x3eea, 0x3f25, 0x3f54, - 0x3f70, 0x3faf, 0x3fcf, 0x3fe8, 0x3fe9, 0x00c6, 0x2061, 0x9200, - 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9, 0x6006, - 0x00ce, 0x0005, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0002, - 0x708b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x40af, 0x080c, 0x5725, - 0x0005, 0x00f6, 0x7080, 0xa086, 0x0014, 0x1518, 0x6043, 0x0000, - 0x6020, 0xd0b4, 0x11f0, 0x2079, 0x9780, 0x7a30, 0xa296, 0x1102, - 0x11b0, 0x7834, 0xa005, 0x1198, 0x7a38, 0xd2fc, 0x0138, 0x70b0, - 0xa005, 0x1120, 0x080c, 0x419d, 0x70b3, 0x0001, 0x2011, 0x40af, - 0x080c, 0x5731, 0x708b, 0x0010, 0x080c, 0x3e1b, 0x0010, 0x7083, - 0x0000, 0x00fe, 0x0005, 0x708b, 0x0003, 0x6043, 0x0004, 0x080c, - 0x416e, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9, 0x000a, 0x20a3, - 0x0000, 0x1f04, 0x3c4f, 0x60c3, 0x0014, 0x080c, 0x40ec, 0x0005, - 0x00f6, 0x7080, 0xa005, 0x0500, 0x2011, 0x40af, 0x080c, 0x5731, - 0xa086, 0x0014, 0x11b8, 0x2079, 0x9780, 0x7a30, 0xa296, 0x1102, - 0x1188, 0x7834, 0xa005, 0x1170, 0x7a38, 0xd2fc, 0x0138, 0x70b0, - 0xa005, 0x1120, 0x080c, 0x419d, 0x70b3, 0x0001, 0x708b, 0x0004, - 0x0029, 0x0010, 0x080c, 0x41b6, 0x00fe, 0x0005, 0x708b, 0x0005, - 0x080c, 0x416e, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, - 0x978e, 0x080c, 0x41bd, 0x1160, 0x7074, 0xa005, 0x1148, 0x714c, - 0xa186, 0xffff, 0x0128, 0x080c, 0x4074, 0x0110, 0x080c, 0x419d, - 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, - 0x0000, 0x60c3, 0x0014, 0x080c, 0x40ec, 0x0005, 0x00f6, 0x7080, - 0xa005, 0x0500, 0x2011, 0x40af, 0x080c, 0x5731, 0xa086, 0x0014, - 0x11b8, 0x2079, 0x9780, 0x7a30, 0xa296, 0x1103, 0x1188, 0x7834, - 0xa005, 0x1170, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, - 0x080c, 0x419d, 0x70b3, 0x0001, 0x708b, 0x0006, 0x0029, 0x0010, - 0x080c, 0x41b6, 0x00fe, 0x0005, 0x708b, 0x0007, 0x080c, 0x416e, - 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0x978e, 0x080c, - 0x41bd, 0x11a8, 0x7074, 0xa005, 0x1190, 0x7154, 0xa186, 0xffff, - 0x0170, 0xa180, 0x2719, 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, - 0x4074, 0x0128, 0x080c, 0x3919, 0x0110, 0x080c, 0x2455, 0x20a9, - 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, - 0x60c3, 0x0014, 0x080c, 0x40ec, 0x0005, 0x00f6, 0x7080, 0xa005, - 0x0500, 0x2011, 0x40af, 0x080c, 0x5731, 0xa086, 0x0014, 0x11b8, - 0x2079, 0x9780, 0x7a30, 0xa296, 0x1104, 0x1188, 0x7834, 0xa005, - 0x1170, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, - 0x419d, 0x70b3, 0x0001, 0x708b, 0x0008, 0x0029, 0x0010, 0x080c, - 0x41b6, 0x00fe, 0x0005, 0x708b, 0x0009, 0x080c, 0x416e, 0x20a3, - 0x1105, 0x20a3, 0x0100, 0x3430, 0x080c, 0x41bd, 0x1150, 0x7074, - 0xa005, 0x1138, 0x080c, 0x3fea, 0x1170, 0xa085, 0x0001, 0x080c, - 0x2455, 0x20a9, 0x0008, 0x2099, 0x978e, 0x26a0, 0x53a6, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x40ec, 0x0010, - 0x080c, 0x3bfd, 0x0005, 0x00f6, 0x7080, 0xa005, 0x05a8, 0x2011, - 0x40af, 0x080c, 0x5731, 0xa086, 0x0014, 0x1560, 0x2079, 0x9780, - 0x7a30, 0xa296, 0x1105, 0x1530, 0x7834, 0x2011, 0x0100, 0xa21e, + 0x0a04, 0x284b, 0xa182, 0x00ff, 0x1a04, 0x284b, 0x0126, 0x2091, + 0x8000, 0x080c, 0x7bbb, 0x1188, 0xa190, 0x8c34, 0x2204, 0xa065, + 0x0160, 0x080c, 0x4118, 0x2001, 0x8b32, 0x2004, 0xd0ac, 0x0110, + 0x6017, 0x0000, 0x012e, 0x0804, 0x2823, 0x012e, 0x0804, 0x2848, + 0x080c, 0x1488, 0x0188, 0xa006, 0x6802, 0x7010, 0xa005, 0x1120, + 0x2d00, 0x7012, 0x7016, 0x0030, 0x7014, 0x6802, 0x2060, 0x2d00, + 0x6006, 0x7016, 0xad80, 0x000d, 0x0005, 0x7924, 0x810f, 0xa18c, + 0x00ff, 0x080c, 0x430a, 0x1130, 0x7e28, 0xa684, 0x3fff, 0xa082, + 0x4000, 0x0208, 0xa066, 0x8cff, 0x0005, 0x7e24, 0x860f, 0xa18c, + 0x00ff, 0x080c, 0x430a, 0x1128, 0xa6b4, 0x00ff, 0xa682, 0x4000, + 0x0208, 0xa066, 0x8cff, 0x0005, 0x0016, 0x7110, 0x81ff, 0x0128, + 0x2168, 0x6904, 0x080c, 0x149f, 0x0cc8, 0x7112, 0x7116, 0x001e, + 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x8bd1, + 0x6606, 0x6112, 0x600e, 0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, + 0x080c, 0x14d3, 0x7007, 0x0002, 0x701b, 0x2823, 0x0005, 0x00f6, + 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x8b8f, 0x2004, + 0xa005, 0x1168, 0x0e04, 0x362f, 0x7818, 0xd084, 0x1140, 0x7a22, + 0x7b26, 0x7c2a, 0x781b, 0x0001, 0x2091, 0x4080, 0x0408, 0x0016, + 0x00c6, 0x00e6, 0x2071, 0x8b81, 0x7138, 0xa182, 0x0010, 0x0218, + 0x7030, 0x2060, 0x0078, 0x7030, 0xa0e0, 0x0004, 0xac82, 0x8bd1, + 0x0210, 0x2061, 0x8b91, 0x2c00, 0x7032, 0x81ff, 0x1108, 0x7036, + 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce, 0x001e, + 0x012e, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x8b81, 0x7038, 0xa005, + 0x0570, 0x0126, 0x2091, 0x8000, 0x0e04, 0x3686, 0x00f6, 0x2079, + 0x0000, 0x7818, 0xd084, 0x1508, 0x00c6, 0x7034, 0x2060, 0x2c04, + 0x7822, 0x6004, 0x7826, 0x6008, 0x782a, 0x781b, 0x0001, 0x2091, + 0x4080, 0x7038, 0x8001, 0x703a, 0xa005, 0x1130, 0x7033, 0x8b91, + 0x7037, 0x8b91, 0x00ce, 0x0048, 0xac80, 0x0004, 0xa0fa, 0x8bd1, + 0x0210, 0x2001, 0x8b91, 0x7036, 0x00ce, 0x00fe, 0x012e, 0x00ee, + 0x0005, 0x0026, 0x2001, 0x8b52, 0x2004, 0xd0c4, 0x0120, 0x2011, + 0x8014, 0x080c, 0x3617, 0x002e, 0x0005, 0x81ff, 0x1904, 0x2848, + 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d, 0x6032, 0x080c, 0x4c42, + 0x1158, 0x2001, 0x8d9d, 0x2003, 0x0001, 0x2001, 0x8b00, 0x2003, + 0x0001, 0x080c, 0x4b8b, 0x0010, 0x080c, 0x403d, 0x012e, 0x0804, + 0x2823, 0x7824, 0x2008, 0xa18c, 0xfffd, 0x1128, 0x61d4, 0xa10d, + 0x61d6, 0x0804, 0x2823, 0x0804, 0x284b, 0x81ff, 0x1904, 0x2848, + 0x6000, 0xa086, 0x0003, 0x1904, 0x2848, 0x2001, 0x8b52, 0x2004, + 0xd0a4, 0x1904, 0x2848, 0x080c, 0x35e5, 0x0904, 0x284b, 0x6004, + 0xa084, 0x00ff, 0xa086, 0x0006, 0x1120, 0x7828, 0xa005, 0x0904, + 0x2823, 0x00c6, 0x080c, 0x35c0, 0x00ce, 0x0904, 0x2848, 0x6837, + 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x7d78, + 0x0904, 0x2848, 0x7007, 0x0003, 0x701b, 0x36ef, 0x0005, 0x6830, + 0xa086, 0x0100, 0x0904, 0x2848, 0x0804, 0x2823, 0x2001, 0x8b00, + 0x2004, 0xa086, 0x0003, 0x1904, 0x2848, 0x7f24, 0x7a2c, 0x7b28, + 0x7c3c, 0x7d38, 0x080c, 0x35c0, 0x0904, 0x2848, 0x2009, 0x0000, + 0x2031, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80, 0x0005, + 0x7026, 0x20a0, 0x080c, 0x430a, 0x1560, 0x6004, 0xa0c4, 0x00ff, + 0xa8c6, 0x0006, 0x0128, 0xa0c4, 0xff00, 0xa8c6, 0x0600, 0x1508, + 0x2001, 0x8b52, 0x2004, 0xd0ac, 0x1118, 0x080c, 0x457e, 0x01c8, + 0xd784, 0x0150, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9, 0x0004, + 0x53a3, 0x080c, 0x345e, 0x0048, 0xac80, 0x000a, 0x2098, 0x3400, + 0x20a9, 0x0004, 0x53a3, 0x080c, 0x345e, 0x21a2, 0x94a0, 0xa6b0, + 0x0005, 0x8108, 0x2001, 0x8b32, 0x2004, 0xd0ac, 0x0118, 0xa186, + 0x0100, 0x0040, 0xd78c, 0x0120, 0xa186, 0x0100, 0x0148, 0x0018, + 0xa186, 0x007e, 0x0128, 0xa686, 0x0028, 0x0150, 0x0804, 0x3712, + 0x86ff, 0x1120, 0x7120, 0x810b, 0x0804, 0x2823, 0x702f, 0x0001, + 0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0x8bd1, 0x6007, + 0x0000, 0x6612, 0x7024, 0x600e, 0x6226, 0x632a, 0x642e, 0x6532, + 0x2c10, 0x080c, 0x14d3, 0x7007, 0x0002, 0x701b, 0x3778, 0x0005, + 0x702c, 0xa005, 0x1170, 0x711c, 0x7024, 0x20a0, 0x7728, 0x2031, + 0x0000, 0x2061, 0x8bd1, 0x6224, 0x6328, 0x642c, 0x6530, 0x0804, + 0x3712, 0x7120, 0x810b, 0x0804, 0x2823, 0x2029, 0x007e, 0x7924, + 0x7a28, 0x7b2c, 0x7c38, 0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020, + 0x0a04, 0x284b, 0xa502, 0x0a04, 0x284b, 0xa184, 0x00ff, 0xa0e2, + 0x0020, 0x0a04, 0x284b, 0xa502, 0x0a04, 0x284b, 0xa284, 0xff00, + 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x284b, 0xa502, 0x0a04, 0x284b, + 0xa284, 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x284b, 0xa502, 0x0a04, + 0x284b, 0xa384, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x284b, + 0xa502, 0x0a04, 0x284b, 0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0a04, + 0x284b, 0xa502, 0x0a04, 0x284b, 0xa484, 0xff00, 0x8007, 0xa0e2, + 0x0020, 0x0a04, 0x284b, 0xa502, 0x0a04, 0x284b, 0xa484, 0x00ff, + 0xa0e2, 0x0020, 0x0a04, 0x284b, 0xa502, 0x0a04, 0x284b, 0x2061, + 0x8da4, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x2823, 0x0006, + 0x2001, 0x8b52, 0x2004, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x2001, + 0x8b71, 0x2004, 0xd0bc, 0x000e, 0x0005, 0x6164, 0x7a24, 0x6300, + 0x82ff, 0x1118, 0x7926, 0x0804, 0x2823, 0x83ff, 0x1904, 0x284b, + 0x2001, 0xfff0, 0xa200, 0x1a04, 0x284b, 0x2019, 0xffff, 0x6068, + 0xa302, 0xa200, 0x0a04, 0x284b, 0x7926, 0x6266, 0x0804, 0x2823, + 0x2001, 0x8b00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2848, 0x7c28, + 0x7d24, 0x7e38, 0x7f2c, 0x080c, 0x35c0, 0x0904, 0x2848, 0x2009, + 0x0000, 0x2019, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80, + 0x0003, 0x7026, 0x20a0, 0xa1e0, 0x8c34, 0x2c64, 0x8cff, 0x01b8, + 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0130, 0x6004, 0xa084, + 0xff00, 0xa086, 0x0600, 0x1158, 0x6014, 0x20a2, 0x94a0, 0x6010, + 0x8007, 0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, 0x8108, + 0xa182, 0x00ff, 0x0120, 0xa386, 0x002a, 0x0148, 0x08e0, 0x83ff, + 0x1120, 0x7120, 0x810c, 0x0804, 0x2823, 0x702f, 0x0001, 0x711e, + 0x7020, 0xa300, 0x7022, 0x2061, 0x8bd1, 0x6007, 0x0000, 0x6312, + 0x7024, 0x600e, 0x6426, 0x652a, 0x662e, 0x6732, 0x2c10, 0x080c, + 0x14d3, 0x7007, 0x0002, 0x701b, 0x386e, 0x0005, 0x702c, 0xa005, + 0x1158, 0x711c, 0x7024, 0x20a0, 0x2019, 0x0000, 0x6424, 0x6528, + 0x662c, 0x6730, 0x0804, 0x382b, 0x7120, 0x810c, 0x0804, 0x2823, + 0x81ff, 0x1904, 0x2848, 0x60c8, 0xd0ac, 0x1118, 0xd09c, 0x0904, + 0x2848, 0x080c, 0x35c0, 0x0904, 0x2848, 0x7924, 0x7a2c, 0x7b28, + 0x7c3c, 0x7d38, 0x080c, 0x3601, 0x701b, 0x3897, 0x0005, 0x00d6, + 0xade8, 0x000d, 0x6828, 0xa0be, 0x7000, 0x0148, 0xa0be, 0x7100, + 0x0130, 0xa0be, 0x7200, 0x0118, 0x00de, 0x0804, 0x284b, 0x6820, + 0x6924, 0x080c, 0x22e9, 0x1500, 0x080c, 0x42d6, 0x11e8, 0x7122, + 0x6612, 0x6516, 0x6e18, 0x00c6, 0x080c, 0x35c0, 0x01a8, 0x080c, + 0x35c0, 0x0190, 0x00ce, 0x00de, 0x6837, 0x0000, 0x6838, 0xc0fd, + 0x683a, 0x6823, 0x0000, 0x080c, 0x7cfd, 0x0904, 0x2848, 0x7007, + 0x0003, 0x701b, 0x38cf, 0x0005, 0x00de, 0x0804, 0x2848, 0x7120, + 0x080c, 0x42f5, 0x6820, 0xa086, 0x8001, 0x0904, 0x2848, 0x2d00, + 0x701e, 0x6804, 0xa080, 0x0002, 0x0006, 0x20a9, 0x002a, 0x2098, + 0x20a0, 0x080c, 0x409e, 0x000e, 0xade8, 0x000d, 0x6a08, 0x6b0c, + 0x6c10, 0x6d14, 0x2061, 0x8bd1, 0x6007, 0x0000, 0x6e00, 0x6f28, + 0xa7c6, 0x7000, 0x1108, 0x0018, 0xa7c6, 0x7100, 0x1140, 0xa6c2, + 0x0004, 0x0a04, 0x284b, 0x2009, 0x0004, 0x0804, 0x3604, 0xa7c6, + 0x7200, 0x1904, 0x284b, 0xa6c2, 0x0054, 0x0a04, 0x284b, 0x600e, + 0x6013, 0x002a, 0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x080c, + 0x14d3, 0x7007, 0x0002, 0x701b, 0x3916, 0x0005, 0x701c, 0x2068, + 0x6804, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002, 0x0006, 0x20a9, + 0x002a, 0x2098, 0x20a0, 0x080c, 0x409e, 0x000e, 0x2009, 0x002a, + 0x2061, 0x8bd1, 0x6224, 0x6328, 0x642c, 0x6530, 0x0804, 0x3604, + 0x81ff, 0x1904, 0x2848, 0x080c, 0x35d5, 0x0904, 0x284b, 0x080c, + 0x43ad, 0x0904, 0x2848, 0x080c, 0x44dd, 0x0804, 0x2823, 0x7824, + 0xd084, 0x0904, 0x31d9, 0x080c, 0x35e5, 0x0904, 0x284b, 0x00c6, + 0x080c, 0x35c0, 0x00ce, 0x0904, 0x2848, 0x6004, 0xa084, 0x00ff, + 0xa086, 0x0006, 0x11f0, 0x2001, 0x8b52, 0x2004, 0xd0b4, 0x0904, + 0x3206, 0x6000, 0xd08c, 0x1904, 0x3206, 0x6837, 0x0000, 0x6838, + 0xc0fd, 0x683a, 0x080c, 0x7d17, 0x0904, 0x2848, 0x7007, 0x0003, + 0x701b, 0x396b, 0x0005, 0x080c, 0x35e5, 0x0904, 0x284b, 0x0804, + 0x3206, 0x2009, 0x8b2f, 0x210c, 0x81ff, 0x1904, 0x2848, 0x2001, + 0x8b00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2848, 0x2001, 0x8b52, + 0x2004, 0xd0ac, 0x1904, 0x2848, 0x6837, 0x0000, 0x6833, 0x0000, + 0x6838, 0xc0fd, 0x683a, 0x080c, 0x7d78, 0x0904, 0x2848, 0x7007, + 0x0003, 0x701b, 0x3994, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, + 0x2848, 0x080c, 0x35e5, 0x0904, 0x284b, 0x0804, 0x3953, 0x0126, + 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x8b00, 0x6044, 0xd0a4, + 0x11b0, 0xd084, 0x0118, 0x080c, 0x3b0c, 0x0068, 0xd08c, 0x0118, + 0x080c, 0x3a2d, 0x0040, 0xd094, 0x0118, 0x080c, 0x3a05, 0x0018, + 0xd09c, 0x0108, 0x0061, 0x00ee, 0x00ce, 0x012e, 0x0005, 0x0016, + 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0ca0, 0x624c, + 0xa286, 0xf0f0, 0x1150, 0x6048, 0xa086, 0xf0f0, 0x0130, 0x624a, + 0x6043, 0x0090, 0x6043, 0x0010, 0x0478, 0xa294, 0xff00, 0xa296, + 0xf700, 0x0160, 0x6240, 0xa295, 0x0100, 0x6242, 0xa294, 0x0010, + 0x0128, 0x2009, 0x00f7, 0x080c, 0x40be, 0x00f0, 0x6040, 0xa084, + 0x0010, 0xa085, 0x0040, 0x6042, 0x6043, 0x0000, 0x7077, 0x0000, + 0x7093, 0x0001, 0x70b3, 0x0000, 0x70cb, 0x0000, 0x2009, 0x91c0, + 0x200b, 0x0000, 0x7087, 0x0000, 0x707b, 0x000f, 0x2009, 0x000f, + 0x2011, 0x3fe0, 0x080c, 0x568c, 0x0005, 0x0156, 0x7078, 0xa005, + 0x1510, 0x2011, 0x3fe0, 0x080c, 0x560d, 0x6040, 0xa094, 0x0010, + 0xa285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168, + 0x1f04, 0x3a15, 0x6242, 0x708b, 0x0000, 0x6040, 0xa094, 0x0010, + 0xa285, 0x0080, 0x6042, 0x6242, 0x0030, 0x6242, 0x708b, 0x0000, + 0x707f, 0x0000, 0x0000, 0x015e, 0x0005, 0x707c, 0xa08a, 0x0003, + 0x1210, 0x0023, 0x0010, 0x080c, 0x1410, 0x0005, 0x3a39, 0x3a89, + 0x3b0b, 0x00f6, 0x707f, 0x0001, 0x20e1, 0xa000, 0xe000, 0x20e1, + 0x8700, 0x080c, 0x1fbd, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2079, + 0x9000, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, 0x0000, 0x780f, + 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b, 0x0000, 0x781f, + 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b, 0x0000, 0x782f, + 0x0000, 0x2079, 0x900c, 0x207b, 0x1101, 0x7807, 0x0000, 0x2099, + 0x8b05, 0x20a1, 0x900e, 0x20a9, 0x0004, 0x53a3, 0x2079, 0x9012, + 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0x9000, 0x20a1, 0x020b, + 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000, 0x080c, + 0x4024, 0x00fe, 0x7083, 0x0000, 0x6043, 0x0008, 0x6043, 0x0000, + 0x0005, 0x00d6, 0x7080, 0x7083, 0x0000, 0xa025, 0x0904, 0x3af3, + 0x6020, 0xd0b4, 0x1904, 0x3af1, 0x7190, 0x81ff, 0x0904, 0x3adb, + 0xa486, 0x000c, 0x1904, 0x3ae6, 0xa480, 0x0018, 0x8004, 0x20a8, + 0x2011, 0x9080, 0x2019, 0x9000, 0x220c, 0x2304, 0xa106, 0x1188, + 0x8210, 0x8318, 0x1f04, 0x3aa4, 0x6043, 0x0004, 0x608b, 0xbc94, + 0x608f, 0xf0f0, 0x6043, 0x0006, 0x707f, 0x0002, 0x708b, 0x0002, + 0x04c0, 0x2069, 0x9080, 0x6930, 0xa18e, 0x1101, 0x1538, 0x6834, + 0xa005, 0x1520, 0x6900, 0xa18c, 0x00ff, 0x1118, 0x6804, 0xa005, + 0x0190, 0x2011, 0x908e, 0x2019, 0x8b05, 0x20a9, 0x0004, 0x220c, + 0x2304, 0xa102, 0x0230, 0x1190, 0x8210, 0x8318, 0x1f04, 0x3acf, + 0x0068, 0x7093, 0x0000, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, + 0x9080, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043, 0x0008, + 0x6043, 0x0000, 0x6020, 0xd0b4, 0x1120, 0x60c3, 0x000c, 0x080c, + 0x4024, 0x00de, 0x0005, 0x6040, 0xa085, 0x0100, 0x6042, 0x6020, + 0xd0b4, 0x1db8, 0x60c3, 0x000c, 0x2011, 0x8db4, 0x2013, 0x0000, + 0x7083, 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, + 0x080c, 0x66ee, 0x0c30, 0x0005, 0x7088, 0xa08a, 0x001d, 0x1210, + 0x0023, 0x0010, 0x080c, 0x1410, 0x0005, 0x3b3f, 0x3b4e, 0x3b78, + 0x3b8d, 0x3bb3, 0x3bdb, 0x3c01, 0x3c32, 0x3c58, 0x3c80, 0x3cbb, + 0x3ce3, 0x3cff, 0x3d15, 0x3d35, 0x3d48, 0x3d50, 0x3d7a, 0x3da0, + 0x3dc8, 0x3dee, 0x3e1f, 0x3e5b, 0x3e8a, 0x3ea6, 0x3ee5, 0x3f05, + 0x3f1e, 0x3f1f, 0x00c6, 0x2061, 0x8b00, 0x6003, 0x0007, 0x2061, + 0x0100, 0x6004, 0xa084, 0xfff9, 0x6006, 0x00ce, 0x0005, 0x608b, + 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0002, 0x708b, 0x0001, 0x2009, + 0x07d0, 0x2011, 0x3fe7, 0x080c, 0x5601, 0x0005, 0x00f6, 0x7080, + 0xa086, 0x0014, 0x1518, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x11f0, + 0x2079, 0x9080, 0x7a30, 0xa296, 0x1102, 0x11b0, 0x7834, 0xa005, + 0x1198, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, + 0x40d5, 0x70b3, 0x0001, 0x2011, 0x3fe7, 0x080c, 0x560d, 0x708b, + 0x0010, 0x080c, 0x3d50, 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005, + 0x708b, 0x0003, 0x6043, 0x0004, 0x080c, 0x40a6, 0x20a3, 0x1102, + 0x20a3, 0x0000, 0x20a9, 0x000a, 0x20a3, 0x0000, 0x1f04, 0x3b84, + 0x60c3, 0x0014, 0x080c, 0x4024, 0x0005, 0x00f6, 0x7080, 0xa005, + 0x0500, 0x2011, 0x3fe7, 0x080c, 0x560d, 0xa086, 0x0014, 0x11b8, + 0x2079, 0x9080, 0x7a30, 0xa296, 0x1102, 0x1188, 0x7834, 0xa005, 0x1170, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, - 0x419d, 0x70b3, 0x0001, 0x708b, 0x000a, 0x00c1, 0x00a8, 0xa005, - 0x1188, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, - 0x419d, 0x70b3, 0x0001, 0x7087, 0x0000, 0x708b, 0x000e, 0x080c, - 0x3e00, 0x0010, 0x080c, 0x41b6, 0x00fe, 0x0005, 0x708b, 0x000b, - 0x2011, 0x970e, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, 0x43a4, - 0x20a9, 0x0002, 0x2009, 0x0000, 0x41a4, 0x080c, 0x416e, 0x20a3, - 0x1106, 0x20a3, 0x0000, 0x080c, 0x41bd, 0x0118, 0x2013, 0x0000, - 0x0020, 0x7050, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, - 0x53a6, 0x60c3, 0x0084, 0x080c, 0x40ec, 0x0005, 0x00f6, 0x7080, - 0xa005, 0x01b0, 0x2011, 0x40af, 0x080c, 0x5731, 0xa086, 0x0084, - 0x1168, 0x2079, 0x9780, 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834, - 0xa005, 0x1120, 0x708b, 0x000c, 0x0029, 0x0010, 0x080c, 0x41b6, - 0x00fe, 0x0005, 0x708b, 0x000d, 0x080c, 0x416e, 0x20a3, 0x1107, - 0x20a3, 0x0000, 0x2099, 0x978e, 0x20a9, 0x0040, 0x53a6, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x40ec, 0x0005, - 0x00f6, 0x7080, 0xa005, 0x01d0, 0x2011, 0x40af, 0x080c, 0x5731, - 0xa086, 0x0084, 0x1188, 0x2079, 0x9780, 0x7a30, 0xa296, 0x1107, - 0x1158, 0x7834, 0xa005, 0x1140, 0x7087, 0x0001, 0x080c, 0x4160, - 0x708b, 0x000e, 0x0029, 0x0010, 0x080c, 0x41b6, 0x00fe, 0x0005, - 0x708b, 0x000f, 0x7083, 0x0000, 0x608b, 0xbc85, 0x608f, 0xb5b5, - 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x40af, - 0x080c, 0x5725, 0x0005, 0x7080, 0xa005, 0x0120, 0x2011, 0x40af, - 0x080c, 0x5731, 0x0005, 0x708b, 0x0011, 0x716c, 0x81ff, 0x0170, - 0x2009, 0x0000, 0x7070, 0xa084, 0x00ff, 0x080c, 0x240b, 0xa186, - 0x0080, 0x0120, 0x2011, 0x978e, 0x080c, 0x4074, 0x20e1, 0x9080, - 0x20e1, 0x4000, 0x2099, 0x9780, 0x20a1, 0x020b, 0x7480, 0xa480, - 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, - 0x60c3, 0x0014, 0x080c, 0x40ec, 0x0005, 0x00f6, 0x7080, 0xa005, - 0x0500, 0x2011, 0x40af, 0x080c, 0x5731, 0xa086, 0x0014, 0x11b8, - 0x2079, 0x9780, 0x7a30, 0xa296, 0x1103, 0x1188, 0x7834, 0xa005, - 0x1170, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, - 0x419d, 0x70b3, 0x0001, 0x708b, 0x0012, 0x0029, 0x0010, 0x7083, - 0x0000, 0x00fe, 0x0005, 0x708b, 0x0013, 0x080c, 0x417a, 0x20a3, - 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0x978e, 0x080c, 0x41bd, + 0x40d5, 0x70b3, 0x0001, 0x708b, 0x0004, 0x0029, 0x0010, 0x080c, + 0x40ee, 0x00fe, 0x0005, 0x708b, 0x0005, 0x080c, 0x40a6, 0x20a3, + 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0x908e, 0x080c, 0x40f5, 0x1160, 0x7074, 0xa005, 0x1148, 0x714c, 0xa186, 0xffff, 0x0128, - 0x080c, 0x4074, 0x0110, 0x080c, 0x419d, 0x20a9, 0x0008, 0x2298, + 0x080c, 0x3fab, 0x0110, 0x080c, 0x40d5, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, - 0x080c, 0x40ec, 0x0005, 0x00f6, 0x7080, 0xa005, 0x0500, 0x2011, - 0x40af, 0x080c, 0x5731, 0xa086, 0x0014, 0x11b8, 0x2079, 0x9780, - 0x7a30, 0xa296, 0x1104, 0x1188, 0x7834, 0xa005, 0x1170, 0x7a38, - 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, 0x419d, 0x70b3, - 0x0001, 0x708b, 0x0014, 0x0029, 0x0010, 0x7083, 0x0000, 0x00fe, - 0x0005, 0x708b, 0x0015, 0x080c, 0x417a, 0x20a3, 0x1104, 0x20a3, - 0x0000, 0x3430, 0x2011, 0x978e, 0x080c, 0x41bd, 0x11a8, 0x7074, - 0xa005, 0x1190, 0x7154, 0xa186, 0xffff, 0x0170, 0xa180, 0x2719, - 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x4074, 0x0128, 0x080c, - 0x3919, 0x0110, 0x080c, 0x2455, 0x20a9, 0x0008, 0x2298, 0x26a0, + 0x080c, 0x4024, 0x0005, 0x00f6, 0x7080, 0xa005, 0x0500, 0x2011, + 0x3fe7, 0x080c, 0x560d, 0xa086, 0x0014, 0x11b8, 0x2079, 0x9080, + 0x7a30, 0xa296, 0x1103, 0x1188, 0x7834, 0xa005, 0x1170, 0x7a38, + 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, 0x40d5, 0x70b3, + 0x0001, 0x708b, 0x0006, 0x0029, 0x0010, 0x080c, 0x40ee, 0x00fe, + 0x0005, 0x708b, 0x0007, 0x080c, 0x40a6, 0x20a3, 0x1104, 0x20a3, + 0x0000, 0x3430, 0x2011, 0x908e, 0x080c, 0x40f5, 0x11a8, 0x7074, + 0xa005, 0x1190, 0x7154, 0xa186, 0xffff, 0x0170, 0xa180, 0x263d, + 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x3fab, 0x0128, 0x080c, + 0x37ee, 0x0110, 0x080c, 0x2333, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, - 0x40ec, 0x0005, 0x00f6, 0x7080, 0xa005, 0x05a8, 0x2011, 0x40af, - 0x080c, 0x5731, 0xa086, 0x0014, 0x1560, 0x2079, 0x9780, 0x7a30, - 0xa296, 0x1105, 0x1530, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1178, - 0x7a38, 0xd2f4, 0x0110, 0x70cb, 0x0008, 0xd2fc, 0x0138, 0x70b0, - 0xa005, 0x1120, 0x080c, 0x419d, 0x70b3, 0x0001, 0x0070, 0xa005, - 0x1180, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, - 0x419d, 0x70b3, 0x0001, 0x7087, 0x0000, 0x708b, 0x0016, 0x0029, - 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005, 0x20e1, 0x9080, 0x20e1, - 0x4000, 0x2099, 0x9780, 0x20a1, 0x020b, 0x20a9, 0x000e, 0x53a6, - 0x3430, 0x2011, 0x978e, 0x708b, 0x0017, 0x080c, 0x41bd, 0x1150, - 0x7074, 0xa005, 0x1138, 0x080c, 0x3fea, 0x1170, 0xa085, 0x0001, - 0x080c, 0x2455, 0x20a9, 0x0008, 0x2099, 0x978e, 0x26a0, 0x53a6, - 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x40ec, - 0x0010, 0x080c, 0x3bfd, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01b0, - 0x2011, 0x40af, 0x080c, 0x5731, 0xa086, 0x0084, 0x1168, 0x2079, - 0x9780, 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834, 0xa005, 0x1120, - 0x708b, 0x0018, 0x0029, 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005, - 0x708b, 0x0019, 0x080c, 0x417a, 0x20a3, 0x1106, 0x20a3, 0x0000, - 0x3430, 0x2099, 0x978e, 0x2039, 0x970e, 0x27a0, 0x20a9, 0x0040, - 0x53a3, 0x080c, 0x41bd, 0x11e8, 0x2728, 0x2514, 0x8207, 0xa084, - 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007, 0xa205, 0x202a, - 0x7050, 0x2310, 0x8214, 0xa2a0, 0x970e, 0x2414, 0xa38c, 0x0001, - 0x0118, 0xa294, 0xff00, 0x0018, 0xa294, 0x00ff, 0x8007, 0xa215, - 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, - 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x40ec, 0x0005, 0x00f6, - 0x7080, 0xa005, 0x01d0, 0x2011, 0x40af, 0x080c, 0x5731, 0xa086, - 0x0084, 0x1188, 0x2079, 0x9780, 0x7a30, 0xa296, 0x1107, 0x1158, - 0x7834, 0xa005, 0x1140, 0x7087, 0x0001, 0x080c, 0x4160, 0x708b, - 0x001a, 0x0029, 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005, 0x708b, - 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x9780, 0x20a1, - 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, - 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x080c, 0x40ec, 0x0005, - 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0x9252, 0x252c, 0x20a9, - 0x0008, 0x2041, 0x970e, 0x28a0, 0x2099, 0x978e, 0x53a3, 0x20a9, - 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0110, 0x2011, 0x0000, 0x2800, - 0xa200, 0x200c, 0xa1a6, 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, - 0x0008, 0x8211, 0x1f04, 0x3fff, 0x0804, 0x406c, 0x82ff, 0x1160, - 0xd5d4, 0x0120, 0xa1a6, 0x3fff, 0x0d90, 0x0020, 0xa1a6, 0x3fff, - 0x0904, 0x406c, 0xa18d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, - 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, - 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, - 0x1f04, 0x4025, 0x04c8, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, - 0x1f04, 0x4037, 0x2328, 0x8529, 0xa2be, 0x0007, 0x0158, 0x0006, - 0x2039, 0x0007, 0x2200, 0xa73a, 0x000e, 0x27a8, 0xa5a8, 0x0010, - 0x1f04, 0x4046, 0x754e, 0xa5c8, 0x2719, 0x292d, 0xa5ac, 0x00ff, - 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x2435, 0x001e, 0x60e7, - 0x0000, 0x65ea, 0x2018, 0x2304, 0xa405, 0x201a, 0x7077, 0x0001, - 0x26a0, 0x2898, 0x20a9, 0x0008, 0x53a6, 0x20a3, 0x0000, 0x20a3, - 0x0000, 0xa085, 0x0001, 0x0028, 0xa006, 0x0018, 0xa006, 0x080c, - 0x13fe, 0x009e, 0x008e, 0x0005, 0x2118, 0x2021, 0x0000, 0x2001, - 0x0007, 0xa39a, 0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, - 0x84ff, 0x0120, 0xa39a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, - 0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8, 0xa238, 0x2704, 0xa42c, - 0x11b0, 0xa405, 0x203a, 0x714e, 0xa1a0, 0x2719, 0x242d, 0xa5ac, - 0x00ff, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x2435, 0x001e, + 0x4024, 0x0005, 0x00f6, 0x7080, 0xa005, 0x0500, 0x2011, 0x3fe7, + 0x080c, 0x560d, 0xa086, 0x0014, 0x11b8, 0x2079, 0x9080, 0x7a30, + 0xa296, 0x1104, 0x1188, 0x7834, 0xa005, 0x1170, 0x7a38, 0xd2fc, + 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, 0x40d5, 0x70b3, 0x0001, + 0x708b, 0x0008, 0x0029, 0x0010, 0x080c, 0x40ee, 0x00fe, 0x0005, + 0x708b, 0x0009, 0x080c, 0x40a6, 0x20a3, 0x1105, 0x20a3, 0x0100, + 0x3430, 0x080c, 0x40f5, 0x1150, 0x7074, 0xa005, 0x1138, 0x080c, + 0x3f20, 0x1170, 0xa085, 0x0001, 0x080c, 0x2333, 0x20a9, 0x0008, + 0x2099, 0x908e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0014, 0x080c, 0x4024, 0x0010, 0x080c, 0x3b32, 0x0005, + 0x00f6, 0x7080, 0xa005, 0x05a8, 0x2011, 0x3fe7, 0x080c, 0x560d, + 0xa086, 0x0014, 0x1560, 0x2079, 0x9080, 0x7a30, 0xa296, 0x1105, + 0x1530, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1170, 0x7a38, 0xd2fc, + 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, 0x40d5, 0x70b3, 0x0001, + 0x708b, 0x000a, 0x00c1, 0x00a8, 0xa005, 0x1188, 0x7a38, 0xd2fc, + 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, 0x40d5, 0x70b3, 0x0001, + 0x7087, 0x0000, 0x708b, 0x000e, 0x080c, 0x3d35, 0x0010, 0x080c, + 0x40ee, 0x00fe, 0x0005, 0x708b, 0x000b, 0x2011, 0x900e, 0x22a0, + 0x20a9, 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, 0x2009, + 0x0000, 0x41a4, 0x080c, 0x40a6, 0x20a3, 0x1106, 0x20a3, 0x0000, + 0x080c, 0x40f5, 0x0118, 0x2013, 0x0000, 0x0020, 0x7050, 0xa085, + 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6, 0x60c3, 0x0084, + 0x080c, 0x4024, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01b0, 0x2011, + 0x3fe7, 0x080c, 0x560d, 0xa086, 0x0084, 0x1168, 0x2079, 0x9080, + 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834, 0xa005, 0x1120, 0x708b, + 0x000c, 0x0029, 0x0010, 0x080c, 0x40ee, 0x00fe, 0x0005, 0x708b, + 0x000d, 0x080c, 0x40a6, 0x20a3, 0x1107, 0x20a3, 0x0000, 0x2099, + 0x908e, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0084, 0x080c, 0x4024, 0x0005, 0x00f6, 0x7080, 0xa005, + 0x01d0, 0x2011, 0x3fe7, 0x080c, 0x560d, 0xa086, 0x0084, 0x1188, + 0x2079, 0x9080, 0x7a30, 0xa296, 0x1107, 0x1158, 0x7834, 0xa005, + 0x1140, 0x7087, 0x0001, 0x080c, 0x4098, 0x708b, 0x000e, 0x0029, + 0x0010, 0x080c, 0x40ee, 0x00fe, 0x0005, 0x708b, 0x000f, 0x7083, + 0x0000, 0x608b, 0xbc85, 0x608f, 0xb5b5, 0x6043, 0x0005, 0x6043, + 0x0004, 0x2009, 0x07d0, 0x2011, 0x3fe7, 0x080c, 0x5601, 0x0005, + 0x7080, 0xa005, 0x0120, 0x2011, 0x3fe7, 0x080c, 0x560d, 0x0005, + 0x708b, 0x0011, 0x716c, 0x81ff, 0x0170, 0x2009, 0x0000, 0x7070, + 0xa084, 0x00ff, 0x080c, 0x22e9, 0xa186, 0x0080, 0x0120, 0x2011, + 0x908e, 0x080c, 0x3fab, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, + 0x9080, 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007, + 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014, 0x080c, + 0x4024, 0x0005, 0x00f6, 0x7080, 0xa005, 0x0500, 0x2011, 0x3fe7, + 0x080c, 0x560d, 0xa086, 0x0014, 0x11b8, 0x2079, 0x9080, 0x7a30, + 0xa296, 0x1103, 0x1188, 0x7834, 0xa005, 0x1170, 0x7a38, 0xd2fc, + 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, 0x40d5, 0x70b3, 0x0001, + 0x708b, 0x0012, 0x0029, 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005, + 0x708b, 0x0013, 0x080c, 0x40b2, 0x20a3, 0x1103, 0x20a3, 0x0000, + 0x3430, 0x2011, 0x908e, 0x080c, 0x40f5, 0x1160, 0x7074, 0xa005, + 0x1148, 0x714c, 0xa186, 0xffff, 0x0128, 0x080c, 0x3fab, 0x0110, + 0x080c, 0x40d5, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x4024, 0x0005, + 0x00f6, 0x7080, 0xa005, 0x0500, 0x2011, 0x3fe7, 0x080c, 0x560d, + 0xa086, 0x0014, 0x11b8, 0x2079, 0x9080, 0x7a30, 0xa296, 0x1104, + 0x1188, 0x7834, 0xa005, 0x1170, 0x7a38, 0xd2fc, 0x0138, 0x70b0, + 0xa005, 0x1120, 0x080c, 0x40d5, 0x70b3, 0x0001, 0x708b, 0x0014, + 0x0029, 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005, 0x708b, 0x0015, + 0x080c, 0x40b2, 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, + 0x908e, 0x080c, 0x40f5, 0x11a8, 0x7074, 0xa005, 0x1190, 0x7154, + 0xa186, 0xffff, 0x0170, 0xa180, 0x263d, 0x200d, 0xa18c, 0xff00, + 0x810f, 0x080c, 0x3fab, 0x0128, 0x080c, 0x37ee, 0x0110, 0x080c, + 0x2333, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x4024, 0x0005, 0x00f6, + 0x7080, 0xa005, 0x05b0, 0x2011, 0x3fe7, 0x080c, 0x560d, 0xa086, + 0x0014, 0x1568, 0x2079, 0x9080, 0x7a30, 0xa296, 0x1105, 0x1538, + 0x7834, 0x2011, 0x0100, 0xa21e, 0x1158, 0x7a38, 0xd2fc, 0x0138, + 0x70b0, 0xa005, 0x1120, 0x080c, 0x40d5, 0x70b3, 0x0001, 0x0070, + 0xa005, 0x11a8, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, + 0x080c, 0x40d5, 0x70b3, 0x0001, 0x7087, 0x0000, 0x7a38, 0xd2f4, + 0x0110, 0x70cb, 0x0008, 0x708b, 0x0016, 0x0029, 0x0010, 0x7083, + 0x0000, 0x00fe, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, + 0x9080, 0x20a1, 0x020b, 0x20a9, 0x000e, 0x53a6, 0x3430, 0x2011, + 0x908e, 0x708b, 0x0017, 0x080c, 0x40f5, 0x1150, 0x7074, 0xa005, + 0x1138, 0x080c, 0x3f20, 0x1170, 0xa085, 0x0001, 0x080c, 0x2333, + 0x20a9, 0x0008, 0x2099, 0x908e, 0x26a0, 0x53a6, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x4024, 0x0010, 0x080c, + 0x3b32, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01b0, 0x2011, 0x3fe7, + 0x080c, 0x560d, 0xa086, 0x0084, 0x1168, 0x2079, 0x9080, 0x7a30, + 0xa296, 0x1106, 0x1138, 0x7834, 0xa005, 0x1120, 0x708b, 0x0018, + 0x0029, 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005, 0x708b, 0x0019, + 0x080c, 0x40b2, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x3430, 0x2099, + 0x908e, 0x2039, 0x900e, 0x27a0, 0x20a9, 0x0040, 0x53a3, 0x080c, + 0x40f5, 0x11e8, 0x2728, 0x2514, 0x8207, 0xa084, 0x00ff, 0x8000, + 0x2018, 0xa294, 0x00ff, 0x8007, 0xa205, 0x202a, 0x7050, 0x2310, + 0x8214, 0xa2a0, 0x900e, 0x2414, 0xa38c, 0x0001, 0x0118, 0xa294, + 0xff00, 0x0018, 0xa294, 0x00ff, 0x8007, 0xa215, 0x2222, 0x2798, + 0x26a0, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0084, 0x080c, 0x4024, 0x0005, 0x00f6, 0x7080, 0xa005, + 0x01d0, 0x2011, 0x3fe7, 0x080c, 0x560d, 0xa086, 0x0084, 0x1188, + 0x2079, 0x9080, 0x7a30, 0xa296, 0x1107, 0x1158, 0x7834, 0xa005, + 0x1140, 0x7087, 0x0001, 0x080c, 0x4098, 0x708b, 0x001a, 0x0029, + 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005, 0x708b, 0x001b, 0x20e1, + 0x9080, 0x20e1, 0x4000, 0x2099, 0x9080, 0x20a1, 0x020b, 0x7480, + 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8, + 0x53a6, 0x60c3, 0x0084, 0x080c, 0x4024, 0x0005, 0x0005, 0x0005, + 0x0086, 0x0096, 0x2029, 0x8b52, 0x252c, 0x20a9, 0x0008, 0x2041, + 0x900e, 0x28a0, 0x2099, 0x908e, 0x53a3, 0x20a9, 0x0008, 0x2011, + 0x0007, 0xd5d4, 0x0110, 0x2011, 0x0000, 0x2800, 0xa200, 0x200c, + 0xa1a6, 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, + 0x1f04, 0x3f35, 0x0804, 0x3fa3, 0x82ff, 0x1160, 0xd5d4, 0x0120, + 0xa1a6, 0x3fff, 0x0d90, 0x0020, 0xa1a6, 0x3fff, 0x0904, 0x3fa3, + 0xa18d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, + 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, + 0x1240, 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, 0x1f04, 0x3f5b, + 0x04d0, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x1f04, 0x3f6d, + 0x2328, 0x8529, 0xa2be, 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, + 0x2200, 0xa73a, 0x000e, 0x27a8, 0xa5a8, 0x0010, 0x1f04, 0x3f7c, + 0x754e, 0xa5c8, 0x263d, 0x292d, 0xa5ac, 0x00ff, 0x7572, 0x6532, + 0x6536, 0x0016, 0x2508, 0x080c, 0x2313, 0x001e, 0x60e7, 0x0000, + 0x65ea, 0x2018, 0x2304, 0xa405, 0x201a, 0x7077, 0x0001, 0x26a0, + 0x2898, 0x20a9, 0x0008, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0xa085, 0x0001, 0x0028, 0xa006, 0x0018, 0xa006, 0x080c, 0x1410, + 0x009e, 0x008e, 0x0005, 0x2118, 0x2021, 0x0000, 0x2001, 0x0007, + 0xa39a, 0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, + 0x0120, 0xa39a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, + 0x0118, 0x8423, 0x8319, 0x1de8, 0xa238, 0x2704, 0xa42c, 0x11b8, + 0xa405, 0x203a, 0x714e, 0xa1a0, 0x263d, 0x242d, 0xa5ac, 0x00ff, + 0x7572, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x2313, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7077, 0x0001, 0xa084, 0x0000, 0x0005, - 0x00e6, 0x2071, 0x9200, 0x707b, 0x0000, 0x00ee, 0x0005, 0x00e6, - 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x6f1e, 0x7004, + 0x00e6, 0x2071, 0x8b00, 0x707b, 0x0000, 0x00ee, 0x0005, 0x00e6, + 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x66f7, 0x7004, 0xa084, 0x4000, 0x0120, 0x7003, 0x1000, 0x7003, 0x0000, 0x080c, - 0x4dcd, 0x01b0, 0x080c, 0x4deb, 0x1198, 0x2001, 0x94d7, 0x2003, - 0xaaaa, 0x2001, 0x0204, 0x2004, 0x0016, 0x2009, 0x94c8, 0x200a, - 0x001e, 0x2001, 0x94d8, 0x2003, 0x0000, 0x080c, 0x4d10, 0x0080, - 0x0126, 0x2091, 0x8000, 0x2071, 0x9222, 0x2073, 0x0000, 0x7840, + 0x4c4a, 0x01b0, 0x080c, 0x4c68, 0x1198, 0x2001, 0x8d9c, 0x2003, + 0xaaaa, 0x2001, 0x0204, 0x2004, 0x0016, 0x2009, 0x8d8d, 0x200a, + 0x001e, 0x2001, 0x8d9d, 0x2003, 0x0000, 0x080c, 0x4b8b, 0x0080, + 0x0126, 0x2091, 0x8000, 0x2071, 0x8b22, 0x2073, 0x0000, 0x7840, 0x0026, 0xa094, 0x0010, 0xa285, 0x0080, 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x2011, - 0x94ef, 0x2013, 0x0000, 0x7083, 0x0000, 0x012e, 0x20e1, 0x9080, - 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x6f15, 0x2009, 0x07d0, - 0x2011, 0x40af, 0x080c, 0x57b3, 0x0005, 0x0016, 0x0026, 0x00c6, - 0x0126, 0x2091, 0x8000, 0x2009, 0x00f7, 0x080c, 0x4186, 0x2061, - 0x94f8, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0x9200, 0x6003, + 0x8db4, 0x2013, 0x0000, 0x7083, 0x0000, 0x012e, 0x20e1, 0x9080, + 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x66ee, 0x2009, 0x07d0, + 0x2011, 0x3fe7, 0x080c, 0x568c, 0x0005, 0x0016, 0x0026, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x2009, 0x00f7, 0x080c, 0x40be, 0x2061, + 0x8dbd, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0x8b00, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, - 0x001e, 0x2011, 0x412a, 0x080c, 0x5725, 0x012e, 0x00ce, 0x002e, + 0x001e, 0x2011, 0x4062, 0x080c, 0x5601, 0x012e, 0x00ce, 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, - 0x0100, 0x080c, 0x6f1e, 0x2071, 0x0140, 0x7004, 0xa084, 0x4000, - 0x0120, 0x7003, 0x1000, 0x7003, 0x0000, 0x080c, 0x4dcd, 0x01b0, - 0x080c, 0x4deb, 0x1198, 0x2001, 0x94d7, 0x2003, 0xaaaa, 0x2001, - 0x0204, 0x2004, 0x0016, 0x2009, 0x94c8, 0x200a, 0x001e, 0x2001, - 0x94d8, 0x2003, 0x0000, 0x080c, 0x4d10, 0x0030, 0x2001, 0x0001, - 0x080c, 0x23ba, 0x080c, 0x4105, 0x012e, 0x000e, 0x00ee, 0x0005, - 0x20a9, 0x0040, 0x20a1, 0x98c0, 0x2099, 0x978e, 0x3304, 0x8007, - 0x20a2, 0x9398, 0x94a0, 0x1f04, 0x4166, 0x0005, 0x20e1, 0x9080, - 0x20e1, 0x4000, 0x2099, 0x9700, 0x20a1, 0x020b, 0x20a9, 0x000c, - 0x53a6, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x9780, + 0x0100, 0x080c, 0x66f7, 0x2071, 0x0140, 0x7004, 0xa084, 0x4000, + 0x0120, 0x7003, 0x1000, 0x7003, 0x0000, 0x080c, 0x4c4a, 0x01b0, + 0x080c, 0x4c68, 0x1198, 0x2001, 0x8d9c, 0x2003, 0xaaaa, 0x2001, + 0x0204, 0x2004, 0x0016, 0x2009, 0x8d8d, 0x200a, 0x001e, 0x2001, + 0x8d9d, 0x2003, 0x0000, 0x080c, 0x4b8b, 0x0030, 0x2001, 0x0001, + 0x080c, 0x2298, 0x080c, 0x403d, 0x012e, 0x000e, 0x00ee, 0x0005, + 0x20a9, 0x0040, 0x20a1, 0x91c0, 0x2099, 0x908e, 0x3304, 0x8007, + 0x20a2, 0x9398, 0x94a0, 0x1f04, 0x409e, 0x0005, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x2099, 0x9000, 0x20a1, 0x020b, 0x20a9, 0x000c, + 0x53a6, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x9080, 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x0005, 0x00c6, 0x0006, - 0x2061, 0x0100, 0x810f, 0x2001, 0x922f, 0x2004, 0xa005, 0x1138, - 0x2001, 0x9214, 0x2004, 0xa084, 0x00ff, 0xa105, 0x0010, 0xa185, + 0x2061, 0x0100, 0x810f, 0x2001, 0x8b2f, 0x2004, 0xa005, 0x1138, + 0x2001, 0x8b14, 0x2004, 0xa084, 0x00ff, 0xa105, 0x0010, 0xa185, 0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x2001, - 0x9252, 0x2004, 0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a, - 0x080c, 0x90d7, 0x2001, 0x920c, 0x200c, 0xc195, 0x2102, 0x2019, - 0x002a, 0x080c, 0x264b, 0x004e, 0x001e, 0x0005, 0x080c, 0x4105, - 0x708b, 0x0000, 0x7083, 0x0000, 0x0005, 0x0006, 0x2001, 0x920c, + 0x8b52, 0x2004, 0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a, + 0x080c, 0x8982, 0x2001, 0x8b0c, 0x200c, 0xc195, 0x2102, 0x2019, + 0x002a, 0x080c, 0x2542, 0x004e, 0x001e, 0x0005, 0x080c, 0x403d, + 0x708b, 0x0000, 0x7083, 0x0000, 0x0005, 0x0006, 0x2001, 0x8b0c, 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0xa18d, 0x0006, 0x2102, 0x012e, 0x001e, 0x000e, 0x0005, 0x0156, 0x20a9, 0x00ff, 0x2009, - 0x936e, 0xa006, 0x200a, 0x8108, 0x1f04, 0x41da, 0x015e, 0x0005, - 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x9251, 0xa006, - 0x6002, 0x6007, 0x0707, 0x600a, 0x600e, 0x6012, 0xa198, 0x2719, + 0x8c34, 0xa006, 0x200a, 0x8108, 0x1f04, 0x4112, 0x015e, 0x0005, + 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x8b51, 0xa006, + 0x6002, 0x6007, 0x0707, 0x600a, 0x600e, 0x6012, 0xa198, 0x263d, 0x231d, 0xa39c, 0x00ff, 0x6316, 0x20a9, 0x0004, 0xac98, 0x0006, 0x23a0, 0x40a4, 0x20a9, 0x0004, 0xac98, 0x000a, 0x23a0, 0x40a4, 0x603e, 0x6042, 0x604e, 0x6052, 0x6056, 0x605a, 0x605e, 0x6062, 0x6066, 0x606a, 0x606e, 0x6072, 0x6076, 0x607a, 0x607e, 0x6082, 0x6086, 0x608a, 0x608e, 0x6092, 0x6096, 0x609a, 0x609e, 0x61a2, - 0x00d6, 0x60a4, 0xa06d, 0x0110, 0x080c, 0x1493, 0x60a7, 0x0000, - 0x60a8, 0xa06d, 0x0110, 0x080c, 0x1493, 0x60ab, 0x0000, 0x00de, - 0xa006, 0x604a, 0x6810, 0x603a, 0x680c, 0x6046, 0xa006, 0x60b2, - 0x60ae, 0x60b6, 0x60bb, 0x0520, 0x6814, 0xa084, 0x00ff, 0x6042, - 0x014e, 0x013e, 0x015e, 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, - 0x8000, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082, 0x4000, 0x1a04, - 0x42cf, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, 0x1a04, 0x42d4, - 0x2001, 0x920c, 0x2004, 0xa084, 0x0003, 0x1904, 0x42bd, 0xa188, - 0x936e, 0x2104, 0xa065, 0x0904, 0x42a9, 0x6004, 0xa084, 0x00ff, - 0xa08e, 0x0006, 0x1904, 0x42ae, 0x60a4, 0xa00d, 0x0118, 0x080c, - 0x4630, 0x05d0, 0x60a8, 0xa00d, 0x0188, 0x080c, 0x467a, 0x1170, - 0x694c, 0xd1fc, 0x1118, 0x080c, 0x43c4, 0x0448, 0x080c, 0x4386, - 0x694c, 0xd1ec, 0x1520, 0x080c, 0x452b, 0x0408, 0x694c, 0xa184, - 0xa000, 0x0178, 0xd1ec, 0x0140, 0xd1fc, 0x0118, 0x080c, 0x453a, - 0x0028, 0x080c, 0x453a, 0x0028, 0xd1fc, 0x0118, 0x080c, 0x4386, - 0x0070, 0x6050, 0xa00d, 0x0130, 0x2d00, 0x200a, 0x6803, 0x0000, - 0x6052, 0x0028, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x080c, - 0x6015, 0xa006, 0x012e, 0x0005, 0x2001, 0x0005, 0x2009, 0x0000, - 0x0478, 0x2001, 0x0028, 0x2009, 0x0000, 0x0450, 0xa082, 0x0006, - 0x1260, 0x2001, 0x9232, 0x2004, 0xd0ac, 0x1120, 0x60a0, 0xd0bc, - 0x0904, 0x4264, 0x2001, 0x0028, 0x0078, 0x2009, 0x920c, 0x210c, - 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, - 0x0004, 0x0010, 0x2001, 0x0029, 0x2009, 0x0000, 0x0048, 0x2001, - 0x0029, 0x2009, 0x0000, 0x0020, 0x2001, 0x0029, 0x2009, 0x0000, - 0xa005, 0x012e, 0x0005, 0x00e6, 0x0126, 0x2091, 0x8000, 0x6844, - 0x0006, 0x000e, 0x0006, 0x000e, 0xa084, 0xff00, 0xa08e, 0xff00, - 0x1120, 0x2001, 0x94c6, 0x2064, 0x0098, 0x6844, 0x8007, 0xa084, - 0x00ff, 0x2008, 0xa182, 0x00ff, 0x16c8, 0xa188, 0x936e, 0x2104, - 0xa065, 0x01f0, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x11d8, - 0x2c70, 0x080c, 0x749c, 0x0580, 0x2e00, 0x601a, 0x2d00, 0x6012, - 0x601f, 0x0009, 0x600b, 0x0000, 0x6844, 0xa08e, 0xff00, 0x1110, - 0x600b, 0x8000, 0x2009, 0x0100, 0x080c, 0x7518, 0xa006, 0x00c8, - 0x2001, 0x0028, 0x00a8, 0xa082, 0x0006, 0x0e10, 0x2009, 0x920c, - 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, - 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, - 0xa005, 0x012e, 0x00ee, 0x0005, 0x2001, 0x002c, 0x0cc8, 0x6944, - 0x6e48, 0xa684, 0x3fff, 0xa082, 0x4000, 0x1678, 0xa18c, 0xff00, - 0x810f, 0xa182, 0x00ff, 0x12e0, 0xa188, 0x936e, 0x2104, 0xa065, - 0x01b8, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x11b0, 0x684c, - 0xd0ec, 0x0120, 0x080c, 0x453a, 0x0489, 0x0030, 0x0479, 0x684c, - 0xd0fc, 0x0110, 0x080c, 0x452b, 0x080c, 0x4578, 0xa006, 0x0088, - 0x2001, 0x0028, 0x2009, 0x0000, 0x0060, 0xa082, 0x0006, 0x0e38, - 0x2001, 0x0029, 0x2009, 0x0000, 0x0020, 0x2001, 0x0029, 0x2009, - 0x0000, 0xa005, 0x0005, 0x0126, 0x2091, 0x8000, 0x6050, 0xa00d, - 0x0138, 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x012e, 0x0005, - 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x0cc0, 0x0126, 0x2091, - 0x8000, 0x604c, 0xa005, 0x0170, 0x00e6, 0x2071, 0x94e5, 0x7004, - 0xa086, 0x0002, 0x0168, 0x00ee, 0x604c, 0x6802, 0x2d00, 0x604e, - 0x012e, 0x0005, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x0cc0, - 0x701c, 0xac06, 0x1d80, 0x604c, 0x2070, 0x7000, 0x6802, 0x2d00, - 0x7002, 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x604c, - 0xa06d, 0x0130, 0x6800, 0xa005, 0x1108, 0x6052, 0x604e, 0xad05, - 0x012e, 0x0005, 0x604c, 0xa06d, 0x0130, 0x6800, 0xa005, 0x1108, - 0x6052, 0x604e, 0xad05, 0x0005, 0x6803, 0x0000, 0x6084, 0xa00d, - 0x0120, 0x2d00, 0x200a, 0x6086, 0x0005, 0x2d00, 0x6086, 0x6082, - 0x0cd8, 0x0126, 0x00c6, 0x0026, 0x2091, 0x8000, 0x6218, 0x2260, - 0x6200, 0xa005, 0x0110, 0xc285, 0x0008, 0xc284, 0x6202, 0x002e, - 0x00ce, 0x012e, 0x0005, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6218, - 0x2260, 0x6204, 0xa294, 0xff00, 0xa215, 0x6206, 0x00ce, 0x012e, + 0x00d6, 0x60a4, 0xa06d, 0x0110, 0x080c, 0x149f, 0x60a7, 0x0000, + 0x60a8, 0xa06d, 0x0110, 0x080c, 0x149f, 0x60ab, 0x0000, 0x00de, + 0xa006, 0x604a, 0x6810, 0x603a, 0x680c, 0x6046, 0x6814, 0xa084, + 0x00ff, 0x6042, 0x014e, 0x013e, 0x015e, 0x003e, 0x00de, 0x0005, + 0x0126, 0x2091, 0x8000, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082, + 0x4000, 0x1a04, 0x4201, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, + 0x1a04, 0x4206, 0x2001, 0x8b0c, 0x2004, 0xa084, 0x0003, 0x1904, + 0x41ef, 0xa188, 0x8c34, 0x2104, 0xa065, 0x0904, 0x41db, 0x6004, + 0xa084, 0x00ff, 0xa08e, 0x0006, 0x1904, 0x41e0, 0x60a4, 0xa00d, + 0x0118, 0x080c, 0x4509, 0x05d0, 0x60a8, 0xa00d, 0x0188, 0x080c, + 0x4553, 0x1170, 0x694c, 0xd1fc, 0x1118, 0x080c, 0x429a, 0x0448, + 0x080c, 0x425c, 0x694c, 0xd1ec, 0x1520, 0x080c, 0x4404, 0x0408, + 0x694c, 0xa184, 0xa000, 0x0178, 0xd1ec, 0x0140, 0xd1fc, 0x0118, + 0x080c, 0x4413, 0x0028, 0x080c, 0x4413, 0x0028, 0xd1fc, 0x0118, + 0x080c, 0x425c, 0x0070, 0x6050, 0xa00d, 0x0130, 0x2d00, 0x200a, + 0x6803, 0x0000, 0x6052, 0x0028, 0x2d00, 0x6052, 0x604e, 0x6803, + 0x0000, 0x080c, 0x58b9, 0xa006, 0x012e, 0x0005, 0x2001, 0x0005, + 0x2009, 0x0000, 0x0478, 0x2001, 0x0028, 0x2009, 0x0000, 0x0450, + 0xa082, 0x0006, 0x1260, 0x2001, 0x8b32, 0x2004, 0xd0ac, 0x1120, + 0x60a0, 0xd0bc, 0x0904, 0x4196, 0x2001, 0x0028, 0x0078, 0x2009, + 0x8b0c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, + 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x2009, 0x0000, + 0x0048, 0x2001, 0x0029, 0x2009, 0x0000, 0x0020, 0x2001, 0x0029, + 0x2009, 0x0000, 0xa005, 0x012e, 0x0005, 0x6944, 0x6e48, 0xa684, + 0x3fff, 0xa082, 0x4000, 0x1678, 0xa18c, 0xff00, 0x810f, 0xa182, + 0x00ff, 0x12e0, 0xa188, 0x8c34, 0x2104, 0xa065, 0x01b8, 0x6004, + 0xa084, 0x00ff, 0xa08e, 0x0006, 0x11b0, 0x684c, 0xd0ec, 0x0120, + 0x080c, 0x4413, 0x0489, 0x0030, 0x0479, 0x684c, 0xd0fc, 0x0110, + 0x080c, 0x4404, 0x080c, 0x4451, 0xa006, 0x0088, 0x2001, 0x0028, + 0x2009, 0x0000, 0x0060, 0xa082, 0x0006, 0x0e38, 0x2001, 0x0029, + 0x2009, 0x0000, 0x0020, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, + 0x0005, 0x0126, 0x2091, 0x8000, 0x6050, 0xa00d, 0x0138, 0x2d00, + 0x200a, 0x6803, 0x0000, 0x6052, 0x012e, 0x0005, 0x2d00, 0x6052, + 0x604e, 0x6803, 0x0000, 0x0cc0, 0x0126, 0x2091, 0x8000, 0x604c, + 0xa005, 0x0170, 0x00e6, 0x2071, 0x8daa, 0x7004, 0xa086, 0x0002, + 0x0168, 0x00ee, 0x604c, 0x6802, 0x2d00, 0x604e, 0x012e, 0x0005, + 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x0cc0, 0x701c, 0xac06, + 0x1d80, 0x604c, 0x2070, 0x7000, 0x6802, 0x2d00, 0x7002, 0x00ee, + 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x604c, 0xa06d, 0x0130, + 0x6800, 0xa005, 0x1108, 0x6052, 0x604e, 0xad05, 0x012e, 0x0005, + 0x604c, 0xa06d, 0x0130, 0x6800, 0xa005, 0x1108, 0x6052, 0x604e, + 0xad05, 0x0005, 0x6803, 0x0000, 0x6084, 0xa00d, 0x0120, 0x2d00, + 0x200a, 0x6086, 0x0005, 0x2d00, 0x6086, 0x6082, 0x0cd8, 0x0126, + 0x00c6, 0x0026, 0x2091, 0x8000, 0x6218, 0x2260, 0x6200, 0xa005, + 0x0110, 0xc285, 0x0008, 0xc284, 0x6202, 0x002e, 0x00ce, 0x012e, 0x0005, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204, - 0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x00ce, 0x012e, 0x0005, - 0x0026, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x00b0, 0xa190, - 0x936e, 0x2204, 0xa065, 0x1180, 0x0016, 0x00d6, 0x080c, 0x145f, - 0x2d60, 0x00de, 0x001e, 0x0d80, 0x2c00, 0x2012, 0x60a7, 0x0000, - 0x60ab, 0x0000, 0x080c, 0x41e0, 0xa006, 0x002e, 0x0005, 0x0026, - 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x0060, 0x00d6, 0xa190, - 0x936e, 0x2204, 0xa06d, 0x0120, 0x2013, 0x0000, 0x080c, 0x1493, - 0x00de, 0xa006, 0x002e, 0x0005, 0x0016, 0xa182, 0x00ff, 0x0218, - 0xa085, 0x0001, 0x0030, 0xa188, 0x936e, 0x2104, 0xa065, 0x0dc0, - 0xa006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x600b, - 0x0000, 0x600f, 0x0000, 0x6000, 0xc08c, 0x6002, 0x080c, 0x4dc5, - 0x1520, 0x60a0, 0xa086, 0x007e, 0x2069, 0x9790, 0x0130, 0x2001, - 0x9232, 0x2004, 0xd0ac, 0x11c8, 0x0098, 0x2d04, 0xd0e4, 0x01a8, - 0x00d6, 0x2069, 0x978e, 0x00c6, 0x2061, 0x94d9, 0x6810, 0x2062, - 0x6814, 0x6006, 0x6818, 0x600a, 0x681c, 0x600e, 0x00ce, 0x00de, - 0x8d69, 0x2d04, 0x2069, 0x0140, 0x6886, 0x2069, 0x978e, 0x6808, - 0x605e, 0x6810, 0x6062, 0x6138, 0xa10a, 0x0208, 0x603a, 0x6814, - 0x6066, 0x2099, 0x9796, 0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004, - 0x53a3, 0x2099, 0x979a, 0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004, - 0x53a3, 0x2069, 0x97ae, 0x6808, 0x606a, 0x690c, 0x616e, 0x6810, - 0x6072, 0x6818, 0x6076, 0xa182, 0x0211, 0x1218, 0x2009, 0x0008, - 0x0400, 0xa182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0xa182, - 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0xa182, 0x0349, 0x1218, - 0x2009, 0x0005, 0x0070, 0xa182, 0x0421, 0x1218, 0x2009, 0x0004, - 0x0040, 0xa182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, - 0x0002, 0x6192, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x00e6, - 0x2071, 0x978d, 0x2e04, 0x6896, 0x2071, 0x978e, 0x7004, 0x689a, - 0x701c, 0x689e, 0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, - 0x60a4, 0xa06d, 0x01c0, 0x6900, 0x81ff, 0x1540, 0x6a04, 0xa282, - 0x0010, 0x1648, 0xad88, 0x0004, 0x20a9, 0x0010, 0x2104, 0xa086, - 0xffff, 0x0128, 0x8108, 0x1f04, 0x44e6, 0x080c, 0x13fe, 0x260a, - 0x8210, 0x6a06, 0x0098, 0x080c, 0x145f, 0x01a8, 0x2d00, 0x60a6, - 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, - 0x8108, 0x1f04, 0x44fe, 0x6807, 0x0001, 0x6e12, 0xa085, 0x0001, - 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x0126, 0x2091, 0x8000, - 0x00d6, 0x60a4, 0xa00d, 0x01a0, 0x2168, 0x6800, 0xa005, 0x1160, - 0x080c, 0x4630, 0x1168, 0x200b, 0xffff, 0x6804, 0xa08a, 0x0002, - 0x0218, 0x8001, 0x6806, 0x0020, 0x080c, 0x1493, 0x60a7, 0x0000, - 0x00de, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x468d, - 0x0010, 0x080c, 0x4373, 0x080c, 0x45af, 0x1dd8, 0x080c, 0x4578, - 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x60a8, 0xa06d, - 0x01c0, 0x6950, 0x81ff, 0x1540, 0x6a54, 0xa282, 0x0010, 0x1670, - 0xad88, 0x0018, 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0128, - 0x8108, 0x1f04, 0x454c, 0x080c, 0x13fe, 0x260a, 0x8210, 0x6a56, - 0x0098, 0x080c, 0x145f, 0x01d0, 0x2d00, 0x60aa, 0x6853, 0x0000, - 0xad88, 0x0018, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x1f04, - 0x4564, 0x6857, 0x0001, 0x6e62, 0x0010, 0x080c, 0x43c4, 0x0089, - 0x1de0, 0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, - 0x0126, 0x2091, 0x8000, 0x080c, 0x6015, 0x012e, 0x0005, 0xa01e, - 0x0010, 0x2019, 0x0001, 0xa00e, 0x0126, 0x2091, 0x8000, 0x604c, - 0x2068, 0x6000, 0xd0dc, 0x1170, 0x8dff, 0x01e8, 0x83ff, 0x0120, - 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406, 0x1118, 0x6840, - 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70, 0x6a00, 0x604c, - 0xad06, 0x1110, 0x624e, 0x0018, 0xa180, 0x0000, 0x2202, 0x82ff, - 0x1110, 0x6152, 0x8dff, 0x012e, 0x0005, 0xa01e, 0x0010, 0x2019, - 0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x01e8, 0x83ff, 0x0120, - 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406, 0x1118, 0x6840, - 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70, 0x6a00, 0x6080, - 0xad06, 0x1110, 0x6282, 0x0018, 0xa180, 0x0000, 0x2202, 0x82ff, - 0x1110, 0x6186, 0x8dff, 0x0005, 0xa016, 0x080c, 0x462a, 0x1110, - 0x2011, 0x0001, 0x080c, 0x4674, 0x1110, 0xa295, 0x0002, 0x0005, - 0x080c, 0x46a5, 0x0118, 0x080c, 0x83ab, 0x0010, 0xa085, 0x0001, - 0x0005, 0x080c, 0x46a5, 0x0118, 0x080c, 0x8338, 0x0010, 0xa085, - 0x0001, 0x0005, 0x080c, 0x46a5, 0x0118, 0x080c, 0x837e, 0x0010, - 0xa085, 0x0001, 0x0005, 0x080c, 0x46a5, 0x0118, 0x080c, 0x8352, - 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x46a5, 0x0118, 0x080c, - 0x83d8, 0x0010, 0xa085, 0x0001, 0x0005, 0x0126, 0x0006, 0x00d6, - 0x2091, 0x8000, 0x6080, 0xa06d, 0x0168, 0x6800, 0x0006, 0x6837, - 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x8527, 0x080c, 0x4809, - 0x000e, 0x0c88, 0x6083, 0x0000, 0x6087, 0x0000, 0x00de, 0x000e, - 0x012e, 0x0005, 0x60a4, 0xa00d, 0x1118, 0xa085, 0x0001, 0x0005, - 0x00e6, 0x2170, 0x7000, 0xa005, 0x1160, 0x20a9, 0x0010, 0xae88, - 0x0004, 0x2104, 0xa606, 0x0128, 0x8108, 0x1f04, 0x4639, 0xa085, - 0x0001, 0xa006, 0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, - 0x60a4, 0xa06d, 0x1128, 0x080c, 0x145f, 0x01a0, 0x2d00, 0x60a6, - 0x6803, 0x0001, 0x6807, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, - 0x200b, 0xffff, 0x8108, 0x1f04, 0x4658, 0xa085, 0x0001, 0x012e, - 0x00de, 0x0005, 0xa006, 0x0cd8, 0x00d6, 0x0126, 0x2091, 0x8000, - 0x60a4, 0xa06d, 0x0130, 0x60a7, 0x0000, 0x080c, 0x1493, 0xa085, - 0x0001, 0x012e, 0x00de, 0x0005, 0x60a8, 0xa00d, 0x1118, 0xa085, - 0x0001, 0x0005, 0x00e6, 0x2170, 0x7050, 0xa005, 0x1160, 0x20a9, - 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0128, 0x8108, 0x1f04, - 0x4683, 0xa085, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, - 0x0c19, 0x1188, 0x200b, 0xffff, 0x00d6, 0x60a8, 0x2068, 0x6854, - 0xa08a, 0x0002, 0x0218, 0x8001, 0x6856, 0x0020, 0x080c, 0x1493, - 0x60ab, 0x0000, 0x00de, 0x012e, 0x0005, 0x609c, 0xd0a4, 0x0005, - 0x00f6, 0x2079, 0x9251, 0x7804, 0xd0a4, 0x0518, 0x0156, 0x00c6, - 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4434, 0x1168, - 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004, 0x0118, 0xa086, - 0x0006, 0x1118, 0x6000, 0xc0ed, 0x6002, 0x001e, 0x8108, 0x1f04, - 0x46b4, 0x00ce, 0x015e, 0x2009, 0x07d0, 0x2011, 0x46d3, 0x080c, - 0x57b3, 0x00fe, 0x0005, 0x2011, 0x46d3, 0x080c, 0x5731, 0x0156, - 0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4434, - 0x1530, 0x6000, 0xd0ec, 0x0518, 0x0046, 0x62a0, 0xa294, 0x00ff, - 0x8227, 0xa006, 0x2009, 0x0029, 0x080c, 0x90d7, 0x6000, 0xc0e5, - 0xc0ec, 0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700, 0x6006, - 0x2019, 0x0029, 0x080c, 0x6127, 0x0086, 0x2041, 0x0000, 0x080c, - 0x606d, 0x2009, 0x0000, 0x080c, 0x8ee4, 0x008e, 0x004e, 0x001e, - 0x8108, 0x1f04, 0x46dd, 0x00ce, 0x015e, 0x0005, 0x00c6, 0x6018, - 0x2060, 0x6000, 0xc0ec, 0x6002, 0x00ce, 0x0005, 0x00c6, 0x00d6, - 0x080c, 0x145f, 0x2d60, 0x090c, 0x13fe, 0x2009, 0x00ff, 0x080c, - 0x41e0, 0x6007, 0x0006, 0x6013, 0x00ff, 0x6017, 0xffff, 0x606f, - 0x0200, 0x606c, 0x6093, 0x0002, 0x60bb, 0x0520, 0x60a3, 0x00ff, - 0x60b7, 0x0000, 0x60af, 0x0000, 0x2c08, 0x2001, 0x94c6, 0x2102, - 0x00de, 0x00ce, 0x0005, 0x0156, 0x00e6, 0x00d6, 0x00c6, 0x20a9, - 0x00ff, 0x2009, 0x0000, 0x0016, 0x080c, 0x4434, 0x1138, 0x2c70, - 0x70ac, 0xa005, 0x0118, 0x2060, 0x080c, 0x5cf4, 0x001e, 0x8108, - 0x1f04, 0x4743, 0x00ce, 0x00de, 0x00ee, 0x015e, 0x0005, 0x2071, - 0x9328, 0x7003, 0x0001, 0x7007, 0x0000, 0x7013, 0x0000, 0x7017, + 0xa294, 0xff00, 0xa215, 0x6206, 0x00ce, 0x012e, 0x0005, 0x0126, + 0x00c6, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204, 0xa294, 0x00ff, + 0x8007, 0xa215, 0x6206, 0x00ce, 0x012e, 0x0005, 0x0026, 0xa182, + 0x00ff, 0x0218, 0xa085, 0x0001, 0x00b0, 0xa190, 0x8c34, 0x2204, + 0xa065, 0x1180, 0x0016, 0x00d6, 0x080c, 0x146f, 0x2d60, 0x00de, + 0x001e, 0x0d80, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab, 0x0000, + 0x080c, 0x4118, 0xa006, 0x002e, 0x0005, 0x0026, 0xa182, 0x00ff, + 0x0218, 0xa085, 0x0001, 0x0060, 0x00d6, 0xa190, 0x8c34, 0x2204, + 0xa06d, 0x0120, 0x2013, 0x0000, 0x080c, 0x149f, 0x00de, 0xa006, + 0x002e, 0x0005, 0x0016, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, + 0x0030, 0xa188, 0x8c34, 0x2104, 0xa065, 0x0dc0, 0xa006, 0x001e, + 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x600b, 0x0000, 0x600f, + 0x0000, 0x6000, 0xc08c, 0x6002, 0x080c, 0x4c42, 0x1538, 0x60a0, + 0xa086, 0x007e, 0x2069, 0x9090, 0x0130, 0x2001, 0x8b32, 0x2004, + 0xd0ac, 0x11e0, 0x0098, 0x2d04, 0xd0e4, 0x01c0, 0x00d6, 0x2069, + 0x908e, 0x00c6, 0x2061, 0x8d9e, 0x6810, 0x2062, 0x6814, 0x6006, + 0x6818, 0x600a, 0x681c, 0x600e, 0x00ce, 0x00de, 0x8d69, 0x2d04, + 0x2069, 0x0140, 0x6886, 0x2069, 0x8b00, 0x689e, 0x2069, 0x908e, + 0x6808, 0x605e, 0x6810, 0x6062, 0x6138, 0xa10a, 0x0208, 0x603a, + 0x6814, 0x6066, 0x2099, 0x9096, 0xac88, 0x000a, 0x21a0, 0x20a9, + 0x0004, 0x53a3, 0x2099, 0x909a, 0xac88, 0x0006, 0x21a0, 0x20a9, + 0x0004, 0x53a3, 0x2069, 0x90ae, 0x6808, 0x606a, 0x690c, 0x616e, + 0x6810, 0x6072, 0x6818, 0x6076, 0xa182, 0x0211, 0x1218, 0x2009, + 0x0008, 0x0400, 0xa182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, + 0xa182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0xa182, 0x0349, + 0x1218, 0x2009, 0x0005, 0x0070, 0xa182, 0x0421, 0x1218, 0x2009, + 0x0004, 0x0040, 0xa182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, + 0x2009, 0x0002, 0x6192, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, + 0x00e6, 0x2071, 0x908d, 0x2e04, 0x6896, 0x2071, 0x908e, 0x7004, + 0x689a, 0x701c, 0x689e, 0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091, + 0x8000, 0x60a4, 0xa06d, 0x01c0, 0x6900, 0x81ff, 0x1540, 0x6a04, + 0xa282, 0x0010, 0x1648, 0xad88, 0x0004, 0x20a9, 0x0010, 0x2104, + 0xa086, 0xffff, 0x0128, 0x8108, 0x1f04, 0x43bf, 0x080c, 0x1410, + 0x260a, 0x8210, 0x6a06, 0x0098, 0x080c, 0x1488, 0x01a8, 0x2d00, + 0x60a6, 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, + 0xffff, 0x8108, 0x1f04, 0x43d7, 0x6807, 0x0001, 0x6e12, 0xa085, + 0x0001, 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x0126, 0x2091, + 0x8000, 0x00d6, 0x60a4, 0xa00d, 0x01a0, 0x2168, 0x6800, 0xa005, + 0x1160, 0x080c, 0x4509, 0x1168, 0x200b, 0xffff, 0x6804, 0xa08a, + 0x0002, 0x0218, 0x8001, 0x6806, 0x0020, 0x080c, 0x149f, 0x60a7, + 0x0000, 0x00de, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, + 0x4566, 0x0010, 0x080c, 0x4249, 0x080c, 0x4488, 0x1dd8, 0x080c, + 0x4451, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x60a8, + 0xa06d, 0x01c0, 0x6950, 0x81ff, 0x1540, 0x6a54, 0xa282, 0x0010, + 0x1670, 0xad88, 0x0018, 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, + 0x0128, 0x8108, 0x1f04, 0x4425, 0x080c, 0x1410, 0x260a, 0x8210, + 0x6a56, 0x0098, 0x080c, 0x1488, 0x01d0, 0x2d00, 0x60aa, 0x6853, + 0x0000, 0xad88, 0x0018, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, + 0x1f04, 0x443d, 0x6857, 0x0001, 0x6e62, 0x0010, 0x080c, 0x429a, + 0x0089, 0x1de0, 0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0xa006, + 0x0cd8, 0x0126, 0x2091, 0x8000, 0x080c, 0x58b9, 0x012e, 0x0005, + 0xa01e, 0x0010, 0x2019, 0x0001, 0xa00e, 0x0126, 0x2091, 0x8000, + 0x604c, 0x2068, 0x6000, 0xd0dc, 0x1170, 0x8dff, 0x01e8, 0x83ff, + 0x0120, 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406, 0x1118, + 0x6840, 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70, 0x6a00, + 0x604c, 0xad06, 0x1110, 0x624e, 0x0018, 0xa180, 0x0000, 0x2202, + 0x82ff, 0x1110, 0x6152, 0x8dff, 0x012e, 0x0005, 0xa01e, 0x0010, + 0x2019, 0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x01e8, 0x83ff, + 0x0120, 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406, 0x1118, + 0x6840, 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70, 0x6a00, + 0x6080, 0xad06, 0x1110, 0x6282, 0x0018, 0xa180, 0x0000, 0x2202, + 0x82ff, 0x1110, 0x6186, 0x8dff, 0x0005, 0xa016, 0x080c, 0x4503, + 0x1110, 0x2011, 0x0001, 0x080c, 0x454d, 0x1110, 0xa295, 0x0002, + 0x0005, 0x080c, 0x457e, 0x0118, 0x080c, 0x7c4c, 0x0010, 0xa085, + 0x0001, 0x0005, 0x080c, 0x457e, 0x0118, 0x080c, 0x7bd9, 0x0010, + 0xa085, 0x0001, 0x0005, 0x080c, 0x457e, 0x0118, 0x080c, 0x7c1f, + 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x457e, 0x0118, 0x080c, + 0x7bf3, 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x457e, 0x0118, + 0x080c, 0x7c79, 0x0010, 0xa085, 0x0001, 0x0005, 0x0126, 0x0006, + 0x00d6, 0x2091, 0x8000, 0x6080, 0xa06d, 0x0168, 0x6800, 0x0006, + 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x7dc8, 0x080c, + 0x46a1, 0x000e, 0x0c88, 0x6083, 0x0000, 0x6087, 0x0000, 0x00de, + 0x000e, 0x012e, 0x0005, 0x60a4, 0xa00d, 0x1118, 0xa085, 0x0001, + 0x0005, 0x00e6, 0x2170, 0x7000, 0xa005, 0x1160, 0x20a9, 0x0010, + 0xae88, 0x0004, 0x2104, 0xa606, 0x0128, 0x8108, 0x1f04, 0x4512, + 0xa085, 0x0001, 0xa006, 0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091, + 0x8000, 0x60a4, 0xa06d, 0x1128, 0x080c, 0x1488, 0x01a0, 0x2d00, + 0x60a6, 0x6803, 0x0001, 0x6807, 0x0000, 0xad88, 0x0004, 0x20a9, + 0x0010, 0x200b, 0xffff, 0x8108, 0x1f04, 0x4531, 0xa085, 0x0001, + 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x00d6, 0x0126, 0x2091, + 0x8000, 0x60a4, 0xa06d, 0x0130, 0x60a7, 0x0000, 0x080c, 0x149f, + 0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0x60a8, 0xa00d, 0x1118, + 0xa085, 0x0001, 0x0005, 0x00e6, 0x2170, 0x7050, 0xa005, 0x1160, + 0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0128, 0x8108, + 0x1f04, 0x455c, 0xa085, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, + 0x8000, 0x0c19, 0x1188, 0x200b, 0xffff, 0x00d6, 0x60a8, 0x2068, + 0x6854, 0xa08a, 0x0002, 0x0218, 0x8001, 0x6856, 0x0020, 0x080c, + 0x149f, 0x60ab, 0x0000, 0x00de, 0x012e, 0x0005, 0x609c, 0xd0a4, + 0x0005, 0x00f6, 0x2079, 0x8b51, 0x7804, 0xd0a4, 0x0518, 0x0156, + 0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x430a, + 0x1168, 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004, 0x0118, + 0xa086, 0x0006, 0x1118, 0x6000, 0xc0ed, 0x6002, 0x001e, 0x8108, + 0x1f04, 0x458d, 0x00ce, 0x015e, 0x2009, 0x07d0, 0x2011, 0x45ac, + 0x080c, 0x568c, 0x00fe, 0x0005, 0x2011, 0x45ac, 0x080c, 0x560d, + 0x0156, 0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, + 0x430a, 0x1530, 0x6000, 0xd0ec, 0x0518, 0x0046, 0x62a0, 0xa294, + 0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x080c, 0x8982, 0x6000, + 0xc0e5, 0xc0ec, 0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700, + 0x6006, 0x2019, 0x0029, 0x080c, 0x59d5, 0x0086, 0x2041, 0x0000, + 0x080c, 0x5911, 0x2009, 0x0000, 0x080c, 0x878f, 0x008e, 0x004e, + 0x001e, 0x8108, 0x1f04, 0x45b6, 0x00ce, 0x015e, 0x0005, 0x00c6, + 0x6018, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x00ce, 0x0005, 0x2071, + 0x8c13, 0x7003, 0x0001, 0x7007, 0x0000, 0x7013, 0x0000, 0x7017, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000, 0x705b, 0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x2071, - 0x94b6, 0x7003, 0x9328, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f, - 0x9496, 0x7013, 0x0020, 0x7017, 0x0040, 0x7037, 0x0000, 0x0005, - 0x0016, 0x00e6, 0x2071, 0x946e, 0xa00e, 0x7186, 0x718a, 0x7097, - 0x0001, 0x2001, 0x9252, 0x2004, 0xd0fc, 0x1148, 0x2001, 0x9252, + 0x8d7c, 0x7003, 0x8c13, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f, + 0x8d5c, 0x7013, 0x0020, 0x7017, 0x0040, 0x7037, 0x0000, 0x0005, + 0x0016, 0x00e6, 0x2071, 0x8d34, 0xa00e, 0x7186, 0x718a, 0x7097, + 0x0001, 0x2001, 0x8b52, 0x2004, 0xd0fc, 0x1148, 0x2001, 0x8b52, 0x2004, 0xa00e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x04f0, 0x2001, - 0x9271, 0x200c, 0xa184, 0x000f, 0x2009, 0x9272, 0x210c, 0x0002, - 0x478e, 0x47b0, 0x47b7, 0x47c1, 0x47c6, 0x478e, 0x478e, 0x478e, - 0x478e, 0x478e, 0x478e, 0x478e, 0x478e, 0x478e, 0x478e, 0x478e, + 0x8b71, 0x200c, 0xa184, 0x000f, 0x2009, 0x8b72, 0x210c, 0x0002, + 0x4626, 0x4648, 0x464f, 0x4659, 0x465e, 0x4626, 0x4626, 0x4626, + 0x4626, 0x4626, 0x4626, 0x4626, 0x4626, 0x4626, 0x4626, 0x4626, 0x708f, 0x0005, 0x7007, 0x0122, 0x2001, 0x0002, 0x0030, 0x708f, 0x0002, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002, 0x7097, 0x0001, 0x0088, 0x7007, 0x0122, 0x2001, 0x0002, 0x0020, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002, 0xa006, 0x7096, 0x708e, 0xa184, 0xff00, 0x8007, 0x709a, 0xa184, 0x00ff, 0x7092, 0x00ee, 0x001e, 0x0005, - 0x00e6, 0x2071, 0x9328, 0x684c, 0xa005, 0x1130, 0x7028, 0xc085, + 0x00e6, 0x2071, 0x8c13, 0x684c, 0xa005, 0x1130, 0x7028, 0xc085, 0x702a, 0xa085, 0x0001, 0x0418, 0x6a60, 0x7236, 0x6b64, 0x733a, 0x6868, 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c, 0x702e, 0x6844, 0x7032, 0x2009, 0x000d, 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, 0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0xa006, 0x00ee, - 0x0005, 0x0156, 0x00e6, 0x0026, 0x6838, 0xd0fc, 0x1904, 0x4861, - 0x6804, 0xa00d, 0x0188, 0x00d6, 0x2071, 0x9200, 0xa016, 0x702c, + 0x0005, 0x0156, 0x00e6, 0x0026, 0x6838, 0xd0fc, 0x1904, 0x46f9, + 0x6804, 0xa00d, 0x0188, 0x00d6, 0x2071, 0x8b00, 0xa016, 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x1dc8, 0x702e, - 0x70ac, 0xa200, 0x70ae, 0x00de, 0x2071, 0x9328, 0x701c, 0xa005, - 0x1904, 0x4871, 0x20a9, 0x0032, 0x0f04, 0x486f, 0x0e04, 0x482c, - 0x2071, 0x946e, 0x7200, 0x82ff, 0x05d0, 0x6934, 0xa186, 0x0103, - 0x1904, 0x487f, 0x6948, 0x6844, 0xa105, 0x1538, 0x2009, 0x8020, - 0x2200, 0x0002, 0x486f, 0x4846, 0x48e6, 0x48f3, 0x2071, 0x0000, - 0x20a9, 0x0032, 0x0f04, 0x486f, 0x7018, 0xd084, 0x1dd8, 0x7122, + 0x70ac, 0xa200, 0x70ae, 0x00de, 0x2071, 0x8c13, 0x701c, 0xa005, + 0x1904, 0x4709, 0x20a9, 0x0032, 0x0f04, 0x4707, 0x0e04, 0x46c4, + 0x2071, 0x8d34, 0x7200, 0x82ff, 0x05d0, 0x6934, 0xa186, 0x0103, + 0x1904, 0x4717, 0x6948, 0x6844, 0xa105, 0x1538, 0x2009, 0x8020, + 0x2200, 0x0002, 0x4707, 0x46de, 0x472f, 0x473b, 0x2071, 0x0000, + 0x20a9, 0x0032, 0x0f04, 0x4707, 0x7018, 0xd084, 0x1dd8, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, - 0x2071, 0x9200, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70ac, 0x8000, + 0x2071, 0x8b00, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70ac, 0x8000, 0x70ae, 0x002e, 0x00ee, 0x015e, 0x0005, 0x6844, 0xa086, 0x0100, 0x1130, 0x6868, 0xa005, 0x1118, 0x2009, 0x8020, 0x0888, 0x2071, - 0x9328, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000, 0x7012, 0x7018, + 0x8c13, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000, 0x7012, 0x7018, 0xa06d, 0x711a, 0x0110, 0x6902, 0x0008, 0x711e, 0x0c10, 0xa18c, - 0x00ff, 0xa186, 0x0013, 0x01e0, 0xa186, 0x001b, 0x01c8, 0xa186, - 0x0023, 0x01e8, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e, 0x0118, - 0xa18e, 0x001f, 0x19e0, 0x684c, 0xd0cc, 0x09c8, 0x6850, 0xa084, - 0x00ff, 0xa086, 0x0001, 0x1998, 0x2009, 0x8021, 0x0804, 0x4840, - 0x6848, 0xa005, 0x1960, 0x2009, 0x8022, 0x0804, 0x4840, 0x2071, - 0x0000, 0x7018, 0xd084, 0x1918, 0x00e6, 0x2071, 0x9281, 0x7140, - 0x00ee, 0x6838, 0xa102, 0x0a04, 0x486f, 0x684c, 0xa005, 0x1158, - 0x00e6, 0x2071, 0x9281, 0x7004, 0x00ee, 0xd08c, 0x1904, 0x486f, - 0x2001, 0x8024, 0x0040, 0x6848, 0xd084, 0x1118, 0x2001, 0x8023, - 0x0010, 0x2001, 0x8027, 0x7022, 0x6840, 0x7026, 0x683c, 0x702a, - 0x6850, 0x702e, 0x0026, 0x0036, 0x6b38, 0x2e10, 0xa290, 0x0072, - 0x2d00, 0xa080, 0x0015, 0x200c, 0x2112, 0x8000, 0x200c, 0x8210, - 0x8319, 0x1dd0, 0x003e, 0x002e, 0x0804, 0x4854, 0x7084, 0x8008, - 0xa092, 0x001e, 0x1a04, 0x486f, 0x7186, 0xae90, 0x0003, 0xa210, - 0x683c, 0x2012, 0x0080, 0x7084, 0x8008, 0xa092, 0x000f, 0x1a04, - 0x486f, 0x7186, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, - 0x8210, 0x6840, 0x2012, 0x7088, 0xa10a, 0x0a04, 0x4858, 0x718c, - 0x7084, 0xa10a, 0x0a04, 0x4858, 0x2071, 0x0000, 0x7018, 0xd084, - 0x1904, 0x4858, 0x2071, 0x946e, 0x7000, 0xa086, 0x0002, 0x1150, - 0x080c, 0x4b12, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, - 0x0804, 0x4858, 0x080c, 0x4b3c, 0x2071, 0x0000, 0x701b, 0x0001, - 0x2091, 0x4080, 0x0804, 0x4858, 0x0006, 0x6837, 0x0103, 0x20a9, - 0x001c, 0xad80, 0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x000e, - 0x684a, 0x6952, 0x0005, 0x2071, 0x9328, 0x7004, 0x0002, 0x4948, - 0x4958, 0x4afd, 0x4afe, 0x4b0b, 0x4b11, 0x4949, 0x4aee, 0x4a9a, - 0x0005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4956, 0x2009, 0x000d, - 0x7030, 0x200a, 0x2091, 0x4080, 0x7007, 0x0001, 0x012e, 0x0005, - 0x2069, 0x94f8, 0x683c, 0xa005, 0x03f8, 0x11f0, 0x0126, 0x2091, - 0x8000, 0x2069, 0x0000, 0x6934, 0x2001, 0x9334, 0x2004, 0xa10a, - 0x0170, 0x0e04, 0x497c, 0x2069, 0x0000, 0x6818, 0xd084, 0x1158, - 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, 0x2069, - 0x94f8, 0x683f, 0xffff, 0x012e, 0x2069, 0x9200, 0x6844, 0x6964, - 0xa102, 0x2069, 0x946e, 0x688a, 0x6984, 0x701c, 0xa06d, 0x0120, - 0x81ff, 0x0904, 0x49d1, 0x00a0, 0x81ff, 0x0904, 0x4a6f, 0x2071, - 0x946e, 0x7184, 0x7088, 0xa10a, 0x1258, 0x7190, 0x2071, 0x94f8, - 0x7038, 0xa005, 0x0128, 0x1b04, 0x4a6f, 0x713a, 0x0804, 0x4a6f, - 0x2071, 0x946e, 0x718c, 0x0126, 0x2091, 0x8000, 0x7084, 0xa10a, - 0x0a04, 0x4a70, 0x0e04, 0x4a2d, 0x2071, 0x0000, 0x7018, 0xd084, - 0x1904, 0x4a2d, 0x2001, 0xffff, 0x2071, 0x94f8, 0x703a, 0x2071, - 0x946e, 0x7000, 0xa086, 0x0002, 0x1150, 0x080c, 0x4b12, 0x2071, - 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804, 0x4a2d, 0x080c, - 0x4b3c, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804, - 0x4a2d, 0x2071, 0x946e, 0x7000, 0xa005, 0x0904, 0x4a51, 0x6934, - 0xa186, 0x0103, 0x1904, 0x4a30, 0x6948, 0x6844, 0xa105, 0x1904, - 0x4a47, 0x2071, 0x946e, 0x7000, 0x0002, 0x4a51, 0x4a11, 0x49e9, - 0x49fb, 0x7084, 0x8008, 0xa092, 0x001e, 0x1a04, 0x4a6f, 0xae90, - 0x0003, 0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0x9328, 0x080c, - 0x4b95, 0x0804, 0x4a6f, 0x7084, 0x8008, 0xa092, 0x000f, 0x1a04, - 0x4a6f, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210, - 0x6840, 0x2012, 0x7186, 0x2071, 0x9328, 0x080c, 0x4b95, 0x0804, - 0x4a6f, 0x2009, 0x8020, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4a2d, - 0x2071, 0x0000, 0x7018, 0xd084, 0x1180, 0x7122, 0x683c, 0x7026, - 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x012e, 0x2071, - 0x9328, 0x080c, 0x4b95, 0x0804, 0x4a6f, 0x012e, 0x0804, 0x4a6f, - 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e, 0x0118, - 0xa18e, 0x001f, 0x11b0, 0x684c, 0xd0cc, 0x0198, 0x6850, 0xa084, - 0x00ff, 0xa086, 0x0001, 0x1168, 0x2009, 0x8021, 0x0860, 0x6844, - 0xa086, 0x0100, 0x1130, 0x6868, 0xa005, 0x1118, 0x2009, 0x8020, - 0x0810, 0x2071, 0x9328, 0x080c, 0x4ba7, 0x01c8, 0x2071, 0x9328, - 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003, 0x1130, - 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x7007, 0x0003, - 0x080c, 0x4bc0, 0x7050, 0xa086, 0x0100, 0x0904, 0x4afe, 0x0005, - 0x2071, 0x9328, 0x080c, 0x4ba7, 0x0518, 0x2071, 0x946e, 0x7084, - 0x700a, 0x20a9, 0x0020, 0x2099, 0x946f, 0x20a1, 0x9496, 0x53a3, - 0x7087, 0x0000, 0x2071, 0x9328, 0x2069, 0x94b6, 0x706c, 0x6826, - 0x7070, 0x682a, 0x7074, 0x682e, 0x7078, 0x6832, 0x2d10, 0x080c, - 0x14c7, 0x7007, 0x0008, 0x2001, 0xffff, 0x2071, 0x94f8, 0x703a, - 0x012e, 0x08a8, 0x2069, 0x94b6, 0x6808, 0xa08e, 0x0000, 0x0904, - 0x4aed, 0xa08e, 0x0200, 0x0904, 0x4aeb, 0xa08e, 0x0100, 0x1904, - 0x4aed, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4ae9, 0x2069, 0x0000, - 0x6818, 0xd084, 0x15b0, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, - 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0048, 0x706c, 0xa080, - 0x0040, 0x706e, 0x1220, 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, - 0x6936, 0x2001, 0x9493, 0x2004, 0xa005, 0x1190, 0x6934, 0x2069, - 0x946e, 0x689c, 0x699e, 0x2069, 0x94f8, 0xa102, 0x1118, 0x683c, - 0xa005, 0x1368, 0x2001, 0x9494, 0x200c, 0x810d, 0x693e, 0x0038, - 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, 0x7007, - 0x0001, 0x012e, 0x0010, 0x7007, 0x0005, 0x0005, 0x701c, 0xa06d, - 0x0158, 0x080c, 0x4ba7, 0x0140, 0x7007, 0x0003, 0x080c, 0x4bc0, - 0x7050, 0xa086, 0x0100, 0x0110, 0x0005, 0x0005, 0x7050, 0xa09e, - 0x0100, 0x1118, 0x7007, 0x0004, 0x0030, 0xa086, 0x0200, 0x1110, - 0x7007, 0x0005, 0x0005, 0x080c, 0x4b61, 0x7006, 0x080c, 0x4b95, - 0x0005, 0x0005, 0x00e6, 0x0156, 0x2071, 0x946e, 0x7184, 0x81ff, - 0x0500, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, - 0x2014, 0x7226, 0x8000, 0x0f04, 0x4b36, 0x2014, 0x722a, 0x8000, - 0x0f04, 0x4b36, 0x2014, 0x722e, 0x8000, 0x0f04, 0x4b36, 0x2014, - 0x723a, 0x8000, 0x0f04, 0x4b36, 0x2014, 0x723e, 0xa180, 0x8030, - 0x7022, 0x015e, 0x00ee, 0x0005, 0x00e6, 0x0156, 0x2071, 0x946e, - 0x7184, 0x81ff, 0x01d8, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, - 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x2014, 0x722a, 0x8000, - 0x0f04, 0x4b58, 0x2014, 0x723a, 0x8000, 0x2014, 0x723e, 0x0018, - 0x2001, 0x8020, 0x0010, 0xa180, 0x8042, 0x7022, 0x015e, 0x00ee, - 0x0005, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034, - 0x706e, 0x7038, 0x7072, 0x0048, 0x706c, 0xa080, 0x0040, 0x706e, - 0x1220, 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x700c, 0x8001, - 0x700e, 0x11a0, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4b91, 0x2001, - 0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x012e, 0x0005, - 0x2001, 0x000d, 0x2102, 0x2001, 0x0001, 0x0005, 0x2001, 0x0007, - 0x0005, 0x2001, 0x0006, 0x012e, 0x0005, 0x701c, 0xa06d, 0x0170, - 0x0126, 0x2091, 0x8000, 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, - 0xa005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1493, 0x0005, 0x2019, - 0x000d, 0x2304, 0x230c, 0xa10e, 0x0130, 0x2304, 0x230c, 0xa10e, - 0x0110, 0xa006, 0x0060, 0x732c, 0x8319, 0x7130, 0xa102, 0x1118, - 0x2300, 0xa005, 0x0020, 0x0210, 0xa302, 0x0008, 0x8002, 0x0005, - 0x2d00, 0x7026, 0xa080, 0x000d, 0x7056, 0x7053, 0x0000, 0x0126, - 0x2091, 0x8000, 0x2009, 0x9508, 0x2104, 0xc08d, 0x200a, 0x012e, - 0x080c, 0x14df, 0x0005, 0x7088, 0xa08a, 0x0027, 0x1220, 0xa082, - 0x001d, 0x0033, 0x0010, 0x080c, 0x13fe, 0x6027, 0x1e00, 0x0005, - 0x4c57, 0x4be9, 0x4bff, 0x4c27, 0x4c4a, 0x4c7c, 0x4c8e, 0x4bff, - 0x4c68, 0x6803, 0x0010, 0x6124, 0xd1e4, 0x1180, 0x080c, 0x4cd7, - 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1cc, 0x0140, 0x708b, 0x0020, + 0x00ff, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e, 0x0118, 0xa18e, + 0x001f, 0x1d28, 0x684c, 0xd0cc, 0x0d10, 0x6850, 0xa084, 0x00ff, + 0xa086, 0x0001, 0x19e0, 0x2009, 0x8021, 0x0804, 0x46d8, 0x7084, + 0x8008, 0xa092, 0x001e, 0x1a98, 0x7186, 0xae90, 0x0003, 0xa210, + 0x683c, 0x2012, 0x0078, 0x7084, 0x8008, 0xa092, 0x000f, 0x1a38, + 0x7186, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210, + 0x6840, 0x2012, 0x7088, 0xa10a, 0x0a04, 0x46f0, 0x718c, 0x7084, + 0xa10a, 0x0a04, 0x46f0, 0x2071, 0x0000, 0x7018, 0xd084, 0x1904, + 0x46f0, 0x2071, 0x8d34, 0x7000, 0xa086, 0x0002, 0x1150, 0x080c, + 0x495f, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804, + 0x46f0, 0x080c, 0x4989, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, + 0x4080, 0x0804, 0x46f0, 0x0006, 0x684c, 0x0006, 0x6837, 0x0103, + 0x20a9, 0x001c, 0xad80, 0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4, + 0x000e, 0xa084, 0x00ff, 0x684e, 0x000e, 0x684a, 0x6952, 0x0005, + 0x2071, 0x8c13, 0x7004, 0x0002, 0x4795, 0x47a5, 0x494a, 0x494b, + 0x4958, 0x495e, 0x4796, 0x493b, 0x48e7, 0x0005, 0x0126, 0x2091, + 0x8000, 0x0e04, 0x47a3, 0x2009, 0x000d, 0x7030, 0x200a, 0x2091, + 0x4080, 0x7007, 0x0001, 0x012e, 0x0005, 0x2069, 0x8dbd, 0x683c, + 0xa005, 0x03f8, 0x11f0, 0x0126, 0x2091, 0x8000, 0x2069, 0x0000, + 0x6934, 0x2001, 0x8c1f, 0x2004, 0xa10a, 0x0170, 0x0e04, 0x47c8, + 0x2069, 0x0000, 0x6818, 0xd084, 0x1158, 0x2009, 0x8040, 0x6922, + 0x681b, 0x0001, 0x2091, 0x4080, 0x2069, 0x8dbd, 0x683f, 0xffff, + 0x012e, 0x2069, 0x8b00, 0x6844, 0x6964, 0xa102, 0x2069, 0x8d34, + 0x688a, 0x6984, 0x701c, 0xa06d, 0x0120, 0x81ff, 0x0904, 0x481e, + 0x00a0, 0x81ff, 0x0904, 0x48bc, 0x2071, 0x8d34, 0x7184, 0x7088, + 0xa10a, 0x1258, 0x7190, 0x2071, 0x8dbd, 0x7038, 0xa005, 0x0128, + 0x1b04, 0x48bc, 0x713a, 0x0804, 0x48bc, 0x2071, 0x8d34, 0x718c, + 0x0126, 0x2091, 0x8000, 0x7084, 0xa10a, 0x0a04, 0x48bd, 0x0e04, + 0x487a, 0x2071, 0x0000, 0x7018, 0xd084, 0x1904, 0x487a, 0x2001, + 0xffff, 0x2071, 0x8dbd, 0x703a, 0x2071, 0x8d34, 0x7000, 0xa086, + 0x0002, 0x1150, 0x080c, 0x495f, 0x2071, 0x0000, 0x701b, 0x0001, + 0x2091, 0x4080, 0x0804, 0x487a, 0x080c, 0x4989, 0x2071, 0x0000, + 0x701b, 0x0001, 0x2091, 0x4080, 0x0804, 0x487a, 0x2071, 0x8d34, + 0x7000, 0xa005, 0x0904, 0x489e, 0x6934, 0xa186, 0x0103, 0x1904, + 0x487d, 0x6948, 0x6844, 0xa105, 0x1904, 0x4894, 0x2071, 0x8d34, + 0x7000, 0x0002, 0x489e, 0x485e, 0x4836, 0x4848, 0x7084, 0x8008, + 0xa092, 0x001e, 0x1a04, 0x48bc, 0xae90, 0x0003, 0xa210, 0x683c, + 0x2012, 0x7186, 0x2071, 0x8c13, 0x080c, 0x49e2, 0x0804, 0x48bc, + 0x7084, 0x8008, 0xa092, 0x000f, 0x1a04, 0x48bc, 0xae90, 0x0003, + 0x8003, 0xa210, 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7186, + 0x2071, 0x8c13, 0x080c, 0x49e2, 0x0804, 0x48bc, 0x2009, 0x8020, + 0x0126, 0x2091, 0x8000, 0x0e04, 0x487a, 0x2071, 0x0000, 0x7018, + 0xd084, 0x1180, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b, + 0x0001, 0x2091, 0x4080, 0x012e, 0x2071, 0x8c13, 0x080c, 0x49e2, + 0x0804, 0x48bc, 0x012e, 0x0804, 0x48bc, 0xa18c, 0x00ff, 0xa186, + 0x0017, 0x0130, 0xa186, 0x001e, 0x0118, 0xa18e, 0x001f, 0x11b0, + 0x684c, 0xd0cc, 0x0198, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, + 0x1168, 0x2009, 0x8021, 0x0860, 0x6844, 0xa086, 0x0100, 0x1130, + 0x6868, 0xa005, 0x1118, 0x2009, 0x8020, 0x0810, 0x2071, 0x8c13, + 0x080c, 0x49f4, 0x01c8, 0x2071, 0x8c13, 0x700f, 0x0001, 0x6934, + 0xa184, 0x00ff, 0xa086, 0x0003, 0x1130, 0x810f, 0xa18c, 0x00ff, + 0x8101, 0x0108, 0x710e, 0x7007, 0x0003, 0x080c, 0x4a0d, 0x7050, + 0xa086, 0x0100, 0x0904, 0x494b, 0x0005, 0x2071, 0x8c13, 0x080c, + 0x49f4, 0x0518, 0x2071, 0x8d34, 0x7084, 0x700a, 0x20a9, 0x0020, + 0x2099, 0x8d35, 0x20a1, 0x8d5c, 0x53a3, 0x7087, 0x0000, 0x2071, + 0x8c13, 0x2069, 0x8d7c, 0x706c, 0x6826, 0x7070, 0x682a, 0x7074, + 0x682e, 0x7078, 0x6832, 0x2d10, 0x080c, 0x14d3, 0x7007, 0x0008, + 0x2001, 0xffff, 0x2071, 0x8dbd, 0x703a, 0x012e, 0x08a8, 0x2069, + 0x8d7c, 0x6808, 0xa08e, 0x0000, 0x0904, 0x493a, 0xa08e, 0x0200, + 0x0904, 0x4938, 0xa08e, 0x0100, 0x1904, 0x493a, 0x0126, 0x2091, + 0x8000, 0x0e04, 0x4936, 0x2069, 0x0000, 0x6818, 0xd084, 0x15b0, + 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034, 0x706e, + 0x7038, 0x7072, 0x0048, 0x706c, 0xa080, 0x0040, 0x706e, 0x1220, + 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x2001, 0x8d59, + 0x2004, 0xa005, 0x1190, 0x6934, 0x2069, 0x8d34, 0x689c, 0x699e, + 0x2069, 0x8dbd, 0xa102, 0x1118, 0x683c, 0xa005, 0x1368, 0x2001, + 0x8d5a, 0x200c, 0x810d, 0x693e, 0x0038, 0x2009, 0x8040, 0x6922, + 0x681b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x012e, 0x0010, + 0x7007, 0x0005, 0x0005, 0x701c, 0xa06d, 0x0158, 0x080c, 0x49f4, + 0x0140, 0x7007, 0x0003, 0x080c, 0x4a0d, 0x7050, 0xa086, 0x0100, + 0x0110, 0x0005, 0x0005, 0x7050, 0xa09e, 0x0100, 0x1118, 0x7007, + 0x0004, 0x0030, 0xa086, 0x0200, 0x1110, 0x7007, 0x0005, 0x0005, + 0x080c, 0x49ae, 0x7006, 0x080c, 0x49e2, 0x0005, 0x0005, 0x00e6, + 0x0156, 0x2071, 0x8d34, 0x7184, 0x81ff, 0x0500, 0xa006, 0x7086, + 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, + 0x0f04, 0x4983, 0x2014, 0x722a, 0x8000, 0x0f04, 0x4983, 0x2014, + 0x722e, 0x8000, 0x0f04, 0x4983, 0x2014, 0x723a, 0x8000, 0x0f04, + 0x4983, 0x2014, 0x723e, 0xa180, 0x8030, 0x7022, 0x015e, 0x00ee, + 0x0005, 0x00e6, 0x0156, 0x2071, 0x8d34, 0x7184, 0x81ff, 0x01d8, + 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, + 0x7226, 0x8000, 0x2014, 0x722a, 0x8000, 0x0f04, 0x49a5, 0x2014, + 0x723a, 0x8000, 0x2014, 0x723e, 0x0018, 0x2001, 0x8020, 0x0010, + 0xa180, 0x8042, 0x7022, 0x015e, 0x00ee, 0x0005, 0x702c, 0x7130, + 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, + 0x0048, 0x706c, 0xa080, 0x0040, 0x706e, 0x1220, 0x7070, 0xa081, + 0x0000, 0x7072, 0x7132, 0x700c, 0x8001, 0x700e, 0x11a0, 0x0126, + 0x2091, 0x8000, 0x0e04, 0x49de, 0x2001, 0x000d, 0x2102, 0x2091, + 0x4080, 0x2001, 0x0001, 0x012e, 0x0005, 0x2001, 0x000d, 0x2102, + 0x2001, 0x0001, 0x0005, 0x2001, 0x0007, 0x0005, 0x2001, 0x0006, + 0x012e, 0x0005, 0x701c, 0xa06d, 0x0170, 0x0126, 0x2091, 0x8000, + 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, 0xa005, 0x1108, 0x701a, + 0x012e, 0x080c, 0x149f, 0x0005, 0x2019, 0x000d, 0x2304, 0x230c, + 0xa10e, 0x0130, 0x2304, 0x230c, 0xa10e, 0x0110, 0xa006, 0x0060, + 0x732c, 0x8319, 0x7130, 0xa102, 0x1118, 0x2300, 0xa005, 0x0020, + 0x0210, 0xa302, 0x0008, 0x8002, 0x0005, 0x2d00, 0x7026, 0xa080, + 0x000d, 0x7056, 0x7053, 0x0000, 0x0126, 0x2091, 0x8000, 0x2009, + 0x8dcd, 0x2104, 0xc08d, 0x200a, 0x012e, 0x080c, 0x14eb, 0x0005, + 0x7088, 0xa08a, 0x0028, 0x1220, 0xa082, 0x001d, 0x0033, 0x0010, + 0x080c, 0x1410, 0x6027, 0x1e00, 0x0005, 0x4ab8, 0x4a4a, 0x4a60, + 0x4a88, 0x4aab, 0x4add, 0x4aef, 0x4a60, 0x4ac9, 0x4a37, 0x00d6, + 0x2069, 0x0200, 0x6804, 0xa005, 0x1158, 0x6808, 0xa005, 0x1140, + 0x708b, 0x0027, 0x7003, 0x0003, 0x6028, 0xa085, 0x0400, 0x602a, + 0x00de, 0x0005, 0x6803, 0x0010, 0x6124, 0xd1e4, 0x1180, 0x080c, + 0x4b52, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1cc, 0x0140, 0x708b, + 0x0020, 0x0028, 0x708b, 0x001d, 0x0010, 0x708b, 0x001f, 0x0005, + 0x6803, 0x0008, 0x6124, 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, + 0x1198, 0xa184, 0x1e00, 0x11d8, 0x60e3, 0x0001, 0x600c, 0xc0b4, + 0x600e, 0x080c, 0x4c72, 0x6803, 0x0000, 0x708b, 0x0027, 0x2001, + 0x8b25, 0x2003, 0x0000, 0x0058, 0x708b, 0x001e, 0x0040, 0x708b, + 0x001d, 0x0028, 0x708b, 0x0020, 0x0010, 0x708b, 0x001f, 0x0005, + 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x4c72, 0x6803, + 0x0000, 0x6124, 0xd1d4, 0x11a0, 0xd1dc, 0x1178, 0xd1e4, 0x1150, + 0xa184, 0x1e00, 0x1178, 0x708b, 0x0027, 0x2001, 0x8b25, 0x2003, + 0x0000, 0x0040, 0x708b, 0x001e, 0x0028, 0x708b, 0x001d, 0x0010, + 0x708b, 0x001f, 0x0005, 0x6803, 0x0020, 0x6124, 0xd1dc, 0x1128, + 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b, 0x001d, 0x0005, + 0x080c, 0x4b7e, 0x6124, 0xd1dc, 0x1158, 0x080c, 0x4b52, 0xd1d4, + 0x1128, 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b, 0x001f, + 0x0005, 0x6803, 0x0020, 0x6124, 0xd1d4, 0x1160, 0xd1cc, 0x1150, + 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b, 0x001e, 0x0028, 0x708b, + 0x001d, 0x0010, 0x708b, 0x0021, 0x0005, 0x080c, 0x4b7e, 0x6124, + 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b, 0x001e, 0x0028, 0x708b, 0x001d, 0x0010, 0x708b, 0x001f, 0x0005, 0x6803, - 0x0008, 0x6124, 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, - 0xa184, 0x1e00, 0x11d8, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, - 0x080c, 0x4df5, 0x6803, 0x0000, 0x708b, 0x0026, 0x2001, 0x9225, - 0x2003, 0x0000, 0x0058, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d, - 0x0028, 0x708b, 0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x60e3, - 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x4df5, 0x6803, 0x0000, - 0x6124, 0xd1d4, 0x11a0, 0xd1dc, 0x1178, 0xd1e4, 0x1150, 0xa184, - 0x1e00, 0x1178, 0x708b, 0x0026, 0x2001, 0x9225, 0x2003, 0x0000, - 0x0040, 0x708b, 0x001e, 0x0028, 0x708b, 0x001d, 0x0010, 0x708b, - 0x001f, 0x0005, 0x6803, 0x0020, 0x6124, 0xd1dc, 0x1128, 0xd1e4, - 0x0128, 0x708b, 0x001e, 0x0010, 0x708b, 0x001d, 0x0005, 0x080c, - 0x4d03, 0x6124, 0xd1dc, 0x1158, 0x080c, 0x4cd7, 0xd1d4, 0x1128, - 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b, 0x001f, 0x0005, - 0x6803, 0x0020, 0x6124, 0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, - 0x1128, 0xd1e4, 0x0140, 0x708b, 0x001e, 0x0028, 0x708b, 0x001d, - 0x0010, 0x708b, 0x0021, 0x0005, 0x080c, 0x4d03, 0x6124, 0xd1d4, - 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b, 0x001e, 0x0028, - 0x708b, 0x001d, 0x0010, 0x708b, 0x001f, 0x0005, 0x6803, 0x0010, - 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, - 0x0158, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d, 0x0028, 0x708b, - 0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x00c6, 0x00d6, 0x00e6, - 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x9200, 0x2091, - 0x8000, 0x080c, 0x4de1, 0x0150, 0x080c, 0x4dd7, 0x1138, 0x2001, - 0x0001, 0x080c, 0x23ba, 0x080c, 0x4d9a, 0x00a0, 0x080c, 0x4d00, - 0x0178, 0x2001, 0x0001, 0x080c, 0x23ba, 0x7088, 0xa086, 0x001e, - 0x0120, 0x7088, 0xa086, 0x0022, 0x1118, 0x708b, 0x0025, 0x0010, - 0x708b, 0x0021, 0x012e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0016, - 0x0026, 0x2009, 0x0064, 0x2011, 0x4ce2, 0x080c, 0x57b3, 0x002e, - 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c, 0x6f1e, 0x2071, - 0x9200, 0x080c, 0x4ca5, 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0026, - 0x00e6, 0x2011, 0x4ce2, 0x2071, 0x94f8, 0x701c, 0xa206, 0x1118, - 0x7018, 0xa005, 0x0110, 0xa085, 0x0001, 0x00ee, 0x002e, 0x0005, - 0x6020, 0xd09c, 0x0005, 0x6803, 0x0040, 0x0156, 0x20a9, 0x002d, - 0x1d04, 0x4d08, 0x2091, 0x6000, 0x1f04, 0x4d08, 0x015e, 0x0005, - 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, - 0x9200, 0x2001, 0x94d8, 0x200c, 0xa186, 0x0000, 0x0158, 0xa186, - 0x0001, 0x0158, 0xa186, 0x0002, 0x0158, 0xa186, 0x0003, 0x0158, - 0x0804, 0x4d88, 0x708b, 0x0022, 0x0048, 0x708b, 0x0021, 0x0030, - 0x708b, 0x0023, 0x0038, 0x708b, 0x0024, 0x0020, 0xa085, 0x0001, - 0x080c, 0x4e05, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, - 0x080c, 0x2460, 0x0026, 0x2011, 0x0003, 0x080c, 0x718f, 0x002e, - 0x7000, 0xa08e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b, - 0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024, - 0xd0ac, 0x0118, 0x012e, 0x015e, 0x04c8, 0x6803, 0x0080, 0x6803, - 0x0000, 0x6904, 0xd1d4, 0x1130, 0x6803, 0x0100, 0x1f04, 0x4d57, - 0x080c, 0x4e12, 0x012e, 0x015e, 0x080c, 0x4dd7, 0x01a8, 0x6044, - 0xa005, 0x0168, 0x6050, 0x0006, 0xa085, 0x0020, 0x6052, 0x080c, - 0x4e12, 0xa006, 0x8001, 0x1df0, 0x000e, 0x6052, 0x0028, 0x6804, - 0xd0d4, 0x1110, 0x080c, 0x4e12, 0x2001, 0x94d8, 0x2003, 0x0004, - 0x080c, 0x4bd3, 0x080c, 0x4dd7, 0x0148, 0x6804, 0xd0d4, 0x1130, - 0xd0dc, 0x1100, 0x2001, 0x94d8, 0x2003, 0x0000, 0x00ee, 0x00de, - 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, - 0x0140, 0x2071, 0x9200, 0x2001, 0x94d7, 0x2003, 0x0000, 0x2001, - 0x94c8, 0x2003, 0x0000, 0x708b, 0x0000, 0x60e3, 0x0000, 0x6887, - 0x0000, 0x2001, 0x0000, 0x080c, 0x2460, 0x6803, 0x0000, 0x6043, - 0x0090, 0x6027, 0xffff, 0x602b, 0x002f, 0x2001, 0x9225, 0x2003, - 0x0000, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, 0x94d7, - 0x2004, 0xa086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x2001, 0x9271, - 0x2004, 0xa084, 0x0030, 0xa086, 0x0000, 0x000e, 0x0005, 0x0006, - 0x2001, 0x9271, 0x2004, 0xa084, 0x0030, 0xa086, 0x0030, 0x000e, - 0x0005, 0x0006, 0x2001, 0x9271, 0x2004, 0xa084, 0x0030, 0xa086, - 0x0010, 0x000e, 0x0005, 0x0006, 0x2001, 0x9271, 0x2004, 0xa084, - 0x0030, 0xa086, 0x0020, 0x000e, 0x0005, 0x2001, 0x920c, 0x2004, - 0xd0a4, 0x0150, 0x080c, 0x2480, 0x0036, 0x2019, 0x0028, 0x080c, - 0x264b, 0x003e, 0xa006, 0x0009, 0x0005, 0x00e6, 0x2071, 0x920c, - 0x2e04, 0x0118, 0xa085, 0x0010, 0x0010, 0xa084, 0xffef, 0x2072, - 0x00ee, 0x0005, 0x6050, 0x0006, 0x60f0, 0x0006, 0x60ec, 0x0006, - 0x600c, 0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x602f, 0x0100, - 0x602f, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x000e, 0x602a, - 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2, - 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x2460, - 0x6803, 0x0080, 0x6803, 0x0000, 0x6803, 0x0020, 0x000e, 0x6052, - 0x6050, 0x0005, 0x2071, 0x92f6, 0x7003, 0x0000, 0x7007, 0x0000, - 0x700f, 0x0000, 0x702b, 0x0001, 0x704f, 0x0000, 0x7053, 0x0001, - 0x705f, 0x0020, 0x7063, 0x0040, 0x7083, 0x0000, 0x708b, 0x0000, - 0x708f, 0x0001, 0x70bf, 0x0000, 0x0005, 0x00e6, 0x2071, 0x92f6, - 0x6848, 0xa005, 0x1130, 0x7028, 0xc085, 0x702a, 0xa085, 0x0001, - 0x0428, 0x6a50, 0x7236, 0x6b54, 0x733a, 0x6858, 0x703e, 0x707a, - 0x685c, 0x7042, 0x707e, 0x6848, 0x702e, 0x6840, 0x7032, 0x2009, - 0x000c, 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, - 0xffc0, 0xa210, 0x2100, 0xa319, 0x7272, 0x7376, 0x7028, 0xc084, - 0x702a, 0x7007, 0x0001, 0x700f, 0x0000, 0xa006, 0x00ee, 0x0005, - 0x2b78, 0x2071, 0x92f6, 0x7004, 0x0043, 0x700c, 0x0002, 0x4e9c, - 0x4e93, 0x4e93, 0x4e93, 0x4e93, 0x0005, 0x4ef2, 0x4ef3, 0x4f25, - 0x4f26, 0x4ef0, 0x4f5a, 0x4f5f, 0x4f90, 0x4f91, 0x4fac, 0x4fad, - 0x4fae, 0x4faf, 0x4fb0, 0x4fb1, 0x502d, 0x5054, 0x700c, 0x0002, - 0x4eb5, 0x4ef0, 0x4ef0, 0x4ef1, 0x4ef1, 0x7830, 0x7930, 0xa106, - 0x0120, 0x7830, 0x7930, 0xa106, 0x1510, 0x7030, 0xa10a, 0x01f8, - 0x1210, 0x712c, 0xa10a, 0xa18a, 0x0002, 0x12d0, 0x080c, 0x145f, - 0x01b0, 0x2d00, 0x705a, 0x7063, 0x0040, 0x2001, 0x0003, 0x7057, - 0x0000, 0x0126, 0x0006, 0x2091, 0x8000, 0x2009, 0x9508, 0x2104, - 0xc085, 0x200a, 0x000e, 0x700e, 0x012e, 0x080c, 0x14df, 0x0005, - 0x080c, 0x145f, 0x0de0, 0x2d00, 0x705a, 0x080c, 0x145f, 0x1108, - 0x0c10, 0x2d00, 0x7086, 0x7063, 0x0080, 0x2001, 0x0004, 0x08f8, - 0x0005, 0x0005, 0x0005, 0x700c, 0x0002, 0x4efa, 0x4efd, 0x4f0b, - 0x4f24, 0x4f24, 0x080c, 0x4eae, 0x0005, 0x0126, 0x8001, 0x700e, - 0x7058, 0x0006, 0x080c, 0x5311, 0x0120, 0x2091, 0x8000, 0x080c, - 0x4eae, 0x00de, 0x0048, 0x0126, 0x8001, 0x700e, 0x080c, 0x5311, - 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, - 0x6834, 0xa084, 0x00ff, 0xa08a, 0x0020, 0x1218, 0x00db, 0x012e, - 0x0005, 0x012e, 0x080c, 0x4fb2, 0x0005, 0x0005, 0x0005, 0x00e6, - 0x2071, 0x92f6, 0x700c, 0x0002, 0x4f31, 0x4f31, 0x4f31, 0x4f33, - 0x4f36, 0x00ee, 0x0005, 0x700f, 0x0001, 0x0010, 0x700f, 0x0002, - 0x00ee, 0x0005, 0x4fb2, 0x4fb2, 0x4fce, 0x4fb2, 0x50e0, 0x4fb2, - 0x4fb2, 0x4fb2, 0x4fb2, 0x4fb2, 0x4fce, 0x5119, 0x515c, 0x51a5, - 0x51b9, 0x4fb2, 0x4fb2, 0x4fea, 0x4fce, 0x4ffe, 0x4fb2, 0x5013, - 0x5243, 0x525e, 0x4fb2, 0x4fea, 0x4fb2, 0x4ffe, 0x4fb2, 0x4fb2, - 0x5013, 0x525e, 0x7020, 0x2068, 0x080c, 0x1493, 0x0005, 0x700c, - 0x0002, 0x4f66, 0x4f69, 0x4f77, 0x4f8f, 0x4f8f, 0x080c, 0x4eae, - 0x0005, 0x0126, 0x8001, 0x700e, 0x7058, 0x0006, 0x080c, 0x5311, - 0x0120, 0x2091, 0x8000, 0x080c, 0x4eae, 0x00de, 0x0048, 0x0126, - 0x8001, 0x700e, 0x080c, 0x5311, 0x7058, 0x2068, 0x7084, 0x705a, + 0x0010, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, + 0xd1e4, 0x0158, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d, 0x0028, + 0x708b, 0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x00c6, 0x00d6, + 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x8b00, + 0x2091, 0x8000, 0x080c, 0x4c42, 0x11b8, 0x7088, 0xa086, 0x0027, + 0x1198, 0x6027, 0x0200, 0xe000, 0xe000, 0x6024, 0xd0cc, 0x0148, + 0x2001, 0x8d9d, 0x2003, 0x0001, 0x2001, 0x8b00, 0x2003, 0x0001, + 0x0420, 0x6028, 0xc0cd, 0x602a, 0x080c, 0x4c5e, 0x0150, 0x080c, + 0x4c54, 0x1138, 0x2001, 0x0001, 0x080c, 0x2298, 0x080c, 0x4c15, + 0x00a0, 0x080c, 0x4b7b, 0x0178, 0x2001, 0x0001, 0x080c, 0x2298, + 0x7088, 0xa086, 0x001e, 0x0120, 0x7088, 0xa086, 0x0022, 0x1118, + 0x708b, 0x0025, 0x0010, 0x708b, 0x0021, 0x012e, 0x00ee, 0x00de, + 0x00ce, 0x0005, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x4b5d, + 0x080c, 0x5601, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016, + 0x080c, 0x66f7, 0x2071, 0x8b00, 0x080c, 0x4b06, 0x001e, 0x00fe, + 0x00ee, 0x0005, 0x0026, 0x00e6, 0x2011, 0x4b5d, 0x2071, 0x8dbd, + 0x701c, 0xa206, 0x1118, 0x7018, 0xa005, 0x0110, 0xa085, 0x0001, + 0x00ee, 0x002e, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6803, 0x0040, + 0x0156, 0x20a9, 0x002d, 0x1d04, 0x4b83, 0x2091, 0x6000, 0x1f04, + 0x4b83, 0x015e, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, + 0x2069, 0x0140, 0x2071, 0x8b00, 0x2001, 0x8d9d, 0x200c, 0xa186, + 0x0000, 0x0158, 0xa186, 0x0001, 0x0158, 0xa186, 0x0002, 0x0158, + 0xa186, 0x0003, 0x0158, 0x0804, 0x4c03, 0x708b, 0x0022, 0x0048, + 0x708b, 0x0021, 0x0030, 0x708b, 0x0023, 0x0038, 0x708b, 0x0024, + 0x0020, 0xa085, 0x0001, 0x080c, 0x4c82, 0x60e3, 0x0000, 0x6887, + 0x0001, 0x2001, 0x0001, 0x080c, 0x233e, 0x0026, 0x2011, 0x0003, + 0x080c, 0x695c, 0x002e, 0x7000, 0xa08e, 0x0004, 0x0118, 0x602b, + 0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000, + 0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0118, 0x012e, 0x015e, 0x04c8, + 0x6803, 0x0080, 0x6803, 0x0000, 0x6904, 0xd1d4, 0x1130, 0x6803, + 0x0100, 0x1f04, 0x4bd2, 0x080c, 0x4c8f, 0x012e, 0x015e, 0x080c, + 0x4c54, 0x01a8, 0x6044, 0xa005, 0x0168, 0x6050, 0x0006, 0xa085, + 0x0020, 0x6052, 0x080c, 0x4c8f, 0xa006, 0x8001, 0x1df0, 0x000e, + 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, 0x4c8f, 0x2001, + 0x8d9d, 0x2003, 0x0004, 0x080c, 0x4a20, 0x080c, 0x4c54, 0x0148, + 0x6804, 0xd0d4, 0x1130, 0xd0dc, 0x1100, 0x2001, 0x8d9d, 0x2003, + 0x0000, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, + 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x8b00, 0x2001, 0x8d9c, + 0x2003, 0x0000, 0x2001, 0x8d8d, 0x2003, 0x0000, 0x708b, 0x0000, + 0x60e3, 0x0000, 0x6887, 0x0000, 0x2001, 0x0000, 0x080c, 0x233e, + 0x6803, 0x0000, 0x6043, 0x0090, 0x6043, 0x0010, 0x2001, 0x8b25, + 0x2003, 0x0000, 0x6027, 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, + 0x00ce, 0x0005, 0x0006, 0x2001, 0x8d9c, 0x2004, 0xa086, 0xaaaa, + 0x000e, 0x0005, 0x0006, 0x2001, 0x8b71, 0x2004, 0xa084, 0x0030, + 0xa086, 0x0000, 0x000e, 0x0005, 0x0006, 0x2001, 0x8b71, 0x2004, + 0xa084, 0x0030, 0xa086, 0x0030, 0x000e, 0x0005, 0x0006, 0x2001, + 0x8b71, 0x2004, 0xa084, 0x0030, 0xa086, 0x0010, 0x000e, 0x0005, + 0x0006, 0x2001, 0x8b71, 0x2004, 0xa084, 0x0030, 0xa086, 0x0020, + 0x000e, 0x0005, 0x2001, 0x8b0c, 0x2004, 0xd0a4, 0x0150, 0x080c, + 0x235e, 0x0036, 0x2019, 0x0028, 0x080c, 0x2542, 0x003e, 0xa006, + 0x0009, 0x0005, 0x00e6, 0x2071, 0x8b0c, 0x2e04, 0x0118, 0xa085, + 0x0010, 0x0010, 0xa084, 0xffef, 0x2072, 0x00ee, 0x0005, 0x6050, + 0x0006, 0x60f0, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, 0x6004, + 0x0006, 0x6028, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000, 0x602f, + 0x0080, 0x602f, 0x0000, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, + 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2, 0x60e3, 0x0000, 0x6887, + 0x0001, 0x2001, 0x0001, 0x080c, 0x233e, 0x6803, 0x0080, 0x6803, + 0x0000, 0x6803, 0x0020, 0x000e, 0x6052, 0x6050, 0x0005, 0x0156, + 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, + 0x2071, 0x8b00, 0x6028, 0xa084, 0xe1ff, 0x602a, 0x6027, 0x0200, + 0x6803, 0x0010, 0x20a9, 0x04e2, 0x6024, 0xd0cc, 0x1188, 0x1d04, + 0x4cd4, 0x2091, 0x6000, 0x1f04, 0x4cd4, 0x2001, 0x8d9d, 0x2003, + 0x0001, 0x2001, 0x8b00, 0x2003, 0x0001, 0xa085, 0x0001, 0x0410, + 0x6803, 0x0000, 0x20a9, 0x04e2, 0x6027, 0x1e00, 0x2009, 0x1e00, + 0xe000, 0x6024, 0xa10c, 0x0138, 0x1d04, 0x4cec, 0x2091, 0x6000, + 0x1f04, 0x4cec, 0x0c10, 0x6028, 0xa085, 0x1e00, 0x602a, 0x60e3, + 0x0000, 0x709c, 0x6886, 0x2001, 0x8d8d, 0x2004, 0x080c, 0x233e, + 0x60e2, 0xa006, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x015e, 0x0005, + 0x0156, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, + 0x8b00, 0x2069, 0x0200, 0x6804, 0xa005, 0x1118, 0x6808, 0xa005, + 0x0158, 0x6028, 0xa084, 0xfbff, 0x602a, 0x6027, 0x0400, 0x708b, + 0x0026, 0x7003, 0x0001, 0x0460, 0x2069, 0x0140, 0x6803, 0x0008, + 0x20a9, 0x04e2, 0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024, + 0xa10c, 0x0188, 0x1d04, 0x4d32, 0x2091, 0x6000, 0x1f04, 0x4d32, + 0x2001, 0x8d9d, 0x2003, 0x0001, 0x2001, 0x8b00, 0x2003, 0x0001, + 0xa085, 0x0001, 0x0068, 0x6803, 0x0000, 0x60e3, 0x0000, 0x709c, + 0x6886, 0x2001, 0x8d8d, 0x2004, 0x080c, 0x233e, 0x60e2, 0xa006, + 0x00ee, 0x00de, 0x00ce, 0x001e, 0x015e, 0x0005, 0x2071, 0x8be1, + 0x7003, 0x0000, 0x7007, 0x0000, 0x700f, 0x0000, 0x702b, 0x0001, + 0x704f, 0x0000, 0x7053, 0x0001, 0x705f, 0x0020, 0x7063, 0x0040, + 0x7083, 0x0000, 0x708b, 0x0000, 0x708f, 0x0001, 0x70bf, 0x0000, + 0x0005, 0x00e6, 0x2071, 0x8be1, 0x6848, 0xa005, 0x1130, 0x7028, + 0xc085, 0x702a, 0xa085, 0x0001, 0x0428, 0x6a50, 0x7236, 0x6b54, + 0x733a, 0x6858, 0x703e, 0x707a, 0x685c, 0x7042, 0x707e, 0x6848, + 0x702e, 0x6840, 0x7032, 0x2009, 0x000c, 0x200a, 0x8007, 0x8006, + 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, + 0x7272, 0x7376, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700f, + 0x0000, 0xa006, 0x00ee, 0x0005, 0x2b78, 0x2071, 0x8be1, 0x7004, + 0x0043, 0x700c, 0x0002, 0x4db8, 0x4daf, 0x4daf, 0x4daf, 0x4daf, + 0x0005, 0x4e0e, 0x4e0f, 0x4e41, 0x4e42, 0x4e0c, 0x4e76, 0x4e7b, + 0x4eac, 0x4ead, 0x4ec8, 0x4ec9, 0x4eca, 0x4ecb, 0x4ecc, 0x4ecd, + 0x4f32, 0x4f59, 0x700c, 0x0002, 0x4dd1, 0x4e0c, 0x4e0c, 0x4e0d, + 0x4e0d, 0x7830, 0x7930, 0xa106, 0x0120, 0x7830, 0x7930, 0xa106, + 0x1510, 0x7030, 0xa10a, 0x01f8, 0x1210, 0x712c, 0xa10a, 0xa18a, + 0x0002, 0x12d0, 0x080c, 0x146f, 0x01b0, 0x2d00, 0x705a, 0x7063, + 0x0040, 0x2001, 0x0003, 0x7057, 0x0000, 0x0126, 0x0006, 0x2091, + 0x8000, 0x2009, 0x8dcd, 0x2104, 0xc085, 0x200a, 0x000e, 0x700e, + 0x012e, 0x080c, 0x14eb, 0x0005, 0x080c, 0x146f, 0x0de0, 0x2d00, + 0x705a, 0x080c, 0x146f, 0x1108, 0x0c10, 0x2d00, 0x7086, 0x7063, + 0x0080, 0x2001, 0x0004, 0x08f8, 0x0005, 0x0005, 0x0005, 0x700c, + 0x0002, 0x4e16, 0x4e19, 0x4e27, 0x4e40, 0x4e40, 0x080c, 0x4dca, + 0x0005, 0x0126, 0x8001, 0x700e, 0x7058, 0x0006, 0x080c, 0x51f4, + 0x0120, 0x2091, 0x8000, 0x080c, 0x4dca, 0x00de, 0x0048, 0x0126, + 0x8001, 0x700e, 0x080c, 0x51f4, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, - 0x001a, 0x1218, 0x003b, 0x012e, 0x0005, 0x012e, 0x0419, 0x0005, - 0x0005, 0x0005, 0x4fb2, 0x4fce, 0x50cc, 0x4fb2, 0x4fce, 0x4fb2, - 0x4fce, 0x4fce, 0x4fb2, 0x4fce, 0x50cc, 0x4fce, 0x4fce, 0x4fce, - 0x4fce, 0x4fce, 0x4fb2, 0x4fce, 0x50cc, 0x4fb2, 0x4fb2, 0x4fce, - 0x4fb2, 0x4fb2, 0x4fb2, 0x4fce, 0x0005, 0x0005, 0x0005, 0x0005, - 0x0005, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0d5, - 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x4809, 0x012e, 0x0005, - 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0e5, 0x683a, 0x0126, - 0x2091, 0x8000, 0x080c, 0x4809, 0x012e, 0x0005, 0x7007, 0x0001, - 0x6838, 0xa084, 0x00ff, 0xc0ed, 0x683a, 0x0126, 0x2091, 0x8000, - 0x080c, 0x4809, 0x012e, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, - 0x00ff, 0xc0dd, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x4809, - 0x012e, 0x0005, 0x6834, 0x8007, 0xa084, 0x00ff, 0x0988, 0x8001, - 0x1120, 0x7007, 0x0001, 0x0804, 0x508d, 0x7007, 0x0006, 0x7012, - 0x2d00, 0x7016, 0x701a, 0x704b, 0x508d, 0x0005, 0x6834, 0x8007, - 0xa084, 0x00ff, 0x0904, 0x4fc0, 0x8001, 0x1120, 0x7007, 0x0001, - 0x0804, 0x50ac, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, - 0x704b, 0x50ac, 0x0005, 0x2d00, 0x7016, 0x701a, 0x20a9, 0x0004, - 0xa080, 0x0024, 0x2098, 0x20a1, 0x9321, 0x53a3, 0x6858, 0x7012, - 0xa082, 0x0401, 0x1a04, 0x4fdc, 0x6884, 0xa08a, 0x0003, 0x1a04, - 0x4fdc, 0xa080, 0x507e, 0x2005, 0x70c6, 0x7010, 0xa015, 0x0904, - 0x5072, 0x080c, 0x145f, 0x1118, 0x7007, 0x000f, 0x0005, 0x2d00, - 0x7022, 0x70c4, 0x2060, 0x2c05, 0x6836, 0xe004, 0xad00, 0x7096, - 0xe008, 0xa20a, 0x1210, 0xa00e, 0x2200, 0x7112, 0xe20c, 0x8003, - 0x800b, 0xa296, 0x0004, 0x0108, 0xa108, 0x719a, 0x810b, 0x719e, - 0xae90, 0x0022, 0x080c, 0x14c7, 0x7090, 0xa08e, 0x0100, 0x0170, - 0xa086, 0x0200, 0x0118, 0x7007, 0x0010, 0x0005, 0x7020, 0x2068, - 0x080c, 0x1493, 0x7014, 0x2068, 0x0804, 0x4fdc, 0x7020, 0x2068, - 0x7018, 0x6802, 0x6807, 0x0000, 0x2d08, 0x2068, 0x6906, 0x711a, - 0x0804, 0x502d, 0x7014, 0x2068, 0x7007, 0x0001, 0x6834, 0xa084, - 0x00ff, 0xa086, 0x001e, 0x0904, 0x5276, 0x0078, 0x5081, 0x5085, - 0x5089, 0x0002, 0x0011, 0x0007, 0x0004, 0x000a, 0x000f, 0x0005, - 0x0006, 0x0012, 0x000f, 0x0005, 0x0006, 0x2009, 0x922f, 0x210c, - 0x81ff, 0x11a8, 0x6838, 0xa084, 0x00ff, 0x683a, 0x6853, 0x0000, - 0x080c, 0x423e, 0x1108, 0x0005, 0x080c, 0x492c, 0x0126, 0x2091, - 0x8000, 0x080c, 0x8527, 0x080c, 0x4809, 0x012e, 0x0ca0, 0x2001, - 0x0028, 0x2009, 0x0000, 0x0c80, 0x2009, 0x922f, 0x210c, 0x81ff, - 0x11a8, 0x6858, 0xa005, 0x01a8, 0x6838, 0xa084, 0x00ff, 0x683a, - 0x6853, 0x0000, 0x080c, 0x42db, 0x1108, 0x0005, 0x684a, 0x0126, - 0x2091, 0x8000, 0x080c, 0x4809, 0x012e, 0x0cb8, 0x2001, 0x0028, - 0x0ca8, 0x2001, 0x0000, 0x0c90, 0x7018, 0x6802, 0x2d08, 0x2068, - 0x6906, 0x711a, 0x7010, 0x8001, 0x7012, 0x0118, 0x7007, 0x0006, - 0x0030, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x080f, 0x0005, - 0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848, 0xa084, - 0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x01b0, 0x2009, 0x0000, - 0x20a9, 0x007e, 0xa096, 0x0002, 0x0178, 0xa005, 0x11f8, 0x6944, - 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4434, 0x11c0, 0x0066, 0x6e50, - 0x080c, 0x450d, 0x006e, 0x0090, 0x0046, 0x2011, 0x920c, 0x2224, - 0xc484, 0xc48c, 0x2412, 0x004e, 0x00c6, 0x080c, 0x4434, 0x1110, - 0x080c, 0x4664, 0x8108, 0x1f04, 0x510d, 0x00ce, 0x080c, 0x1493, - 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0x9252, - 0x2004, 0xd0a4, 0x0580, 0x2061, 0x9566, 0x6100, 0xd184, 0x0178, - 0x6858, 0xa084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, - 0xa005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, - 0x0001, 0x6860, 0xa005, 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, - 0x6858, 0xa084, 0x00ff, 0x0178, 0x6006, 0x6858, 0x8007, 0xa084, - 0x00ff, 0x0148, 0x600a, 0x6858, 0x8000, 0x1108, 0xc28d, 0x6202, - 0x012e, 0x0804, 0x5300, 0x012e, 0x0804, 0x52fa, 0x012e, 0x0804, - 0x52f4, 0x012e, 0x0804, 0x52f7, 0x0126, 0x2091, 0x8000, 0x7007, - 0x0001, 0x2001, 0x9252, 0x2004, 0xd0a4, 0x05e0, 0x2061, 0x9566, - 0x6000, 0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0x6c48, - 0xa484, 0x0003, 0x0170, 0x6958, 0xa18c, 0x00ff, 0x8001, 0x1120, - 0x2100, 0xa210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0xa212, - 0x02f0, 0xa484, 0x000c, 0x0188, 0x6958, 0x810f, 0xa18c, 0x00ff, - 0xa082, 0x0004, 0x1120, 0x2100, 0xa318, 0x0288, 0x0030, 0xa082, - 0x0004, 0x1168, 0x2100, 0xa31a, 0x0250, 0x6860, 0xa005, 0x0110, - 0x8000, 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x5300, 0x012e, - 0x0804, 0x52fd, 0x012e, 0x0804, 0x52fa, 0x0126, 0x2091, 0x8000, - 0x7007, 0x0001, 0x2061, 0x9566, 0x6300, 0xd38c, 0x1120, 0x6308, - 0x8318, 0x0220, 0x630a, 0x012e, 0x0804, 0x530e, 0x012e, 0x0804, - 0x52fd, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, - 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x9566, 0x6000, 0xa084, 0xfcff, - 0x6002, 0x00ce, 0x04d8, 0x6858, 0xa005, 0x0904, 0x521a, 0x685c, - 0xa065, 0x0904, 0x5216, 0x2001, 0x922f, 0x2004, 0xa005, 0x0118, - 0x080c, 0x849b, 0x0030, 0x6013, 0x0400, 0x2009, 0x0041, 0x080c, - 0x7518, 0x6958, 0xa18c, 0xf600, 0xa186, 0x2000, 0x01b8, 0xa186, - 0x0400, 0x01a0, 0xa186, 0x1000, 0x0140, 0xa186, 0x4000, 0x01b0, - 0x6118, 0x2104, 0xc0fc, 0x200a, 0x0088, 0x00c6, 0x2061, 0x9566, - 0x6000, 0xa084, 0xfdff, 0x6002, 0x00ce, 0x0040, 0x0026, 0x2009, - 0x0000, 0x2011, 0xfdff, 0x080c, 0x585b, 0x002e, 0x684c, 0xd0c4, - 0x0148, 0x2061, 0x9566, 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, - 0x0208, 0x600a, 0x00ce, 0x012e, 0x0804, 0x5300, 0x00ce, 0x012e, - 0x0804, 0x52fa, 0x6954, 0xa186, 0x002e, 0x0d40, 0xa186, 0x002d, - 0x0d28, 0xa186, 0x002a, 0x1130, 0x2001, 0x920c, 0x200c, 0xc194, - 0x2102, 0x08e0, 0xa186, 0x0020, 0x0170, 0xa186, 0x0029, 0x1d30, - 0x6944, 0xa18c, 0xff00, 0x810f, 0x080c, 0x4434, 0x1978, 0x6000, - 0xc0e4, 0x6002, 0x0858, 0x685c, 0xa065, 0x09c0, 0x2001, 0x94dd, - 0x2004, 0x6016, 0x0818, 0x2061, 0x9566, 0x6000, 0xd084, 0x0190, - 0xd08c, 0x1904, 0x530e, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210, - 0x0220, 0x6206, 0x012e, 0x0804, 0x530e, 0x012e, 0x6853, 0x0016, - 0x0804, 0x5307, 0x6853, 0x0007, 0x0804, 0x5307, 0x6834, 0x8007, - 0xa084, 0x00ff, 0x1118, 0x080c, 0x4fc0, 0x0078, 0x2030, 0x8001, - 0x1120, 0x7007, 0x0001, 0x0051, 0x0040, 0x7007, 0x0006, 0x7012, - 0x2d00, 0x7016, 0x701a, 0x704b, 0x5276, 0x0005, 0x00e6, 0x0126, - 0x2091, 0x8000, 0x2009, 0x922f, 0x210c, 0x81ff, 0x1904, 0x52e9, - 0x2009, 0x920c, 0x210c, 0xd194, 0x1904, 0x52f1, 0x6848, 0x2070, - 0xae82, 0x9900, 0x0a04, 0x52dd, 0x2001, 0x9216, 0x2004, 0xae02, - 0x1a04, 0x52dd, 0x2061, 0x9566, 0x6100, 0xa184, 0x0001, 0x0578, - 0xa184, 0x0100, 0x1904, 0x52e0, 0xa184, 0x0200, 0x1904, 0x52e3, - 0x601c, 0xa005, 0x1904, 0x52e6, 0x711c, 0xa186, 0x0006, 0x1520, - 0x7018, 0xa005, 0x05f0, 0x2004, 0xd0e4, 0x15f0, 0xd0fc, 0x1598, - 0x6853, 0x0000, 0x6803, 0x0000, 0x2d08, 0x7010, 0xa005, 0x1138, - 0x7112, 0x2e60, 0x080c, 0x57ca, 0x012e, 0x00ee, 0x0005, 0x2068, - 0x6800, 0xa005, 0x1de0, 0x6902, 0x012e, 0x00ee, 0x0005, 0x012e, - 0x00ee, 0x6853, 0x0006, 0x04d8, 0x6944, 0xa18c, 0xff00, 0x810f, - 0x080c, 0x4434, 0x11c8, 0x6000, 0xd0e4, 0x11b0, 0x711c, 0xa186, - 0x0007, 0x1118, 0x6853, 0x0002, 0x0088, 0x6853, 0x0008, 0x0070, - 0x6853, 0x000e, 0x0058, 0x6853, 0x0017, 0x0040, 0x6853, 0x0035, - 0x0028, 0x6853, 0x0028, 0x0010, 0x6853, 0x0029, 0x012e, 0x00ee, - 0x00b0, 0x6853, 0x002a, 0x0cd0, 0x2009, 0x003e, 0x0058, 0x2009, - 0x0004, 0x0040, 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, - 0x2009, 0x0001, 0x6854, 0xa084, 0xff00, 0xa105, 0x6856, 0x0126, - 0x2091, 0x8000, 0x080c, 0x4809, 0x012e, 0x0005, 0x080c, 0x1493, - 0x0005, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034, - 0x7072, 0x7038, 0x7076, 0x0058, 0x7070, 0xa080, 0x0040, 0x7072, - 0x1230, 0x7074, 0xa081, 0x0000, 0x7076, 0xa085, 0x0001, 0x7932, - 0x7132, 0x0005, 0x00d6, 0x080c, 0x57c1, 0x00de, 0x0005, 0x00d6, - 0x2011, 0x0004, 0x2204, 0xa085, 0x8002, 0x2012, 0x00de, 0x0005, - 0x20e1, 0x0002, 0x3d08, 0x20e1, 0x2000, 0x3d00, 0xa084, 0x7000, - 0x0118, 0xa086, 0x1000, 0x1520, 0x20e1, 0x0004, 0x3d60, 0xd1bc, - 0x1170, 0x2100, 0xa084, 0xff00, 0xa086, 0x0500, 0x1140, 0x0026, - 0x2c10, 0x080c, 0x566e, 0x002e, 0x0198, 0x0070, 0x3e60, 0xac84, - 0x0003, 0x1170, 0xac82, 0x9900, 0x0258, 0x6858, 0xac02, 0x1240, - 0x2009, 0x0047, 0x080c, 0x7518, 0x7a1c, 0xd284, 0x1988, 0x0005, - 0xa016, 0x080c, 0x16c6, 0x0cc0, 0x0156, 0x0136, 0x0146, 0x20e1, - 0x3000, 0x3d20, 0x3e28, 0xa584, 0x0070, 0x1528, 0xa484, 0x7000, - 0xa086, 0x1000, 0x11a0, 0x04a1, 0x01f0, 0x20e1, 0x3000, 0x7828, - 0x7828, 0x080c, 0x53cc, 0x014e, 0x013e, 0x015e, 0x2009, 0x94ed, - 0x2104, 0xa005, 0x1108, 0x0005, 0x080c, 0x6462, 0x0ce0, 0xa484, - 0x7000, 0x1148, 0x00e9, 0x0190, 0x7000, 0xa084, 0xff00, 0xa086, - 0x8100, 0x0d18, 0x0058, 0xd5a4, 0x0140, 0x080c, 0x1c26, 0x20e1, - 0x9010, 0x2001, 0x0138, 0x2202, 0x0038, 0x0051, 0x080c, 0x9157, - 0x20e1, 0x3000, 0x7828, 0x7828, 0x014e, 0x013e, 0x015e, 0x08d8, - 0xa484, 0x01ff, 0x6882, 0xa005, 0x0160, 0xa080, 0x001f, 0xa084, - 0x03f8, 0x80ac, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, - 0x0005, 0x20a9, 0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, - 0x53a5, 0xa085, 0x0001, 0x0ca0, 0x7000, 0xa084, 0xff00, 0xa08c, - 0xf000, 0x8007, 0xa196, 0x0000, 0x1118, 0x0804, 0x5571, 0x0005, - 0xa196, 0x2000, 0x1148, 0x6900, 0xa18e, 0x0001, 0x1118, 0x080c, - 0x3a6a, 0x0ca8, 0x0039, 0x0c98, 0xa196, 0x8000, 0x1d80, 0x080c, - 0x55f9, 0x0c68, 0x00c6, 0x6a80, 0x82ff, 0x0904, 0x5506, 0x7110, - 0xa18c, 0xff00, 0x810f, 0xa196, 0x0001, 0x0120, 0xa196, 0x0023, - 0x1904, 0x5506, 0xa08e, 0x0023, 0x1558, 0x080c, 0x565c, 0x0904, - 0x5506, 0x7124, 0x610a, 0x7030, 0xa08e, 0x0200, 0x1150, 0x7034, - 0xa005, 0x1904, 0x5506, 0x2009, 0x0015, 0x080c, 0x7518, 0x0804, - 0x5506, 0xa08e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c, 0x7518, - 0x0804, 0x5506, 0xa08e, 0x0100, 0x1904, 0x5506, 0x7034, 0xa005, - 0x1904, 0x5506, 0x2009, 0x0016, 0x080c, 0x7518, 0x0804, 0x5506, - 0xa08e, 0x0022, 0x1904, 0x5506, 0x7030, 0xa08e, 0x0300, 0x1568, - 0x68c8, 0xd0a4, 0x0510, 0xc0b5, 0x68ca, 0x7100, 0xa18c, 0x00ff, - 0x696e, 0x7004, 0x6872, 0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea, - 0x0006, 0xa084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x2435, 0x7932, - 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x240b, 0x694e, 0x703c, - 0x00e6, 0x2071, 0x0140, 0x7086, 0x00ee, 0x7034, 0xa005, 0x1904, - 0x5506, 0x2009, 0x0017, 0x0804, 0x54d9, 0xa08e, 0x0400, 0x1158, - 0x7034, 0xa005, 0x1904, 0x5506, 0x68c8, 0xc0a5, 0x68ca, 0x2009, - 0x0030, 0x0804, 0x54d9, 0xa08e, 0x0500, 0x1140, 0x7034, 0xa005, - 0x1904, 0x5506, 0x2009, 0x0018, 0x0804, 0x54d9, 0xa08e, 0x2010, - 0x1120, 0x2009, 0x0019, 0x0804, 0x54d9, 0xa08e, 0x2110, 0x1120, - 0x2009, 0x001a, 0x0804, 0x54d9, 0xa08e, 0x5200, 0x1140, 0x7034, - 0xa005, 0x1904, 0x5506, 0x2009, 0x001b, 0x0804, 0x54d9, 0xa08e, - 0x5000, 0x1140, 0x7034, 0xa005, 0x1904, 0x5506, 0x2009, 0x001c, - 0x0804, 0x54d9, 0xa08e, 0x1200, 0x1138, 0x7034, 0xa005, 0x1904, - 0x5506, 0x2009, 0x0024, 0x04a8, 0xa08c, 0xff00, 0xa18e, 0x2400, + 0x0020, 0x1218, 0x00db, 0x012e, 0x0005, 0x012e, 0x080c, 0x4ece, + 0x0005, 0x0005, 0x0005, 0x00e6, 0x2071, 0x8be1, 0x700c, 0x0002, + 0x4e4d, 0x4e4d, 0x4e4d, 0x4e4f, 0x4e52, 0x00ee, 0x0005, 0x700f, + 0x0001, 0x0010, 0x700f, 0x0002, 0x00ee, 0x0005, 0x4ece, 0x4ece, + 0x4eea, 0x4ece, 0x4fc5, 0x4ece, 0x4ece, 0x4ece, 0x4ece, 0x4ece, + 0x4eea, 0x4ffe, 0x5041, 0x508a, 0x509e, 0x4ece, 0x4ece, 0x4f06, + 0x4eea, 0x4ece, 0x4ece, 0x4f1a, 0x5128, 0x5143, 0x4ece, 0x4f06, + 0x4ece, 0x4ece, 0x4ece, 0x4ece, 0x4f1a, 0x5143, 0x7020, 0x2068, + 0x080c, 0x149f, 0x0005, 0x700c, 0x0002, 0x4e82, 0x4e85, 0x4e93, + 0x4eab, 0x4eab, 0x080c, 0x4dca, 0x0005, 0x0126, 0x8001, 0x700e, + 0x7058, 0x0006, 0x080c, 0x51f4, 0x0120, 0x2091, 0x8000, 0x080c, + 0x4dca, 0x00de, 0x0048, 0x0126, 0x8001, 0x700e, 0x080c, 0x51f4, + 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, + 0x6834, 0xa084, 0x00ff, 0xa08a, 0x001a, 0x1218, 0x003b, 0x012e, + 0x0005, 0x012e, 0x0419, 0x0005, 0x0005, 0x0005, 0x4ece, 0x4eea, + 0x4fb1, 0x4ece, 0x4eea, 0x4ece, 0x4eea, 0x4eea, 0x4ece, 0x4eea, + 0x4fb1, 0x4eea, 0x4eea, 0x4eea, 0x4eea, 0x4eea, 0x4ece, 0x4eea, + 0x4fb1, 0x4ece, 0x4ece, 0x4eea, 0x4ece, 0x4ece, 0x4ece, 0x4eea, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x7007, 0x0001, + 0x6838, 0xa084, 0x00ff, 0xc0d5, 0x683a, 0x0126, 0x2091, 0x8000, + 0x080c, 0x46a1, 0x012e, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, + 0x00ff, 0xc0e5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x46a1, + 0x012e, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed, + 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x46a1, 0x012e, 0x0005, + 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0dd, 0x683a, 0x0126, + 0x2091, 0x8000, 0x080c, 0x46a1, 0x012e, 0x0005, 0x6834, 0x8007, + 0xa084, 0x00ff, 0x0988, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, + 0x4f92, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, + 0x4f92, 0x0005, 0x2d00, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, + 0x0024, 0x2098, 0x20a1, 0x8c0c, 0x53a3, 0x6858, 0x7012, 0xa082, + 0x0401, 0x1a70, 0x6884, 0xa08a, 0x0003, 0x1a50, 0xa080, 0x4f83, + 0x2005, 0x70c6, 0x7010, 0xa015, 0x0904, 0x4f77, 0x080c, 0x146f, + 0x1118, 0x7007, 0x000f, 0x0005, 0x2d00, 0x7022, 0x70c4, 0x2060, + 0x2c05, 0x6836, 0xe004, 0xad00, 0x7096, 0xe008, 0xa20a, 0x1210, + 0xa00e, 0x2200, 0x7112, 0xe20c, 0x8003, 0x800b, 0xa296, 0x0004, + 0x0108, 0xa108, 0x719a, 0x810b, 0x719e, 0xae90, 0x0022, 0x080c, + 0x14d3, 0x7090, 0xa08e, 0x0100, 0x0170, 0xa086, 0x0200, 0x0118, + 0x7007, 0x0010, 0x0005, 0x7020, 0x2068, 0x080c, 0x149f, 0x7014, + 0x2068, 0x0804, 0x4ef8, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807, + 0x0000, 0x2d08, 0x2068, 0x6906, 0x711a, 0x0804, 0x4f32, 0x7014, + 0x2068, 0x7007, 0x0001, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, + 0x0904, 0x515b, 0x0078, 0x4f86, 0x4f8a, 0x4f8e, 0x0002, 0x0011, + 0x0007, 0x0004, 0x000a, 0x000f, 0x0005, 0x0006, 0x0012, 0x000f, + 0x0005, 0x0006, 0x2009, 0x8b2f, 0x210c, 0x81ff, 0x11a8, 0x6838, + 0xa084, 0x00ff, 0x683a, 0x6853, 0x0000, 0x080c, 0x4170, 0x1108, + 0x0005, 0x080c, 0x4773, 0x0126, 0x2091, 0x8000, 0x080c, 0x7dc8, + 0x080c, 0x46a1, 0x012e, 0x0ca0, 0x2001, 0x0028, 0x2009, 0x0000, + 0x0c80, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906, 0x711a, 0x7010, + 0x8001, 0x7012, 0x0118, 0x7007, 0x0006, 0x0030, 0x7014, 0x2068, + 0x7007, 0x0001, 0x7048, 0x080f, 0x0005, 0x7007, 0x0001, 0x6944, + 0x810f, 0xa18c, 0x00ff, 0x6848, 0xa084, 0x00ff, 0x20a9, 0x0001, + 0xa096, 0x0001, 0x01b0, 0x2009, 0x0000, 0x20a9, 0x007e, 0xa096, + 0x0002, 0x0178, 0xa005, 0x11f8, 0x6944, 0x810f, 0xa18c, 0x00ff, + 0x080c, 0x430a, 0x11c0, 0x0066, 0x6e50, 0x080c, 0x43e6, 0x006e, + 0x0090, 0x0046, 0x2011, 0x8b0c, 0x2224, 0xc484, 0xc48c, 0x2412, + 0x004e, 0x00c6, 0x080c, 0x430a, 0x1110, 0x080c, 0x453d, 0x8108, + 0x1f04, 0x4ff2, 0x00ce, 0x080c, 0x149f, 0x0005, 0x0126, 0x2091, + 0x8000, 0x7007, 0x0001, 0x2001, 0x8b52, 0x2004, 0xd0a4, 0x0580, + 0x2061, 0x8e2a, 0x6100, 0xd184, 0x0178, 0x6858, 0xa084, 0x00ff, + 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, 0xa005, 0x1538, 0x6003, + 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, 0x0001, 0x6860, 0xa005, + 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, 0x6858, 0xa084, 0x00ff, + 0x0178, 0x6006, 0x6858, 0x8007, 0xa084, 0x00ff, 0x0148, 0x600a, + 0x6858, 0x8000, 0x1108, 0xc28d, 0x6202, 0x012e, 0x0804, 0x51e3, + 0x012e, 0x0804, 0x51dd, 0x012e, 0x0804, 0x51d7, 0x012e, 0x0804, + 0x51da, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0x8b52, + 0x2004, 0xd0a4, 0x05e0, 0x2061, 0x8e2a, 0x6000, 0xd084, 0x05b8, + 0x6204, 0x6308, 0xd08c, 0x1530, 0x6c48, 0xa484, 0x0003, 0x0170, + 0x6958, 0xa18c, 0x00ff, 0x8001, 0x1120, 0x2100, 0xa210, 0x0620, + 0x0028, 0x8001, 0x1508, 0x2100, 0xa212, 0x02f0, 0xa484, 0x000c, + 0x0188, 0x6958, 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x1120, + 0x2100, 0xa318, 0x0288, 0x0030, 0xa082, 0x0004, 0x1168, 0x2100, + 0xa31a, 0x0250, 0x6860, 0xa005, 0x0110, 0x8000, 0x6016, 0x6206, + 0x630a, 0x012e, 0x0804, 0x51e3, 0x012e, 0x0804, 0x51e0, 0x012e, + 0x0804, 0x51dd, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, + 0x8e2a, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, 0x630a, + 0x012e, 0x0804, 0x51f1, 0x012e, 0x0804, 0x51e0, 0x0126, 0x00c6, + 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0148, 0x00c6, + 0x2061, 0x8e2a, 0x6000, 0xa084, 0xfcff, 0x6002, 0x00ce, 0x04d8, + 0x6858, 0xa005, 0x0904, 0x50ff, 0x685c, 0xa065, 0x0904, 0x50fb, + 0x2001, 0x8b2f, 0x2004, 0xa005, 0x0118, 0x080c, 0x7d3c, 0x0068, + 0x6013, 0x0400, 0x6027, 0x0000, 0x694c, 0xd1a4, 0x0110, 0x6950, + 0x6126, 0x2009, 0x0041, 0x080c, 0x6d3f, 0x6958, 0xa18c, 0xff00, + 0xa186, 0x2000, 0x0180, 0xa186, 0x0400, 0x0168, 0xa186, 0x1000, + 0x0108, 0x0088, 0x00c6, 0x2061, 0x8e2a, 0x6000, 0xa084, 0xfdff, + 0x6002, 0x00ce, 0x0040, 0x0026, 0x2009, 0x0000, 0x2011, 0xfdff, + 0x080c, 0x5734, 0x002e, 0x684c, 0xd0c4, 0x0148, 0x2061, 0x8e2a, + 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce, + 0x012e, 0x0804, 0x51e3, 0x00ce, 0x012e, 0x0804, 0x51dd, 0x6954, + 0xa186, 0x002e, 0x0d40, 0xa186, 0x002d, 0x0d28, 0xa186, 0x002a, + 0x1130, 0x2001, 0x8b0c, 0x200c, 0xc194, 0x2102, 0x08e0, 0xa186, + 0x0020, 0x0170, 0xa186, 0x0029, 0x1d30, 0x6944, 0xa18c, 0xff00, + 0x810f, 0x080c, 0x430a, 0x1978, 0x6000, 0xc0e4, 0x6002, 0x0858, + 0x685c, 0xa065, 0x09c0, 0x2001, 0x8da2, 0x2004, 0x6016, 0x0818, + 0x2061, 0x8e2a, 0x6000, 0xd084, 0x0190, 0xd08c, 0x1904, 0x51f1, + 0x0126, 0x2091, 0x8000, 0x6204, 0x8210, 0x0220, 0x6206, 0x012e, + 0x0804, 0x51f1, 0x012e, 0x6853, 0x0016, 0x0804, 0x51ea, 0x6853, + 0x0007, 0x0804, 0x51ea, 0x6834, 0x8007, 0xa084, 0x00ff, 0x1118, + 0x080c, 0x4edc, 0x0078, 0x2030, 0x8001, 0x1120, 0x7007, 0x0001, + 0x0051, 0x0040, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, + 0x704b, 0x515b, 0x0005, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2009, + 0x8b2f, 0x210c, 0x81ff, 0x1904, 0x51cc, 0x2009, 0x8b0c, 0x210c, + 0xd194, 0x1904, 0x51d4, 0x6848, 0x2070, 0xae82, 0x9200, 0x0a04, + 0x51c0, 0x2001, 0x8b16, 0x2004, 0xae02, 0x1a04, 0x51c0, 0x2061, + 0x8e2a, 0x6100, 0xa184, 0x0001, 0x0568, 0xa184, 0x0100, 0x1904, + 0x51c3, 0xa184, 0x0200, 0x1904, 0x51c6, 0x601c, 0xa005, 0x1904, + 0x51c9, 0x711c, 0xa186, 0x0006, 0x1510, 0x7018, 0xa005, 0x05e0, + 0x2004, 0xd0e4, 0x15e0, 0x6853, 0x0000, 0x6803, 0x0000, 0x2d08, + 0x7010, 0xa005, 0x1138, 0x7112, 0x2e60, 0x080c, 0x56a3, 0x012e, + 0x00ee, 0x0005, 0x2068, 0x6800, 0xa005, 0x1de0, 0x6902, 0x012e, + 0x00ee, 0x0005, 0x012e, 0x00ee, 0x6853, 0x0006, 0x04d8, 0x6944, + 0xa18c, 0xff00, 0x810f, 0x080c, 0x430a, 0x11c8, 0x6000, 0xd0e4, + 0x11b0, 0x711c, 0xa186, 0x0007, 0x1118, 0x6853, 0x0002, 0x0088, + 0x6853, 0x0008, 0x0070, 0x6853, 0x000e, 0x0058, 0x6853, 0x0017, + 0x0040, 0x6853, 0x0035, 0x0028, 0x6853, 0x0028, 0x0010, 0x6853, + 0x0029, 0x012e, 0x00ee, 0x00b0, 0x6853, 0x002a, 0x0cd0, 0x2009, + 0x003e, 0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006, 0x0028, + 0x2009, 0x0016, 0x0010, 0x2009, 0x0001, 0x6854, 0xa084, 0xff00, + 0xa105, 0x6856, 0x0126, 0x2091, 0x8000, 0x080c, 0x46a1, 0x012e, + 0x0005, 0x080c, 0x149f, 0x0005, 0x702c, 0x7130, 0x8108, 0xa102, + 0x0230, 0xa00e, 0x7034, 0x7072, 0x7038, 0x7076, 0x0058, 0x7070, + 0xa080, 0x0040, 0x7072, 0x1230, 0x7074, 0xa081, 0x0000, 0x7076, + 0xa085, 0x0001, 0x7932, 0x7132, 0x0005, 0x00d6, 0x080c, 0x569a, + 0x00de, 0x0005, 0x00d6, 0x2011, 0x0004, 0x2204, 0xa085, 0x8002, + 0x2012, 0x00de, 0x0005, 0x20e1, 0x0002, 0x3d08, 0x20e1, 0x2000, + 0x3d00, 0xa084, 0x7000, 0x0118, 0xa086, 0x1000, 0x11b8, 0x20e1, + 0x0004, 0x3d60, 0xd1bc, 0x1108, 0x3e60, 0xac84, 0x0003, 0x1170, + 0xac82, 0x9200, 0x0258, 0x6858, 0xac02, 0x1240, 0x2009, 0x0047, + 0x080c, 0x6d3f, 0x7a1c, 0xd284, 0x19f0, 0x0005, 0xa016, 0x080c, + 0x16d1, 0x0cc0, 0x0156, 0x0136, 0x0146, 0x20e1, 0x3000, 0x3d20, + 0x3e28, 0xa584, 0x0070, 0x1530, 0xa484, 0x7000, 0xa086, 0x1000, + 0x11a8, 0x080c, 0x5295, 0x01f0, 0x20e1, 0x3000, 0x7828, 0x7828, + 0x080c, 0x52b1, 0x014e, 0x013e, 0x015e, 0x2009, 0x8db2, 0x2104, + 0xa005, 0x1108, 0x0005, 0x080c, 0x5d10, 0x0ce0, 0xa484, 0x7000, + 0x1508, 0x0459, 0x01a8, 0x7000, 0xa084, 0xff00, 0xa086, 0x8100, + 0x0d18, 0x0070, 0xd5a4, 0x0158, 0x080c, 0x1b5e, 0x20e1, 0x9010, + 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0038, 0x00a9, + 0x080c, 0x8a02, 0x20e1, 0x3000, 0x7828, 0x7828, 0x014e, 0x013e, + 0x015e, 0x08c0, 0x0051, 0x0da0, 0x080c, 0x8a02, 0x20e1, 0x3000, + 0x7828, 0x7828, 0x080c, 0x5556, 0x0c88, 0xa484, 0x01ff, 0x6882, + 0xa005, 0x0160, 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac, 0x20e1, + 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x0005, 0x20a9, 0x000c, + 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085, 0x0001, + 0x0ca0, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000, 0x8007, 0xa196, + 0x0000, 0x1118, 0x0804, 0x5459, 0x0005, 0xa196, 0x2000, 0x1148, + 0x6900, 0xa18e, 0x0001, 0x1118, 0x080c, 0x399f, 0x0ca8, 0x0039, + 0x0c98, 0xa196, 0x8000, 0x1d80, 0x080c, 0x54e1, 0x0c68, 0x00c6, + 0x6a80, 0x82ff, 0x0904, 0x53ee, 0x7110, 0xa18c, 0xff00, 0x810f, + 0xa196, 0x0001, 0x0120, 0xa196, 0x0023, 0x1904, 0x53ee, 0xa08e, + 0x0023, 0x1558, 0x080c, 0x5544, 0x0904, 0x53ee, 0x7124, 0x610a, + 0x7030, 0xa08e, 0x0200, 0x1150, 0x7034, 0xa005, 0x1904, 0x53ee, + 0x2009, 0x0015, 0x080c, 0x6d3f, 0x0804, 0x53ee, 0xa08e, 0x0210, + 0x1130, 0x2009, 0x0015, 0x080c, 0x6d3f, 0x0804, 0x53ee, 0xa08e, + 0x0100, 0x1904, 0x53ee, 0x7034, 0xa005, 0x1904, 0x53ee, 0x2009, + 0x0016, 0x080c, 0x6d3f, 0x0804, 0x53ee, 0xa08e, 0x0022, 0x1904, + 0x53ee, 0x7030, 0xa08e, 0x0300, 0x1580, 0x68c8, 0xd0a4, 0x0528, + 0xc0b5, 0x68ca, 0x7100, 0xa18c, 0x00ff, 0x696e, 0x7004, 0x6872, + 0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea, 0x0006, 0xa084, 0x00ff, + 0x0016, 0x2008, 0x080c, 0x2313, 0x7932, 0x7936, 0x001e, 0x000e, + 0x00fe, 0x080c, 0x22e9, 0x694e, 0x703c, 0x00e6, 0x2071, 0x0140, + 0x7086, 0x2071, 0x8b00, 0x709e, 0x00ee, 0x7034, 0xa005, 0x1904, + 0x53ee, 0x2009, 0x0017, 0x0804, 0x53c1, 0xa08e, 0x0400, 0x1158, + 0x7034, 0xa005, 0x1904, 0x53ee, 0x68c8, 0xc0a5, 0x68ca, 0x2009, + 0x0030, 0x0804, 0x53c1, 0xa08e, 0x0500, 0x1140, 0x7034, 0xa005, + 0x1904, 0x53ee, 0x2009, 0x0018, 0x0804, 0x53c1, 0xa08e, 0x2010, + 0x1120, 0x2009, 0x0019, 0x0804, 0x53c1, 0xa08e, 0x2110, 0x1120, + 0x2009, 0x001a, 0x0804, 0x53c1, 0xa08e, 0x5200, 0x1140, 0x7034, + 0xa005, 0x1904, 0x53ee, 0x2009, 0x001b, 0x0804, 0x53c1, 0xa08e, + 0x5000, 0x1140, 0x7034, 0xa005, 0x1904, 0x53ee, 0x2009, 0x001c, + 0x0804, 0x53c1, 0xa08e, 0x1200, 0x1138, 0x7034, 0xa005, 0x1904, + 0x53ee, 0x2009, 0x0024, 0x04a8, 0xa08c, 0xff00, 0xa18e, 0x2400, 0x1118, 0x2009, 0x002d, 0x0468, 0xa08c, 0xff00, 0xa18e, 0x5300, 0x1118, 0x2009, 0x002a, 0x0428, 0xa08e, 0x0f00, 0x1118, 0x2009, 0x0020, 0x00f8, 0xa08e, 0x5300, 0x1108, 0x00c8, 0xa08e, 0x6104, - 0x11b0, 0x2011, 0x978d, 0x8208, 0x2204, 0xa082, 0x0004, 0x20a8, + 0x11b0, 0x2011, 0x908d, 0x8208, 0x2204, 0xa082, 0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011, 0x8015, 0x211c, 0x8108, 0x2124, 0x080c, - 0x3698, 0x8108, 0x1f04, 0x54ca, 0x2009, 0x0023, 0x0010, 0x2009, - 0x001d, 0x0016, 0x2011, 0x9783, 0x2204, 0x8211, 0x220c, 0x080c, - 0x240b, 0x1530, 0x080c, 0x4400, 0x1518, 0x6612, 0x6516, 0x86ff, + 0x3617, 0x8108, 0x1f04, 0x53b2, 0x2009, 0x0023, 0x0010, 0x2009, + 0x001d, 0x0016, 0x2011, 0x9083, 0x2204, 0x8211, 0x220c, 0x080c, + 0x22e9, 0x1530, 0x080c, 0x42d6, 0x1518, 0x6612, 0x6516, 0x86ff, 0x0180, 0x001e, 0x0016, 0xa186, 0x0017, 0x1158, 0x686c, 0xa606, 0x1140, 0x6870, 0xa506, 0xa084, 0xff00, 0x1118, 0x6000, 0xc0f5, - 0x6002, 0x00c6, 0x080c, 0x749c, 0x0168, 0x001e, 0x611a, 0x601f, - 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0x7518, 0x00ce, 0x0005, + 0x6002, 0x00c6, 0x080c, 0x6cc2, 0x0168, 0x001e, 0x611a, 0x601f, + 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0x6d3f, 0x00ce, 0x0005, 0x001e, 0x0ce0, 0x00ce, 0x0ce0, 0x00e6, 0x00d6, 0x2028, 0x2130, 0xa696, 0x00ff, 0x1518, 0xa596, 0xfffd, 0x1120, 0x2009, 0x007f, - 0x0804, 0x556d, 0xa596, 0xfffe, 0x1120, 0x2009, 0x007e, 0x0804, - 0x556d, 0xa596, 0xfffc, 0x1120, 0x2009, 0x0080, 0x0804, 0x556d, + 0x0804, 0x5455, 0xa596, 0xfffe, 0x1120, 0x2009, 0x007e, 0x0804, + 0x5455, 0xa596, 0xfffc, 0x1120, 0x2009, 0x0080, 0x0804, 0x5455, 0xa594, 0xff00, 0xa296, 0xfc00, 0x1148, 0x2011, 0x0000, 0x2021, - 0x0081, 0x20a9, 0x007e, 0x2071, 0x93ef, 0x00a0, 0x2011, 0x0000, - 0x2019, 0x9232, 0x231c, 0xd3ac, 0x0138, 0x2021, 0x0000, 0x20a9, - 0x00ff, 0x2071, 0x936e, 0x0030, 0x2021, 0x0081, 0x20a9, 0x007e, - 0x2071, 0x93ef, 0x2e1c, 0x83ff, 0x1128, 0x82ff, 0x1198, 0x2410, + 0x0081, 0x20a9, 0x007e, 0x2071, 0x8cb5, 0x00a0, 0x2011, 0x0000, + 0x2019, 0x8b32, 0x231c, 0xd3ac, 0x0138, 0x2021, 0x0000, 0x20a9, + 0x00ff, 0x2071, 0x8c34, 0x0030, 0x2021, 0x0081, 0x20a9, 0x007e, + 0x2071, 0x8cb5, 0x2e1c, 0x83ff, 0x1128, 0x82ff, 0x1198, 0x2410, 0xc2fd, 0x0080, 0x2368, 0x6f10, 0x0006, 0x2100, 0xa706, 0x000e, 0x6b14, 0x1120, 0xa346, 0x1110, 0x2408, 0x0078, 0x87ff, 0x1110, - 0x83ff, 0x0d58, 0x8420, 0x8e70, 0x1f04, 0x554a, 0x82ff, 0x1118, + 0x83ff, 0x0d58, 0x8420, 0x8e70, 0x1f04, 0x5432, 0x82ff, 0x1118, 0xa085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0xa006, 0x00de, 0x00ee, - 0x0005, 0xa084, 0x0007, 0x000a, 0x0005, 0x557d, 0x557d, 0x557d, - 0x557d, 0x557d, 0x557e, 0x5593, 0x55e6, 0x0005, 0x7110, 0xd1bc, - 0x0188, 0x7120, 0x2160, 0xac8c, 0x0003, 0x1160, 0xac8a, 0x9900, + 0x0005, 0xa084, 0x0007, 0x000a, 0x0005, 0x5465, 0x5465, 0x5465, + 0x5465, 0x5465, 0x5466, 0x547b, 0x54ce, 0x0005, 0x7110, 0xd1bc, + 0x0188, 0x7120, 0x2160, 0xac8c, 0x0003, 0x1160, 0xac8a, 0x9200, 0x0248, 0x6858, 0xac02, 0x1230, 0x7124, 0x610a, 0x2009, 0x0046, - 0x080c, 0x7518, 0x0005, 0x00c6, 0x7110, 0xd1bc, 0x1904, 0x55e4, - 0x2011, 0x9783, 0x2204, 0x8211, 0x220c, 0x080c, 0x240b, 0x1904, - 0x55e4, 0x080c, 0x4434, 0x1904, 0x55e4, 0x6000, 0xd0ec, 0x15e0, + 0x080c, 0x6d3f, 0x0005, 0x00c6, 0x7110, 0xd1bc, 0x1904, 0x54cc, + 0x2011, 0x9083, 0x2204, 0x8211, 0x220c, 0x080c, 0x22e9, 0x1904, + 0x54cc, 0x080c, 0x430a, 0x1904, 0x54cc, 0x6000, 0xd0ec, 0x15e0, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, 0x0160, 0x080c, - 0x4dc5, 0x11d0, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x11a0, - 0xa295, 0x0600, 0x6206, 0x00c6, 0x080c, 0x749c, 0x001e, 0x0520, + 0x4c42, 0x11d0, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x11a0, + 0xa295, 0x0600, 0x6206, 0x00c6, 0x080c, 0x6cc2, 0x001e, 0x0520, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130, 0x6122, 0x2009, - 0x0044, 0x080c, 0x7518, 0x00c0, 0x00c6, 0x080c, 0x749c, 0x001e, + 0x0044, 0x080c, 0x6d3f, 0x00c0, 0x00c6, 0x080c, 0x6cc2, 0x001e, 0x0198, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0xa286, 0x0004, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001, - 0x080c, 0x603e, 0x080c, 0x6462, 0x00ce, 0x0005, 0x7110, 0xd1bc, - 0x0178, 0x7020, 0x2060, 0xac84, 0x0003, 0x1150, 0xac82, 0x9900, - 0x0238, 0x6858, 0xac02, 0x1220, 0x2009, 0x0045, 0x080c, 0x7518, + 0x080c, 0x58e2, 0x080c, 0x5d10, 0x00ce, 0x0005, 0x7110, 0xd1bc, + 0x0178, 0x7020, 0x2060, 0xac84, 0x0003, 0x1150, 0xac82, 0x9200, + 0x0238, 0x6858, 0xac02, 0x1220, 0x2009, 0x0045, 0x080c, 0x6d3f, 0x0005, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000, 0x1138, - 0xa084, 0x000f, 0xa08a, 0x0006, 0x1a0c, 0x13fe, 0x000b, 0x0005, - 0x560e, 0x560f, 0x560e, 0x560e, 0x5644, 0x5650, 0x0005, 0x7110, - 0xd1bc, 0x1588, 0x700c, 0x7108, 0x080c, 0x240b, 0x1560, 0x080c, - 0x4400, 0x1548, 0x6612, 0x6516, 0x6204, 0xa294, 0xff00, 0x8217, + 0xa084, 0x000f, 0xa08a, 0x0006, 0x1a0c, 0x1410, 0x000b, 0x0005, + 0x54f6, 0x54f7, 0x54f6, 0x54f6, 0x552c, 0x5538, 0x0005, 0x7110, + 0xd1bc, 0x1588, 0x700c, 0x7108, 0x080c, 0x22e9, 0x1560, 0x080c, + 0x42d6, 0x1548, 0x6612, 0x6516, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0004, 0x0118, 0xa286, 0x0006, 0x1178, 0x00c6, 0x080c, - 0x749c, 0x001e, 0x01c0, 0x611a, 0x601f, 0x0005, 0x7120, 0x610a, - 0x2009, 0x0088, 0x080c, 0x7518, 0x0070, 0x00c6, 0x080c, 0x749c, + 0x6cc2, 0x001e, 0x01c0, 0x611a, 0x601f, 0x0005, 0x7120, 0x610a, + 0x2009, 0x0088, 0x080c, 0x6d3f, 0x0070, 0x00c6, 0x080c, 0x6cc2, 0x001e, 0x0148, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x2009, - 0x0001, 0x080c, 0x7518, 0x0005, 0x7110, 0xd1bc, 0x0140, 0x00a1, - 0x0130, 0x7124, 0x610a, 0x2009, 0x0089, 0x080c, 0x7518, 0x0005, + 0x0001, 0x080c, 0x6d3f, 0x0005, 0x7110, 0xd1bc, 0x0140, 0x00a1, + 0x0130, 0x7124, 0x610a, 0x2009, 0x0089, 0x080c, 0x6d3f, 0x0005, 0x7110, 0xd1bc, 0x0140, 0x0041, 0x0130, 0x7124, 0x610a, 0x2009, - 0x008a, 0x080c, 0x7518, 0x0005, 0x7020, 0x2060, 0xac84, 0x0003, - 0x1158, 0xac82, 0x9900, 0x0240, 0x2001, 0x9216, 0x2004, 0xac02, + 0x008a, 0x080c, 0x6d3f, 0x0005, 0x7020, 0x2060, 0xac84, 0x0003, + 0x1158, 0xac82, 0x9200, 0x0240, 0x2001, 0x8b16, 0x2004, 0xac02, 0x1218, 0xa085, 0x0001, 0x0005, 0xa006, 0x0ce8, 0x00c6, 0x00d6, - 0x00e6, 0x20e1, 0x0000, 0x3d08, 0xa18c, 0x00ff, 0xa18e, 0x00ff, - 0x1150, 0x3e00, 0xa086, 0xffff, 0x1130, 0x2001, 0x94c6, 0x2064, - 0x2009, 0x00ff, 0x0060, 0x20e1, 0x0001, 0x3d08, 0x3e00, 0x0156, - 0x080c, 0x240b, 0x015e, 0x1578, 0x080c, 0x4434, 0x1560, 0x2138, - 0x873f, 0x2c00, 0x2070, 0x20e1, 0x0003, 0x3d18, 0x831f, 0xa39c, - 0x00ff, 0x0036, 0x0036, 0x003e, 0x003e, 0x20e1, 0x2000, 0x3d00, - 0xa084, 0x7000, 0xa086, 0x1000, 0x0120, 0x080c, 0x5cc0, 0x1198, - 0x0040, 0x080c, 0x749c, 0x0178, 0x2e00, 0x601a, 0x620a, 0x601f, - 0x0009, 0x2009, 0x0101, 0x080c, 0x7518, 0xa085, 0x0001, 0x00ee, - 0x00de, 0x00ce, 0x0005, 0xa006, 0x00ee, 0x00de, 0x00ce, 0x0005, - 0x2071, 0x94f8, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, - 0x7012, 0x7017, 0x9900, 0x7007, 0x0000, 0x7026, 0x702b, 0x6f2b, - 0x7032, 0x7037, 0x6f69, 0x703b, 0xffff, 0x703f, 0xffff, 0x0005, - 0x2071, 0x94f8, 0x1d04, 0x5720, 0x2091, 0x6000, 0x700c, 0x8001, - 0x700e, 0x1120, 0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, - 0x8000, 0x7024, 0xa00d, 0x0158, 0x7020, 0x8001, 0x7022, 0x1138, - 0x7023, 0x0009, 0x8109, 0x7126, 0x1110, 0x7028, 0x080f, 0x7030, - 0xa00d, 0x0158, 0x702c, 0x8001, 0x702e, 0x1138, 0x702f, 0x0009, - 0x8109, 0x7132, 0x1110, 0x7034, 0x080f, 0x7038, 0xa005, 0x0118, - 0x0310, 0x8001, 0x703a, 0x703c, 0xa005, 0x0118, 0x0310, 0x8001, - 0x703e, 0x7018, 0xa00d, 0x0158, 0x7008, 0x8001, 0x700a, 0x1138, - 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, 0x080f, 0x012e, - 0x7004, 0x0002, 0x5746, 0x5747, 0x575f, 0x00e6, 0x2071, 0x94f8, - 0x7018, 0xa005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, - 0x0005, 0x00e6, 0x0006, 0x2071, 0x94f8, 0x701c, 0xa206, 0x1110, - 0x701a, 0x701e, 0x000e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x94f8, - 0x6088, 0xa102, 0x0208, 0x618a, 0x00ee, 0x0005, 0x0005, 0x7110, - 0x080c, 0x4434, 0x1158, 0x6088, 0x8001, 0x0240, 0x608a, 0x1130, - 0x0126, 0x2091, 0x8000, 0x080c, 0x6462, 0x012e, 0x8108, 0xa182, - 0x00ff, 0x0218, 0xa00e, 0x7007, 0x0002, 0x7112, 0x0005, 0x7014, - 0x2060, 0x0126, 0x2091, 0x8000, 0x6014, 0xa005, 0x0518, 0x8001, - 0x6016, 0x1500, 0x611c, 0xa186, 0x0003, 0x0130, 0xa186, 0x0006, - 0x0118, 0xa186, 0x0009, 0x11a0, 0x6010, 0x2068, 0x6854, 0xa08a, - 0x199a, 0x0270, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a, 0x0210, - 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x0010, - 0x080c, 0x8185, 0x012e, 0xac88, 0x000c, 0x7116, 0x2001, 0x9217, - 0x2004, 0xa102, 0x0220, 0x7017, 0x9900, 0x7007, 0x0000, 0x0005, - 0x00e6, 0x2071, 0x94f8, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee, - 0x0005, 0x2001, 0x9501, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071, - 0x94f8, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0x9504, - 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x94f8, 0x711a, 0x721e, - 0x700b, 0x0009, 0x00ee, 0x0005, 0x00c6, 0x2061, 0x9566, 0x00ce, - 0x0005, 0xa184, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x9566, - 0x2060, 0x0005, 0x6854, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999, - 0xa005, 0x1150, 0x00c6, 0x2061, 0x9566, 0x6014, 0x00ce, 0xa005, - 0x1138, 0x2001, 0x001e, 0x0020, 0xa08e, 0xffff, 0x1108, 0xa006, - 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c, 0x00c0, - 0xa18e, 0x00c0, 0x0588, 0xd0b4, 0x1138, 0xd0bc, 0x11f0, 0x2009, - 0x0006, 0x080c, 0x5838, 0x0005, 0xd0fc, 0x0140, 0xa084, 0x0003, - 0xa08e, 0x0003, 0x05b8, 0xa08e, 0x0000, 0x15a0, 0x2009, 0x9273, - 0x2104, 0xd084, 0x0128, 0x2009, 0x0042, 0x080c, 0x7518, 0x0005, - 0x2009, 0x0043, 0x080c, 0x7518, 0x0005, 0xd0fc, 0x0140, 0xa084, - 0x0003, 0xa08e, 0x0003, 0x01f0, 0xa08e, 0x0000, 0x11d8, 0x2009, - 0x0042, 0x080c, 0x7518, 0x0005, 0xd0fc, 0x0168, 0xa084, 0x0003, - 0xa08e, 0x0003, 0x0178, 0xa08e, 0x0002, 0x0138, 0x2009, 0x0041, - 0x080c, 0x7518, 0x0005, 0x0051, 0x0ce8, 0x2009, 0x0043, 0x080c, - 0x7518, 0x0cc0, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009, 0x0001, - 0x6010, 0xa0ec, 0xf000, 0x01f0, 0x2068, 0x6952, 0x6800, 0x6012, - 0xa186, 0x0001, 0x1188, 0x694c, 0xa18c, 0x8100, 0xa18e, 0x8100, - 0x1158, 0x00c6, 0x2061, 0x9566, 0x6200, 0xd28c, 0x1120, 0x6204, - 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x4809, 0x6010, 0xa06d, - 0x190c, 0x57ca, 0x0005, 0x0156, 0x00c6, 0x2061, 0x9566, 0x6000, - 0x81ff, 0x0110, 0xa205, 0x0008, 0xa204, 0x6002, 0x00ce, 0x015e, - 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, 0xa005, 0x0120, 0x8001, - 0x680a, 0xa085, 0x0001, 0x0005, 0x2071, 0x9349, 0x7003, 0x0006, - 0x7007, 0x0000, 0x700f, 0x0000, 0x7013, 0x0001, 0x702f, 0x0006, - 0x7033, 0x0001, 0x7063, 0x0000, 0x0005, 0x00e6, 0x2071, 0x9349, - 0x6a2c, 0x721e, 0x6b30, 0x7322, 0x6834, 0x7026, 0x705a, 0x6838, - 0x702a, 0x705e, 0x6824, 0x7016, 0x683c, 0x701a, 0x2009, 0x0070, - 0x200a, 0xa005, 0x0150, 0x2009, 0x0000, 0xa188, 0x000c, 0x8001, - 0x1de0, 0x2100, 0xa210, 0x1208, 0x8318, 0x7252, 0x7356, 0x7010, - 0xc084, 0x7012, 0x7007, 0x0001, 0x700f, 0x0000, 0xa006, 0x00ee, - 0x0005, 0x2b78, 0x2071, 0x9349, 0x7004, 0x004b, 0x700c, 0x0002, - 0x58bb, 0x58b4, 0x58b4, 0x0005, 0x58c5, 0x5913, 0x5914, 0x5915, - 0x5916, 0x5929, 0x592a, 0x700c, 0x0cba, 0x2f00, 0xa080, 0x0070, - 0x2004, 0x2f08, 0xa188, 0x0070, 0x210c, 0xa106, 0x0150, 0x2f00, - 0xa080, 0x0070, 0x2004, 0x2f08, 0xa188, 0x0070, 0x210c, 0xa106, - 0x15c8, 0x7018, 0xa10a, 0x05b0, 0x1210, 0x7114, 0xa10a, 0xa192, - 0x000a, 0x0210, 0x2009, 0x000a, 0x00d6, 0x0016, 0x2001, 0x9281, - 0xa080, 0x0011, 0x2014, 0x2001, 0x9363, 0xa080, 0x0005, 0x2004, - 0xa100, 0xa202, 0x001e, 0x00de, 0x02e8, 0x080c, 0x5976, 0x2200, - 0xa102, 0x0208, 0x2208, 0x713a, 0x080c, 0x5a67, 0x2100, 0x7042, - 0x2001, 0x0002, 0x7037, 0x0000, 0x0126, 0x0006, 0x2091, 0x8000, - 0x2009, 0x9508, 0x2104, 0xc095, 0x200a, 0x000e, 0x700e, 0x012e, - 0x080c, 0x14df, 0x0005, 0x0005, 0x0005, 0x0005, 0x700c, 0x0002, - 0x591b, 0x591e, 0x5928, 0x080c, 0x58c3, 0x0005, 0x0126, 0x8001, - 0x700e, 0x7138, 0x0041, 0x2091, 0x8000, 0x080c, 0x58c3, 0x012e, - 0x0005, 0x0005, 0x0005, 0x7018, 0xa100, 0x7214, 0xa21a, 0x1130, - 0x701c, 0x7052, 0x7020, 0x7056, 0xa006, 0x0068, 0x0006, 0x080c, - 0x5a67, 0x2100, 0x7250, 0xa210, 0x7252, 0x1220, 0x7054, 0xa081, - 0x0000, 0x7056, 0x000e, 0x2f08, 0xa188, 0x0070, 0x200a, 0x701a, - 0x0005, 0x00e6, 0x2071, 0x9349, 0x700c, 0x0002, 0x5951, 0x5951, - 0x5953, 0x00ee, 0x0005, 0x700f, 0x0001, 0x00ee, 0x0005, 0x00d6, - 0x00e6, 0x2071, 0x9363, 0xa006, 0x7006, 0x700e, 0x701a, 0x701e, - 0x7022, 0x702a, 0x7026, 0x080c, 0x5b1b, 0x0170, 0x080c, 0x5b4d, - 0x0158, 0x2d00, 0x7002, 0x700a, 0x701a, 0x7013, 0x0001, 0x701f, - 0x0007, 0x00ee, 0x00de, 0x0005, 0xa00e, 0x0cd8, 0x00e6, 0x00d6, - 0x00c6, 0x2071, 0x9363, 0x721c, 0x2100, 0xa202, 0x1618, 0x080c, - 0x5b4d, 0x090c, 0x13fe, 0x7018, 0xa005, 0x1160, 0x2d00, 0x7002, - 0x700a, 0x701a, 0xa006, 0x7006, 0x700e, 0x6806, 0x6802, 0x7012, - 0x701e, 0x0038, 0x2060, 0x6806, 0x2d00, 0x6002, 0x701a, 0x6803, - 0x0000, 0x7010, 0x8000, 0x7012, 0x701c, 0xa080, 0x0007, 0x701e, - 0x721c, 0x08d0, 0x721c, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x0156, - 0x0136, 0x0146, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x9363, - 0x7300, 0xa398, 0x0003, 0x7104, 0x080c, 0x5a67, 0x810c, 0x2100, - 0xa318, 0x8003, 0x2228, 0x2021, 0x0054, 0xa402, 0xa532, 0x0208, - 0x2028, 0x2500, 0x8004, 0x20a8, 0x23a0, 0xe000, 0xe000, 0xe000, - 0x53a5, 0x2508, 0x080c, 0x5a70, 0x2130, 0x7014, 0xa600, 0x7016, - 0x2600, 0x711c, 0xa102, 0x701e, 0x7004, 0xa600, 0x2008, 0xa082, - 0x0007, 0x1180, 0x7000, 0x2004, 0xa005, 0x1140, 0x2009, 0x0001, - 0x0026, 0x080c, 0x5976, 0x002e, 0x7000, 0x2004, 0x7002, 0x7007, - 0x0000, 0x0008, 0x7106, 0x2500, 0xa212, 0x1910, 0x012e, 0x00ee, - 0x014e, 0x013e, 0x015e, 0x0005, 0x0016, 0x0026, 0x00e6, 0x00d6, - 0x04e9, 0x15c8, 0x2170, 0x2805, 0xac68, 0x2900, 0x0002, 0x5a0f, - 0x5a0f, 0x5a13, 0x5a0f, 0x5a13, 0x5a0f, 0x5a0f, 0x5a0f, 0x5a0f, - 0x5a0f, 0x5a1c, 0x5a0f, 0x5a1c, 0x5a0f, 0x5a0f, 0x5a0f, 0x080c, - 0x13fe, 0xa005, 0x00d8, 0x7000, 0x6802, 0x7004, 0x6806, 0x7010, - 0x680a, 0x680f, 0x0000, 0x0060, 0x7010, 0x6812, 0x6817, 0x0000, - 0x7000, 0x6802, 0x7004, 0x6806, 0x7008, 0x680a, 0x700c, 0x680e, - 0x00de, 0x685c, 0x8000, 0x685e, 0x00d6, 0xa006, 0x00de, 0x00ee, - 0x002e, 0x001e, 0x0005, 0xa085, 0x0001, 0x0cc0, 0x00e6, 0x0036, - 0x2071, 0x9363, 0x7014, 0xa005, 0x0538, 0x8001, 0x7016, 0x7008, - 0xa080, 0x0003, 0x710c, 0x2110, 0x0411, 0x810c, 0xa118, 0x8210, - 0xa282, 0x0007, 0x11b0, 0x7008, 0x2004, 0xa005, 0x0178, 0x00d6, - 0x0006, 0x7008, 0x2068, 0x080c, 0x5b5c, 0x000e, 0x2068, 0x6807, - 0x0000, 0x700a, 0x00de, 0x7010, 0x8001, 0x7012, 0x700f, 0x0000, - 0x0008, 0x720e, 0x2308, 0xa006, 0x003e, 0x00ee, 0x0005, 0x0006, - 0x810b, 0x810b, 0x2100, 0x810b, 0xa100, 0x2008, 0x000e, 0x0005, - 0x0006, 0x0026, 0x2100, 0xa005, 0x0160, 0xa092, 0x000c, 0x0248, - 0x2009, 0x0000, 0x8108, 0xa082, 0x000c, 0x1de0, 0x002e, 0x000e, - 0x0005, 0x2009, 0x0000, 0x0cd0, 0x2d00, 0xa0b8, 0x0008, 0x690c, - 0x6810, 0x2019, 0x0001, 0x2031, 0x5ab2, 0xa112, 0x0220, 0x0118, - 0x8318, 0x2208, 0x0cd0, 0x6808, 0xa005, 0x0108, 0x8318, 0x233a, - 0x6804, 0xd084, 0x2300, 0x2021, 0x0001, 0x1150, 0xa082, 0x0003, - 0x0967, 0x0a67, 0x8420, 0xa082, 0x0007, 0x0967, 0x0a67, 0x0cd0, - 0xa082, 0x0002, 0x0967, 0x0a67, 0x8420, 0xa082, 0x0005, 0x0967, - 0x0a67, 0x0cd0, 0x6c1a, 0x2d00, 0xa0b8, 0x0007, 0x00e6, 0x2071, - 0x9200, 0x7128, 0x6810, 0x2019, 0x0001, 0xa10a, 0x0118, 0x0210, - 0x8318, 0x0cd8, 0x2031, 0x5ac5, 0x0870, 0x6c16, 0x00ee, 0x0005, - 0x00e6, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2e00, 0x2060, 0x2071, - 0x9363, 0x2009, 0x0001, 0x0026, 0x080c, 0x5976, 0x002e, 0x7300, - 0xa398, 0x0003, 0x7104, 0x080c, 0x5a67, 0x810c, 0x2100, 0xa318, - 0x6834, 0xa084, 0x00ff, 0xa086, 0x0024, 0x00d6, 0x2368, 0x1138, - 0x6000, 0x6802, 0x6004, 0x6806, 0x6008, 0x6812, 0x0050, 0x6000, - 0x6802, 0x6004, 0x6806, 0x6008, 0x680a, 0x600c, 0x680e, 0x6010, - 0x6812, 0x00de, 0x7014, 0x8000, 0x7016, 0x711c, 0x8109, 0x711e, - 0x7004, 0x8000, 0x2008, 0xa082, 0x0007, 0x1180, 0x7000, 0x2004, - 0xa005, 0x1140, 0x2009, 0x0001, 0x0026, 0x080c, 0x5976, 0x002e, - 0x7000, 0x2004, 0x7002, 0x7007, 0x0000, 0x0008, 0x7106, 0x012e, - 0x00ce, 0x00ee, 0x0005, 0x00d6, 0x0046, 0x0126, 0x2091, 0x8000, - 0x2001, 0x9281, 0xa080, 0x0011, 0x2004, 0x8003, 0x2020, 0x080c, - 0x145f, 0x01d0, 0x2d00, 0x7026, 0x6803, 0x0000, 0x6807, 0x0000, - 0x080c, 0x145f, 0x0188, 0x7024, 0x6802, 0x6807, 0x0000, 0x2d00, - 0x7026, 0xa4a2, 0x0007, 0x0110, 0x0208, 0x0c90, 0xa085, 0x0001, - 0x012e, 0x004e, 0x00de, 0x0005, 0x7024, 0xa005, 0x0dc8, 0x2068, - 0x2024, 0x080c, 0x1493, 0x2400, 0x0cc0, 0x0126, 0x2091, 0x8000, - 0x7024, 0x2068, 0xa005, 0x0130, 0x2004, 0x7026, 0x6803, 0x0000, - 0x6807, 0x0000, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x7024, - 0x6802, 0x2d00, 0x7026, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x00d6, - 0x00c6, 0x0086, 0x0046, 0x0056, 0x0026, 0x2031, 0x0000, 0x2001, - 0x934a, 0x2004, 0xa005, 0x0904, 0x5bee, 0x2071, 0x9281, 0x20e1, - 0x0002, 0x3d08, 0xd19c, 0x0140, 0x2069, 0x9200, 0x6a28, 0x761c, - 0x7114, 0x2041, 0x0000, 0x0028, 0x7118, 0x720c, 0x7620, 0x7008, - 0x2040, 0x080c, 0x5d03, 0x0904, 0x5bee, 0x7004, 0xd084, 0x1128, - 0x2021, 0x0024, 0x2029, 0x0002, 0x0020, 0x2021, 0x002c, 0x2029, - 0x000a, 0x080c, 0x147c, 0x0904, 0x5bee, 0x2d00, 0x2060, 0x6436, - 0x0016, 0x20e1, 0x0001, 0x3d08, 0x3e00, 0xa18c, 0x00ff, 0x6142, - 0x603e, 0x001e, 0x6746, 0x2700, 0xa086, 0xff00, 0x1118, 0x6063, - 0x0000, 0x0010, 0x6063, 0x0003, 0xa006, 0x6002, 0x602a, 0x602e, - 0x6006, 0x603a, 0x604a, 0x6052, 0x6056, 0x605e, 0x6066, 0x604e, - 0x2800, 0x606a, 0x604c, 0xc0ad, 0x604e, 0x665a, 0x2c00, 0x2078, - 0x0479, 0x607f, 0xffff, 0x6083, 0x0000, 0x8109, 0x0180, 0x080c, - 0x147c, 0x01c0, 0x2d00, 0x7806, 0x2f00, 0x6802, 0x6d36, 0xa006, - 0x2d00, 0x2520, 0x00e9, 0x2d00, 0x2078, 0x8109, 0x1d80, 0x2c00, - 0xa005, 0x002e, 0x005e, 0x004e, 0x008e, 0x00ce, 0x00de, 0x00ee, - 0x00fe, 0x0005, 0x2c00, 0x2068, 0x080c, 0x14a3, 0x2600, 0x2071, - 0x9363, 0x7120, 0xa102, 0x0a0c, 0x13fe, 0x7022, 0xa006, 0x0c48, - 0x00d6, 0x00c6, 0x0136, 0x0146, 0x0156, 0x0016, 0x2068, 0x2400, - 0xa084, 0x000f, 0xa080, 0x1f59, 0x2005, 0x2005, 0xad60, 0x2c00, - 0x2d08, 0xa188, 0x0030, 0xa102, 0x20a8, 0x2c00, 0x20a0, 0x2001, - 0xffff, 0x40a4, 0x001e, 0x015e, 0x014e, 0x013e, 0x00ce, 0x00de, - 0x0005, 0x00c6, 0x00e6, 0x00f6, 0x6858, 0x2071, 0x9363, 0x7120, - 0xa102, 0x0a0c, 0x13fe, 0x7022, 0x6960, 0x694e, 0x697c, 0x2009, - 0xffff, 0x7818, 0xa102, 0xe000, 0x0006, 0x0006, 0x0006, 0x0006, - 0x0006, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x6852, 0x684b, - 0x0000, 0x6868, 0xa005, 0x0118, 0x6848, 0xc085, 0x684a, 0x2d00, - 0xa080, 0x0015, 0x2038, 0x2031, 0x0018, 0x6864, 0x2020, 0x683a, - 0x685c, 0xa08a, 0x00ff, 0x1a0c, 0x13fe, 0x2028, 0x2d00, 0x2060, - 0x2078, 0x6934, 0xa18c, 0x000f, 0xa188, 0x1f59, 0x2145, 0x685c, - 0x2050, 0xa005, 0x0530, 0x2805, 0xac70, 0x6834, 0xa084, 0x00ff, - 0xa086, 0x0024, 0x1110, 0x7008, 0x0040, 0x6834, 0xa084, 0x00ff, - 0xa086, 0x002c, 0x190c, 0x13fe, 0x7010, 0x0006, 0x2400, 0xa005, - 0x000e, 0x0168, 0x203a, 0x8738, 0x8631, 0x090c, 0x13fe, 0x8421, - 0x8529, 0x0138, 0x080c, 0x1f1b, 0x090c, 0x13fe, 0x08e0, 0x080c, - 0x5ac8, 0x6837, 0x0023, 0x00fe, 0x00ee, 0x00ce, 0x0005, 0x00e6, - 0x00c6, 0x00a6, 0x0086, 0x0056, 0x6858, 0x2071, 0x9363, 0x7120, - 0xa102, 0x0a0c, 0x13fe, 0x7022, 0x2d00, 0x2060, 0x6934, 0xa18c, - 0x000f, 0xa188, 0x1f59, 0x2145, 0x685c, 0x2050, 0xa005, 0x01d0, - 0x2028, 0x2805, 0xac70, 0x6834, 0xa084, 0x00ff, 0xa086, 0x0024, - 0x1110, 0x7008, 0x0008, 0x7010, 0x0006, 0xa086, 0xffff, 0x000e, - 0x0110, 0x080c, 0x5ac8, 0x8529, 0x0128, 0x080c, 0x1f1b, 0x090c, - 0x13fe, 0x0c38, 0x005e, 0x008e, 0x00ae, 0x00ce, 0x00ee, 0x0005, - 0x70ac, 0xa005, 0x0138, 0x2060, 0x6008, 0xa306, 0x0110, 0x600c, - 0x0cc0, 0x0005, 0xa085, 0x0001, 0x0ce0, 0x70ac, 0x600e, 0x2c00, - 0x70ae, 0x0005, 0x00f6, 0x00d6, 0x0036, 0x70ac, 0xa005, 0x090c, - 0x13fe, 0x2068, 0x2079, 0x0000, 0x2c08, 0xa11e, 0x1118, 0x680c, - 0x70ae, 0x0060, 0xa106, 0x0140, 0x2d00, 0x2078, 0x680c, 0xa005, - 0x090c, 0x13fe, 0x2068, 0x0cb0, 0x6b0c, 0x7b0e, 0x600f, 0x0000, - 0x003e, 0x00de, 0x00fe, 0x0005, 0x00e6, 0x080c, 0x5c87, 0x6018, - 0x2070, 0xa006, 0x70b2, 0x70b6, 0x080c, 0x14a3, 0x0899, 0x080c, - 0x74f2, 0x00ee, 0x0005, 0x00d6, 0x0026, 0x0016, 0x2061, 0x9363, - 0x6020, 0x6414, 0xa600, 0xa42a, 0x02c8, 0x6022, 0x2069, 0x9281, - 0x6828, 0x6114, 0xa102, 0x1260, 0x2011, 0x8025, 0x080c, 0x3698, - 0xa080, 0x0013, 0x2004, 0xa080, 0x0000, 0x200c, 0x8108, 0x2102, - 0xa085, 0x0001, 0x001e, 0x002e, 0x00de, 0x0005, 0x2069, 0x9281, - 0x6804, 0xd09c, 0x0120, 0x2011, 0x8026, 0x080c, 0x3698, 0x2001, - 0x9281, 0xa080, 0x0013, 0x2004, 0xa080, 0x0001, 0x200c, 0x8108, - 0x2102, 0xa006, 0x2031, 0x0000, 0x0c28, 0x0066, 0x6000, 0xa0b2, - 0x0010, 0x1a0c, 0x13fe, 0x0013, 0x006e, 0x0005, 0x5d56, 0x5d56, - 0x5d56, 0x5d58, 0x5db1, 0x5d56, 0x5d56, 0x5d56, 0x5de6, 0x5d56, - 0x5e34, 0x5d56, 0x5d56, 0x5d56, 0x5d56, 0x5d56, 0x080c, 0x13fe, - 0xa182, 0x0100, 0x0002, 0x5d6a, 0x5d6a, 0x5d6a, 0x5d6c, 0x5d85, - 0x5d9d, 0x5d6a, 0x5d6a, 0x5d6a, 0x5d6a, 0x5d6a, 0x5d6a, 0x5d6a, - 0x5d6a, 0x5d6a, 0x080c, 0x13fe, 0x00d6, 0x080c, 0x641b, 0x080c, - 0x651c, 0x6110, 0x2168, 0x684b, 0x0000, 0x00d6, 0x6018, 0x2068, - 0x6008, 0x68b6, 0x68bb, 0x0500, 0xa006, 0x68b2, 0x00de, 0x080c, - 0x4809, 0x080c, 0x74f2, 0x00de, 0x0005, 0x080c, 0x641b, 0x00f6, - 0x00d6, 0x6110, 0x2178, 0x080c, 0x82ee, 0x0140, 0x784b, 0x0006, - 0xa006, 0x70b2, 0x70b6, 0x2f68, 0x080c, 0x4809, 0x00de, 0x00fe, - 0x080c, 0x74f2, 0x080c, 0x651c, 0x0005, 0x080c, 0x641b, 0x080c, - 0x266c, 0x00d6, 0x6110, 0x2168, 0x080c, 0x82ee, 0x0120, 0x684b, - 0x0029, 0x080c, 0x4809, 0x00de, 0x080c, 0x74f2, 0x080c, 0x651c, - 0x0005, 0xa182, 0x0100, 0x0002, 0x5dc3, 0x5dc5, 0x5dcd, 0x5dc3, - 0x5dc3, 0x5dc3, 0x5de1, 0x5dc3, 0x5dc3, 0x5dc3, 0x5dc3, 0x5dc3, - 0x5dc3, 0x5dc3, 0x5dc3, 0x080c, 0x13fe, 0x20e1, 0x0005, 0x3d18, - 0x3e20, 0x2c10, 0x080c, 0x16c6, 0x0005, 0x00d6, 0x00e6, 0x6110, - 0x2168, 0x080c, 0x5c19, 0x080c, 0x4809, 0x6018, 0x2070, 0xa006, - 0x70b2, 0x70b6, 0x080c, 0x5cd2, 0x00ee, 0x00de, 0x080c, 0x74f2, - 0x0005, 0x080c, 0x5cf4, 0x080c, 0x473b, 0x0005, 0xa182, 0x0100, - 0x0002, 0x5dfb, 0x5e16, 0x5df9, 0x5df9, 0x5df9, 0x5df9, 0x5df9, - 0x5df9, 0x5df9, 0x5df9, 0x5df9, 0x5df9, 0x5df9, 0x5df9, 0x5df9, - 0x5df9, 0x080c, 0x13fe, 0x00d6, 0x6003, 0x0003, 0x6106, 0x6010, - 0x2068, 0x687c, 0x680a, 0x6880, 0x680e, 0x6813, 0x0000, 0x6817, - 0x0000, 0x00de, 0x2c10, 0x080c, 0x1c88, 0x080c, 0x605b, 0x0126, - 0x2091, 0x8000, 0x080c, 0x651c, 0x012e, 0x0005, 0x6003, 0x0004, - 0x630a, 0x080c, 0x5b65, 0x0168, 0x6012, 0x600f, 0x0000, 0x080c, - 0x5ccd, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x16c6, - 0x0005, 0x2011, 0x0000, 0x080c, 0x16c6, 0x70b3, 0x0000, 0x70b7, - 0x0000, 0x080c, 0x74f2, 0x0005, 0x00d6, 0x080c, 0x641b, 0x080c, - 0x651c, 0x6110, 0x2168, 0x684b, 0x0000, 0x00d6, 0x6018, 0x2068, - 0x6008, 0x68b6, 0x68bb, 0x0500, 0xa006, 0x68b2, 0x00de, 0x080c, - 0x4809, 0x080c, 0x74f2, 0x00de, 0x0005, 0x6000, 0xa08a, 0x0010, - 0x1a0c, 0x13fe, 0x000b, 0x0005, 0x5e64, 0x5e64, 0x5e64, 0x5e66, - 0x5e7f, 0x5e64, 0x5e64, 0x5e64, 0x5e64, 0x5e64, 0x5e64, 0x5e64, - 0x5e64, 0x5e64, 0x5e64, 0x5e64, 0x080c, 0x13fe, 0x080c, 0x7366, - 0x190c, 0x13fe, 0x6110, 0x2168, 0x684b, 0x0006, 0x00d6, 0x6018, - 0x2068, 0x6008, 0x68b6, 0x68bb, 0x0500, 0xa006, 0x68b2, 0x00de, - 0x080c, 0x4809, 0x080c, 0x74f2, 0x00de, 0x0005, 0x0005, 0x0005, - 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x13fe, 0x000b, 0x0005, 0x5e97, - 0x5e97, 0x5e97, 0x5e99, 0x5e9b, 0x5e97, 0x5e97, 0x5e97, 0x5e97, - 0x5e97, 0x5e97, 0x5e97, 0x5e97, 0x5e97, 0x5e97, 0x5e97, 0x080c, - 0x13fe, 0x080c, 0x13fe, 0x00d6, 0x6010, 0x2068, 0x080c, 0x5cf4, - 0x00de, 0x0005, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, - 0x1208, 0xa200, 0x1f04, 0x5ea6, 0x8086, 0x818e, 0x0005, 0x0156, - 0x20a9, 0x0010, 0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213, 0x818d, - 0x0228, 0xa11a, 0x1220, 0x1f04, 0x5eb6, 0x0028, 0xa11a, 0x2308, - 0x8210, 0x1f04, 0x5eb6, 0x0006, 0x3200, 0xa084, 0xefff, 0x2080, - 0x000e, 0x015e, 0x0005, 0x0006, 0x3200, 0xa085, 0x1000, 0x0cb8, - 0x0126, 0x2091, 0x2400, 0x2079, 0x94e5, 0x012e, 0x00d6, 0x2069, - 0x94e5, 0x6803, 0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, - 0x206a, 0x00de, 0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0xa084, - 0x0007, 0x0002, 0x5ef4, 0x5f15, 0x5f68, 0x5efa, 0x5f15, 0x5ef4, - 0x5ef2, 0x5ef2, 0x080c, 0x13fe, 0x080c, 0x57a1, 0x080c, 0x6462, - 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, - 0x40af, 0x080c, 0x5731, 0x7828, 0xa092, 0x0002, 0x1228, 0x8000, - 0x782a, 0x080c, 0x40fc, 0x0c88, 0x080c, 0x40af, 0x7807, 0x0003, - 0x7827, 0x0000, 0x782b, 0x0000, 0x0c40, 0x080c, 0x57a1, 0x3c00, - 0x0006, 0x2011, 0x0209, 0x20e1, 0x4000, 0x2214, 0x000e, 0x20e0, - 0x82ff, 0x0178, 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, - 0xa065, 0x090c, 0x13fe, 0x2009, 0x0013, 0x080c, 0x7518, 0x00ce, - 0x0005, 0x3900, 0xa082, 0x9606, 0x1210, 0x080c, 0x7432, 0x00c6, - 0x7824, 0xa065, 0x090c, 0x13fe, 0x7804, 0xa086, 0x0004, 0x0904, - 0x5fa8, 0x7828, 0xa092, 0x2710, 0x1230, 0x8000, 0x782a, 0x00ce, - 0x080c, 0x6f11, 0x0c20, 0x6104, 0xa186, 0x0003, 0x1188, 0x00e6, - 0x2071, 0x9200, 0x70d4, 0x00ee, 0xd08c, 0x0150, 0x00c6, 0x00e6, - 0x2061, 0x0100, 0x2071, 0x9200, 0x080c, 0x4105, 0x00ee, 0x00ce, - 0x080c, 0x91a0, 0x2009, 0x0014, 0x080c, 0x7518, 0x00ce, 0x0838, - 0x2001, 0x9501, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b, - 0x0000, 0x7824, 0xa065, 0x090c, 0x13fe, 0x2009, 0x0013, 0x080c, - 0x7563, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x3900, 0xa082, 0x9606, - 0x1210, 0x080c, 0x7432, 0x7824, 0xa005, 0x090c, 0x13fe, 0x781c, - 0xa06d, 0x090c, 0x13fe, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, - 0x080c, 0x74f2, 0x693c, 0x81ff, 0x090c, 0x13fe, 0x8109, 0x693e, - 0x6854, 0xa015, 0x0110, 0x7a1e, 0x0010, 0x7918, 0x791e, 0x7807, - 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce, 0x080c, 0x6462, 0x0888, - 0x6104, 0xa186, 0x0002, 0x0128, 0xa186, 0x0004, 0x0110, 0x0804, - 0x5f41, 0x7808, 0xac06, 0x0904, 0x5f41, 0x080c, 0x6389, 0x080c, - 0x603e, 0x00ce, 0x080c, 0x6462, 0x0804, 0x5f2f, 0x00c6, 0x6027, - 0x0002, 0x62c8, 0x60c4, 0xa205, 0x11a0, 0x793c, 0xa1e5, 0x0000, - 0x0150, 0x2009, 0x0049, 0x601c, 0xa086, 0x0009, 0x1110, 0x2009, - 0x0103, 0x080c, 0x7518, 0x2011, 0x9504, 0x2013, 0x0000, 0x00ce, - 0x0005, 0x3908, 0xa192, 0x9606, 0x1210, 0x080c, 0x7432, 0x6017, - 0x0010, 0x793c, 0x81ff, 0x0d78, 0x793c, 0xa188, 0x0007, 0x210c, - 0xa18e, 0x0006, 0x1118, 0x6017, 0x0012, 0x0c48, 0x793c, 0xa188, - 0x0007, 0x210c, 0xa18e, 0x0009, 0x0db0, 0x6017, 0x0016, 0x08f8, - 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, - 0x2c08, 0x2061, 0x94e5, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005, - 0x0148, 0xa080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e, - 0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, 0x94e5, - 0x6000, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0xa086, 0x0001, - 0x1110, 0x2c00, 0x681e, 0x6804, 0xa084, 0x0007, 0x0804, 0x646f, - 0xc0d5, 0x6002, 0x6818, 0xa005, 0x0158, 0x6056, 0x605b, 0x0000, - 0x0006, 0x2c00, 0x681a, 0x00de, 0x685a, 0x2069, 0x94e5, 0x0c18, - 0x6056, 0x605a, 0x2c00, 0x681a, 0x681e, 0x08e8, 0x0006, 0x0016, - 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, - 0x94e5, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0148, 0xa080, - 0x0003, 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, - 0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061, - 0x94e5, 0x6034, 0xa005, 0x0130, 0xa080, 0x0003, 0x2102, 0x6136, - 0x00ce, 0x0005, 0x613a, 0x6136, 0x0cd8, 0x00f6, 0x00e6, 0x00d6, - 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x0126, 0x2071, 0x94e5, - 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x60cb, - 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, 0x60c6, 0x88ff, - 0x0118, 0x6020, 0xa106, 0x15d0, 0x703c, 0xac06, 0x1120, 0x6003, - 0x000a, 0x630a, 0x0498, 0x7038, 0xac36, 0x1110, 0x660c, 0x763a, - 0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036, - 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, - 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0x82ee, 0x0188, - 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x11f8, 0x6837, 0x0103, - 0x6b4a, 0x6847, 0x0000, 0x080c, 0x8527, 0x080c, 0x4809, 0x080c, - 0x848f, 0x080c, 0x849b, 0x00ce, 0x0804, 0x607d, 0x2c78, 0x600c, - 0x2060, 0x0804, 0x607d, 0x012e, 0x000e, 0x001e, 0x002e, 0x006e, - 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, - 0x19e8, 0x080c, 0x9097, 0x0c28, 0x0006, 0x0066, 0x00c6, 0x00d6, - 0x00f6, 0x2031, 0x0000, 0x0126, 0x2091, 0x8000, 0x2079, 0x94e5, - 0x7838, 0xa065, 0x0510, 0x600c, 0x0006, 0x600f, 0x0000, 0x783c, - 0xac06, 0x1128, 0x6003, 0x000a, 0x630a, 0x2c30, 0x00a0, 0x080c, - 0x82ee, 0x0178, 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x11b0, - 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x4809, 0x080c, - 0x848f, 0x080c, 0x849b, 0x000e, 0x08e0, 0x7e3a, 0x7e36, 0x012e, + 0x00f6, 0x7000, 0xa084, 0xf000, 0xa086, 0xc000, 0x0598, 0x080c, + 0x6cc2, 0x0580, 0x00c6, 0x0046, 0x2011, 0x9083, 0x2204, 0x8211, + 0x220c, 0x080c, 0x22e9, 0x1568, 0x080c, 0x42d6, 0x1550, 0x6612, + 0x6516, 0x2c00, 0x004e, 0x00ce, 0x601a, 0x080c, 0x1488, 0x01f0, + 0x2d00, 0x6026, 0x6803, 0x0000, 0x6837, 0x0000, 0x6c3a, 0xadf8, + 0x000f, 0x20a9, 0x000e, 0x2fa0, 0x2e98, 0x53a3, 0x6013, 0x0205, + 0x6007, 0x003e, 0x601f, 0x0001, 0x6003, 0x0001, 0x080c, 0x58e2, + 0x080c, 0x5d10, 0x00fe, 0x00de, 0x00ce, 0x0005, 0x080c, 0x6d18, + 0x0cc8, 0x004e, 0x00ce, 0x0cd0, 0x2071, 0x8dbd, 0x7003, 0x0003, + 0x700f, 0x0361, 0xa006, 0x701a, 0x7012, 0x7017, 0x9200, 0x7007, + 0x0000, 0x7026, 0x702b, 0x6704, 0x7032, 0x7037, 0x6745, 0x703b, + 0xffff, 0x703f, 0xffff, 0x0005, 0x2071, 0x8dbd, 0x1d04, 0x55fc, + 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1120, 0x700f, 0x0361, + 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x7024, 0xa00d, 0x0158, + 0x7020, 0x8001, 0x7022, 0x1138, 0x7023, 0x0009, 0x8109, 0x7126, + 0x1110, 0x7028, 0x080f, 0x7030, 0xa00d, 0x0158, 0x702c, 0x8001, + 0x702e, 0x1138, 0x702f, 0x0009, 0x8109, 0x7132, 0x1110, 0x7034, + 0x080f, 0x7038, 0xa005, 0x0118, 0x0310, 0x8001, 0x703a, 0x703c, + 0xa005, 0x0118, 0x0310, 0x8001, 0x703e, 0x7018, 0xa00d, 0x0158, + 0x7008, 0x8001, 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, + 0x1110, 0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x5622, 0x5623, + 0x563b, 0x00e6, 0x2071, 0x8dbd, 0x7018, 0xa005, 0x1120, 0x711a, + 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, + 0x8dbd, 0x701c, 0xa206, 0x1110, 0x701a, 0x701e, 0x000e, 0x00ee, + 0x0005, 0x00e6, 0x2071, 0x8dbd, 0x6088, 0xa102, 0x0208, 0x618a, + 0x00ee, 0x0005, 0x0005, 0x7110, 0x080c, 0x430a, 0x1158, 0x6088, + 0x8001, 0x0240, 0x608a, 0x1130, 0x0126, 0x2091, 0x8000, 0x080c, + 0x5d10, 0x012e, 0x8108, 0xa182, 0x00ff, 0x0218, 0xa00e, 0x7007, + 0x0002, 0x7112, 0x0005, 0x7014, 0x2060, 0x0126, 0x2091, 0x8000, + 0x6014, 0xa005, 0x0500, 0x8001, 0x6016, 0x11e8, 0x611c, 0xa186, + 0x0003, 0x0118, 0xa186, 0x0006, 0x11a0, 0x6010, 0x2068, 0x6854, + 0xa08a, 0x199a, 0x0270, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a, + 0x0210, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, + 0x0010, 0x080c, 0x79ec, 0x012e, 0xac88, 0x000c, 0x7116, 0x2001, + 0x8b17, 0x2004, 0xa102, 0x0220, 0x7017, 0x9200, 0x7007, 0x0000, + 0x0005, 0x00e6, 0x2071, 0x8dbd, 0x7027, 0x07d0, 0x7023, 0x0009, + 0x00ee, 0x0005, 0x2001, 0x8dc6, 0x2003, 0x0000, 0x0005, 0x00e6, + 0x2071, 0x8dbd, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, + 0x8dc9, 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x8dbd, 0x711a, + 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00c6, 0x2061, 0x8e2a, + 0x00ce, 0x0005, 0xa184, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, + 0x8e2a, 0x2060, 0x0005, 0x6854, 0xa08a, 0x199a, 0x0210, 0x2001, + 0x1999, 0xa005, 0x1150, 0x00c6, 0x2061, 0x8e2a, 0x6014, 0x00ce, + 0xa005, 0x1138, 0x2001, 0x001e, 0x0020, 0xa08e, 0xffff, 0x1108, + 0xa006, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c, + 0x00c0, 0xa18e, 0x00c0, 0x0588, 0xd0b4, 0x1138, 0xd0bc, 0x11f0, + 0x2009, 0x0006, 0x080c, 0x5711, 0x0005, 0xd0fc, 0x0140, 0xa084, + 0x0003, 0xa08e, 0x0003, 0x05b8, 0xa08e, 0x0000, 0x15a0, 0x2009, + 0x8b73, 0x2104, 0xd084, 0x0128, 0x2009, 0x0042, 0x080c, 0x6d3f, + 0x0005, 0x2009, 0x0043, 0x080c, 0x6d3f, 0x0005, 0xd0fc, 0x0140, + 0xa084, 0x0003, 0xa08e, 0x0003, 0x01f0, 0xa08e, 0x0000, 0x11d8, + 0x2009, 0x0042, 0x080c, 0x6d3f, 0x0005, 0xd0fc, 0x0168, 0xa084, + 0x0003, 0xa08e, 0x0003, 0x0178, 0xa08e, 0x0002, 0x0138, 0x2009, + 0x0041, 0x080c, 0x6d3f, 0x0005, 0x0051, 0x0ce8, 0x2009, 0x0043, + 0x080c, 0x6d3f, 0x0cc0, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009, + 0x0001, 0x6010, 0xa0ec, 0xf000, 0x01f0, 0x2068, 0x6952, 0x6800, + 0x6012, 0xa186, 0x0001, 0x1188, 0x694c, 0xa18c, 0x8100, 0xa18e, + 0x8100, 0x1158, 0x00c6, 0x2061, 0x8e2a, 0x6200, 0xd28c, 0x1120, + 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x46a1, 0x6010, + 0xa06d, 0x190c, 0x56a3, 0x0005, 0x0156, 0x00c6, 0x2061, 0x8e2a, + 0x6000, 0x81ff, 0x0110, 0xa205, 0x0008, 0xa204, 0x6002, 0x00ce, + 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, 0xa005, 0x0120, + 0x8001, 0x680a, 0xa085, 0x0001, 0x0005, 0x20a9, 0x0010, 0xa006, + 0x8004, 0x8086, 0x818e, 0x1208, 0xa200, 0x1f04, 0x5751, 0x8086, + 0x818e, 0x0005, 0x0156, 0x20a9, 0x0010, 0xa005, 0x01b8, 0xa11a, + 0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a, 0x1220, 0x1f04, 0x5761, + 0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04, 0x5761, 0x0006, 0x3200, + 0xa084, 0xefff, 0x2080, 0x000e, 0x015e, 0x0005, 0x0006, 0x3200, + 0xa085, 0x1000, 0x0cb8, 0x0126, 0x2091, 0x2400, 0x2079, 0x8daa, + 0x012e, 0x00d6, 0x2069, 0x8daa, 0x6803, 0x0005, 0x2069, 0x0004, + 0x2d04, 0xa085, 0x8001, 0x206a, 0x00de, 0x0005, 0x00c6, 0x6027, + 0x0001, 0x7804, 0xa084, 0x0007, 0x0002, 0x579f, 0x57c0, 0x5813, + 0x57a5, 0x57c0, 0x579f, 0x579d, 0x579d, 0x080c, 0x1410, 0x080c, + 0x567a, 0x080c, 0x5d10, 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110, + 0x00ce, 0x0005, 0x2011, 0x3fe7, 0x080c, 0x560d, 0x7828, 0xa092, + 0x0002, 0x1228, 0x8000, 0x782a, 0x080c, 0x4034, 0x0c88, 0x080c, + 0x3fe7, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0c40, + 0x080c, 0x567a, 0x3c00, 0x0006, 0x2011, 0x0209, 0x20e1, 0x4000, + 0x2214, 0x000e, 0x20e0, 0x82ff, 0x0178, 0x62c0, 0x82ff, 0x1160, + 0x782b, 0x0000, 0x7824, 0xa065, 0x090c, 0x1410, 0x2009, 0x0013, + 0x080c, 0x6d3f, 0x00ce, 0x0005, 0x3900, 0xa082, 0x8eca, 0x1210, + 0x080c, 0x6c01, 0x00c6, 0x7824, 0xa065, 0x090c, 0x1410, 0x7804, + 0xa086, 0x0004, 0x0904, 0x5853, 0x7828, 0xa092, 0x2710, 0x1230, + 0x8000, 0x782a, 0x00ce, 0x080c, 0x66ea, 0x0c20, 0x6104, 0xa186, + 0x0003, 0x1188, 0x00e6, 0x2071, 0x8b00, 0x70d4, 0x00ee, 0xd08c, + 0x0150, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x8b00, 0x080c, + 0x403d, 0x00ee, 0x00ce, 0x080c, 0x8a4b, 0x2009, 0x0014, 0x080c, + 0x6d3f, 0x00ce, 0x0838, 0x2001, 0x8dc6, 0x2003, 0x0000, 0x62c0, + 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, 0xa065, 0x090c, 0x1410, + 0x2009, 0x0013, 0x080c, 0x6d92, 0x00ce, 0x0005, 0x00c6, 0x00d6, + 0x3900, 0xa082, 0x8eca, 0x1210, 0x080c, 0x6c01, 0x7824, 0xa005, + 0x090c, 0x1410, 0x781c, 0xa06d, 0x090c, 0x1410, 0x6800, 0xc0dc, + 0x6802, 0x7924, 0x2160, 0x080c, 0x6d18, 0x693c, 0x81ff, 0x090c, + 0x1410, 0x8109, 0x693e, 0x6854, 0xa015, 0x0110, 0x7a1e, 0x0010, + 0x7918, 0x791e, 0x7807, 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce, + 0x080c, 0x5d10, 0x0888, 0x6104, 0xa186, 0x0002, 0x0128, 0xa186, + 0x0004, 0x0110, 0x0804, 0x57ec, 0x7808, 0xac06, 0x0904, 0x57ec, + 0x080c, 0x5c37, 0x080c, 0x58e2, 0x00ce, 0x080c, 0x5d10, 0x0804, + 0x57da, 0x00c6, 0x6027, 0x0002, 0x62c8, 0x60c4, 0xa205, 0x1170, + 0x793c, 0xa1e5, 0x0000, 0x0120, 0x2009, 0x0049, 0x080c, 0x6d3f, + 0x2011, 0x8dc9, 0x2013, 0x0000, 0x00ce, 0x0005, 0x3908, 0xa192, + 0x8eca, 0x1210, 0x080c, 0x6c01, 0x793c, 0x81ff, 0x0d88, 0x793c, + 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x1138, 0x6014, 0xa084, + 0x0184, 0xa085, 0x0012, 0x6016, 0x0c38, 0x6014, 0xa084, 0x0184, + 0xa085, 0x0016, 0x6016, 0x0c00, 0x0006, 0x0016, 0x00c6, 0x0126, + 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0x8daa, 0x6020, + 0x8000, 0x6022, 0x6010, 0xa005, 0x0148, 0xa080, 0x0003, 0x2102, + 0x6112, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x6116, 0x6112, + 0x0cc0, 0x00d6, 0x2069, 0x8daa, 0x6000, 0xd0d4, 0x0168, 0x6820, + 0x8000, 0x6822, 0xa086, 0x0001, 0x1110, 0x2c00, 0x681e, 0x6804, + 0xa084, 0x0007, 0x0804, 0x5d16, 0xc0d5, 0x6002, 0x6818, 0xa005, + 0x0158, 0x6056, 0x605b, 0x0000, 0x0006, 0x2c00, 0x681a, 0x00de, + 0x685a, 0x2069, 0x8daa, 0x0c18, 0x6056, 0x605a, 0x2c00, 0x681a, + 0x681e, 0x08e8, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, + 0x600f, 0x0000, 0x2c08, 0x2061, 0x8daa, 0x6020, 0x8000, 0x6022, + 0x6008, 0xa005, 0x0148, 0xa080, 0x0003, 0x2102, 0x610a, 0x012e, + 0x00ce, 0x001e, 0x000e, 0x0005, 0x610e, 0x610a, 0x0cc0, 0x00c6, + 0x600f, 0x0000, 0x2c08, 0x2061, 0x8daa, 0x6034, 0xa005, 0x0130, + 0xa080, 0x0003, 0x2102, 0x6136, 0x00ce, 0x0005, 0x613a, 0x6136, + 0x0cd8, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, + 0x0006, 0x0126, 0x2071, 0x8daa, 0x7638, 0x2660, 0x2678, 0x2091, + 0x8000, 0x8cff, 0x0904, 0x597a, 0x6018, 0xa080, 0x0028, 0x2004, + 0xa206, 0x1904, 0x5975, 0x88ff, 0x0120, 0x6020, 0xa106, 0x1904, + 0x5975, 0x703c, 0xac06, 0x1170, 0x0036, 0x2019, 0x0001, 0x080c, + 0x68e5, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047, + 0x0000, 0x003e, 0x7038, 0xac36, 0x1110, 0x660c, 0x763a, 0x7034, + 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, + 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, + 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0x7b8f, 0x0188, 0x6010, + 0x2068, 0x601c, 0xa086, 0x0003, 0x11f8, 0x6837, 0x0103, 0x6b4a, + 0x6847, 0x0000, 0x080c, 0x7dc8, 0x080c, 0x46a1, 0x080c, 0x7d30, + 0x080c, 0x7d3c, 0x00ce, 0x0804, 0x5921, 0x2c78, 0x600c, 0x2060, + 0x0804, 0x5921, 0x012e, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x19e8, + 0x080c, 0x8942, 0x0c28, 0x0006, 0x0066, 0x00c6, 0x00d6, 0x00f6, + 0x2031, 0x0000, 0x0126, 0x2091, 0x8000, 0x2079, 0x8daa, 0x7838, + 0xa065, 0x0558, 0x600c, 0x0006, 0x600f, 0x0000, 0x783c, 0xac06, + 0x1170, 0x0036, 0x2019, 0x0001, 0x080c, 0x68e5, 0x7833, 0x0000, + 0x783f, 0x0000, 0x7843, 0x0000, 0x7847, 0x0000, 0x003e, 0x080c, + 0x7b8f, 0x0178, 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x11b0, + 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x46a1, 0x080c, + 0x7d30, 0x080c, 0x7d3c, 0x000e, 0x0898, 0x7e3a, 0x7e36, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x601c, 0xa086, - 0x0006, 0x0150, 0x601c, 0xa086, 0x0009, 0x1d10, 0x6b4a, 0x080c, - 0x4809, 0x080c, 0x74f2, 0x0c38, 0x080c, 0x9097, 0x0c10, 0x0016, - 0x0026, 0x0086, 0x2041, 0x0000, 0x0099, 0x080c, 0x61d3, 0x008e, - 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0x94e5, 0x2091, - 0x8000, 0x080c, 0x625e, 0x080c, 0x62be, 0x012e, 0x00fe, 0x0005, - 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, - 0x2091, 0x8000, 0x2071, 0x94e5, 0x7614, 0x2660, 0x2678, 0x8cff, - 0x0904, 0x61c3, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, - 0x61be, 0x88ff, 0x0120, 0x6020, 0xa106, 0x1904, 0x61be, 0x7024, - 0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, - 0x57a1, 0x080c, 0x6f1e, 0x68c3, 0x0000, 0x080c, 0x7356, 0x7027, - 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, - 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, - 0x0110, 0x6827, 0x0001, 0x003e, 0x0020, 0x6003, 0x0009, 0x630a, - 0x04a8, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, 0x7010, 0xac36, - 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, - 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, - 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c, 0x82ee, 0x0178, - 0x601c, 0xa086, 0x0003, 0x1500, 0x6837, 0x0103, 0x6b4a, 0x6847, - 0x0000, 0x080c, 0x8527, 0x080c, 0x4809, 0x080c, 0x848f, 0x080c, - 0x849b, 0x080c, 0x7238, 0x00ce, 0x0804, 0x614f, 0x2c78, 0x600c, - 0x2060, 0x0804, 0x614f, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, - 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x19e0, - 0x080c, 0x9097, 0x0c20, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, - 0xa280, 0x936e, 0x2004, 0xa065, 0x0904, 0x625a, 0x00f6, 0x00e6, - 0x00d6, 0x0066, 0x2071, 0x94e5, 0x6654, 0x7018, 0xac06, 0x1108, - 0x761a, 0x701c, 0xac06, 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, - 0x0008, 0x761e, 0x6058, 0xa07d, 0x0108, 0x7e56, 0xa6ed, 0x0000, - 0x0110, 0x2f00, 0x685a, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, - 0xc0d4, 0xc0dc, 0x6002, 0x080c, 0x43ba, 0x0904, 0x6256, 0x7624, - 0x86ff, 0x05e8, 0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, - 0x2069, 0x0100, 0x68c0, 0xa005, 0x0548, 0x080c, 0x57a1, 0x080c, - 0x6f1e, 0x68c3, 0x0000, 0x080c, 0x7356, 0x7027, 0x0000, 0x0036, + 0x0006, 0x1d30, 0x080c, 0x8942, 0x0c60, 0x0016, 0x0026, 0x0086, + 0x2041, 0x0000, 0x0099, 0x080c, 0x5a81, 0x008e, 0x002e, 0x001e, + 0x0005, 0x00f6, 0x0126, 0x2079, 0x8daa, 0x2091, 0x8000, 0x080c, + 0x5b0c, 0x080c, 0x5b6c, 0x012e, 0x00fe, 0x0005, 0x00f6, 0x00e6, + 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, + 0x2071, 0x8daa, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x5a71, + 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, 0x5a6c, 0x88ff, + 0x0120, 0x6020, 0xa106, 0x1904, 0x5a6c, 0x7024, 0xac06, 0x1538, + 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, 0x567a, 0x080c, + 0x66f7, 0x68c3, 0x0000, 0x080c, 0x6b23, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, - 0x0001, 0x003e, 0x00de, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, - 0x603e, 0x2660, 0x080c, 0x849b, 0x00ce, 0x0048, 0x00de, 0x00c6, - 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x6203, 0x8dff, - 0x0148, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x8527, - 0x080c, 0x4809, 0x080c, 0x7238, 0x0804, 0x6203, 0x006e, 0x00de, - 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce, 0x0005, 0x0006, 0x0066, - 0x00c6, 0x00d6, 0x2031, 0x0000, 0x7814, 0xa065, 0x0904, 0x62b0, - 0x600c, 0x0006, 0x600f, 0x0000, 0x7824, 0xac06, 0x1540, 0x2069, - 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, 0x57a1, 0x080c, 0x6f1e, - 0x68c3, 0x0000, 0x080c, 0x7356, 0x7827, 0x0000, 0x0036, 0x2069, - 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, - 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, - 0x003e, 0x0028, 0x6003, 0x0009, 0x630a, 0x2c30, 0x00b0, 0x6010, - 0x2068, 0x080c, 0x82ee, 0x0168, 0x601c, 0xa086, 0x0003, 0x11b8, - 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x4809, 0x080c, - 0x848f, 0x080c, 0x849b, 0x080c, 0x7238, 0x000e, 0x0804, 0x6265, - 0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x601c, - 0xa086, 0x0006, 0x1d28, 0x080c, 0x9097, 0x0c58, 0x0006, 0x0066, - 0x00c6, 0x00d6, 0x7818, 0xa065, 0x0904, 0x6324, 0x6054, 0x0006, - 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, - 0x080c, 0x43ba, 0x0904, 0x6321, 0x7e24, 0x86ff, 0x05e8, 0xa680, - 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069, 0x0100, 0x68c0, - 0xa005, 0x0548, 0x080c, 0x57a1, 0x080c, 0x6f1e, 0x68c3, 0x0000, - 0x080c, 0x7356, 0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, + 0x0001, 0x003e, 0x0020, 0x6003, 0x0009, 0x630a, 0x04a8, 0x7014, + 0xac36, 0x1110, 0x660c, 0x7616, 0x7010, 0xac36, 0x1140, 0x2c00, + 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, + 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, + 0x0000, 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0178, 0x601c, 0xa086, + 0x0003, 0x1500, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, + 0x7dc8, 0x080c, 0x46a1, 0x080c, 0x7d30, 0x080c, 0x7d3c, 0x080c, + 0x6a05, 0x00ce, 0x0804, 0x59fd, 0x2c78, 0x600c, 0x2060, 0x0804, + 0x59fd, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee, + 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x19e0, 0x080c, 0x8942, + 0x0c20, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0xa280, 0x8c34, + 0x2004, 0xa065, 0x0904, 0x5b08, 0x00f6, 0x00e6, 0x00d6, 0x0066, + 0x2071, 0x8daa, 0x6654, 0x7018, 0xac06, 0x1108, 0x761a, 0x701c, + 0xac06, 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e, + 0x6058, 0xa07d, 0x0108, 0x7e56, 0xa6ed, 0x0000, 0x0110, 0x2f00, + 0x685a, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, + 0x6002, 0x080c, 0x4290, 0x0904, 0x5b04, 0x7624, 0x86ff, 0x05e8, + 0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069, 0x0100, + 0x68c0, 0xa005, 0x0548, 0x080c, 0x567a, 0x080c, 0x66f7, 0x68c3, + 0x0000, 0x080c, 0x6b23, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, + 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, + 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, + 0x00de, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e, 0x2660, + 0x080c, 0x7d3c, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, + 0x0009, 0x630a, 0x00ce, 0x0804, 0x5ab1, 0x8dff, 0x0148, 0x6837, + 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x7dc8, 0x080c, 0x46a1, + 0x080c, 0x6a05, 0x0804, 0x5ab1, 0x006e, 0x00de, 0x00ee, 0x00fe, + 0x012e, 0x000e, 0x00ce, 0x0005, 0x0006, 0x0066, 0x00c6, 0x00d6, + 0x2031, 0x0000, 0x7814, 0xa065, 0x0904, 0x5b5e, 0x600c, 0x0006, + 0x600f, 0x0000, 0x7824, 0xac06, 0x1540, 0x2069, 0x0100, 0x68c0, + 0xa005, 0x01f0, 0x080c, 0x567a, 0x080c, 0x66f7, 0x68c3, 0x0000, + 0x080c, 0x6b23, 0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, - 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, + 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, + 0x6003, 0x0009, 0x630a, 0x2c30, 0x00b0, 0x6010, 0x2068, 0x080c, + 0x7b8f, 0x0168, 0x601c, 0xa086, 0x0003, 0x11b8, 0x6837, 0x0103, + 0x6b4a, 0x6847, 0x0000, 0x080c, 0x46a1, 0x080c, 0x7d30, 0x080c, + 0x7d3c, 0x080c, 0x6a05, 0x000e, 0x0804, 0x5b13, 0x7e16, 0x7e12, + 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x601c, 0xa086, 0x0006, + 0x1d28, 0x080c, 0x8942, 0x0c58, 0x0006, 0x0066, 0x00c6, 0x00d6, + 0x7818, 0xa065, 0x0904, 0x5bd2, 0x6054, 0x0006, 0x6057, 0x0000, + 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x080c, 0x4290, + 0x0904, 0x5bcf, 0x7e24, 0x86ff, 0x05e8, 0xa680, 0x0004, 0x2004, + 0xad06, 0x15c0, 0x00d6, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0548, + 0x080c, 0x567a, 0x080c, 0x66f7, 0x68c3, 0x0000, 0x080c, 0x6b23, + 0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, + 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, + 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x603c, + 0xa005, 0x0110, 0x8001, 0x603e, 0x2660, 0x080c, 0x7d3c, 0x00ce, + 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, + 0x0804, 0x5b7e, 0x8dff, 0x0138, 0x6837, 0x0103, 0x6b4a, 0x6847, + 0x0000, 0x080c, 0x46a1, 0x080c, 0x6a05, 0x0804, 0x5b7e, 0x000e, + 0x0804, 0x5b71, 0x781e, 0x781a, 0x00de, 0x00ce, 0x006e, 0x000e, + 0x0005, 0x00e6, 0x00d6, 0x0066, 0x6000, 0xd0dc, 0x0188, 0x604c, + 0xa06d, 0x0170, 0x6848, 0xa606, 0x1158, 0x2071, 0x8daa, 0x7024, + 0xa035, 0x0130, 0xa080, 0x0004, 0x2004, 0xad06, 0x1108, 0x0021, + 0x006e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079, 0x0100, 0x78c0, + 0xa005, 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, + 0x04a0, 0x080c, 0x66f7, 0x78c3, 0x0000, 0x080c, 0x6b23, 0x7027, + 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0xa384, 0x1000, 0x0120, + 0x7803, 0x0100, 0x7803, 0x0000, 0x2079, 0x0100, 0x7824, 0xd084, + 0x0110, 0x7827, 0x0001, 0x080c, 0x6b23, 0x003e, 0x080c, 0x4290, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e, 0x2660, 0x080c, - 0x849b, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, - 0x630a, 0x00ce, 0x0804, 0x62d0, 0x8dff, 0x0138, 0x6837, 0x0103, - 0x6b4a, 0x6847, 0x0000, 0x080c, 0x4809, 0x080c, 0x7238, 0x0804, - 0x62d0, 0x000e, 0x0804, 0x62c3, 0x781e, 0x781a, 0x00de, 0x00ce, - 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0066, 0x6000, 0xd0dc, - 0x0188, 0x604c, 0xa06d, 0x0170, 0x6848, 0xa606, 0x1158, 0x2071, - 0x94e5, 0x7024, 0xa035, 0x0130, 0xa080, 0x0004, 0x2004, 0xad06, - 0x1108, 0x0021, 0x006e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079, - 0x0100, 0x78c0, 0xa005, 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009, - 0x630a, 0x00ce, 0x04a0, 0x080c, 0x6f1e, 0x78c3, 0x0000, 0x080c, - 0x7356, 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0xa384, - 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, 0x2079, 0x0100, - 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c, 0x7356, 0x003e, - 0x080c, 0x43ba, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e, - 0x2660, 0x080c, 0x74f2, 0x00ce, 0x6837, 0x0103, 0x6b4a, 0x6847, - 0x0000, 0x080c, 0x8527, 0x080c, 0x4809, 0x080c, 0x7238, 0x00fe, - 0x0005, 0x00e6, 0x00c6, 0x2071, 0x94e5, 0x7004, 0xa084, 0x0007, - 0x0002, 0x639b, 0x639e, 0x63b4, 0x63cd, 0x6406, 0x639b, 0x6399, - 0x6399, 0x080c, 0x13fe, 0x00ce, 0x00ee, 0x0005, 0x7024, 0xa065, - 0x0148, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015, 0x0150, 0x7216, - 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, - 0x0005, 0x7216, 0x7212, 0x0cb0, 0x6018, 0x2060, 0x080c, 0x43ba, - 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022, 0x0120, 0x6054, - 0xa015, 0x0140, 0x721e, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, - 0x00ee, 0x0005, 0x7218, 0x721e, 0x0cb0, 0x7024, 0xa065, 0x0598, - 0x700c, 0xac06, 0x1160, 0x080c, 0x7238, 0x600c, 0xa015, 0x0120, - 0x720e, 0x600f, 0x0000, 0x0428, 0x720e, 0x720a, 0x0410, 0x7014, - 0xac06, 0x1160, 0x080c, 0x7238, 0x600c, 0xa015, 0x0120, 0x7216, - 0x600f, 0x0000, 0x00b0, 0x7216, 0x7212, 0x0098, 0x6018, 0x2060, - 0x080c, 0x43ba, 0x6000, 0xc0dc, 0x6002, 0x080c, 0x7238, 0x701c, - 0xa065, 0x0138, 0x6054, 0xa015, 0x0110, 0x721e, 0x0010, 0x7218, - 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005, 0x7024, 0xa065, - 0x0140, 0x080c, 0x7238, 0x600c, 0xa015, 0x0150, 0x720e, 0x600f, - 0x0000, 0x080c, 0x7356, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005, - 0x720e, 0x720a, 0x0cb0, 0x00d6, 0x2069, 0x94e5, 0x6830, 0xa084, - 0x0003, 0x0002, 0x6428, 0x642a, 0x644a, 0x6426, 0x080c, 0x13fe, - 0x00de, 0x0005, 0x00c6, 0x6840, 0xa086, 0x0001, 0x0198, 0x683c, - 0xa065, 0x0130, 0x600c, 0xa015, 0x0150, 0x6a3a, 0x600f, 0x0000, - 0x6833, 0x0000, 0x683f, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, - 0x6836, 0x0cb0, 0x6843, 0x0000, 0x6838, 0xa065, 0x0d88, 0x6003, - 0x0003, 0x0c70, 0x00c6, 0x6843, 0x0000, 0x6847, 0x0000, 0x683c, - 0xa065, 0x0168, 0x600c, 0xa015, 0x0130, 0x6a3a, 0x600f, 0x0000, - 0x683f, 0x0000, 0x0020, 0x683f, 0x0000, 0x683a, 0x6836, 0x00ce, - 0x00de, 0x0005, 0x00d6, 0x2001, 0x9295, 0x2004, 0xd084, 0x0110, - 0x00de, 0x0005, 0x2069, 0x94e5, 0x6804, 0xa084, 0x0007, 0x0002, - 0x647a, 0x650c, 0x650c, 0x650c, 0x650c, 0x650e, 0x6478, 0x6478, - 0x080c, 0x13fe, 0x6820, 0xa005, 0x1110, 0x00de, 0x0005, 0x00c6, - 0x680c, 0xa065, 0x0150, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, - 0x080c, 0x656d, 0x00ce, 0x00de, 0x0005, 0x6814, 0xa065, 0x0150, - 0x6807, 0x0001, 0x6826, 0x682b, 0x0000, 0x080c, 0x656d, 0x00ce, - 0x00de, 0x0005, 0x00e6, 0x0036, 0x6a1c, 0xa2f5, 0x0000, 0x0904, - 0x6508, 0x704c, 0xa00d, 0x0118, 0x7088, 0xa005, 0x01a0, 0x7054, - 0xa075, 0x0120, 0xa20e, 0x0904, 0x6508, 0x0028, 0x6818, 0xa20e, - 0x0904, 0x6508, 0x2070, 0x704c, 0xa00d, 0x0d88, 0x7088, 0xa005, - 0x1d70, 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, 0x1e40, 0x080c, - 0x74c9, 0x0904, 0x6508, 0x8318, 0x733e, 0x6112, 0x2e10, 0x621a, - 0xa180, 0x0015, 0x2004, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999, - 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x00f6, 0x2c78, - 0x71a0, 0x2001, 0x9232, 0x2004, 0xd0ac, 0x1110, 0xd1bc, 0x0150, - 0x7100, 0xd1f4, 0x0120, 0x7114, 0xa18c, 0x00ff, 0x0040, 0x2009, - 0x0000, 0x0028, 0xa1e0, 0x2719, 0x2c0d, 0xa18c, 0x00ff, 0x2061, - 0x0100, 0x619a, 0x080c, 0x6a46, 0x7300, 0xc3dd, 0x7302, 0x6807, - 0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000, 0x781f, 0x0003, 0x7803, - 0x0001, 0x7807, 0x0040, 0x00fe, 0x00ee, 0x00ce, 0x00de, 0x0005, - 0x003e, 0x00ee, 0x00ce, 0x0cd0, 0x00de, 0x0005, 0x00c6, 0x680c, - 0xa065, 0x0138, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, - 0x656d, 0x00ce, 0x00de, 0x0005, 0x00f6, 0x00d6, 0x2069, 0x94e5, - 0x6830, 0xa086, 0x0000, 0x1590, 0x6838, 0xa07d, 0x0578, 0x781c, - 0xa086, 0x0009, 0x1140, 0x7808, 0xd0fc, 0x0128, 0x2001, 0x94e6, - 0x2004, 0xa005, 0x1518, 0x2f00, 0x6833, 0x0001, 0x683e, 0x6847, - 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, 0x1d0f, - 0x11c0, 0x012e, 0xe000, 0xe000, 0xe000, 0x6a3c, 0x2278, 0x781c, - 0xa086, 0x0009, 0x1148, 0x7808, 0xd0fc, 0x0118, 0x080c, 0x6cf9, - 0x0028, 0x080c, 0x6d75, 0x0010, 0x080c, 0x6dec, 0x00de, 0x00fe, - 0x0005, 0x012e, 0xe000, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, - 0xa015, 0x0140, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, - 0x0000, 0x0c60, 0x683a, 0x6836, 0x0cc0, 0x601c, 0xa084, 0x000f, - 0x000b, 0x0005, 0x657b, 0x6580, 0x68f8, 0x6a03, 0x6580, 0x68f8, - 0x6a03, 0x657b, 0x6580, 0x080c, 0x6389, 0x080c, 0x6462, 0x0005, - 0x0156, 0x0136, 0x0146, 0x00c6, 0x00f6, 0x6004, 0xa08a, 0x003e, - 0x1a0c, 0x13fe, 0x6118, 0x2178, 0x79a0, 0x2011, 0x9232, 0x2214, - 0xd2ac, 0x1110, 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120, 0x7914, - 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8, 0x2719, - 0x2f0d, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0x0033, - 0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005, 0x65f5, 0x662d, - 0x6647, 0x66fa, 0x6725, 0x672d, 0x674e, 0x675f, 0x6770, 0x6778, - 0x6789, 0x6778, 0x67ce, 0x675f, 0x67ef, 0x67f7, 0x6770, 0x67f7, - 0x6808, 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x65ec, - 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x6fda, 0x6fef, 0x7012, - 0x7036, 0x674e, 0x65ec, 0x674e, 0x6778, 0x65ec, 0x6647, 0x66fa, - 0x65ec, 0x744f, 0x6778, 0x65ec, 0x746f, 0x6778, 0x65ec, 0x6770, - 0x65ee, 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x65ec, - 0x65ec, 0x65ec, 0x65ec, 0x704b, 0x080c, 0x13fe, 0x2001, 0x9214, - 0x2004, 0x609a, 0x080c, 0x6f0b, 0x0005, 0x20a1, 0x020b, 0x080c, - 0x681d, 0x20a3, 0x5200, 0x20a3, 0x0000, 0x00d6, 0x2069, 0x9251, + 0x6d18, 0x00ce, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, + 0x7dc8, 0x080c, 0x46a1, 0x080c, 0x6a05, 0x00fe, 0x0005, 0x00e6, + 0x00c6, 0x2071, 0x8daa, 0x7004, 0xa084, 0x0007, 0x0002, 0x5c49, + 0x5c4c, 0x5c62, 0x5c7b, 0x5cb4, 0x5c49, 0x5c47, 0x5c47, 0x080c, + 0x1410, 0x00ce, 0x00ee, 0x0005, 0x7024, 0xa065, 0x0148, 0x7020, + 0x8001, 0x7022, 0x600c, 0xa015, 0x0150, 0x7216, 0x600f, 0x0000, + 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005, 0x7216, + 0x7212, 0x0cb0, 0x6018, 0x2060, 0x080c, 0x4290, 0x6000, 0xc0dc, + 0x6002, 0x7020, 0x8001, 0x7022, 0x0120, 0x6054, 0xa015, 0x0140, + 0x721e, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005, + 0x7218, 0x721e, 0x0cb0, 0x7024, 0xa065, 0x0598, 0x700c, 0xac06, + 0x1160, 0x080c, 0x6a05, 0x600c, 0xa015, 0x0120, 0x720e, 0x600f, + 0x0000, 0x0428, 0x720e, 0x720a, 0x0410, 0x7014, 0xac06, 0x1160, + 0x080c, 0x6a05, 0x600c, 0xa015, 0x0120, 0x7216, 0x600f, 0x0000, + 0x00b0, 0x7216, 0x7212, 0x0098, 0x6018, 0x2060, 0x080c, 0x4290, + 0x6000, 0xc0dc, 0x6002, 0x080c, 0x6a05, 0x701c, 0xa065, 0x0138, + 0x6054, 0xa015, 0x0110, 0x721e, 0x0010, 0x7218, 0x721e, 0x7027, + 0x0000, 0x00ce, 0x00ee, 0x0005, 0x7024, 0xa065, 0x0140, 0x080c, + 0x6a05, 0x600c, 0xa015, 0x0150, 0x720e, 0x600f, 0x0000, 0x080c, + 0x6b23, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005, 0x720e, 0x720a, + 0x0cb0, 0x00d6, 0x2069, 0x8daa, 0x6830, 0xa084, 0x0003, 0x0002, + 0x5cd6, 0x5cd8, 0x5cf8, 0x5cd4, 0x080c, 0x1410, 0x00de, 0x0005, + 0x00c6, 0x6840, 0xa086, 0x0001, 0x0198, 0x683c, 0xa065, 0x0130, + 0x600c, 0xa015, 0x0150, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, + 0x683f, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, 0x6836, 0x0cb0, + 0x6843, 0x0000, 0x6838, 0xa065, 0x0d88, 0x6003, 0x0003, 0x0c70, + 0x00c6, 0x6843, 0x0000, 0x6847, 0x0000, 0x683c, 0xa065, 0x0168, + 0x600c, 0xa015, 0x0130, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000, + 0x0020, 0x683f, 0x0000, 0x683a, 0x6836, 0x00ce, 0x00de, 0x0005, + 0x00d6, 0x2069, 0x8daa, 0x6804, 0xa084, 0x0007, 0x0002, 0x5d21, + 0x5db3, 0x5db3, 0x5db3, 0x5db3, 0x5db5, 0x5d1f, 0x5d1f, 0x080c, + 0x1410, 0x6820, 0xa005, 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c, + 0xa065, 0x0150, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, + 0x5df4, 0x00ce, 0x00de, 0x0005, 0x6814, 0xa065, 0x0150, 0x6807, + 0x0001, 0x6826, 0x682b, 0x0000, 0x080c, 0x5df4, 0x00ce, 0x00de, + 0x0005, 0x00e6, 0x0036, 0x6a1c, 0xa2f5, 0x0000, 0x0904, 0x5daf, + 0x704c, 0xa00d, 0x0118, 0x7088, 0xa005, 0x01a0, 0x7054, 0xa075, + 0x0120, 0xa20e, 0x0904, 0x5daf, 0x0028, 0x6818, 0xa20e, 0x0904, + 0x5daf, 0x2070, 0x704c, 0xa00d, 0x0d88, 0x7088, 0xa005, 0x1d70, + 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, 0x1e40, 0x080c, 0x6cef, + 0x0904, 0x5daf, 0x8318, 0x733e, 0x6112, 0x2e10, 0x621a, 0xa180, + 0x0015, 0x2004, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, + 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x00f6, 0x2c78, 0x71a0, + 0x2001, 0x8b32, 0x2004, 0xd0ac, 0x1110, 0xd1bc, 0x0150, 0x7100, + 0xd1f4, 0x0120, 0x7114, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, + 0x0028, 0xa1e0, 0x263d, 0x2c0d, 0xa18c, 0x00ff, 0x2061, 0x0100, + 0x619a, 0x080c, 0x62f1, 0x7300, 0xc3dd, 0x7302, 0x6807, 0x0002, + 0x2f18, 0x6b26, 0x682b, 0x0000, 0x781f, 0x0003, 0x7803, 0x0001, + 0x7807, 0x0040, 0x00fe, 0x00ee, 0x00ce, 0x00de, 0x0005, 0x003e, + 0x00ee, 0x00ce, 0x0cd0, 0x00de, 0x0005, 0x00c6, 0x680c, 0xa065, + 0x0130, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x04a9, 0x00ce, + 0x00de, 0x0005, 0x00f6, 0x00d6, 0x2069, 0x8daa, 0x6830, 0xa086, + 0x0000, 0x1198, 0x6838, 0xa07d, 0x0180, 0x6833, 0x0001, 0x683e, + 0x6847, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, + 0x1c40, 0x1130, 0x012e, 0x080c, 0x65ca, 0x00de, 0x00fe, 0x0005, + 0x012e, 0xe000, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0xa015, + 0x0140, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, + 0x0c60, 0x683a, 0x6836, 0x0cc0, 0x601c, 0xa084, 0x000f, 0x000b, + 0x0005, 0x5e02, 0x5e07, 0x618e, 0x62ae, 0x5e07, 0x618e, 0x62ae, + 0x5e02, 0x5e07, 0x080c, 0x5c37, 0x080c, 0x5d10, 0x0005, 0x0156, + 0x0136, 0x0146, 0x00c6, 0x00f6, 0x6004, 0xa08a, 0x0040, 0x1a0c, + 0x1410, 0x6118, 0x2178, 0x79a0, 0x2011, 0x8b32, 0x2214, 0xd2ac, + 0x1110, 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c, + 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8, 0x263d, 0x2f0d, + 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0x0033, 0x00fe, + 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005, 0x5e7d, 0x5eb5, 0x5ecf, + 0x5f82, 0x5fad, 0x5fb5, 0x5fd6, 0x5fe7, 0x5ff8, 0x6000, 0x6011, + 0x6000, 0x6056, 0x5fe7, 0x6077, 0x607f, 0x5ff8, 0x607f, 0x6090, + 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74, + 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x67ad, 0x67c2, 0x67e5, 0x6809, + 0x5fd6, 0x5e74, 0x5fd6, 0x6000, 0x5e74, 0x5ecf, 0x5f82, 0x5e74, + 0x6c1e, 0x6000, 0x5e74, 0x6c3e, 0x6000, 0x5e74, 0x5ff8, 0x5e76, + 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74, + 0x5e74, 0x5e74, 0x681e, 0x6c63, 0x080c, 0x1410, 0x2001, 0x8b14, + 0x2004, 0x609a, 0x080c, 0x66e4, 0x0005, 0x20a1, 0x020b, 0x080c, + 0x60a5, 0x20a3, 0x5200, 0x20a3, 0x0000, 0x00d6, 0x2069, 0x8b51, 0x6804, 0xd084, 0x0150, 0x6828, 0x20a3, 0x0000, 0x0016, 0x080c, - 0x241f, 0x21a2, 0x001e, 0x00de, 0x0028, 0x00de, 0x20a3, 0x0000, - 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0x9205, 0x53a6, 0x20a9, - 0x0004, 0x2099, 0x9201, 0x53a6, 0x20a3, 0x0000, 0x2001, 0x9214, + 0x22fd, 0x21a2, 0x001e, 0x00de, 0x0028, 0x00de, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0x8b05, 0x53a6, 0x20a9, + 0x0004, 0x2099, 0x8b01, 0x53a6, 0x20a3, 0x0000, 0x2001, 0x8b14, 0x2004, 0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, - 0x60c3, 0x001c, 0x080c, 0x6f0b, 0x0005, 0x20a1, 0x020b, 0x080c, - 0x681d, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x2001, 0x921b, 0x2004, - 0x20a2, 0x2001, 0x921c, 0x2004, 0x20a2, 0x20a9, 0x0004, 0x2099, - 0x9205, 0x53a6, 0x60c3, 0x0010, 0x080c, 0x6f0b, 0x0005, 0x20a1, - 0x020b, 0x080c, 0x681d, 0x7818, 0xa080, 0x0028, 0x2004, 0xa086, + 0x60c3, 0x001c, 0x080c, 0x66e4, 0x0005, 0x20a1, 0x020b, 0x080c, + 0x60a5, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x2001, 0x8b1b, 0x2004, + 0x20a2, 0x2001, 0x8b1c, 0x2004, 0x20a2, 0x20a9, 0x0004, 0x2099, + 0x8b05, 0x53a6, 0x60c3, 0x0010, 0x080c, 0x66e4, 0x0005, 0x20a1, + 0x020b, 0x080c, 0x60a5, 0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x1130, 0x20a3, 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0010, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x7818, 0xa080, 0x0028, 0x2004, - 0xa086, 0x007e, 0x1904, 0x66bc, 0x2001, 0x9232, 0x2004, 0xd0a4, - 0x01c8, 0x2099, 0x94c7, 0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398, + 0xa086, 0x007e, 0x1904, 0x5f44, 0x2001, 0x8b32, 0x2004, 0xd0a4, + 0x01c8, 0x2099, 0x8d8c, 0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398, 0x3304, 0xa084, 0x2000, 0x20a2, 0x9398, 0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398, 0x2001, 0x2710, 0x20a2, 0x9398, 0x33a6, 0x9398, - 0x33a6, 0x00d0, 0x2099, 0x94c7, 0x33a6, 0x9398, 0x33a6, 0x9398, - 0x3304, 0x080c, 0x4dc5, 0x1118, 0xa084, 0x37ff, 0x0010, 0xa084, + 0x33a6, 0x00d0, 0x2099, 0x8d8c, 0x33a6, 0x9398, 0x33a6, 0x9398, + 0x3304, 0x080c, 0x4c42, 0x1118, 0xa084, 0x37ff, 0x0010, 0xa084, 0x3fff, 0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000, - 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0x9205, - 0x53a6, 0x20a9, 0x0004, 0x2099, 0x9201, 0x53a6, 0x20a9, 0x0008, - 0x20a3, 0x0000, 0x1f04, 0x66a8, 0x20a9, 0x0008, 0x20a3, 0x0000, - 0x1f04, 0x66ae, 0x2099, 0x94cf, 0x33a6, 0x20a9, 0x0007, 0x20a3, - 0x0000, 0x1f04, 0x66b7, 0x0468, 0x2001, 0x9232, 0x2004, 0xd0a4, - 0x0140, 0x2001, 0x94c8, 0x2004, 0x60e3, 0x0000, 0x080c, 0x2460, - 0x60e2, 0x2099, 0x94c7, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004, - 0x2099, 0x9205, 0x53a6, 0x20a9, 0x0004, 0x2099, 0x9201, 0x53a6, - 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x66da, 0x20a9, 0x0008, - 0x20a3, 0x0000, 0x1f04, 0x66e0, 0x2099, 0x94cf, 0x20a9, 0x0008, - 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x66eb, 0x20a9, - 0x000a, 0x20a3, 0x0000, 0x1f04, 0x66f1, 0x60c3, 0x0074, 0x080c, - 0x6f0b, 0x0005, 0x20a1, 0x020b, 0x080c, 0x681d, 0x20a3, 0x2010, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0x8b05, + 0x53a6, 0x20a9, 0x0004, 0x2099, 0x8b01, 0x53a6, 0x20a9, 0x0008, + 0x20a3, 0x0000, 0x1f04, 0x5f30, 0x20a9, 0x0008, 0x20a3, 0x0000, + 0x1f04, 0x5f36, 0x2099, 0x8d94, 0x33a6, 0x20a9, 0x0007, 0x20a3, + 0x0000, 0x1f04, 0x5f3f, 0x0468, 0x2001, 0x8b32, 0x2004, 0xd0a4, + 0x0140, 0x2001, 0x8d8d, 0x2004, 0x60e3, 0x0000, 0x080c, 0x233e, + 0x60e2, 0x2099, 0x8d8c, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004, + 0x2099, 0x8b05, 0x53a6, 0x20a9, 0x0004, 0x2099, 0x8b01, 0x53a6, + 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x5f62, 0x20a9, 0x0008, + 0x20a3, 0x0000, 0x1f04, 0x5f68, 0x2099, 0x8d94, 0x20a9, 0x0008, + 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x5f73, 0x20a9, + 0x000a, 0x20a3, 0x0000, 0x1f04, 0x5f79, 0x60c3, 0x0074, 0x080c, + 0x66e4, 0x0005, 0x20a1, 0x020b, 0x080c, 0x60a5, 0x20a3, 0x2010, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000, 0xa006, 0x20a2, - 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x00f6, 0x2079, 0x9251, 0x7904, + 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x00f6, 0x2079, 0x8b51, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010, 0xa085, 0x0002, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, - 0x60c3, 0x0014, 0x080c, 0x6f0b, 0x0005, 0x20a1, 0x020b, 0x080c, - 0x681d, 0x20a3, 0x5000, 0x0804, 0x665a, 0x20a1, 0x020b, 0x080c, - 0x681d, 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, + 0x60c3, 0x0014, 0x080c, 0x66e4, 0x0005, 0x20a1, 0x020b, 0x080c, + 0x60a5, 0x20a3, 0x5000, 0x0804, 0x5ee2, 0x20a1, 0x020b, 0x080c, + 0x60a5, 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, - 0x0000, 0x60c3, 0x0014, 0x080c, 0x6f0b, 0x0005, 0x20a1, 0x020b, - 0x080c, 0x68a0, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000, - 0x20a3, 0x0000, 0x60c3, 0x0004, 0x080c, 0x6f0b, 0x0005, 0x20a1, - 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, - 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x6f0b, 0x0005, - 0x20a1, 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0200, 0x0804, 0x665a, - 0x20a1, 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0100, 0x20a3, 0x0000, - 0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x6f0b, - 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0210, + 0x0000, 0x60c3, 0x0014, 0x080c, 0x66e4, 0x0005, 0x20a1, 0x020b, + 0x080c, 0x612f, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x0004, 0x080c, 0x66e4, 0x0005, 0x20a1, + 0x020b, 0x080c, 0x612f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, + 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x66e4, 0x0005, + 0x20a1, 0x020b, 0x080c, 0x612f, 0x20a3, 0x0200, 0x0804, 0x5ee2, + 0x20a1, 0x020b, 0x080c, 0x612f, 0x20a3, 0x0100, 0x20a3, 0x0000, + 0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x66e4, + 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x612f, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x7818, 0x2068, 0x6894, 0xa086, 0x0014, 0x1178, 0x6998, 0xa184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x20a3, 0x2100, 0x0040, 0x20a3, 0x0100, 0x0028, 0x20a3, 0x0400, 0x0010, 0x20a3, 0x0700, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, - 0x20a2, 0x00f6, 0x2079, 0x9251, 0x7904, 0x00fe, 0xd1ac, 0x1110, - 0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010, 0x2009, 0x9273, + 0x20a2, 0x00f6, 0x2079, 0x8b51, 0x7904, 0x00fe, 0xd1ac, 0x1110, + 0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010, 0x2009, 0x8b73, 0x210c, 0xd184, 0x1110, 0xa085, 0x0002, 0x20a2, 0x20a2, 0x20a2, - 0x60c3, 0x0014, 0x080c, 0x6f0b, 0x00de, 0x0005, 0x20a1, 0x020b, - 0x080c, 0x68a0, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0000, + 0x60c3, 0x0014, 0x080c, 0x66e4, 0x00de, 0x0005, 0x20a1, 0x020b, + 0x080c, 0x612f, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, - 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x6f0b, 0x0005, 0x20a1, - 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0200, 0x0804, 0x65fb, 0x20a1, - 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, - 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x6f0b, 0x0005, - 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, 0x020b, 0x080c, 0x68a0, + 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x66e4, 0x0005, 0x20a1, + 0x020b, 0x080c, 0x612f, 0x20a3, 0x0200, 0x0804, 0x5e83, 0x20a1, + 0x020b, 0x080c, 0x612f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, + 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x66e4, 0x0005, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, 0x020b, 0x080c, 0x612f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3, 0x0000, - 0x60c3, 0x0008, 0x080c, 0x6f0b, 0x0005, 0x0026, 0x20e1, 0x9080, + 0x60c3, 0x0008, 0x080c, 0x66e4, 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x1198, 0x20a3, 0x22ff, 0x20a3, 0xfffe, 0x20a3, 0x0000, 0x2011, - 0x9214, 0x2214, 0x2001, 0x94d7, 0x2004, 0xa005, 0x0118, 0x2011, - 0x921c, 0x2214, 0x22a2, 0x0498, 0xa286, 0x007f, 0x1130, 0x00d6, - 0x20a3, 0x22ff, 0x20a3, 0xfffd, 0x00c8, 0x2001, 0x9232, 0x2004, + 0x8b14, 0x2214, 0x2001, 0x8d9c, 0x2004, 0xa005, 0x0118, 0x2011, + 0x8b1c, 0x2214, 0x22a2, 0x04d0, 0xa286, 0x007f, 0x1130, 0x00d6, + 0x20a3, 0x22ff, 0x20a3, 0xfffd, 0x00c8, 0x2001, 0x8b32, 0x2004, 0xd0ac, 0x1110, 0xd2bc, 0x01c8, 0xa286, 0x0080, 0x00d6, 0x1128, - 0x20a3, 0x22ff, 0x20a3, 0xfffc, 0x0048, 0xa2e8, 0x936e, 0x2d6c, - 0x6810, 0xa085, 0x2200, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x921b, - 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0050, 0x20a3, 0x2200, 0x6298, - 0x22a2, 0x20a3, 0x0000, 0x2011, 0x9214, 0x2214, 0x22a2, 0x20a3, - 0x0129, 0x20a3, 0x0000, 0x080c, 0x6efa, 0x22a2, 0x20a3, 0x0000, - 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, - 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, - 0x2011, 0xfffc, 0x22a2, 0x00d6, 0x2069, 0x921b, 0x2da6, 0x8d68, - 0x2da6, 0x00de, 0x20a3, 0x2029, 0x20a3, 0x0000, 0x08e0, 0x20a3, - 0x0100, 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, 0x0005, - 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, - 0x2004, 0x2011, 0x9232, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, - 0x02e0, 0x00d6, 0xa0e8, 0x936e, 0x2d6c, 0x6810, 0xa085, 0x2300, - 0x20a2, 0x6814, 0x20a2, 0x6810, 0xa005, 0x1140, 0x6814, 0xa005, - 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0028, 0x2069, 0x921b, - 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0050, 0x20a3, 0x2300, 0x6298, - 0x22a2, 0x20a3, 0x0000, 0x2011, 0x9214, 0x2214, 0x22a2, 0x20a3, - 0x0198, 0x20a3, 0x0000, 0x080c, 0x6efa, 0x22a2, 0x20a3, 0x0000, - 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, - 0x0005, 0x080c, 0x6efa, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, - 0x7810, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, - 0x00c6, 0x00f6, 0x6004, 0xa08a, 0x0085, 0x0a0c, 0x13fe, 0xa08a, - 0x008c, 0x1a0c, 0x13fe, 0x6118, 0x2178, 0x79a0, 0x2011, 0x9232, - 0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120, - 0x7914, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8, - 0x2719, 0x2f0d, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, - 0xa082, 0x0085, 0x001b, 0x00fe, 0x00ce, 0x0005, 0x692f, 0x6939, - 0x6954, 0x692d, 0x692d, 0x692d, 0x692f, 0x080c, 0x13fe, 0x0146, - 0x20a1, 0x020b, 0x04a1, 0x60c3, 0x0000, 0x080c, 0x6f0b, 0x014e, - 0x0005, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6999, 0x20a3, 0x0000, - 0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000, - 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c, - 0x080c, 0x6f0b, 0x014e, 0x0005, 0x0146, 0x20a1, 0x020b, 0x080c, - 0x69d1, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3, - 0x0000, 0x60c3, 0x0004, 0x080c, 0x6f0b, 0x014e, 0x0005, 0x0026, + 0x20a3, 0x22ff, 0x20a3, 0xfffc, 0x0048, 0xa2e8, 0x8c34, 0x2d6c, + 0x6810, 0xa085, 0x2200, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x8b1b, + 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa2e8, 0x8c34, + 0x2d6c, 0x6810, 0xa085, 0x2200, 0x20a2, 0x6814, 0x20a2, 0x00de, + 0x20a3, 0x0000, 0x2011, 0x8b14, 0x2214, 0x22a2, 0x20a3, 0x0129, + 0x20a3, 0x0000, 0x080c, 0x66d3, 0x22a2, 0x20a3, 0x0000, 0x2fa2, + 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, + 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, 0x2011, + 0xfffc, 0x22a2, 0x00d6, 0x2069, 0x8b1b, 0x2da6, 0x8d68, 0x2da6, + 0x00de, 0x20a3, 0x2029, 0x20a3, 0x0000, 0x08e0, 0x20a3, 0x0100, + 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, - 0x2011, 0x9232, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288, - 0x00d6, 0xa0e8, 0x936e, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, - 0x6814, 0x20a2, 0x2069, 0x921b, 0x2da6, 0x8d68, 0x2da6, 0x00de, - 0x0050, 0x20a3, 0x8100, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x2011, - 0x9214, 0x2214, 0x22a2, 0x20a3, 0x0009, 0x20a3, 0x0000, 0x0804, - 0x6873, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, - 0x0028, 0x2004, 0x2011, 0x9232, 0x2214, 0xd2ac, 0x1118, 0xa092, - 0x007e, 0x0288, 0x00d6, 0xa0e8, 0x936e, 0x2d6c, 0x6810, 0xa085, - 0x8400, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x921b, 0x2da6, 0x8d68, - 0x2da6, 0x00de, 0x0050, 0x20a3, 0x8400, 0x6298, 0x22a2, 0x20a3, - 0x0000, 0x2011, 0x9214, 0x2214, 0x22a2, 0x080c, 0x4dc5, 0x1118, - 0x20a3, 0x0099, 0x0010, 0x20a3, 0x00d1, 0x20a3, 0x0000, 0x0804, - 0x68e9, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, - 0x0028, 0x2004, 0x2011, 0x9232, 0x2214, 0xd2ac, 0x1118, 0xa092, - 0x007e, 0x0288, 0x00d6, 0xa0e8, 0x936e, 0x2d6c, 0x6810, 0xa085, - 0x8500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x921b, 0x2da6, 0x8d68, - 0x2da6, 0x00de, 0x0050, 0x20a3, 0x8500, 0x6298, 0x22a2, 0x20a3, - 0x0000, 0x2011, 0x9214, 0x2214, 0x22a2, 0x20a3, 0x0099, 0x20a3, - 0x0000, 0x0804, 0x68e9, 0x00c6, 0x00f6, 0x2c78, 0x7804, 0xa08a, - 0x0040, 0x0a0c, 0x13fe, 0xa08a, 0x0053, 0x1a0c, 0x13fe, 0x7918, - 0x2160, 0x61a0, 0x2011, 0x9232, 0x2214, 0xd2ac, 0x1110, 0xd1bc, - 0x0150, 0x6100, 0xd1f4, 0x0120, 0x6114, 0xa18c, 0x00ff, 0x0040, - 0x2009, 0x0000, 0x0028, 0xa1e0, 0x2719, 0x2c0d, 0xa18c, 0x00ff, - 0x2061, 0x0100, 0x619a, 0xa082, 0x0040, 0x001b, 0x00fe, 0x00ce, - 0x0005, 0x6a46, 0x6b3a, 0x6ade, 0x6c75, 0x6a44, 0x6a44, 0x6a44, - 0x6a44, 0x6a44, 0x6a44, 0x6a44, 0x71f1, 0x7201, 0x7211, 0x7221, - 0x6a44, 0x6a44, 0x6a44, 0x71e0, 0x080c, 0x13fe, 0x00d6, 0x0156, - 0x0146, 0x20a1, 0x020b, 0x080c, 0x6a9c, 0x7910, 0x2168, 0x6948, - 0x7922, 0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184, - 0x000f, 0x1118, 0x2001, 0x0005, 0x0040, 0xd184, 0x0118, 0x2001, - 0x0004, 0x0018, 0xa084, 0x0006, 0x8004, 0x20a2, 0xd1ac, 0x0118, - 0x20a3, 0x0002, 0x0048, 0xd1b4, 0x0118, 0x20a3, 0x0001, 0x0020, - 0x20a3, 0x0000, 0x2230, 0x0010, 0x6a80, 0x6e7c, 0x20a9, 0x0008, - 0x0136, 0xad88, 0x0017, 0x2198, 0x20a1, 0x021b, 0x53a6, 0x013e, - 0x20a1, 0x020b, 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, - 0x6014, 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0x9501, - 0x2003, 0x07d0, 0x2001, 0x9500, 0x2003, 0x0009, 0x080c, 0x165a, - 0x014e, 0x015e, 0x00de, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, - 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, - 0x8217, 0x7818, 0xa080, 0x0028, 0x2004, 0x2019, 0x9232, 0x231c, - 0xd3ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0x936e, 0x2d6c, - 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x921b, - 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0050, 0x20a3, 0x0600, 0x6198, - 0x21a2, 0x20a3, 0x0000, 0x2009, 0x9214, 0x210c, 0x21a2, 0x20a3, - 0x0829, 0x20a3, 0x0000, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, - 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x0005, 0x00d6, 0x0156, - 0x0136, 0x0146, 0x20a1, 0x020b, 0x00c1, 0x7810, 0x2068, 0x6860, - 0x20a2, 0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, - 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c, 0x080c, 0x6f0b, - 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0026, 0x20e1, 0x9080, - 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0x9232, - 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0x936e, - 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2, 0x2069, - 0x921b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0050, 0x20a3, 0x0500, - 0x6298, 0x22a2, 0x20a3, 0x0000, 0x2011, 0x9214, 0x2214, 0x22a2, - 0x20a3, 0x0889, 0x20a3, 0x0000, 0x080c, 0x6efa, 0x22a2, 0x20a3, - 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, - 0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x20a1, 0x020b, - 0x080c, 0x6c38, 0x7810, 0x2068, 0xa016, 0x22a2, 0x22a2, 0x22a2, - 0x22a2, 0x22a2, 0x7810, 0xa084, 0xf000, 0x1130, 0x7810, 0xa084, - 0x0700, 0x8007, 0x0043, 0x0010, 0xa006, 0x002b, 0x014e, 0x013e, - 0x015e, 0x00de, 0x0005, 0x6b65, 0x6bde, 0x6be1, 0x6c04, 0x6c11, - 0x6c23, 0x6c26, 0x6b63, 0x080c, 0x13fe, 0x0016, 0x0036, 0x694c, - 0xa18c, 0x0003, 0xa186, 0x0000, 0x1150, 0x6b78, 0x23a2, 0x6868, - 0x20a2, 0x6864, 0x20a2, 0x003e, 0x001e, 0x0804, 0x6c08, 0xa186, - 0x0001, 0x1904, 0x6bd9, 0x6b78, 0x23a2, 0x6868, 0x20a2, 0x6864, - 0x20a2, 0x22a2, 0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, - 0x0018, 0xa384, 0x0300, 0x0904, 0x6bd8, 0xd3c4, 0x0110, 0x687c, - 0xa108, 0xd3cc, 0x0110, 0x6874, 0xa108, 0x0156, 0x20a9, 0x000d, - 0xad80, 0x0020, 0x201c, 0x831f, 0x23a2, 0x8000, 0x1f04, 0x6b9a, - 0x015e, 0x22a2, 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0588, 0x20a1, - 0x020b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x0006, 0x7818, 0xa080, - 0x0028, 0x2004, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0x936e, 0x2d6c, - 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x921b, - 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0050, 0x20a3, 0x0700, 0x6298, - 0x22a2, 0x20a3, 0x0000, 0x2011, 0x9214, 0x2214, 0x22a2, 0x000e, - 0x20a3, 0x0898, 0x20a2, 0x080c, 0x6efa, 0x22a2, 0x20a3, 0x0000, - 0x61c2, 0x003e, 0x001e, 0x080c, 0x6f0b, 0x0005, 0x20a3, 0x0008, + 0x2011, 0x8b32, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x02e0, + 0x00d6, 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x2300, 0x20a2, + 0x6814, 0x20a2, 0x6810, 0xa005, 0x1140, 0x6814, 0xa005, 0x1128, + 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0028, 0x2069, 0x8b1b, 0x2da6, + 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0x8c34, 0x2d6c, + 0x6810, 0xa085, 0x2300, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, + 0x0000, 0x2011, 0x8b14, 0x2214, 0x22a2, 0x20a3, 0x0198, 0x20a3, + 0x0000, 0x080c, 0x66d3, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, + 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x080c, + 0x66d3, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x7810, 0x20a2, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00c6, 0x00f6, + 0x6004, 0xa08a, 0x0085, 0x0a0c, 0x1410, 0xa08a, 0x008c, 0x1a0c, + 0x1410, 0x6118, 0x2178, 0x79a0, 0x2011, 0x8b32, 0x2214, 0xd2ac, + 0x1110, 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c, + 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8, 0x263d, 0x2f0d, + 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa082, 0x0085, + 0x001b, 0x00fe, 0x00ce, 0x0005, 0x61c5, 0x61cf, 0x61ea, 0x61c3, + 0x61c3, 0x61c3, 0x61c5, 0x080c, 0x1410, 0x0146, 0x20a1, 0x020b, + 0x04a1, 0x60c3, 0x0000, 0x080c, 0x66e4, 0x014e, 0x0005, 0x0146, + 0x20a1, 0x020b, 0x080c, 0x6236, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0xffff, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c, 0x080c, 0x66e4, + 0x014e, 0x0005, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6275, 0x20a3, + 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, + 0x0004, 0x080c, 0x66e4, 0x014e, 0x0005, 0x0026, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0x8b32, + 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8, + 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, + 0x2069, 0x8b1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, + 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, + 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0x8b14, 0x2214, 0x22a2, + 0x20a3, 0x0009, 0x20a3, 0x0000, 0x0804, 0x6102, 0x0026, 0x20e1, + 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, + 0x8b32, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288, 0x00d6, + 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2, 0x6814, + 0x20a2, 0x2069, 0x8b1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, + 0x00d6, 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2, + 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0x8b14, 0x2214, + 0x22a2, 0x080c, 0x4c42, 0x1118, 0x20a3, 0x0099, 0x0010, 0x20a3, + 0x00d1, 0x20a3, 0x0000, 0x0804, 0x617f, 0x0026, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0x8b32, + 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8, + 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, + 0x2069, 0x8b1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, + 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, + 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0x8b14, 0x2214, 0x22a2, + 0x20a3, 0x0099, 0x20a3, 0x0000, 0x0804, 0x617f, 0x00c6, 0x00f6, + 0x2c78, 0x7804, 0xa08a, 0x0040, 0x0a0c, 0x1410, 0xa08a, 0x0053, + 0x1a0c, 0x1410, 0x7918, 0x2160, 0x61a0, 0x2011, 0x8b32, 0x2214, + 0xd2ac, 0x1110, 0xd1bc, 0x0150, 0x6100, 0xd1f4, 0x0120, 0x6114, + 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1e0, 0x263d, + 0x2c0d, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0xa082, 0x0040, + 0x001b, 0x00fe, 0x00ce, 0x0005, 0x62f1, 0x63f3, 0x6390, 0x653f, + 0x62ef, 0x62ef, 0x62ef, 0x62ef, 0x62ef, 0x62ef, 0x62ef, 0x69be, + 0x69ce, 0x69de, 0x69ee, 0x62ef, 0x62ef, 0x62ef, 0x69ad, 0x080c, + 0x1410, 0x00d6, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6347, + 0x7910, 0x2168, 0x6948, 0x7922, 0x21a2, 0xa016, 0x22a2, 0x22a2, + 0x22a2, 0x694c, 0xa184, 0x000f, 0x1118, 0x2001, 0x0005, 0x0040, + 0xd184, 0x0118, 0x2001, 0x0004, 0x0018, 0xa084, 0x0006, 0x8004, + 0x20a2, 0xd1ac, 0x0118, 0x20a3, 0x0002, 0x0048, 0xd1b4, 0x0118, + 0x20a3, 0x0001, 0x0020, 0x20a3, 0x0000, 0x2230, 0x0010, 0x6a80, + 0x6e7c, 0x20a9, 0x0008, 0x0136, 0xad88, 0x0017, 0x2198, 0x20a1, + 0x021b, 0x53a6, 0x013e, 0x20a1, 0x020b, 0x22a2, 0x26a2, 0x60c3, + 0x0020, 0x20e1, 0x9080, 0x6014, 0xa084, 0x0004, 0xa085, 0x0009, + 0x6016, 0x2001, 0x8dc6, 0x2003, 0x07d0, 0x2001, 0x8dc5, 0x2003, + 0x0009, 0x080c, 0x166c, 0x014e, 0x015e, 0x00de, 0x0005, 0x20e1, + 0x9080, 0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, + 0xa294, 0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, 0x2004, + 0x2019, 0x8b32, 0x231c, 0xd3ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, + 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, + 0x20a2, 0x2069, 0x8b1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, + 0x00d6, 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, + 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2009, 0x8b14, 0x210c, + 0x21a2, 0x20a3, 0x0829, 0x20a3, 0x0000, 0x22a2, 0x20a3, 0x0000, + 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x0005, + 0x00d6, 0x0156, 0x0136, 0x0146, 0x20a1, 0x020b, 0x00c1, 0x7810, + 0x2068, 0x6860, 0x20a2, 0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c, + 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c, + 0x080c, 0x66e4, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0026, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, + 0x2011, 0x8b32, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, + 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, + 0x20a2, 0x2069, 0x8b1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, + 0x00d6, 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, + 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0x8b14, 0x2214, + 0x22a2, 0x20a3, 0x0889, 0x20a3, 0x0000, 0x080c, 0x66d3, 0x22a2, + 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x20a1, + 0x020b, 0x080c, 0x64fb, 0x7810, 0x2068, 0xa016, 0x22a2, 0x22a2, + 0x22a2, 0x22a2, 0x22a2, 0x7810, 0xa084, 0xf000, 0x1130, 0x7810, + 0xa084, 0x0700, 0x8007, 0x0043, 0x0010, 0xa006, 0x002b, 0x014e, + 0x013e, 0x015e, 0x00de, 0x0005, 0x641e, 0x649e, 0x64a1, 0x64c4, + 0x64d1, 0x64e6, 0x64e9, 0x641c, 0x080c, 0x1410, 0x0016, 0x0036, + 0x694c, 0xa18c, 0x0003, 0xa186, 0x0000, 0x1150, 0x6b78, 0x23a2, + 0x6868, 0x20a2, 0x6864, 0x20a2, 0x003e, 0x001e, 0x0804, 0x64c8, + 0xa186, 0x0001, 0x1904, 0x6499, 0x6b78, 0x23a2, 0x6868, 0x20a2, + 0x6864, 0x20a2, 0x22a2, 0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, + 0x2009, 0x0018, 0xa384, 0x0300, 0x0904, 0x6498, 0xd3c4, 0x0110, + 0x687c, 0xa108, 0xd3cc, 0x0110, 0x6874, 0xa108, 0x0156, 0x20a9, + 0x000d, 0xad80, 0x0020, 0x201c, 0x831f, 0x23a2, 0x8000, 0x1f04, + 0x6453, 0x015e, 0x22a2, 0x22a2, 0x22a2, 0xa184, 0x0003, 0x05c0, + 0x20a1, 0x020b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x0006, 0x7818, + 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0x8c34, + 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, + 0x8b1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, + 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, + 0x00de, 0x20a3, 0x0000, 0x2011, 0x8b14, 0x2214, 0x22a2, 0x000e, + 0x20a3, 0x0898, 0x20a2, 0x080c, 0x66d3, 0x22a2, 0x20a3, 0x0000, + 0x61c2, 0x003e, 0x001e, 0x080c, 0x66e4, 0x0005, 0x20a3, 0x0008, 0x0428, 0x20a3, 0x0302, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0012, 0x22a2, 0x20a3, 0x0008, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x7000, 0x20a3, 0x0500, 0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2, 0x20a3, 0x2500, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, - 0x0032, 0x080c, 0x6f0b, 0x0005, 0x20a3, 0x0028, 0x22a2, 0x22a2, - 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0018, 0x080c, 0x6f0b, + 0x0032, 0x080c, 0x66e4, 0x0005, 0x20a3, 0x0028, 0x22a2, 0x22a2, + 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0018, 0x080c, 0x66e4, 0x0005, 0x20a3, 0x0100, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, - 0x20a3, 0x0008, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0020, - 0x080c, 0x6f0b, 0x0005, 0x20a3, 0x0008, 0x0c00, 0x0036, 0x7b10, - 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001, 0x1118, 0x22a2, - 0x003e, 0x08a0, 0x20a3, 0x0800, 0x22a2, 0x20a2, 0x003e, 0x0880, - 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, - 0x2004, 0x2011, 0x9232, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, - 0x00d6, 0xa0e8, 0x936e, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, - 0x6814, 0x20a2, 0x2069, 0x921b, 0x2da6, 0x8d68, 0x2da6, 0x00de, - 0x0050, 0x20a3, 0x0700, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x2011, - 0x9214, 0x2214, 0x22a2, 0x20a3, 0x0898, 0x20a3, 0x0000, 0x080c, - 0x6efa, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, - 0x0146, 0x0016, 0x0036, 0x7810, 0xa084, 0x0700, 0x8007, 0x003b, - 0x003e, 0x001e, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x6c8f, - 0x6c8f, 0x6c91, 0x6c8f, 0x6c8f, 0x6c8f, 0x6cb3, 0x6c8f, 0x080c, - 0x13fe, 0x7910, 0xa18c, 0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1, - 0x020b, 0x2009, 0x0003, 0x00f9, 0x00d6, 0x2069, 0x9251, 0x6804, - 0xd0bc, 0x0130, 0x682c, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x0010, - 0x20a3, 0x3f00, 0x00de, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, - 0x080c, 0x6f0b, 0x0005, 0x20a1, 0x020b, 0x2009, 0x0003, 0x0019, - 0x20a3, 0x7f00, 0x0c80, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, - 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0x9232, 0x2214, 0xd2ac, - 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0x936e, 0x2d6c, 0x6810, - 0xa085, 0x0100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x921b, 0x2da6, - 0x8d68, 0x2da6, 0x00de, 0x0050, 0x20a3, 0x0100, 0x6298, 0x22a2, - 0x20a3, 0x0000, 0x2011, 0x9214, 0x2214, 0x22a2, 0x20a3, 0x0888, - 0xa18d, 0x0008, 0x21a2, 0x080c, 0x6efa, 0x22a2, 0x20a3, 0x0000, - 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, - 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0036, - 0x2061, 0x0100, 0x2071, 0x9200, 0x2009, 0x9214, 0x210c, 0x7818, - 0x2068, 0x2031, 0x9232, 0x2634, 0xa6b4, 0x0028, 0x0110, 0x736c, - 0x7470, 0x2500, 0x2031, 0x9232, 0x2634, 0xa6b4, 0x0028, 0x0140, - 0x2001, 0x04ff, 0x6062, 0x6067, 0xffff, 0x636a, 0x646e, 0x0050, - 0x2001, 0x00ff, 0xa085, 0x0400, 0x6062, 0x6067, 0xffff, 0x606b, - 0x0000, 0x616e, 0x68b8, 0x6072, 0x6077, 0x0008, 0x688c, 0x8000, - 0xa084, 0x00ff, 0x688e, 0x8007, 0xa085, 0x0020, 0x607a, 0x68b4, - 0x607f, 0x0000, 0x2d00, 0x6082, 0x6087, 0xffff, 0x7810, 0x2070, - 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, 0x60ca, - 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, - 0x2001, 0x9232, 0x2004, 0xd09c, 0x0128, 0x609f, 0x0000, 0x2001, - 0x0012, 0x0048, 0x6028, 0xc0bd, 0x602a, 0x609f, 0x00ff, 0x6027, - 0xffff, 0x2001, 0x0032, 0x6016, 0x2009, 0x07d0, 0x080c, 0x57a6, - 0x2001, 0x9295, 0x200c, 0xc185, 0x2102, 0x003e, 0x004e, 0x005e, - 0x006e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x00e6, 0x00d6, 0x00c6, - 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x9200, - 0x2009, 0x9214, 0x210c, 0x7818, 0x2068, 0x68a0, 0x2028, 0x2031, - 0x9232, 0x2634, 0xd6ac, 0x1140, 0xd0bc, 0x1130, 0xa080, 0x2719, - 0x2015, 0xa294, 0x00ff, 0x0020, 0x6910, 0x6a14, 0x736c, 0x7470, - 0x2001, 0x9232, 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138, 0xa185, - 0x0400, 0x6062, 0x6266, 0x636a, 0x646e, 0x0030, 0x6063, 0x0400, - 0x6266, 0x606b, 0x0000, 0x616e, 0x68b8, 0x6072, 0x6077, 0x0008, - 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0xa085, 0x0020, - 0x607a, 0x68b4, 0x607f, 0x0000, 0x2d00, 0x6082, 0x6087, 0xffff, - 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, - 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, - 0x60d7, 0x0000, 0xa582, 0x0080, 0x0210, 0x2011, 0x0000, 0x629e, - 0x00f6, 0x2079, 0x0140, 0x7803, 0x0000, 0x00fe, 0x6017, 0x0012, - 0x2009, 0x07d0, 0x080c, 0x57a6, 0x003e, 0x004e, 0x005e, 0x006e, - 0x00ce, 0x00de, 0x00ee, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0056, - 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x9200, 0x7150, 0x7818, - 0x2068, 0x68a0, 0x2028, 0x76c8, 0xd6ac, 0x1140, 0xd0bc, 0x1130, - 0xa080, 0x2719, 0x2015, 0xa294, 0x00ff, 0x0020, 0x6910, 0x6a14, - 0x736c, 0x7470, 0x781c, 0xa086, 0x0006, 0x0904, 0x6e65, 0x70c8, - 0xd0ac, 0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266, - 0x636a, 0x646e, 0x0030, 0x6063, 0x0100, 0x6266, 0x606b, 0x0000, - 0x616e, 0x6073, 0x0809, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, - 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, - 0x7808, 0x6086, 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, - 0x700c, 0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, - 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0248, 0x6a00, - 0xd2f4, 0x0120, 0x6a14, 0xa294, 0x00ff, 0x0010, 0x2011, 0x0000, - 0x629e, 0x6017, 0x0016, 0x2009, 0x07d0, 0x60c4, 0xa084, 0xfff0, - 0xa005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x57a6, 0x003e, 0x004e, - 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7810, 0x2070, 0x704c, - 0xa084, 0x0003, 0xa086, 0x0002, 0x0904, 0x6eb4, 0x2001, 0x9232, - 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, - 0x6266, 0x636a, 0x646e, 0x0030, 0x6063, 0x0100, 0x6266, 0x606b, - 0x0000, 0x616e, 0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000, - 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, - 0x6086, 0x7808, 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080, - 0x60c6, 0x707c, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, - 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, - 0x0120, 0x6a14, 0xa294, 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, - 0x6017, 0x0012, 0x0804, 0x6e53, 0x2001, 0x9232, 0x2004, 0xd0ac, - 0x1110, 0xd5bc, 0x0138, 0xa185, 0x0700, 0x6062, 0x6266, 0x636a, - 0x646e, 0x0030, 0x6063, 0x0700, 0x6266, 0x606b, 0x0000, 0x616e, - 0x6073, 0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, - 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, - 0x6082, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, - 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, - 0x0000, 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, - 0xa294, 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x6017, 0x0016, - 0x0804, 0x6e53, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, - 0x00ff, 0x2202, 0x8217, 0x0005, 0x00d6, 0x2069, 0x94e5, 0x6843, - 0x0001, 0x00de, 0x0005, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, - 0x9575, 0x0019, 0x080c, 0x5798, 0x0005, 0x0006, 0x6014, 0xa084, - 0x0004, 0xa085, 0x0009, 0x6016, 0x000e, 0x0005, 0x0006, 0x00c6, - 0x2061, 0x0100, 0x6014, 0xa084, 0x0004, 0xa085, 0x0008, 0x6016, - 0x00ce, 0x000e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x080c, - 0x57a1, 0x2061, 0x0100, 0x2069, 0x0140, 0x6904, 0xa194, 0x4000, - 0x0538, 0x0c21, 0x6803, 0x1000, 0x6803, 0x0000, 0x00c6, 0x2061, - 0x94e5, 0x6128, 0xa192, 0x0002, 0x1250, 0x8108, 0x612a, 0x6124, - 0x00ce, 0x81ff, 0x0180, 0x080c, 0x5798, 0x0839, 0x0060, 0x6124, - 0xa1e5, 0x0000, 0x0130, 0x080c, 0x91a0, 0x2009, 0x0014, 0x080c, - 0x7518, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, - 0x080c, 0x4dc5, 0x1118, 0x080c, 0x6f1e, 0x08c0, 0x080c, 0x4105, - 0x0c90, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c, 0x57ae, - 0x2071, 0x94e5, 0x713c, 0x81ff, 0x0578, 0x2061, 0x0100, 0x2069, - 0x0140, 0x6904, 0xa194, 0x4000, 0x0568, 0x6803, 0x1000, 0x6803, - 0x0000, 0x0036, 0x2019, 0x0001, 0x080c, 0x7110, 0x003e, 0x713c, - 0x2160, 0x080c, 0x91a0, 0x2009, 0x004a, 0x621c, 0xa296, 0x0009, - 0x1110, 0x2009, 0x0104, 0x080c, 0x7518, 0x080c, 0x4dc5, 0x1160, - 0x0006, 0x2001, 0x94d8, 0x2003, 0x0002, 0x2001, 0x9200, 0x2003, - 0x0001, 0x080c, 0x4d10, 0x000e, 0x002e, 0x001e, 0x00ee, 0x00de, - 0x00ce, 0x0005, 0x08b0, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, - 0x0046, 0x0006, 0x0126, 0x2091, 0x8000, 0x6018, 0x2068, 0x6ca0, - 0x2071, 0x94e5, 0x7018, 0x2068, 0x8dff, 0x0198, 0x68a0, 0xa406, - 0x0118, 0x6854, 0x2068, 0x0cc0, 0x6010, 0x2060, 0x643c, 0x6540, - 0x6e48, 0x2d60, 0x080c, 0x457f, 0x0120, 0x080c, 0x7238, 0xa085, - 0x0001, 0x012e, 0x000e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, - 0x00ee, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x681d, - 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, - 0x60c3, 0x0008, 0x080c, 0x6f0b, 0x014e, 0x015e, 0x0005, 0x0156, - 0x0146, 0x20a1, 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0200, 0x20a3, - 0x0000, 0x20a9, 0x0006, 0x2011, 0x9240, 0x2019, 0x9241, 0x23a6, - 0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x1f04, 0x6fff, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c, 0x6f0b, 0x014e, - 0x015e, 0x0005, 0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b, - 0x080c, 0x6881, 0x080c, 0x6897, 0x7810, 0x0006, 0xa080, 0x0015, - 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6, 0xa080, 0x0004, + 0x20a3, 0x0008, 0x22a2, 0x7824, 0xa084, 0x00ff, 0x20a2, 0x22a2, + 0x22a2, 0x60c3, 0x0020, 0x080c, 0x66e4, 0x0005, 0x20a3, 0x0008, + 0x08e8, 0x0036, 0x7b10, 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, + 0x8001, 0x1118, 0x22a2, 0x003e, 0x0888, 0x20a3, 0x0800, 0x22a2, + 0x20a2, 0x003e, 0x0868, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, + 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0x8b32, 0x2214, 0xd2ac, + 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0x8c34, 0x2d6c, 0x6810, + 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x8b1b, 0x2da6, + 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0x8c34, 0x2d6c, + 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, + 0x0000, 0x2011, 0x8b14, 0x2214, 0x22a2, 0x20a3, 0x0898, 0x20a3, + 0x0000, 0x080c, 0x66d3, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, + 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00d6, + 0x0156, 0x0136, 0x0146, 0x0016, 0x0036, 0x7810, 0xa084, 0x0700, + 0x8007, 0x003b, 0x003e, 0x001e, 0x014e, 0x013e, 0x015e, 0x00de, + 0x0005, 0x6559, 0x6559, 0x655b, 0x6559, 0x6559, 0x6559, 0x657d, + 0x6559, 0x080c, 0x1410, 0x7910, 0xa18c, 0xf8ff, 0xa18d, 0x0600, + 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003, 0x00f9, 0x00d6, 0x2069, + 0x8b51, 0x6804, 0xd0bc, 0x0130, 0x682c, 0xa084, 0x00ff, 0x8007, + 0x20a2, 0x0010, 0x20a3, 0x3f00, 0x00de, 0x22a2, 0x22a2, 0x22a2, + 0x60c3, 0x0001, 0x080c, 0x66e4, 0x0005, 0x20a1, 0x020b, 0x2009, + 0x0003, 0x0019, 0x20a3, 0x7f00, 0x0c80, 0x0026, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0x8b32, + 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0x8c34, + 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2, 0x6814, 0x20a2, 0x2069, + 0x8b1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, + 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2, 0x6814, 0x20a2, + 0x00de, 0x20a3, 0x0000, 0x2011, 0x8b14, 0x2214, 0x22a2, 0x20a3, + 0x0888, 0xa18d, 0x0008, 0x21a2, 0x080c, 0x66d3, 0x22a2, 0x20a3, + 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x002e, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0056, 0x0046, 0x0036, + 0x2061, 0x0100, 0x2071, 0x8b00, 0x7150, 0x7818, 0x2068, 0x68a0, + 0x2028, 0x76c8, 0xd6ac, 0x1130, 0xd0bc, 0x1120, 0x6910, 0x6a14, + 0x7450, 0x0020, 0x6910, 0x6a14, 0x736c, 0x7470, 0x781c, 0xa086, + 0x0006, 0x0904, 0x6640, 0x70c8, 0xd0ac, 0x1110, 0xd5bc, 0x0138, + 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0038, 0xa185, + 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x6073, 0x0809, + 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, + 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, 0x7810, + 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, + 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, + 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294, 0x00ff, + 0x0010, 0x2011, 0x0000, 0x629e, 0x080c, 0x6cb4, 0x2009, 0x07d0, + 0x60c4, 0xa084, 0xfff0, 0xa005, 0x0110, 0x2009, 0x1b58, 0x080c, + 0x567f, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, + 0x7810, 0x2070, 0x704c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0904, + 0x668e, 0x2001, 0x8b32, 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138, + 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0038, 0xa185, + 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x6073, 0x0880, + 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, + 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, 0x7060, + 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6, 0x707c, 0x60ca, 0x686c, + 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0248, + 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294, 0x00ff, 0x0010, 0x2011, + 0x0000, 0x629e, 0x080c, 0x6cb1, 0x0804, 0x662e, 0x2001, 0x8b32, + 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138, 0xa185, 0x0700, 0x6062, + 0x6266, 0x636a, 0x646e, 0x0038, 0xa185, 0x0700, 0x6062, 0x6266, + 0x606b, 0x0000, 0x646e, 0x6073, 0x0898, 0x6077, 0x0000, 0x688c, + 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, + 0x2f00, 0x6086, 0x7808, 0x6082, 0x7014, 0x608a, 0x7010, 0x608e, + 0x700c, 0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, + 0x60d7, 0x0000, 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, + 0x6a14, 0xa294, 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c, + 0x6cb4, 0x0804, 0x662e, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, + 0xa294, 0x00ff, 0x2202, 0x8217, 0x0005, 0x00d6, 0x2069, 0x8daa, + 0x6843, 0x0001, 0x00de, 0x0005, 0x20e1, 0x9080, 0x60a3, 0x0056, + 0x60a7, 0x9575, 0x0019, 0x080c, 0x5671, 0x0005, 0x0006, 0x6014, + 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x000e, 0x0005, 0x0006, + 0x00c6, 0x2061, 0x0100, 0x6014, 0xa084, 0x0004, 0xa085, 0x0008, + 0x6016, 0x00ce, 0x000e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, + 0x080c, 0x567a, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x4c42, + 0x1128, 0x0c29, 0x080c, 0x4cbf, 0x0150, 0x0438, 0x6904, 0xa194, + 0x4000, 0x0540, 0x08e1, 0x6803, 0x1000, 0x6803, 0x0000, 0x00c6, + 0x2061, 0x8daa, 0x6128, 0xa192, 0x0002, 0x1258, 0x8108, 0x612a, + 0x6124, 0x00ce, 0x81ff, 0x0188, 0x080c, 0x5671, 0x080c, 0x66ee, + 0x0060, 0x6124, 0xa1e5, 0x0000, 0x0130, 0x080c, 0x8a4b, 0x2009, + 0x0014, 0x080c, 0x6d3f, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, + 0x00ce, 0x0005, 0x080c, 0x403d, 0x0cc0, 0x00c6, 0x00d6, 0x00e6, + 0x0016, 0x0026, 0x080c, 0x5687, 0x2071, 0x8daa, 0x713c, 0x81ff, + 0x0530, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x4c42, 0x1148, + 0x0036, 0x2019, 0x0001, 0x080c, 0x68e5, 0x003e, 0x080c, 0x4cbf, + 0x00b0, 0x6904, 0xa194, 0x4000, 0x01c0, 0x6803, 0x1000, 0x6803, + 0x0000, 0x0036, 0x2019, 0x0001, 0x080c, 0x68e5, 0x003e, 0x713c, + 0x2160, 0x080c, 0x8a4b, 0x2009, 0x004a, 0x080c, 0x6d3f, 0x002e, + 0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0c58, 0x00e6, 0x00d6, + 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, 0x0126, 0x2091, 0x8000, + 0x6018, 0x2068, 0x6ca0, 0x2071, 0x8daa, 0x7018, 0x2068, 0x8dff, + 0x0198, 0x68a0, 0xa406, 0x0118, 0x6854, 0x2068, 0x0cc0, 0x6010, + 0x2060, 0x643c, 0x6540, 0x6e48, 0x2d60, 0x080c, 0x4458, 0x0120, + 0x080c, 0x6a05, 0xa085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e, + 0x006e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x0156, 0x0146, 0x20a1, + 0x020b, 0x080c, 0x60a5, 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x7808, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x66e4, 0x014e, + 0x015e, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x612f, + 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a9, 0x0006, 0x2011, 0x8b40, + 0x2019, 0x8b41, 0x23a6, 0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, + 0x1f04, 0x67d2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, + 0x080c, 0x66e4, 0x014e, 0x015e, 0x0005, 0x0156, 0x0146, 0x0016, + 0x0026, 0x20a1, 0x020b, 0x080c, 0x6110, 0x080c, 0x6126, 0x7810, + 0x0006, 0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, + 0x53a6, 0xa080, 0x0004, 0x8003, 0x60c2, 0x000e, 0xa080, 0x0001, + 0x2004, 0x7812, 0x080c, 0x66e4, 0x002e, 0x001e, 0x014e, 0x015e, + 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x60a5, 0x20a3, + 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, 0x60c3, + 0x0008, 0x080c, 0x66e4, 0x014e, 0x015e, 0x0005, 0x0156, 0x0146, + 0x0016, 0x0026, 0x20a1, 0x020b, 0x080c, 0x60a5, 0x7810, 0x0006, + 0xa080, 0x0017, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x000e, 0xa080, 0x0001, 0x2004, 0x7812, 0x080c, - 0x6f0b, 0x002e, 0x001e, 0x014e, 0x015e, 0x0005, 0x0156, 0x0146, - 0x20a1, 0x020b, 0x080c, 0x681d, 0x20a3, 0x6200, 0x20a3, 0x0000, - 0x20a3, 0x0000, 0x7808, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x6f0b, - 0x014e, 0x015e, 0x0005, 0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, - 0x020b, 0x080c, 0x681d, 0x7810, 0x0006, 0xa080, 0x0017, 0x2098, - 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x000e, - 0xa080, 0x0001, 0x2004, 0x7812, 0x080c, 0x6f0b, 0x002e, 0x001e, - 0x014e, 0x015e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091, - 0x8000, 0x2071, 0x94e5, 0x700c, 0x2060, 0x8cff, 0x0168, 0x080c, - 0x84c8, 0x1110, 0x080c, 0x7776, 0x600c, 0x0006, 0x080c, 0x74f2, - 0x080c, 0x7238, 0x00ce, 0x0c88, 0x700f, 0x0000, 0x700b, 0x0000, - 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0156, 0x00f6, - 0x00e6, 0x00d6, 0x00c6, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, - 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x94e5, 0x7024, 0x2060, - 0x8cff, 0x05a0, 0x080c, 0x6f1e, 0x68c3, 0x0000, 0x080c, 0x57a1, - 0x2009, 0x0013, 0x080c, 0x7518, 0x20a9, 0x01f4, 0x6824, 0xd094, + 0x66e4, 0x002e, 0x001e, 0x014e, 0x015e, 0x0005, 0x00e6, 0x00c6, + 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x8daa, 0x700c, 0x2060, + 0x8cff, 0x0178, 0x080c, 0x7d69, 0x1110, 0x080c, 0x6fb6, 0x600c, + 0x0006, 0x080c, 0x7df6, 0x080c, 0x6d18, 0x080c, 0x6a05, 0x00ce, + 0x0c78, 0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x000e, 0x00ce, + 0x00ee, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, + 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, + 0x0140, 0x2071, 0x8daa, 0x7024, 0x2060, 0x8cff, 0x05a0, 0x080c, + 0x66f7, 0x68c3, 0x0000, 0x080c, 0x567a, 0x2009, 0x0013, 0x080c, + 0x6d3f, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158, 0x6827, 0x0004, + 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, 0x0000, + 0x0078, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0x6883, + 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, + 0x6824, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, 0x00fe, + 0x015e, 0x012e, 0x0005, 0x2001, 0x8b00, 0x2004, 0xa096, 0x0001, + 0x0550, 0xa096, 0x0004, 0x0538, 0x6817, 0x0008, 0x68c3, 0x0000, + 0x2011, 0x3fe7, 0x080c, 0x560d, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0xd084, 0x0118, 0x6827, 0x0001, - 0x0010, 0x1f04, 0x70ae, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, - 0x0100, 0x7803, 0x0000, 0x6824, 0x000e, 0x001e, 0x002e, 0x00ce, - 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x9200, - 0x2004, 0xa096, 0x0001, 0x0550, 0xa096, 0x0004, 0x0538, 0x6817, - 0x0008, 0x68c3, 0x0000, 0x2011, 0x40af, 0x080c, 0x5731, 0x20a9, - 0x01f4, 0x6824, 0xd094, 0x0158, 0x6827, 0x0004, 0x7804, 0xa084, - 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0xd084, - 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0x70e9, 0x7804, 0xa084, - 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, 0x000e, 0x001e, - 0x002e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, - 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0026, 0x0016, - 0x0006, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, - 0x94e5, 0x703c, 0x2060, 0x8cff, 0x0904, 0x7185, 0x6817, 0x0010, - 0x68c7, 0x0000, 0x68cb, 0x0000, 0x080c, 0x57ae, 0x080c, 0x1ef8, - 0x0046, 0x0056, 0x2009, 0x017f, 0x212c, 0x200b, 0x00a5, 0x2021, - 0x0169, 0x2404, 0xa084, 0x000f, 0xa086, 0x0004, 0x11b0, 0x68c7, - 0x0000, 0x68cb, 0x0008, 0x00e6, 0x00f6, 0x2079, 0x0020, 0x2071, - 0x953b, 0x6814, 0xa084, 0x0004, 0xa085, 0x0012, 0x6816, 0x7803, - 0x0008, 0x7003, 0x0000, 0x00fe, 0x00ee, 0x250a, 0x005e, 0x004e, - 0xa39d, 0x0000, 0x1150, 0x2009, 0x0049, 0x601c, 0xa086, 0x0009, - 0x1110, 0x2009, 0x0103, 0x080c, 0x7518, 0x20a9, 0x03e8, 0x6824, - 0xd094, 0x0158, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, - 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0xd094, 0x0118, 0x6827, - 0x0002, 0x0010, 0x1f04, 0x7167, 0x7804, 0xa084, 0x1000, 0x0120, - 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x000e, 0x001e, 0x002e, - 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, - 0x0126, 0x2091, 0x8000, 0x2069, 0x94e5, 0x6a06, 0x012e, 0x00de, - 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x94e5, 0x6a32, - 0x012e, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0006, - 0x0126, 0x2071, 0x94e5, 0x7614, 0x2660, 0x2678, 0x2091, 0x8000, - 0x8cff, 0x0538, 0x601c, 0xa206, 0x1500, 0x7014, 0xac36, 0x1110, - 0x660c, 0x7616, 0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, - 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, - 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, - 0x849b, 0x080c, 0x7238, 0x00ce, 0x08d8, 0x2c78, 0x600c, 0x2060, - 0x08b8, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, - 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6a9c, 0x7810, 0x20a2, - 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0804, - 0x7230, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6a9c, 0x7810, - 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000, - 0x0478, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6a9c, 0x7810, - 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000, - 0x00f8, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6a9c, 0x7810, - 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, - 0x0078, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6a9c, 0x7810, - 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200, - 0x0089, 0x60c3, 0x0020, 0x080c, 0x6f0b, 0x014e, 0x015e, 0x0005, - 0x00e6, 0x2071, 0x94e5, 0x7020, 0xa005, 0x0110, 0x8001, 0x7022, - 0x00ee, 0x0005, 0x20a9, 0x0008, 0x20a2, 0x1f04, 0x7244, 0x20a2, - 0x20a2, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, - 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x94e5, 0x7614, 0x2660, - 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0x72d2, 0x8cff, 0x0904, - 0x72d2, 0x601c, 0xa086, 0x0006, 0x1904, 0x72cd, 0x88ff, 0x0138, - 0x2800, 0xac06, 0x1904, 0x72cd, 0x2039, 0x0000, 0x0050, 0x6018, - 0xa206, 0x1904, 0x72cd, 0x85ff, 0x0120, 0x6020, 0xa106, 0x1904, - 0x72cd, 0x7024, 0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005, - 0x01f0, 0x080c, 0x57a1, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, - 0x7356, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, - 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, - 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0020, 0x6003, - 0x0009, 0x630a, 0x0450, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, - 0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, - 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, - 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c, - 0x82ee, 0x0110, 0x080c, 0x9097, 0x080c, 0x849b, 0x080c, 0x7238, - 0x88ff, 0x1190, 0x00ce, 0x0804, 0x725b, 0x2c78, 0x600c, 0x2060, - 0x0804, 0x725b, 0xa006, 0x012e, 0x000e, 0x006e, 0x007e, 0x00ce, - 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6017, 0x0000, 0x00ce, 0xa8c5, - 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, - 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x94e5, 0x7638, 0x2660, - 0x2678, 0x8cff, 0x0904, 0x7346, 0x601c, 0xa086, 0x0006, 0x1904, - 0x7341, 0x88ff, 0x0128, 0x2800, 0xac06, 0x1904, 0x7341, 0x0040, - 0x6018, 0xa206, 0x15f0, 0x85ff, 0x0118, 0x6020, 0xa106, 0x15c8, - 0x703c, 0xac06, 0x1170, 0x0036, 0x2019, 0x0001, 0x080c, 0x7110, - 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047, 0x0000, - 0x003e, 0x7038, 0xac36, 0x1110, 0x660c, 0x763a, 0x7034, 0xac36, - 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, - 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, - 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c, 0x82ee, 0x0110, - 0x080c, 0x9097, 0x080c, 0x849b, 0x88ff, 0x1190, 0x00ce, 0x0804, - 0x72f1, 0x2c78, 0x600c, 0x2060, 0x0804, 0x72f1, 0xa006, 0x012e, - 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, - 0x6017, 0x0000, 0x00ce, 0xa8c5, 0x0001, 0x0c88, 0x00e6, 0x2071, - 0x94e5, 0x2001, 0x9200, 0x2004, 0xa086, 0x0002, 0x1118, 0x7007, - 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, - 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, - 0x94e5, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0518, 0x2200, - 0xac06, 0x11e0, 0x7038, 0xac36, 0x1110, 0x660c, 0x763a, 0x7034, - 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, - 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, - 0x2678, 0x600f, 0x0000, 0xa085, 0x0001, 0x0020, 0x2c78, 0x600c, - 0x2060, 0x08d8, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, - 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0006, - 0x0126, 0x2091, 0x8000, 0x2071, 0x94e5, 0x760c, 0x2660, 0x2678, - 0x8cff, 0x0904, 0x7423, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, - 0x1904, 0x741e, 0x7024, 0xac06, 0x1500, 0x2069, 0x0100, 0x68c0, - 0xa005, 0x01d8, 0x080c, 0x6f1e, 0x68c3, 0x0000, 0x080c, 0x7356, - 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, - 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, - 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0xac36, 0x1110, - 0x660c, 0x760e, 0x7008, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, - 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, - 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, - 0x84b7, 0x1118, 0x080c, 0x2692, 0x00c0, 0x080c, 0x84c8, 0x1118, - 0x080c, 0x7776, 0x0090, 0x6010, 0x2068, 0x080c, 0x82ee, 0x0168, - 0x601c, 0xa086, 0x0003, 0x11f8, 0x6837, 0x0103, 0x6b4a, 0x6847, - 0x0000, 0x080c, 0x4809, 0x080c, 0x848f, 0x6003, 0x0000, 0x080c, - 0x849b, 0x080c, 0x7238, 0x00ce, 0x0804, 0x73b0, 0x2c78, 0x600c, - 0x2060, 0x0804, 0x73b0, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00de, - 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x19e8, 0x080c, - 0x9097, 0x0c18, 0x0036, 0x0156, 0x0136, 0x0146, 0x3908, 0xa006, - 0xa190, 0x0020, 0x221c, 0xa39e, 0x251b, 0x1118, 0x8210, 0x8000, - 0x0cc8, 0xa005, 0x0138, 0x20a9, 0x0020, 0x2198, 0xa110, 0x22a0, - 0x22c8, 0x53a3, 0x014e, 0x013e, 0x015e, 0x003e, 0x0005, 0x00d6, - 0x20a1, 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0200, 0x20a3, 0x0014, - 0x60c3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2099, 0x94df, - 0x20a9, 0x0004, 0x53a6, 0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x080c, 0x6f0b, 0x00de, 0x0005, 0x20a1, - 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0210, 0x20a3, 0x0018, 0x20a3, - 0x0800, 0x7810, 0xa084, 0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3, - 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7810, - 0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, - 0x0018, 0x080c, 0x6f0b, 0x0005, 0x2061, 0x9900, 0x2a70, 0x7064, - 0x7046, 0x704b, 0x9900, 0x0005, 0x00e6, 0x0126, 0x2071, 0x9200, - 0x2091, 0x8000, 0x7544, 0xa582, 0x0001, 0x0608, 0x7048, 0x2060, + 0x0010, 0x1f04, 0x68be, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, + 0x0100, 0x7803, 0x0000, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, + 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x0126, 0x0156, 0x00f6, + 0x00e6, 0x00d6, 0x00c6, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, + 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x8daa, 0x703c, 0x2060, + 0x8cff, 0x0904, 0x6952, 0x6817, 0x0010, 0x68c7, 0x0000, 0x68cb, + 0x0000, 0x080c, 0x5687, 0x080c, 0x1e15, 0x0046, 0x2009, 0x017f, + 0x200b, 0x00a5, 0x2021, 0x0169, 0x2404, 0xa084, 0x000f, 0xa086, + 0x0004, 0x11b0, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x00e6, 0x00f6, + 0x2079, 0x0020, 0x2071, 0x8dff, 0x6814, 0xa084, 0x0184, 0xa085, + 0x0012, 0x6816, 0x7803, 0x0008, 0x7003, 0x0000, 0x00fe, 0x00ee, + 0x200b, 0x0000, 0x004e, 0xa39d, 0x0000, 0x1120, 0x2009, 0x0049, + 0x080c, 0x6d3f, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0158, 0x6827, + 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, + 0x0000, 0x0078, 0xd094, 0x0118, 0x6827, 0x0002, 0x0010, 0x1f04, + 0x6934, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, + 0x0000, 0x6824, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, + 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, + 0x2069, 0x8daa, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, 0x0126, + 0x2091, 0x8000, 0x2069, 0x8daa, 0x6a32, 0x012e, 0x00de, 0x0005, + 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0006, 0x0126, 0x2071, 0x8daa, + 0x7614, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0538, 0x601c, + 0xa206, 0x1500, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, 0x7010, + 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, + 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, + 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0x7d3c, 0x080c, 0x6a05, + 0x00ce, 0x08d8, 0x2c78, 0x600c, 0x2060, 0x08b8, 0x012e, 0x000e, + 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0156, 0x0146, 0x20a1, + 0x020b, 0x080c, 0x6347, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, + 0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0804, 0x69fd, 0x0156, 0x0146, + 0x20a1, 0x020b, 0x080c, 0x6347, 0x7810, 0x20a2, 0xa006, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000, 0x0478, 0x0156, 0x0146, + 0x20a1, 0x020b, 0x080c, 0x6347, 0x7810, 0x20a2, 0xa006, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000, 0x00f8, 0x0156, 0x0146, + 0x20a1, 0x020b, 0x080c, 0x6347, 0x7810, 0x20a2, 0xa006, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078, 0x0156, 0x0146, + 0x20a1, 0x020b, 0x080c, 0x6347, 0x7810, 0x20a2, 0xa006, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200, 0x0089, 0x60c3, 0x0020, + 0x080c, 0x66e4, 0x014e, 0x015e, 0x0005, 0x00e6, 0x2071, 0x8daa, + 0x7020, 0xa005, 0x0110, 0x8001, 0x7022, 0x00ee, 0x0005, 0x20a9, + 0x0008, 0x20a2, 0x1f04, 0x6a11, 0x20a2, 0x20a2, 0x0005, 0x00f6, + 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, 0x0126, 0x2091, + 0x8000, 0x2071, 0x8daa, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001, + 0x87ff, 0x0904, 0x6a9f, 0x8cff, 0x0904, 0x6a9f, 0x601c, 0xa086, + 0x0006, 0x1904, 0x6a9a, 0x88ff, 0x0138, 0x2800, 0xac06, 0x1904, + 0x6a9a, 0x2039, 0x0000, 0x0050, 0x6018, 0xa206, 0x1904, 0x6a9a, + 0x85ff, 0x0120, 0x6020, 0xa106, 0x1904, 0x6a9a, 0x7024, 0xac06, + 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, 0x567a, + 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0x6b23, 0x7027, 0x0000, + 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, + 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, + 0x6827, 0x0001, 0x003e, 0x0020, 0x6003, 0x0009, 0x630a, 0x0450, + 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, 0x7010, 0xac36, 0x1140, + 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, + 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, + 0x600f, 0x0000, 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0110, 0x080c, + 0x8942, 0x080c, 0x7d3c, 0x080c, 0x6a05, 0x88ff, 0x1190, 0x00ce, + 0x0804, 0x6a28, 0x2c78, 0x600c, 0x2060, 0x0804, 0x6a28, 0xa006, + 0x012e, 0x000e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, + 0x0005, 0x6017, 0x0000, 0x00ce, 0xa8c5, 0x0001, 0x0c88, 0x00f6, + 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, + 0x8000, 0x2071, 0x8daa, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, + 0x6b13, 0x601c, 0xa086, 0x0006, 0x1904, 0x6b0e, 0x88ff, 0x0128, + 0x2800, 0xac06, 0x1904, 0x6b0e, 0x0040, 0x6018, 0xa206, 0x15f0, + 0x85ff, 0x0118, 0x6020, 0xa106, 0x15c8, 0x703c, 0xac06, 0x1170, + 0x0036, 0x2019, 0x0001, 0x080c, 0x68e5, 0x7033, 0x0000, 0x703f, + 0x0000, 0x7043, 0x0000, 0x7047, 0x0000, 0x003e, 0x7038, 0xac36, + 0x1110, 0x660c, 0x763a, 0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, + 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, + 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, + 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0110, 0x080c, 0x8942, 0x080c, + 0x7d3c, 0x88ff, 0x1190, 0x00ce, 0x0804, 0x6abe, 0x2c78, 0x600c, + 0x2060, 0x0804, 0x6abe, 0xa006, 0x012e, 0x000e, 0x002e, 0x006e, + 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6017, 0x0000, 0x00ce, + 0xa8c5, 0x0001, 0x0c88, 0x00e6, 0x2071, 0x8daa, 0x2001, 0x8b00, + 0x2004, 0xa086, 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, 0x7007, + 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, + 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x8daa, 0x2c10, 0x7638, + 0x2660, 0x2678, 0x8cff, 0x0518, 0x2200, 0xac06, 0x11e0, 0x7038, + 0xac36, 0x1110, 0x660c, 0x763a, 0x7034, 0xac36, 0x1140, 0x2c00, + 0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, + 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, + 0xa085, 0x0001, 0x0020, 0x2c78, 0x600c, 0x2060, 0x08d8, 0x012e, + 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00f6, + 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0006, 0x0126, 0x2091, 0x8000, + 0x2071, 0x8daa, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0x6bf2, + 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, 0x6bed, 0x7024, + 0xac06, 0x1500, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01d8, 0x080c, + 0x66f7, 0x68c3, 0x0000, 0x080c, 0x6b23, 0x7027, 0x0000, 0x0036, + 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, + 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, + 0x0001, 0x003e, 0x700c, 0xac36, 0x1110, 0x660c, 0x760e, 0x7008, + 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x700a, 0x0010, + 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, + 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0x7d58, 0x1118, 0x080c, + 0x2589, 0x00c0, 0x080c, 0x7d69, 0x1118, 0x080c, 0x6fb6, 0x0090, + 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0168, 0x601c, 0xa086, 0x0003, + 0x1508, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x46a1, + 0x080c, 0x7d30, 0x6003, 0x0000, 0x080c, 0x7df6, 0x080c, 0x7d3c, + 0x080c, 0x6a05, 0x00ce, 0x0804, 0x6b7d, 0x2c78, 0x600c, 0x2060, + 0x0804, 0x6b7d, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00de, 0x00ee, + 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x19d8, 0x080c, 0x8942, + 0x0c08, 0x0036, 0x0156, 0x0136, 0x0146, 0x3908, 0xa006, 0xa190, + 0x0020, 0x221c, 0xa39e, 0x23f9, 0x1118, 0x8210, 0x8000, 0x0cc8, + 0xa005, 0x0138, 0x20a9, 0x0020, 0x2198, 0xa110, 0x22a0, 0x22c8, + 0x53a3, 0x014e, 0x013e, 0x015e, 0x003e, 0x0005, 0x00d6, 0x20a1, + 0x020b, 0x080c, 0x612f, 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3, + 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2099, 0x8da4, 0x20a9, + 0x0004, 0x53a6, 0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x080c, 0x66e4, 0x00de, 0x0005, 0x20a1, 0x020b, + 0x080c, 0x612f, 0x20a3, 0x0210, 0x20a3, 0x0018, 0x20a3, 0x0800, + 0x7810, 0xa084, 0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7810, 0xa084, + 0x00ff, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, + 0x080c, 0x66e4, 0x0005, 0x20a1, 0x020b, 0x0079, 0x7910, 0x21a2, + 0x20a3, 0x0000, 0x60c3, 0x0000, 0x20e1, 0x9080, 0x60a7, 0x9575, + 0x080c, 0x66ee, 0x080c, 0x5671, 0x0005, 0x0156, 0x0136, 0x0036, + 0x00d6, 0x00e6, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7824, 0x2068, + 0xadf0, 0x000f, 0x7210, 0xa296, 0x00c0, 0xa294, 0xfffd, 0x7212, + 0x7214, 0xa294, 0x0300, 0x7216, 0x7100, 0xa194, 0x00ff, 0x7308, + 0xa384, 0x00ff, 0xa08d, 0xc200, 0x7102, 0xa384, 0xff00, 0xa215, + 0x720a, 0x7004, 0x720c, 0x700e, 0x7206, 0x20a9, 0x000a, 0x2e98, + 0x53a6, 0x60a3, 0x0035, 0x6a38, 0xa294, 0x7000, 0xa286, 0x3000, + 0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x003e, 0x013e, 0x015e, + 0x0005, 0x2009, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, + 0x6116, 0x0005, 0x2061, 0x9200, 0x2a70, 0x7064, 0x7046, 0x704b, + 0x9200, 0x0005, 0x00e6, 0x0126, 0x2071, 0x8b00, 0x2091, 0x8000, + 0x7544, 0xa582, 0x0001, 0x0608, 0x7048, 0x2060, 0x6000, 0xa086, + 0x0000, 0x0148, 0xace0, 0x000c, 0x7058, 0xac02, 0x1208, 0x0cb0, + 0x2061, 0x9200, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8, + 0x000c, 0x7058, 0xa502, 0x1230, 0x754a, 0xa085, 0x0001, 0x012e, + 0x00ee, 0x0005, 0x704b, 0x9200, 0x0cc0, 0xa006, 0x0cc0, 0x00e6, + 0x2071, 0x8b00, 0x7544, 0xa582, 0x0001, 0x0600, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0148, 0xace0, 0x000c, 0x7058, 0xac02, - 0x1208, 0x0cb0, 0x2061, 0x9900, 0x0c98, 0x6003, 0x0008, 0x8529, - 0x7546, 0xaca8, 0x000c, 0x7058, 0xa502, 0x1230, 0x754a, 0xa085, - 0x0001, 0x012e, 0x00ee, 0x0005, 0x704b, 0x9900, 0x0cc0, 0xa006, - 0x0cc0, 0x00e6, 0x2071, 0x9200, 0x7544, 0xa582, 0x0001, 0x0600, - 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0148, 0xace0, 0x000c, - 0x7058, 0xac02, 0x1208, 0x0cb0, 0x2061, 0x9900, 0x0c98, 0x6003, - 0x0008, 0x8529, 0x7546, 0xaca8, 0x000c, 0x7058, 0xa502, 0x1228, - 0x754a, 0xa085, 0x0001, 0x00ee, 0x0005, 0x704b, 0x9900, 0x0cc8, - 0xa006, 0x0cc8, 0xac82, 0x9900, 0x0a0c, 0x13fe, 0x2001, 0x9216, - 0x2004, 0xac02, 0x1a0c, 0x13fe, 0xa006, 0x6006, 0x600a, 0x600e, - 0x6012, 0x6016, 0x601a, 0x601f, 0x0000, 0x6003, 0x0000, 0x6022, - 0x2061, 0x9200, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0108, - 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x6462, 0x012e, 0x0cc0, - 0x601c, 0xa084, 0x000f, 0x0002, 0x7526, 0x752d, 0x7548, 0x7563, - 0x8555, 0x8570, 0x858b, 0x7526, 0x752d, 0x5d3d, 0xa18e, 0x0047, - 0x1118, 0xa016, 0x080c, 0x16c6, 0x0005, 0x0066, 0x6000, 0xa0b2, - 0x0010, 0x1a0c, 0x13fe, 0x0013, 0x006e, 0x0005, 0x7546, 0x7654, - 0x779c, 0x7546, 0x77eb, 0x7546, 0x7546, 0x7546, 0x75f6, 0x7b03, - 0x7546, 0x7546, 0x7546, 0x7546, 0x7546, 0x7546, 0x080c, 0x13fe, - 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x13fe, 0x0013, 0x006e, - 0x0005, 0x7561, 0x7fa1, 0x7561, 0x7561, 0x7561, 0x7561, 0x7561, - 0x7561, 0x7f89, 0x8078, 0x7561, 0x7fce, 0x8023, 0x7fce, 0x8023, - 0x7561, 0x080c, 0x13fe, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, - 0x13fe, 0x0013, 0x006e, 0x0005, 0x757c, 0x7b3f, 0x7bf0, 0x7cb4, - 0x7df4, 0x757c, 0x757c, 0x757c, 0x7b1b, 0x7f40, 0x7f43, 0x757c, - 0x757c, 0x757c, 0x757c, 0x7f66, 0x080c, 0x13fe, 0x20a9, 0x000e, - 0x2e98, 0x6010, 0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420, - 0x9398, 0x94a0, 0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002, - 0xa5a8, 0x0002, 0xa398, 0x0002, 0xa4a0, 0x0002, 0x1f04, 0x758c, - 0x00e6, 0x080c, 0x82ee, 0x0130, 0x6010, 0x2070, 0x7007, 0x0000, - 0x7037, 0x0103, 0x00ee, 0x080c, 0x74f2, 0x0005, 0x00d6, 0x0036, - 0x7330, 0xa386, 0x0200, 0x1130, 0x6018, 0x2068, 0x6813, 0x00ff, - 0x6817, 0xfffd, 0x6010, 0xa005, 0x0130, 0x2068, 0x6807, 0x0000, - 0x6837, 0x0103, 0x6b32, 0x080c, 0x74f2, 0x003e, 0x00de, 0x0005, - 0x0016, 0x20a9, 0x002a, 0xae80, 0x000c, 0x2098, 0x6010, 0xa080, - 0x0002, 0x20a0, 0x53a3, 0x20a9, 0x002a, 0x6010, 0xa080, 0x0001, - 0x2004, 0xa080, 0x0002, 0x20a0, 0x53a3, 0x00e6, 0x6010, 0x2004, - 0x2070, 0x7037, 0x0103, 0x00ee, 0x080c, 0x74f2, 0x001e, 0x0005, - 0x00d6, 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0, 0x53a3, 0xa1b6, - 0x0015, 0x1148, 0x6018, 0x2068, 0x7038, 0x680a, 0x703c, 0x680e, - 0x6800, 0xc08d, 0x6802, 0x00de, 0x0804, 0x7598, 0x2100, 0xa1b2, - 0x003e, 0x1a0c, 0x13fe, 0x0002, 0x763c, 0x7648, 0x763c, 0x763c, - 0x763c, 0x763c, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, - 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, - 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, - 0x763a, 0x763a, 0x763a, 0x763c, 0x763a, 0x763c, 0x763c, 0x763a, - 0x763a, 0x763a, 0x763a, 0x763a, 0x763c, 0x763a, 0x763a, 0x763a, - 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763c, 0x763a, - 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, - 0x763a, 0x763c, 0x080c, 0x13fe, 0x6003, 0x0001, 0x6106, 0x080c, - 0x603e, 0x0126, 0x2091, 0x8000, 0x080c, 0x6462, 0x012e, 0x0005, - 0x6003, 0x0001, 0x6106, 0x080c, 0x603e, 0x0126, 0x2091, 0x8000, - 0x080c, 0x6462, 0x012e, 0x0005, 0x6004, 0xa0b2, 0x003e, 0x1a0c, - 0x13fe, 0xa1b6, 0x0013, 0x0904, 0x76f0, 0xa1b6, 0x0027, 0x1904, - 0x76b6, 0x080c, 0x6389, 0x6004, 0x080c, 0x84b7, 0x0178, 0x080c, - 0x84c8, 0x0904, 0x76b0, 0xa08e, 0x0021, 0x0904, 0x76b3, 0xa08e, - 0x0022, 0x05f0, 0xa08e, 0x003d, 0x05f0, 0x04a8, 0x080c, 0x2692, - 0x2001, 0x0007, 0x080c, 0x43e3, 0x6018, 0xa080, 0x0028, 0x200c, - 0x080c, 0x7776, 0xa186, 0x007e, 0x1148, 0x2001, 0x9232, 0x2014, - 0xc285, 0x080c, 0x4dc5, 0x1108, 0xc2ad, 0x2202, 0x0016, 0x0026, - 0x0036, 0x2110, 0x2019, 0x0028, 0x080c, 0x6127, 0x0086, 0x2041, - 0x0000, 0x080c, 0x606d, 0x00c6, 0x6018, 0xa065, 0x0110, 0x080c, - 0x460d, 0x00ce, 0x2c08, 0x080c, 0x8ee4, 0x008e, 0x003e, 0x002e, - 0x001e, 0x080c, 0x441f, 0x080c, 0x74f2, 0x080c, 0x6462, 0x0005, - 0x080c, 0x7776, 0x0cc0, 0x080c, 0x7790, 0x0ca8, 0xa186, 0x0014, - 0x1db0, 0x080c, 0x6389, 0x080c, 0x266c, 0x080c, 0x84b7, 0x1188, - 0x080c, 0x2692, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x7776, - 0xa186, 0x007e, 0x1128, 0x2001, 0x9232, 0x200c, 0xc185, 0x2102, - 0x08d0, 0x080c, 0x84c8, 0x1118, 0x080c, 0x7776, 0x08a0, 0x6004, - 0xa08e, 0x0032, 0x1158, 0x00e6, 0x00f6, 0x2071, 0x9296, 0x2079, - 0x0000, 0x080c, 0x2924, 0x00fe, 0x00ee, 0x0828, 0x6004, 0xa08e, - 0x0021, 0x0d50, 0xa08e, 0x0022, 0x090c, 0x7790, 0x0804, 0x76ab, - 0x2008, 0x0002, 0x7732, 0x7733, 0x7736, 0x7739, 0x773c, 0x773f, - 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, - 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, - 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, - 0x7742, 0x7747, 0x7730, 0x7750, 0x7747, 0x7730, 0x7730, 0x7730, - 0x7730, 0x7730, 0x7747, 0x7747, 0x7730, 0x7730, 0x7730, 0x7730, - 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, - 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7747, - 0x080c, 0x13fe, 0x00a0, 0x2001, 0x000b, 0x0418, 0x2001, 0x0003, - 0x0400, 0x2001, 0x0005, 0x00e8, 0x2001, 0x0001, 0x00d0, 0x2001, - 0x0009, 0x00b8, 0x080c, 0x13fe, 0x0098, 0x080c, 0x43e3, 0x080c, - 0x6389, 0x6003, 0x0002, 0x6017, 0x0028, 0x080c, 0x6462, 0x0040, - 0x080c, 0x6389, 0x6003, 0x0004, 0x6017, 0x0028, 0x080c, 0x6462, - 0x0005, 0x080c, 0x43e3, 0x080c, 0x6389, 0x6003, 0x0002, 0x0036, - 0x2019, 0x925c, 0x2304, 0xa084, 0xff00, 0x1118, 0x2019, 0x0028, - 0x0040, 0x8007, 0xa09a, 0x0004, 0x0ec8, 0x8003, 0x801b, 0x831b, - 0xa318, 0x6316, 0x003e, 0x080c, 0x6462, 0x0c10, 0x00e6, 0x080c, - 0x82ee, 0x0188, 0x6010, 0x2070, 0x7007, 0x0000, 0x0016, 0x6004, - 0xa08e, 0x0021, 0x0150, 0xa08e, 0x003d, 0x0138, 0x001e, 0x7037, - 0x0103, 0x7033, 0x0100, 0x00ee, 0x0005, 0x001e, 0x0009, 0x0cd8, - 0x00e6, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, - 0x7023, 0x8001, 0x00ee, 0x0005, 0x00d6, 0x6618, 0x2668, 0x6804, - 0xa084, 0x00ff, 0x00de, 0xa0b2, 0x000c, 0x1a0c, 0x13fe, 0x6604, - 0xa6b6, 0x0028, 0x1118, 0x080c, 0x84f2, 0x0468, 0x6604, 0xa6b6, - 0x0029, 0x1118, 0x080c, 0x8509, 0x0430, 0x6604, 0xa6b6, 0x001f, - 0x1118, 0x080c, 0x757e, 0x00f8, 0x6604, 0xa6b6, 0x0000, 0x1118, - 0x080c, 0x75e0, 0x00c0, 0x6604, 0xa6b6, 0x0022, 0x1118, 0x080c, - 0x75a6, 0x0088, 0x6604, 0xa6b6, 0x003d, 0x1118, 0x080c, 0x75c0, - 0x0050, 0xa1b6, 0x0015, 0x1110, 0x0053, 0x0028, 0xa1b6, 0x0016, - 0x1118, 0x0804, 0x7983, 0x0005, 0x080c, 0x7526, 0x0ce0, 0x7805, - 0x7808, 0x7805, 0x7844, 0x7805, 0x7923, 0x7805, 0x7805, 0x7805, - 0x795b, 0x7805, 0x7971, 0xa1b6, 0x0048, 0x0140, 0x20e1, 0x0005, - 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x16c6, 0x0005, 0x00e6, 0xacf0, - 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, 0x00ee, 0x080c, - 0x74f2, 0x0005, 0x080c, 0x74f2, 0x0005, 0xe000, 0xe000, 0x0005, - 0x00e6, 0x2071, 0x9200, 0x7080, 0xa086, 0x0074, 0x11f0, 0x080c, - 0x8ebb, 0x1170, 0x00d6, 0x6018, 0x2068, 0x00e9, 0x00de, 0x2001, - 0x0006, 0x080c, 0x43e3, 0x080c, 0x2692, 0x080c, 0x74f2, 0x0088, - 0x2001, 0x000a, 0x080c, 0x43e3, 0x080c, 0x2692, 0x6003, 0x0001, - 0x6007, 0x0001, 0x080c, 0x603e, 0x0020, 0x2001, 0x0001, 0x080c, - 0x7910, 0x00ee, 0x0005, 0x6800, 0xd084, 0x0168, 0x2001, 0x0000, - 0x080c, 0x43d1, 0x2069, 0x9251, 0x6804, 0xd0a4, 0x0120, 0x2001, - 0x0006, 0x080c, 0x43f1, 0x0005, 0x00d6, 0x2011, 0x9220, 0x2204, - 0xa086, 0x0074, 0x1904, 0x790b, 0x080c, 0x7a64, 0x6018, 0x2068, - 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x0198, 0xa286, 0x0080, - 0x1904, 0x789c, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005, - 0x0588, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833, 0x0200, - 0x0448, 0x00d6, 0x00e6, 0x00f6, 0x6813, 0x00ff, 0x6817, 0xfffe, - 0x2071, 0x9232, 0x2e04, 0xa085, 0x0003, 0x2072, 0x2071, 0x9780, - 0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0x921b, 0x206a, - 0x78e6, 0x8e70, 0x2e04, 0x2069, 0x921c, 0x206a, 0x78ea, 0x7832, - 0x7836, 0xa084, 0x00ff, 0x2008, 0x080c, 0x2435, 0x00fe, 0x00ee, - 0x00de, 0x00f8, 0x2001, 0x0006, 0x080c, 0x43e3, 0x080c, 0x2692, - 0x080c, 0x74f2, 0x0804, 0x790e, 0x6010, 0xa005, 0x0130, 0x2068, - 0x6838, 0xd0f4, 0x0110, 0x0804, 0x7862, 0x2001, 0x0004, 0x080c, - 0x43e3, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x603e, 0x0804, - 0x790e, 0x685c, 0xd0e4, 0x01c8, 0x080c, 0x8531, 0x080c, 0x4dc5, - 0x0110, 0xd0dc, 0x19b8, 0x2011, 0x9232, 0x2204, 0xc0ad, 0x2012, - 0x2001, 0x94c8, 0x2004, 0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, - 0x080c, 0x2460, 0x78e2, 0x00fe, 0x0828, 0x080c, 0x854a, 0x2011, - 0x9232, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0x8fa4, 0x000e, - 0x1904, 0x7892, 0xc0b5, 0x2012, 0x2001, 0x0000, 0x080c, 0x43d1, - 0x00c6, 0x2009, 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932, - 0x7936, 0x00fe, 0x080c, 0x2435, 0x2001, 0x9214, 0x2004, 0x2009, - 0x0000, 0x080c, 0x240b, 0x2001, 0x9213, 0x2102, 0x8108, 0x080c, - 0x4400, 0x2c00, 0x00ce, 0x1904, 0x7892, 0x601a, 0x2001, 0x0002, - 0x080c, 0x43e3, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, - 0x080c, 0x603e, 0x0018, 0x2001, 0x0001, 0x0011, 0x00de, 0x0005, - 0x0006, 0x2001, 0x9200, 0x2004, 0xa086, 0x0003, 0x000e, 0x0130, - 0xa005, 0x0120, 0x2001, 0x0007, 0x080c, 0x43e3, 0x080c, 0x2692, - 0x080c, 0x74f2, 0x0005, 0x00e6, 0x2071, 0x9200, 0x7080, 0xa086, - 0x0014, 0x1548, 0x7000, 0xa086, 0x0003, 0x1128, 0x6010, 0xa005, - 0x1110, 0x080c, 0x370a, 0x00d6, 0x6018, 0x2068, 0x080c, 0x44c7, - 0x080c, 0x7833, 0x00de, 0x080c, 0x7a6e, 0x11a8, 0x2001, 0x0006, - 0x080c, 0x43e3, 0x00e6, 0x6010, 0xa005, 0x0138, 0x2070, 0x7007, - 0x0000, 0x7037, 0x0103, 0x7033, 0x0200, 0x00ee, 0x080c, 0x2692, - 0x080c, 0x74f2, 0x0030, 0x080c, 0x7776, 0x2001, 0x0000, 0x080c, - 0x7910, 0x00ee, 0x0005, 0x2011, 0x9220, 0x2204, 0xa086, 0x0014, - 0x1158, 0x2001, 0x0002, 0x080c, 0x43e3, 0x6003, 0x0001, 0x6007, - 0x0001, 0x080c, 0x603e, 0x0020, 0x2001, 0x0001, 0x080c, 0x7910, - 0x0005, 0x2011, 0x9220, 0x2204, 0xa086, 0x0004, 0x1138, 0x2001, - 0x0007, 0x080c, 0x43e3, 0x080c, 0x74f2, 0x0020, 0x2001, 0x0001, - 0x080c, 0x7910, 0x0005, 0x000b, 0x0005, 0x7805, 0x7991, 0x7805, - 0x79b5, 0x7805, 0x7a1a, 0x7805, 0x7802, 0x7805, 0x7a2f, 0x7805, - 0x7a41, 0x00c6, 0x080c, 0x7a53, 0x1178, 0x2001, 0x0000, 0x080c, - 0x43d1, 0x2001, 0x0002, 0x080c, 0x43e3, 0x6003, 0x0001, 0x6007, - 0x0002, 0x080c, 0x603e, 0x0078, 0x2009, 0x978f, 0x2104, 0xa084, - 0xff00, 0xa086, 0x1900, 0x1118, 0x080c, 0x74f2, 0x0020, 0x2001, - 0x0001, 0x080c, 0x7910, 0x00ce, 0x0005, 0x080c, 0x7a61, 0x00d6, - 0x2069, 0x94d7, 0x2d04, 0xa005, 0x0168, 0x6018, 0x2068, 0x68a0, - 0xa086, 0x007e, 0x1138, 0x2069, 0x921c, 0x2d04, 0x8000, 0x206a, - 0x00de, 0x0010, 0x00de, 0x0078, 0x2001, 0x0000, 0x080c, 0x43d1, - 0x2001, 0x0002, 0x080c, 0x43e3, 0x6003, 0x0001, 0x6007, 0x0002, - 0x080c, 0x603e, 0x0400, 0x080c, 0x7776, 0x2009, 0x978e, 0x2134, - 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x01b8, 0x2009, 0x978f, 0x2104, - 0xa084, 0xff00, 0xa086, 0x1900, 0x1150, 0xa686, 0x0009, 0x0160, - 0x2001, 0x0004, 0x080c, 0x43e3, 0x080c, 0x74f2, 0x0020, 0x2001, - 0x0001, 0x080c, 0x7910, 0x0005, 0x00d6, 0x6010, 0x2068, 0x080c, - 0x82ee, 0x0128, 0x6838, 0xd0fc, 0x0110, 0x00de, 0x0c80, 0x6018, - 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0140, 0x8001, 0x6842, - 0x6017, 0x000a, 0x6007, 0x0016, 0x00de, 0x0c28, 0x080c, 0x266c, - 0x00de, 0x08e8, 0x080c, 0x7a61, 0x1158, 0x2001, 0x0004, 0x080c, - 0x43e3, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x603e, 0x0030, - 0x080c, 0x7776, 0x2001, 0x0000, 0x080c, 0x7910, 0x0005, 0x0489, - 0x1158, 0x2001, 0x0008, 0x080c, 0x43e3, 0x6003, 0x0001, 0x6007, - 0x0005, 0x080c, 0x603e, 0x0020, 0x2001, 0x0001, 0x080c, 0x7910, - 0x0005, 0x00f9, 0x1158, 0x2001, 0x000a, 0x080c, 0x43e3, 0x6003, - 0x0001, 0x6007, 0x0001, 0x080c, 0x603e, 0x0020, 0x2001, 0x0001, - 0x080c, 0x7910, 0x0005, 0x2009, 0x978e, 0x2104, 0xa086, 0x0003, - 0x1138, 0x2009, 0x978f, 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, + 0x1208, 0x0cb0, 0x2061, 0x9200, 0x0c98, 0x6003, 0x0008, 0x8529, + 0x7546, 0xaca8, 0x000c, 0x7058, 0xa502, 0x1228, 0x754a, 0xa085, + 0x0001, 0x00ee, 0x0005, 0x704b, 0x9200, 0x0cc8, 0xa006, 0x0cc8, + 0xac82, 0x9200, 0x0a0c, 0x1410, 0x2001, 0x8b16, 0x2004, 0xac02, + 0x1a0c, 0x1410, 0xa006, 0x6006, 0x600a, 0x600e, 0x6012, 0x6016, + 0x601a, 0x601f, 0x0000, 0x6003, 0x0000, 0x6022, 0x6026, 0x2061, + 0x8b00, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0108, 0x0005, + 0x0126, 0x2091, 0x8000, 0x080c, 0x5d10, 0x012e, 0x0cc0, 0x601c, + 0xa084, 0x000f, 0x0002, 0x6d4d, 0x6d5c, 0x6d77, 0x6d92, 0x7dfe, + 0x7e19, 0x7e34, 0x6d4d, 0x6d5c, 0x6d4d, 0xa186, 0x0013, 0x1128, + 0x080c, 0x5c37, 0x080c, 0x5d10, 0x0005, 0xa18e, 0x0047, 0x1118, + 0xa016, 0x080c, 0x16d1, 0x0005, 0x0066, 0x6000, 0xa0b2, 0x0010, + 0x1a0c, 0x1410, 0x0013, 0x006e, 0x0005, 0x6d75, 0x6e85, 0x6fdf, + 0x6d75, 0x702e, 0x6d75, 0x6d75, 0x6d75, 0x6e25, 0x733b, 0x6d75, + 0x6d75, 0x6d75, 0x6d75, 0x6d75, 0x6d75, 0x080c, 0x1410, 0x0066, + 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x1410, 0x0013, 0x006e, 0x0005, + 0x6d90, 0x77f2, 0x6d90, 0x6d90, 0x6d90, 0x6d90, 0x6d90, 0x6d90, + 0x77da, 0x78d0, 0x6d90, 0x781f, 0x7877, 0x781f, 0x7877, 0x6d90, + 0x080c, 0x1410, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x1410, + 0x0013, 0x006e, 0x0005, 0x6dab, 0x7377, 0x742b, 0x74ef, 0x762f, + 0x6dab, 0x6dab, 0x6dab, 0x7353, 0x778f, 0x7792, 0x6dab, 0x6dab, + 0x6dab, 0x6dab, 0x77b7, 0x080c, 0x1410, 0x20a9, 0x000e, 0x2e98, + 0x6010, 0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420, 0x9398, + 0x94a0, 0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002, 0xa5a8, + 0x0002, 0xa398, 0x0002, 0xa4a0, 0x0002, 0x1f04, 0x6dbb, 0x00e6, + 0x080c, 0x7b8f, 0x0130, 0x6010, 0x2070, 0x7007, 0x0000, 0x7037, + 0x0103, 0x00ee, 0x080c, 0x6d18, 0x0005, 0x00d6, 0x0036, 0x7330, + 0xa386, 0x0200, 0x1130, 0x6018, 0x2068, 0x6813, 0x00ff, 0x6817, + 0xfffd, 0x6010, 0xa005, 0x0130, 0x2068, 0x6807, 0x0000, 0x6837, + 0x0103, 0x6b32, 0x080c, 0x6d18, 0x003e, 0x00de, 0x0005, 0x0016, + 0x20a9, 0x002a, 0xae80, 0x000c, 0x2098, 0x6010, 0xa080, 0x0002, + 0x20a0, 0x53a3, 0x20a9, 0x002a, 0x6010, 0xa080, 0x0001, 0x2004, + 0xa080, 0x0002, 0x20a0, 0x53a3, 0x00e6, 0x6010, 0x2004, 0x2070, + 0x7037, 0x0103, 0x00ee, 0x080c, 0x6d18, 0x001e, 0x0005, 0x00d6, + 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, + 0x1148, 0x6018, 0x2068, 0x7038, 0x680a, 0x703c, 0x680e, 0x6800, + 0xc08d, 0x6802, 0x00de, 0x0804, 0x6dc7, 0x2100, 0xa1b2, 0x0040, + 0x1a0c, 0x1410, 0x0002, 0x6e6d, 0x6e79, 0x6e6d, 0x6e6d, 0x6e6d, + 0x6e6d, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, + 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, + 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, + 0x6e6b, 0x6e6b, 0x6e6d, 0x6e6b, 0x6e6d, 0x6e6d, 0x6e6b, 0x6e6b, + 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6d, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, + 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6d, 0x6e6b, 0x6e6b, + 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, + 0x6e6d, 0x6e6b, 0x6e6b, 0x080c, 0x1410, 0x6003, 0x0001, 0x6106, + 0x080c, 0x58e2, 0x0126, 0x2091, 0x8000, 0x080c, 0x5d10, 0x012e, + 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x58e2, 0x0126, 0x2091, + 0x8000, 0x080c, 0x5d10, 0x012e, 0x0005, 0x6004, 0xa0b2, 0x0040, + 0x1a0c, 0x1410, 0xa1b6, 0x0013, 0x0904, 0x6f25, 0xa1b6, 0x0027, + 0x1904, 0x6eeb, 0x080c, 0x5c37, 0x6004, 0x080c, 0x7d58, 0x0188, + 0x080c, 0x7d69, 0x0904, 0x6ee5, 0xa08e, 0x0021, 0x0904, 0x6ee8, + 0xa08e, 0x0022, 0x0904, 0x6ee5, 0xa08e, 0x003d, 0x0904, 0x6ee8, + 0x04a8, 0x080c, 0x2589, 0x2001, 0x0007, 0x080c, 0x42b9, 0x6018, + 0xa080, 0x0028, 0x200c, 0x080c, 0x6fb6, 0xa186, 0x007e, 0x1148, + 0x2001, 0x8b32, 0x2014, 0xc285, 0x080c, 0x4c42, 0x1108, 0xc2ad, + 0x2202, 0x0016, 0x0026, 0x0036, 0x2110, 0x2019, 0x0028, 0x080c, + 0x59d5, 0x0086, 0x2041, 0x0000, 0x080c, 0x5911, 0x00c6, 0x6018, + 0xa065, 0x0110, 0x080c, 0x44e6, 0x00ce, 0x2c08, 0x080c, 0x878f, + 0x008e, 0x003e, 0x002e, 0x001e, 0x080c, 0x42f5, 0x080c, 0x7df6, + 0x080c, 0x6d18, 0x080c, 0x5d10, 0x0005, 0x080c, 0x6fb6, 0x0cb0, + 0x080c, 0x6fd3, 0x0c98, 0xa186, 0x0014, 0x1db0, 0x080c, 0x5c37, + 0x080c, 0x2563, 0x080c, 0x7d58, 0x1188, 0x080c, 0x2589, 0x6018, + 0xa080, 0x0028, 0x200c, 0x080c, 0x6fb6, 0xa186, 0x007e, 0x1128, + 0x2001, 0x8b32, 0x200c, 0xc185, 0x2102, 0x08c0, 0x080c, 0x7d69, + 0x1118, 0x080c, 0x6fb6, 0x0890, 0x6004, 0xa08e, 0x0032, 0x1158, + 0x00e6, 0x00f6, 0x2071, 0x8b81, 0x2079, 0x0000, 0x080c, 0x2848, + 0x00fe, 0x00ee, 0x0818, 0x6004, 0xa08e, 0x0021, 0x0d50, 0xa08e, + 0x0022, 0x090c, 0x6fd3, 0x0804, 0x6ede, 0x2008, 0x0002, 0x6f69, + 0x6f6a, 0x6f6d, 0x6f70, 0x6f73, 0x6f76, 0x6f67, 0x6f67, 0x6f67, + 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, + 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, + 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f79, 0x6f7e, 0x6f67, + 0x6f87, 0x6f7e, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f7e, + 0x6f7e, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, + 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, + 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f7e, 0x6fad, 0x6f67, 0x080c, + 0x1410, 0x00a0, 0x2001, 0x000b, 0x0418, 0x2001, 0x0003, 0x0400, + 0x2001, 0x0005, 0x00e8, 0x2001, 0x0001, 0x00d0, 0x2001, 0x0009, + 0x00b8, 0x080c, 0x1410, 0x0098, 0x080c, 0x42b9, 0x080c, 0x5c37, + 0x6003, 0x0002, 0x6017, 0x0028, 0x080c, 0x5d10, 0x0040, 0x080c, + 0x5c37, 0x6003, 0x0004, 0x6017, 0x0028, 0x080c, 0x5d10, 0x0005, + 0x080c, 0x42b9, 0x080c, 0x5c37, 0x6003, 0x0002, 0x0036, 0x2019, + 0x8b5c, 0x2304, 0xa084, 0xff00, 0x1118, 0x2019, 0x0028, 0x0040, + 0x8007, 0xa09a, 0x0004, 0x0ec8, 0x8003, 0x801b, 0x831b, 0xa318, + 0x6316, 0x003e, 0x080c, 0x5d10, 0x0c10, 0x080c, 0x5c37, 0x080c, + 0x7df6, 0x080c, 0x6d18, 0x080c, 0x5d10, 0x08c8, 0x00e6, 0x080c, + 0x7b8f, 0x01a0, 0x6010, 0x2070, 0x7038, 0xd0fc, 0x0178, 0x7007, + 0x0000, 0x0016, 0x6004, 0xa08e, 0x0021, 0x0150, 0xa08e, 0x003d, + 0x0138, 0x001e, 0x7037, 0x0103, 0x7033, 0x0100, 0x00ee, 0x0005, + 0x001e, 0x0009, 0x0cd8, 0x00e6, 0xacf0, 0x0004, 0x2e74, 0x7000, + 0x2070, 0x7037, 0x0103, 0x7023, 0x8001, 0x00ee, 0x0005, 0x00d6, + 0x6618, 0x2668, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa0b2, 0x000c, + 0x1a0c, 0x1410, 0x6604, 0xa6b6, 0x0028, 0x1118, 0x080c, 0x7d93, + 0x0468, 0x6604, 0xa6b6, 0x0029, 0x1118, 0x080c, 0x7daa, 0x0430, + 0x6604, 0xa6b6, 0x001f, 0x1118, 0x080c, 0x6dad, 0x00f8, 0x6604, + 0xa6b6, 0x0000, 0x1118, 0x080c, 0x6e0f, 0x00c0, 0x6604, 0xa6b6, + 0x0022, 0x1118, 0x080c, 0x6dd5, 0x0088, 0x6604, 0xa6b6, 0x003d, + 0x1118, 0x080c, 0x6def, 0x0050, 0xa1b6, 0x0015, 0x1110, 0x0053, + 0x0028, 0xa1b6, 0x0016, 0x1118, 0x0804, 0x71c6, 0x0005, 0x080c, + 0x6d55, 0x0ce0, 0x7045, 0x7048, 0x7045, 0x7082, 0x7045, 0x716c, + 0x7045, 0x7045, 0x7045, 0x71a2, 0x7045, 0x71b6, 0xa1b6, 0x0048, + 0x0140, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x16d1, + 0x0005, 0x00e6, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, + 0x0103, 0x00ee, 0x080c, 0x6d18, 0x0005, 0xe000, 0xe000, 0x0005, + 0x00e6, 0x2071, 0x8b00, 0x7080, 0xa086, 0x0074, 0x11f0, 0x080c, + 0x8766, 0x1170, 0x00d6, 0x6018, 0x2068, 0x00d9, 0x00de, 0x2001, + 0x0006, 0x080c, 0x42b9, 0x080c, 0x2589, 0x080c, 0x6d18, 0x0078, + 0x2001, 0x000a, 0x080c, 0x42b9, 0x080c, 0x2589, 0x6003, 0x0001, + 0x6007, 0x0001, 0x080c, 0x58e2, 0x0010, 0x080c, 0x715d, 0x00ee, + 0x0005, 0x6800, 0xd084, 0x0168, 0x2001, 0x0000, 0x080c, 0x42a7, + 0x2069, 0x8b51, 0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, + 0x42c7, 0x0005, 0x00d6, 0x2011, 0x8b20, 0x2204, 0xa086, 0x0074, + 0x1904, 0x715a, 0x080c, 0x72a4, 0x6018, 0x2068, 0xa080, 0x0028, + 0x2014, 0xa286, 0x007e, 0x0198, 0xa286, 0x0080, 0x1904, 0x70da, + 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005, 0x0588, 0x2068, + 0x6807, 0x0000, 0x6837, 0x0103, 0x6833, 0x0200, 0x0448, 0x00d6, + 0x00e6, 0x00f6, 0x6813, 0x00ff, 0x6817, 0xfffe, 0x2071, 0x8b32, + 0x2e04, 0xa085, 0x0003, 0x2072, 0x2071, 0x9080, 0x2079, 0x0100, + 0x2e04, 0xa084, 0x00ff, 0x2069, 0x8b1b, 0x206a, 0x78e6, 0x8e70, + 0x2e04, 0x2069, 0x8b1c, 0x206a, 0x78ea, 0x7832, 0x7836, 0xa084, + 0x00ff, 0x2008, 0x080c, 0x2313, 0x00fe, 0x00ee, 0x00de, 0x0470, + 0x2001, 0x0006, 0x080c, 0x42b9, 0x080c, 0x2589, 0x080c, 0x6d18, + 0x0804, 0x715b, 0x00e6, 0x2071, 0x8b32, 0x2e04, 0xd09c, 0x0188, + 0x2071, 0x9080, 0x7108, 0x720c, 0xa18c, 0x00ff, 0x1118, 0xa284, + 0xff00, 0x0138, 0x6018, 0x2070, 0x70a0, 0xd0bc, 0x1110, 0x7112, + 0x7216, 0x00ee, 0x2001, 0x0004, 0x080c, 0x42b9, 0x6003, 0x0001, + 0x6007, 0x0003, 0x080c, 0x58e2, 0x0804, 0x715b, 0x685c, 0xd0e4, + 0x01d0, 0x080c, 0x7dd2, 0x080c, 0x4c42, 0x0110, 0xd0dc, 0x1940, + 0x2011, 0x8b32, 0x2204, 0xc0ad, 0x2012, 0x2001, 0x8d8d, 0x2004, + 0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, 0x080c, 0x233e, 0x78e2, + 0x00fe, 0x0804, 0x70d0, 0x080c, 0x7deb, 0x2011, 0x8b32, 0x2204, + 0xc0a5, 0x2012, 0x0006, 0x080c, 0x884f, 0x000e, 0x1904, 0x70d0, + 0xc0b5, 0x2012, 0x2001, 0x0000, 0x080c, 0x42a7, 0x00c6, 0x2009, + 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932, 0x7936, 0x00fe, + 0x080c, 0x2313, 0x00f6, 0x2079, 0x8b00, 0x7972, 0x2100, 0x2009, + 0x0000, 0x080c, 0x22e9, 0x794e, 0x00fe, 0x8108, 0x080c, 0x42d6, + 0x2c00, 0x00ce, 0x1904, 0x70d0, 0x601a, 0x2001, 0x0002, 0x080c, + 0x42b9, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, + 0x58e2, 0x0008, 0x0011, 0x00de, 0x0005, 0x2001, 0x8b00, 0x2004, + 0xa086, 0x0003, 0x0120, 0x2001, 0x0007, 0x080c, 0x42b9, 0x080c, + 0x2589, 0x080c, 0x6d18, 0x0005, 0x00e6, 0x2071, 0x8b00, 0x7080, + 0xa086, 0x0014, 0x1548, 0x7000, 0xa086, 0x0003, 0x1128, 0x6010, + 0xa005, 0x1110, 0x080c, 0x3689, 0x00d6, 0x6018, 0x2068, 0x080c, + 0x43a0, 0x080c, 0x7071, 0x00de, 0x080c, 0x72ae, 0x11a8, 0x2001, + 0x0006, 0x080c, 0x42b9, 0x00e6, 0x6010, 0xa005, 0x0138, 0x2070, + 0x7007, 0x0000, 0x7037, 0x0103, 0x7033, 0x0200, 0x00ee, 0x080c, + 0x2589, 0x080c, 0x6d18, 0x0020, 0x080c, 0x6fb6, 0x080c, 0x715d, + 0x00ee, 0x0005, 0x2011, 0x8b20, 0x2204, 0xa086, 0x0014, 0x1158, + 0x2001, 0x0002, 0x080c, 0x42b9, 0x6003, 0x0001, 0x6007, 0x0001, + 0x080c, 0x58e2, 0x0010, 0x080c, 0x715d, 0x0005, 0x2011, 0x8b20, + 0x2204, 0xa086, 0x0004, 0x1138, 0x2001, 0x0007, 0x080c, 0x42b9, + 0x080c, 0x6d18, 0x0010, 0x080c, 0x715d, 0x0005, 0x000b, 0x0005, + 0x7045, 0x71d4, 0x7045, 0x71f6, 0x7045, 0x7260, 0x7045, 0x7045, + 0x7045, 0x7273, 0x7045, 0x7283, 0x00c6, 0x080c, 0x7293, 0x1178, + 0x2001, 0x0000, 0x080c, 0x42a7, 0x2001, 0x0002, 0x080c, 0x42b9, + 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x58e2, 0x0068, 0x2009, + 0x908f, 0x2104, 0xa084, 0xff00, 0xa086, 0x1900, 0x1118, 0x080c, + 0x6d18, 0x0010, 0x080c, 0x715d, 0x00ce, 0x0005, 0x080c, 0x72a1, + 0x00d6, 0x2069, 0x8d9c, 0x2d04, 0xa005, 0x0168, 0x6018, 0x2068, + 0x68a0, 0xa086, 0x007e, 0x1138, 0x2069, 0x8b1c, 0x2d04, 0x8000, + 0x206a, 0x00de, 0x0010, 0x00de, 0x0078, 0x2001, 0x0000, 0x080c, + 0x42a7, 0x2001, 0x0002, 0x080c, 0x42b9, 0x6003, 0x0001, 0x6007, + 0x0002, 0x080c, 0x58e2, 0x0428, 0x080c, 0x6fb6, 0x2009, 0x908e, + 0x2134, 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x01e0, 0xa686, 0x000b, + 0x01b0, 0x2009, 0x908f, 0x2104, 0xa084, 0xff00, 0x1118, 0xa686, + 0x0009, 0x0180, 0xa086, 0x1900, 0x1150, 0xa686, 0x0009, 0x0150, + 0x2001, 0x0004, 0x080c, 0x42b9, 0x080c, 0x6d18, 0x0010, 0x080c, + 0x715d, 0x0005, 0x00d6, 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0128, + 0x6838, 0xd0fc, 0x0110, 0x00de, 0x0c90, 0x6018, 0x2068, 0x6840, + 0xa084, 0x00ff, 0xa005, 0x0140, 0x8001, 0x6842, 0x6017, 0x000a, + 0x6007, 0x0016, 0x00de, 0x0c28, 0x080c, 0x2563, 0x00de, 0x08f8, + 0x080c, 0x72a1, 0x1158, 0x2001, 0x0004, 0x080c, 0x42b9, 0x6003, + 0x0001, 0x6007, 0x0003, 0x080c, 0x58e2, 0x0020, 0x080c, 0x6fb6, + 0x080c, 0x715d, 0x0005, 0x0469, 0x1158, 0x2001, 0x0008, 0x080c, + 0x42b9, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x58e2, 0x0010, + 0x080c, 0x715d, 0x0005, 0x00e9, 0x1158, 0x2001, 0x000a, 0x080c, + 0x42b9, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x58e2, 0x0010, + 0x080c, 0x715d, 0x0005, 0x2009, 0x908e, 0x2104, 0xa086, 0x0003, + 0x1138, 0x2009, 0x908f, 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, 0x0005, 0xa085, 0x0001, 0x0005, 0x00c6, 0x0016, 0xac88, 0x0006, - 0x2164, 0x080c, 0x4443, 0x001e, 0x00ce, 0x0005, 0x00e6, 0x2071, - 0x978c, 0x7004, 0xa086, 0x0014, 0x11a8, 0x7008, 0xa086, 0x0800, + 0x2164, 0x080c, 0x4319, 0x001e, 0x00ce, 0x0005, 0x00e6, 0x2071, + 0x908c, 0x7004, 0xa086, 0x0014, 0x11a8, 0x7008, 0xa086, 0x0800, 0x1188, 0x700c, 0xd0ec, 0x0160, 0xa084, 0x0f00, 0xa086, 0x0100, 0x1138, 0x7024, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0xa006, 0x0010, 0xa085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0056, 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, - 0x94ee, 0x252c, 0x2021, 0x94f4, 0x2424, 0x2061, 0x9900, 0x2071, - 0x9200, 0x7244, 0x7064, 0xa202, 0x1688, 0x080c, 0x90ee, 0x0540, + 0x8db3, 0x252c, 0x2021, 0x8db9, 0x2424, 0x2061, 0x9200, 0x2071, + 0x8b00, 0x7244, 0x7064, 0xa202, 0x1688, 0x080c, 0x8999, 0x0540, 0x671c, 0xa786, 0x0001, 0x0520, 0xa786, 0x0007, 0x0508, 0x2500, 0xac06, 0x01f0, 0x2400, 0xac06, 0x01d8, 0x00c6, 0x6000, 0xa086, - 0x0004, 0x1110, 0x080c, 0x1788, 0x6010, 0x2068, 0x080c, 0x82ee, + 0x0004, 0x1110, 0x080c, 0x179e, 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0160, 0xa786, 0x0003, 0x11e0, 0x6837, 0x0103, 0x6b4a, 0x6847, - 0x0000, 0x080c, 0x4809, 0x080c, 0x848f, 0x080c, 0x849b, 0x00ce, + 0x0000, 0x080c, 0x46a1, 0x080c, 0x7d30, 0x080c, 0x7d3c, 0x00ce, 0xace0, 0x000c, 0x7058, 0xac02, 0x1208, 0x0858, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, - 0xa786, 0x0006, 0x1118, 0x080c, 0x9097, 0x0c38, 0xa786, 0x0009, - 0x19d8, 0x2009, 0x0106, 0x080c, 0x7518, 0x0c08, 0x220c, 0x2304, - 0xa106, 0x1130, 0x8210, 0x8318, 0x1f04, 0x7aee, 0xa006, 0x0005, + 0xa786, 0x0006, 0x1d08, 0x080c, 0x8942, 0x0c38, 0x220c, 0x2304, + 0xa106, 0x1130, 0x8210, 0x8318, 0x1f04, 0x7326, 0xa006, 0x0005, 0x2304, 0xa102, 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, - 0xa18d, 0x0001, 0x0005, 0x6004, 0xa08a, 0x003e, 0x1a0c, 0x13fe, - 0x080c, 0x84b7, 0x0120, 0x080c, 0x84c8, 0x0150, 0x0010, 0x080c, - 0x2692, 0x080c, 0x6389, 0x080c, 0x74f2, 0x080c, 0x6462, 0x0005, - 0x080c, 0x7776, 0x0cb0, 0xa182, 0x0040, 0x0002, 0x7b31, 0x7b31, - 0x7b31, 0x7b31, 0x7b31, 0x7b31, 0x7b31, 0x7b31, 0x7b31, 0x7b31, - 0x7b31, 0x7b33, 0x7b33, 0x7b33, 0x7b33, 0x7b31, 0x7b31, 0x7b31, - 0x7b33, 0x080c, 0x13fe, 0x6003, 0x0001, 0x6106, 0x080c, 0x5ff8, - 0x0126, 0x2091, 0x8000, 0x080c, 0x6462, 0x012e, 0x0005, 0xa186, - 0x0013, 0x1128, 0x6004, 0xa082, 0x0040, 0x0804, 0x7bc5, 0xa186, - 0x0027, 0x11d0, 0x080c, 0x6389, 0x080c, 0x266c, 0x00d6, 0x6110, - 0x2168, 0x080c, 0x82ee, 0x0150, 0x6837, 0x0103, 0x684b, 0x0029, - 0x6847, 0x0000, 0x080c, 0x4809, 0x080c, 0x848f, 0x00de, 0x080c, - 0x74f2, 0x080c, 0x6462, 0x0005, 0xa186, 0x0014, 0x1120, 0x6004, + 0xa18d, 0x0001, 0x0005, 0x6004, 0xa08a, 0x0040, 0x1a0c, 0x1410, + 0x080c, 0x7d58, 0x0120, 0x080c, 0x7d69, 0x0150, 0x0010, 0x080c, + 0x2589, 0x080c, 0x5c37, 0x080c, 0x6d18, 0x080c, 0x5d10, 0x0005, + 0x080c, 0x6fb6, 0x0cb0, 0xa182, 0x0040, 0x0002, 0x7369, 0x7369, + 0x7369, 0x7369, 0x7369, 0x7369, 0x7369, 0x7369, 0x7369, 0x7369, + 0x7369, 0x736b, 0x736b, 0x736b, 0x736b, 0x7369, 0x7369, 0x7369, + 0x736b, 0x080c, 0x1410, 0x6003, 0x0001, 0x6106, 0x080c, 0x589c, + 0x0126, 0x2091, 0x8000, 0x080c, 0x5d10, 0x012e, 0x0005, 0xa186, + 0x0013, 0x1128, 0x6004, 0xa082, 0x0040, 0x0804, 0x7400, 0xa186, + 0x0027, 0x11d0, 0x080c, 0x5c37, 0x080c, 0x2563, 0x00d6, 0x6110, + 0x2168, 0x080c, 0x7b8f, 0x0150, 0x6837, 0x0103, 0x684b, 0x0029, + 0x6847, 0x0000, 0x080c, 0x46a1, 0x080c, 0x7d30, 0x00de, 0x080c, + 0x6d18, 0x080c, 0x5d10, 0x0005, 0xa186, 0x0014, 0x1120, 0x6004, 0xa082, 0x0040, 0x0428, 0xa186, 0x0046, 0x0138, 0xa186, 0x0045, - 0x0120, 0xa186, 0x0047, 0x190c, 0x13fe, 0x2001, 0x0109, 0x2004, + 0x0120, 0xa186, 0x0047, 0x190c, 0x1410, 0x2001, 0x0109, 0x2004, 0xd084, 0x0198, 0x0126, 0x2091, 0x2400, 0x0006, 0x0016, 0x0026, - 0x080c, 0x5ee3, 0x002e, 0x001e, 0x000e, 0x012e, 0xe000, 0x6000, - 0xa086, 0x0002, 0x1110, 0x0804, 0x7bf0, 0x080c, 0x7526, 0x0005, - 0x0002, 0x7ba6, 0x7ba4, 0x7ba4, 0x7ba4, 0x7ba4, 0x7ba4, 0x7ba4, - 0x7ba4, 0x7ba4, 0x7ba4, 0x7ba4, 0x7bbe, 0x7bbe, 0x7bbe, 0x7bbe, - 0x7ba4, 0x7ba4, 0x7ba4, 0x7bbe, 0x080c, 0x13fe, 0x080c, 0x6389, - 0x00d6, 0x6110, 0x2168, 0x080c, 0x82ee, 0x0150, 0x6837, 0x0103, - 0x684b, 0x0006, 0x6847, 0x0000, 0x080c, 0x4809, 0x080c, 0x848f, - 0x00de, 0x080c, 0x74f2, 0x080c, 0x6462, 0x0005, 0x080c, 0x6389, - 0x080c, 0x74f2, 0x080c, 0x6462, 0x0005, 0x0002, 0x7bdb, 0x7bd9, - 0x7bd9, 0x7bd9, 0x7bd9, 0x7bd9, 0x7bd9, 0x7bd9, 0x7bd9, 0x7bd9, - 0x7bd9, 0x7be9, 0x7be9, 0x7be9, 0x7be9, 0x7bd9, 0x7bd9, 0x7bd9, - 0x7be9, 0x080c, 0x13fe, 0x080c, 0x6389, 0x6003, 0x0002, 0x080c, - 0x6462, 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, - 0x0005, 0x080c, 0x6389, 0x6003, 0x000f, 0x080c, 0x6462, 0x0005, - 0xa182, 0x0040, 0x0002, 0x7c06, 0x7c06, 0x7c06, 0x7c06, 0x7c06, - 0x7c08, 0x7c8a, 0x7ca9, 0x7c06, 0x7c06, 0x7c06, 0x7c06, 0x7c06, - 0x7c06, 0x7c06, 0x7c06, 0x7c06, 0x7c06, 0x7c06, 0x080c, 0x13fe, - 0x00e6, 0x00d6, 0x2071, 0x978c, 0x6110, 0x2168, 0x7614, 0xa6b4, - 0x0fff, 0x86ff, 0x0904, 0x7c70, 0xa68c, 0x0c00, 0x0120, 0x7318, - 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0190, - 0xa186, 0x0028, 0x1128, 0x080c, 0x84a6, 0x684b, 0x001c, 0x0060, - 0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b, - 0x0007, 0x0010, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0xa01e, - 0xd6c4, 0x01b0, 0xa686, 0x0100, 0x1138, 0x2001, 0x9799, 0x2004, - 0xa005, 0x1110, 0xc6c4, 0x0868, 0x7328, 0x732c, 0x6b56, 0x0036, - 0x2308, 0x2019, 0x9798, 0xad90, 0x0019, 0x080c, 0x80e6, 0x003e, - 0xd6cc, 0x0560, 0x7124, 0x695a, 0xa192, 0x0021, 0x1250, 0x2071, - 0x9798, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x80e6, - 0x00e8, 0x6838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c78, - 0x00f6, 0x2d78, 0x080c, 0x808b, 0x00fe, 0x080c, 0x80d6, 0x0080, - 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0x684c, 0xd0ac, 0x0130, - 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x7de6, 0x080c, 0x4809, - 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x00de, 0x00ee, 0x080c, - 0x74f2, 0x0005, 0x00f6, 0x6003, 0x0003, 0x2079, 0x978c, 0x7c04, - 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x784c, 0xd0ac, 0x0120, - 0x6003, 0x0002, 0x00fe, 0x0005, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, - 0x00fe, 0x2c10, 0x080c, 0x1c88, 0x080c, 0x605b, 0x080c, 0x651c, - 0x0005, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, - 0x2c10, 0x080c, 0x16c6, 0x0005, 0xa182, 0x0040, 0x0002, 0x7cca, - 0x7cca, 0x7cca, 0x7cca, 0x7cca, 0x7ccc, 0x7d54, 0x7cca, 0x7cca, - 0x7d6a, 0x7dc1, 0x7cca, 0x7cca, 0x7cca, 0x7cca, 0x7dcc, 0x7cca, - 0x7cca, 0x7cca, 0x080c, 0x13fe, 0x0076, 0x00f6, 0x00e6, 0x00d6, - 0x2071, 0x978c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46, - 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, - 0x86ff, 0x0904, 0x7d4f, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0120, - 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0904, 0x7d4f, - 0x080c, 0x147c, 0x090c, 0x13fe, 0x2d00, 0x784a, 0x7f4c, 0xc7cd, - 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e, 0x7840, - 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0120, 0x7318, 0x6b62, 0x731c, - 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0180, 0xa186, 0x0028, - 0x1118, 0x684b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0x684b, 0x0015, - 0x0038, 0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010, 0x684b, 0x0000, - 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0160, - 0x7328, 0x732c, 0x6b56, 0x0036, 0x2308, 0x2019, 0x9798, 0xad90, - 0x0019, 0x080c, 0x80e6, 0x003e, 0xd6cc, 0x01c8, 0x7124, 0x695a, - 0xa192, 0x0021, 0x1250, 0x2071, 0x9798, 0x831c, 0x2300, 0xae18, - 0xad90, 0x001d, 0x080c, 0x80e6, 0x0050, 0x7838, 0xd0fc, 0x0120, - 0x2009, 0x0020, 0x695a, 0x0c78, 0x2d78, 0x080c, 0x808b, 0x00de, - 0x00ee, 0x00fe, 0x007e, 0x0005, 0x00f6, 0x6003, 0x0003, 0x2079, - 0x978c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, - 0x7b16, 0x7e0a, 0x7d0e, 0x00fe, 0x2c10, 0x080c, 0x1c88, 0x080c, - 0x6f04, 0x0005, 0x00d6, 0x6003, 0x0002, 0x080c, 0x641b, 0x080c, - 0x651c, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0904, 0x7dbf, 0xd1cc, - 0x0540, 0x6948, 0x6838, 0xd0fc, 0x01e8, 0x0016, 0x684c, 0x0006, - 0x6850, 0x0006, 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0023, - 0x0156, 0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x1f04, 0x7d8a, - 0x015e, 0x000e, 0x6852, 0x000e, 0x684e, 0x001e, 0x2168, 0x080c, - 0x14a3, 0x0418, 0x0016, 0x080c, 0x14a3, 0x00de, 0x080c, 0x80d6, - 0x00e0, 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, - 0x0180, 0xa086, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd1dc, - 0x0118, 0x684b, 0x0015, 0x0038, 0xd1d4, 0x0118, 0x684b, 0x0007, - 0x0010, 0x684b, 0x0000, 0x080c, 0x4809, 0x080c, 0x74f2, 0x00de, - 0x0005, 0x2019, 0x0001, 0x080c, 0x7110, 0x6003, 0x0002, 0x080c, - 0x641b, 0x080c, 0x651c, 0x0005, 0x080c, 0x641b, 0x080c, 0x266c, - 0x00d6, 0x6110, 0x2168, 0x080c, 0x82ee, 0x0150, 0x6837, 0x0103, - 0x684b, 0x0029, 0x6847, 0x0000, 0x080c, 0x4809, 0x080c, 0x848f, - 0x00de, 0x080c, 0x74f2, 0x080c, 0x651c, 0x0005, 0x684b, 0x0015, - 0xd1fc, 0x0138, 0x684b, 0x0007, 0x8002, 0x8000, 0x810a, 0xa189, - 0x0000, 0x6962, 0x685e, 0x0005, 0xa182, 0x0040, 0x0002, 0x7e0a, - 0x7e0a, 0x7e0a, 0x7e0a, 0x7e0a, 0x7e0c, 0x7e0a, 0x7eac, 0x7eb4, - 0x7e0a, 0x7e0a, 0x7e0a, 0x7e0a, 0x7e0a, 0x7e0a, 0x7e0a, 0x7e0a, - 0x7e0a, 0x7e0a, 0x080c, 0x13fe, 0x0076, 0x00f6, 0x00e6, 0x00d6, - 0x2071, 0x978c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46, - 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, - 0x86ff, 0x0904, 0x7e9d, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0120, - 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0904, 0x7e9b, - 0xa686, 0x0100, 0x1140, 0x2001, 0x9799, 0x2004, 0xa005, 0x1118, - 0xc6c4, 0x7e46, 0x0c28, 0x080c, 0x147c, 0x090c, 0x13fe, 0x2d00, - 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838, - 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, - 0x0120, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, - 0x0002, 0x0180, 0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, - 0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b, - 0x0007, 0x0010, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, - 0x6856, 0xa01e, 0xd6c4, 0x0160, 0x7328, 0x732c, 0x6b56, 0x0036, - 0x2308, 0x2019, 0x9798, 0xad90, 0x0019, 0x080c, 0x80e6, 0x003e, - 0xd6cc, 0x01c8, 0x7124, 0x695a, 0xa192, 0x0021, 0x1250, 0x2071, - 0x9798, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x80e6, - 0x0050, 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c78, - 0x2d78, 0x080c, 0x808b, 0xd6dc, 0x1110, 0xa006, 0x0030, 0x2001, - 0x0001, 0x2071, 0x978c, 0x7218, 0x731c, 0x080c, 0x1700, 0x00de, - 0x00ee, 0x00fe, 0x007e, 0x0005, 0x20e1, 0x0005, 0x3d18, 0x3e20, - 0x2c10, 0x080c, 0x16c6, 0x0005, 0x00d6, 0x6003, 0x0002, 0x6110, - 0x2168, 0x694c, 0xd1e4, 0x0904, 0x7f3e, 0xd1cc, 0x0904, 0x7f17, - 0x6948, 0x6838, 0xd0fc, 0x0590, 0x0016, 0x684c, 0x0006, 0x6850, - 0x0006, 0x684c, 0xd0ac, 0x0180, 0x6810, 0x6914, 0xa115, 0x0160, - 0x080c, 0x7de6, 0x00f6, 0x6948, 0x2178, 0x6848, 0x784a, 0x6860, - 0x7862, 0x685c, 0x785e, 0x00fe, 0x6948, 0xad90, 0x000d, 0xa198, + 0x080c, 0x578e, 0x002e, 0x001e, 0x000e, 0x012e, 0xe000, 0x6000, + 0xa086, 0x0002, 0x1110, 0x0804, 0x742b, 0x080c, 0x6d55, 0x0005, + 0x0002, 0x73de, 0x73dc, 0x73dc, 0x73dc, 0x73dc, 0x73dc, 0x73dc, + 0x73dc, 0x73dc, 0x73dc, 0x73dc, 0x73f9, 0x73f9, 0x73f9, 0x73f9, + 0x73dc, 0x73dc, 0x73dc, 0x73f9, 0x080c, 0x1410, 0x080c, 0x5c37, + 0x00d6, 0x6110, 0x2168, 0x080c, 0x7b8f, 0x0168, 0x6837, 0x0103, + 0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x080c, + 0x46a1, 0x080c, 0x7d30, 0x00de, 0x080c, 0x6d18, 0x080c, 0x5d10, + 0x0005, 0x080c, 0x5c37, 0x080c, 0x6d18, 0x080c, 0x5d10, 0x0005, + 0x0002, 0x7416, 0x7414, 0x7414, 0x7414, 0x7414, 0x7414, 0x7414, + 0x7414, 0x7414, 0x7414, 0x7414, 0x7424, 0x7424, 0x7424, 0x7424, + 0x7414, 0x7414, 0x7414, 0x7424, 0x080c, 0x1410, 0x080c, 0x5c37, + 0x6003, 0x0002, 0x080c, 0x5d10, 0x6010, 0xa088, 0x0013, 0x2104, + 0xa085, 0x0400, 0x200a, 0x0005, 0x080c, 0x5c37, 0x6003, 0x000f, + 0x080c, 0x5d10, 0x0005, 0xa182, 0x0040, 0x0002, 0x7441, 0x7441, + 0x7441, 0x7441, 0x7441, 0x7443, 0x74c5, 0x74e4, 0x7441, 0x7441, + 0x7441, 0x7441, 0x7441, 0x7441, 0x7441, 0x7441, 0x7441, 0x7441, + 0x7441, 0x080c, 0x1410, 0x00e6, 0x00d6, 0x2071, 0x908c, 0x6110, + 0x2168, 0x7614, 0xa6b4, 0x0fff, 0x86ff, 0x0904, 0x74ab, 0xa68c, + 0x0c00, 0x0120, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, + 0xa186, 0x0002, 0x0190, 0xa186, 0x0028, 0x1128, 0x080c, 0x7d47, + 0x684b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038, + 0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010, 0x684b, 0x0000, 0x6837, + 0x0103, 0x6e46, 0xa01e, 0xd6c4, 0x01b0, 0xa686, 0x0100, 0x1138, + 0x2001, 0x9099, 0x2004, 0xa005, 0x1110, 0xc6c4, 0x0868, 0x7328, + 0x732c, 0x6b56, 0x0036, 0x2308, 0x2019, 0x9098, 0xad90, 0x0019, + 0x080c, 0x794f, 0x003e, 0xd6cc, 0x0560, 0x7124, 0x695a, 0xa192, + 0x0021, 0x1250, 0x2071, 0x9098, 0x831c, 0x2300, 0xae18, 0xad90, + 0x001d, 0x080c, 0x794f, 0x00e8, 0x6838, 0xd0fc, 0x0120, 0x2009, + 0x0020, 0x695a, 0x0c78, 0x00f6, 0x2d78, 0x080c, 0x78f4, 0x00fe, + 0x080c, 0x793f, 0x0080, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, + 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, + 0x7621, 0x080c, 0x46a1, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, + 0x00de, 0x00ee, 0x080c, 0x6d18, 0x0005, 0x00f6, 0x6003, 0x0003, + 0x2079, 0x908c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, + 0x784c, 0xd0ac, 0x0120, 0x6003, 0x0002, 0x00fe, 0x0005, 0x7c12, + 0x7b16, 0x7e0a, 0x7d0e, 0x00fe, 0x2c10, 0x080c, 0x1bc8, 0x080c, + 0x58ff, 0x080c, 0x5dc2, 0x0005, 0x6003, 0x0004, 0x6110, 0x20e1, + 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x16d1, 0x0005, 0xa182, + 0x0040, 0x0002, 0x7505, 0x7505, 0x7505, 0x7505, 0x7505, 0x7507, + 0x758f, 0x7505, 0x7505, 0x75a5, 0x75fc, 0x7505, 0x7505, 0x7505, + 0x7505, 0x7607, 0x7505, 0x7505, 0x7505, 0x080c, 0x1410, 0x0076, + 0x00f6, 0x00e6, 0x00d6, 0x2071, 0x908c, 0x6110, 0x2178, 0x7614, + 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, + 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0904, 0x758a, 0xa694, 0xff00, + 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, + 0x0300, 0x0904, 0x758a, 0x080c, 0x1488, 0x090c, 0x1410, 0x2d00, + 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, + 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0120, + 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, + 0x0180, 0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd6dc, + 0x0118, 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b, 0x0007, + 0x0010, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, + 0xa01e, 0xd6c4, 0x0160, 0x7328, 0x732c, 0x6b56, 0x0036, 0x2308, + 0x2019, 0x9098, 0xad90, 0x0019, 0x080c, 0x794f, 0x003e, 0xd6cc, + 0x01c8, 0x7124, 0x695a, 0xa192, 0x0021, 0x1250, 0x2071, 0x9098, + 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x794f, 0x0050, + 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c78, 0x2d78, + 0x080c, 0x78f4, 0x00de, 0x00ee, 0x00fe, 0x007e, 0x0005, 0x00f6, + 0x6003, 0x0003, 0x2079, 0x908c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, + 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x00fe, 0x2c10, + 0x080c, 0x1bc8, 0x080c, 0x66dd, 0x0005, 0x00d6, 0x6003, 0x0002, + 0x080c, 0x5cc9, 0x080c, 0x5dc2, 0x6110, 0x2168, 0x694c, 0xd1e4, + 0x0904, 0x75fa, 0xd1cc, 0x0540, 0x6948, 0x6838, 0xd0fc, 0x01e8, + 0x0016, 0x684c, 0x0006, 0x6850, 0x0006, 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0023, 0x0156, 0x21a8, 0x2304, 0x2012, 0x8318, - 0x8210, 0x1f04, 0x7ee5, 0x015e, 0x000e, 0x6852, 0x000e, 0x684e, - 0x001e, 0x2168, 0x080c, 0x14a3, 0x0804, 0x7f3c, 0x0016, 0x684c, - 0xd0ac, 0x0190, 0x6810, 0x6914, 0xa115, 0x0170, 0x080c, 0x7de6, - 0x00f6, 0x6948, 0x2178, 0x6848, 0x784a, 0x6860, 0x7862, 0x685c, - 0x785e, 0x684c, 0x784e, 0x00fe, 0x6948, 0xa188, 0x0013, 0x684c, - 0x200a, 0x080c, 0x14a3, 0x00de, 0x080c, 0x80d6, 0x0428, 0x6837, - 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0180, 0xa086, - 0x0028, 0x1118, 0x684b, 0x001c, 0x00a8, 0xd1dc, 0x0118, 0x684b, - 0x0015, 0x0080, 0xd1d4, 0x0118, 0x684b, 0x0007, 0x0058, 0x684b, - 0x0000, 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, - 0x080c, 0x7de6, 0x080c, 0x4809, 0x080c, 0x74f2, 0x00de, 0x0005, - 0x080c, 0x6389, 0x0010, 0x080c, 0x641b, 0x080c, 0x82ee, 0x0198, - 0x00d6, 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0x920c, 0x210c, - 0xd18c, 0x1188, 0xd184, 0x1160, 0x6108, 0x694a, 0x6847, 0x0000, - 0x080c, 0x4809, 0x00de, 0x080c, 0x74f2, 0x080c, 0x6462, 0x0005, - 0x684b, 0x0004, 0x0c98, 0x684b, 0x0004, 0x0c80, 0xa182, 0x0040, - 0x0002, 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7e, 0x7f7c, - 0x7f81, 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7c, - 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7c, 0x080c, 0x13fe, 0x080c, 0x74f2, - 0x0005, 0x0006, 0x0026, 0xa016, 0x080c, 0x16c6, 0x002e, 0x000e, - 0x0005, 0xa182, 0x0085, 0x0002, 0x7f95, 0x7f93, 0x7f93, 0x7f93, - 0x7f93, 0x7f93, 0x7f93, 0x080c, 0x13fe, 0x6003, 0x000b, 0x6106, - 0x080c, 0x5ff8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6462, 0x012e, - 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a, 0x0085, 0x0a0c, - 0x13fe, 0xa08a, 0x008c, 0x1a0c, 0x13fe, 0xa082, 0x0085, 0x0072, - 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c, 0x13fe, 0x080c, - 0x6389, 0x080c, 0x849b, 0x080c, 0x6462, 0x0005, 0x7fc5, 0x7fc7, - 0x7fc7, 0x7fc5, 0x7fc5, 0x7fc5, 0x7fc5, 0x080c, 0x13fe, 0x080c, - 0x6389, 0x080c, 0x849b, 0x080c, 0x6462, 0x0005, 0xa186, 0x0013, - 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x0492, 0xa186, 0x0027, - 0x11e8, 0x080c, 0x6389, 0x080c, 0x266c, 0x00d6, 0x6010, 0x2068, - 0x080c, 0x82ee, 0x0150, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b, - 0x0029, 0x080c, 0x4809, 0x080c, 0x848f, 0x00de, 0x080c, 0x74f2, - 0x080c, 0x6462, 0x0005, 0x080c, 0x7526, 0x0ce0, 0xa186, 0x0014, - 0x1dd0, 0x080c, 0x6389, 0x00d6, 0x6010, 0x2068, 0x080c, 0x82ee, - 0x0d60, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b, 0x0006, 0x0c08, - 0x8011, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x801a, 0x080c, - 0x13fe, 0x080c, 0x6389, 0x6017, 0x0014, 0x6003, 0x000c, 0x080c, - 0x6462, 0x0005, 0x080c, 0x6389, 0x6017, 0x0014, 0x6003, 0x000e, - 0x080c, 0x6462, 0x0005, 0xa182, 0x008c, 0x1220, 0xa182, 0x0085, - 0x0208, 0x001a, 0x080c, 0x7526, 0x0005, 0x8034, 0x8034, 0x8034, - 0x8034, 0x8036, 0x8057, 0x8034, 0x080c, 0x13fe, 0x00d6, 0x080c, - 0x848f, 0x080c, 0x82ee, 0x01b8, 0x6010, 0x2068, 0x6837, 0x0103, - 0x6850, 0xd0b4, 0x0118, 0x684b, 0x0006, 0x0048, 0xd0bc, 0x0118, - 0x684b, 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x852d, 0x6847, - 0x0000, 0x080c, 0x4809, 0x080c, 0x74f2, 0x00de, 0x0005, 0x00d6, - 0x6010, 0x2068, 0x080c, 0x82ee, 0x01b8, 0x6837, 0x0103, 0x6850, - 0xd0b4, 0x0118, 0x684b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0x684b, - 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x852d, 0x6847, 0x0000, - 0x080c, 0x4809, 0x080c, 0x848f, 0x00de, 0x080c, 0x74f2, 0x0005, - 0xa186, 0x0013, 0x0148, 0xa186, 0x0014, 0x0130, 0xa186, 0x0027, - 0x0118, 0x080c, 0x7526, 0x0030, 0x080c, 0x6389, 0x080c, 0x849b, - 0x080c, 0x6462, 0x0005, 0x0056, 0x0066, 0x00d6, 0x00f6, 0x2029, - 0x0001, 0xa182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, 0x2130, - 0x2069, 0x9798, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, 0xaf90, - 0x001d, 0x080c, 0x80e6, 0xa6b2, 0x0020, 0x7804, 0xa06d, 0x0110, - 0x080c, 0x14a3, 0x080c, 0x147c, 0x0500, 0x8528, 0x6837, 0x0110, - 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d, 0x1228, 0x2608, - 0xad90, 0x000f, 0x0459, 0x0088, 0xa6b2, 0x003c, 0x2009, 0x003c, - 0x2d78, 0xad90, 0x000f, 0x0411, 0x0c28, 0x00fe, 0x852f, 0xa5ad, - 0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0028, 0x00fe, 0x852f, 0xa5ad, - 0x0003, 0x7d36, 0x00de, 0x006e, 0x005e, 0x0005, 0x00f6, 0x8dff, - 0x0158, 0x6804, 0xa07d, 0x0130, 0x6807, 0x0000, 0x080c, 0x4809, - 0x2f68, 0x0cb8, 0x080c, 0x4809, 0x00fe, 0x0005, 0x0156, 0xa184, - 0x0001, 0x0108, 0x8108, 0x810c, 0x21a8, 0x2304, 0x8007, 0x2012, - 0x8318, 0x8210, 0x1f04, 0x80ed, 0x015e, 0x0005, 0x0126, 0x2091, - 0x8000, 0x601c, 0xa084, 0x000f, 0x0013, 0x012e, 0x0005, 0x8117, - 0x8109, 0x8112, 0x812e, 0x8109, 0x8112, 0x810b, 0x8112, 0x8109, - 0x5e80, 0x080c, 0x13fe, 0x0036, 0x2019, 0x0010, 0x080c, 0x8d4e, - 0x003e, 0x0005, 0xa006, 0x0005, 0xa085, 0x0001, 0x0005, 0x00d6, - 0x6010, 0x2068, 0x080c, 0x82ee, 0x0178, 0xa00e, 0x2001, 0x0005, - 0x080c, 0x492c, 0x080c, 0x852d, 0x080c, 0x4809, 0x080c, 0x74f2, - 0xa085, 0x0001, 0x00de, 0x0005, 0xa006, 0x0ce0, 0x6000, 0xa08a, - 0x0010, 0x1a0c, 0x13fe, 0x000b, 0x0005, 0x8145, 0x8160, 0x8147, - 0x816f, 0x815d, 0x8145, 0x8112, 0x8117, 0x8117, 0x8112, 0x8112, - 0x8112, 0x8112, 0x8112, 0x8112, 0x8112, 0x080c, 0x13fe, 0x00d6, - 0x6010, 0x2068, 0x080c, 0x82ee, 0x0110, 0x080c, 0x852d, 0x00de, - 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x5ff8, - 0x080c, 0x6462, 0xa085, 0x0001, 0x0005, 0x080c, 0x1788, 0x0c38, - 0x00e6, 0x2071, 0x94e5, 0x7024, 0xac06, 0x1110, 0x080c, 0x708d, - 0x080c, 0x6fab, 0x00ee, 0x19d8, 0x080c, 0x8112, 0x0005, 0x0036, - 0x00e6, 0x2071, 0x94e5, 0x703c, 0xac06, 0x1138, 0x2019, 0x0000, - 0x080c, 0x7110, 0x00ee, 0x003e, 0x0850, 0x080c, 0x7366, 0x00ee, - 0x003e, 0x1928, 0x080c, 0x8112, 0x0005, 0x00c6, 0x601c, 0xa084, - 0x000f, 0x0013, 0x00ce, 0x0005, 0x819a, 0x81f7, 0x829a, 0x819e, - 0x819a, 0x819a, 0x8d44, 0x74f2, 0x81f7, 0x080c, 0x84c8, 0x1110, - 0x080c, 0x7776, 0x0005, 0x6017, 0x0001, 0x0005, 0x6000, 0xa08a, - 0x0010, 0x1a0c, 0x13fe, 0x000b, 0x0005, 0x81b5, 0x81b7, 0x81d5, - 0x81e7, 0x81f4, 0x81b5, 0x819a, 0x819a, 0x819a, 0x81e7, 0x81e7, - 0x81b5, 0x81b5, 0x81b5, 0x81b5, 0x81f1, 0x080c, 0x13fe, 0x00e6, - 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071, 0x94e5, 0x7024, - 0xac06, 0x0180, 0x080c, 0x6fab, 0x6007, 0x0085, 0x6003, 0x000b, - 0x601f, 0x0002, 0x6017, 0x0014, 0x080c, 0x5ff8, 0x080c, 0x6462, - 0x00ee, 0x0005, 0x6017, 0x0001, 0x0cd8, 0x00d6, 0x6010, 0x2068, - 0x6850, 0xc0b5, 0x6852, 0x00de, 0x6007, 0x0085, 0x6003, 0x000b, - 0x601f, 0x0002, 0x080c, 0x5ff8, 0x080c, 0x6462, 0x0005, 0x00d6, - 0x6017, 0x0001, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x00de, - 0x0005, 0x080c, 0x74f2, 0x0005, 0x080c, 0x1788, 0x08f0, 0x6000, - 0xa08a, 0x0010, 0x1a0c, 0x13fe, 0x000b, 0x0005, 0x820e, 0x819b, - 0x8210, 0x820e, 0x8210, 0x820e, 0x820e, 0x820e, 0x8195, 0x8195, - 0x820e, 0x820e, 0x820e, 0x820e, 0x820e, 0x820e, 0x080c, 0x13fe, - 0x00d6, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa08a, - 0x000c, 0x1a0c, 0x13fe, 0x000b, 0x0005, 0x8229, 0x824a, 0x8229, - 0x824a, 0x8229, 0x824a, 0x822b, 0x8232, 0x8229, 0x824a, 0x8229, - 0x8243, 0x080c, 0x13fe, 0x6004, 0xa08e, 0x0004, 0x01b0, 0xa08e, - 0x0002, 0x0198, 0x6004, 0x080c, 0x84c8, 0x0904, 0x8292, 0xa08e, - 0x0021, 0x0904, 0x8296, 0xa08e, 0x0022, 0x0904, 0x8292, 0xa08e, - 0x003d, 0x0904, 0x8296, 0x080c, 0x266c, 0x080c, 0x7776, 0x080c, - 0x74f2, 0x0005, 0x00c6, 0x00d6, 0x6104, 0xa186, 0x0016, 0x0598, - 0xa186, 0x0002, 0x11f8, 0x6018, 0x2068, 0x2001, 0x9232, 0x2004, - 0xd0ac, 0x11c0, 0x68a0, 0xd0bc, 0x11a8, 0x6840, 0xa084, 0x00ff, - 0xa005, 0x0180, 0x8001, 0x6842, 0x6013, 0x0000, 0x601f, 0x0007, - 0x6017, 0x0398, 0x080c, 0x749c, 0x0128, 0x2d00, 0x601a, 0x601f, - 0x0001, 0x0088, 0x00de, 0x00ce, 0x080c, 0x7776, 0x080c, 0x266c, - 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x2692, 0x012e, 0x00ee, - 0x080c, 0x74f2, 0x0005, 0x2001, 0x0002, 0x080c, 0x43e3, 0x6003, - 0x0001, 0x6007, 0x0002, 0x080c, 0x603e, 0x080c, 0x6462, 0x00de, - 0x00ce, 0x0c80, 0x080c, 0x7776, 0x0804, 0x8247, 0x080c, 0x7790, - 0x0804, 0x8247, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x13fe, 0x000b, - 0x0005, 0x82b1, 0x82b1, 0x82b1, 0x82b1, 0x82b1, 0x82b1, 0x82b1, - 0x82b1, 0x82b1, 0x819a, 0x82b1, 0x819b, 0x82b3, 0x819b, 0x82bc, - 0x82b1, 0x080c, 0x13fe, 0x6007, 0x008b, 0x6003, 0x000d, 0x080c, - 0x5ff8, 0x080c, 0x6462, 0x0005, 0x080c, 0x848f, 0x0479, 0x01d8, - 0x080c, 0x266c, 0x00d6, 0x0451, 0x0150, 0x6010, 0x2068, 0x6837, - 0x0103, 0x684b, 0x0006, 0x6847, 0x0000, 0x080c, 0x4809, 0x00de, - 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x603e, - 0x080c, 0x6462, 0x0010, 0x080c, 0x74f2, 0x0005, 0xa284, 0x0003, - 0x1158, 0xa282, 0x9900, 0x0240, 0x2001, 0x9216, 0x2004, 0xa202, - 0x1218, 0xa085, 0x0001, 0x0005, 0xa006, 0x0ce8, 0x0026, 0x6210, - 0x82ff, 0x002e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126, - 0x2091, 0x8000, 0x2061, 0x9900, 0x2071, 0x9200, 0x7344, 0x7064, - 0xa302, 0x1290, 0x601c, 0xa206, 0x1148, 0x080c, 0x84c8, 0x1110, - 0x080c, 0x7776, 0x00c6, 0x080c, 0x74f2, 0x00ce, 0xace0, 0x000c, - 0x7058, 0xac02, 0x1208, 0x0c50, 0x012e, 0x000e, 0x003e, 0x00ce, - 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0xa188, 0x936e, 0x210c, - 0x81ff, 0x0170, 0x2061, 0x9900, 0x2071, 0x9200, 0x0016, 0x080c, - 0x749c, 0x001e, 0x0138, 0x611a, 0x080c, 0x266c, 0x080c, 0x74f2, - 0xa006, 0x0010, 0xa085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, - 0x00c6, 0x0056, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x749c, - 0x005e, 0x0170, 0x6612, 0x651a, 0x601f, 0x0003, 0x2009, 0x004b, - 0x080c, 0x7518, 0xa085, 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, - 0xa006, 0x0cd0, 0x00c6, 0x0056, 0x0126, 0x2091, 0x8000, 0x62a0, - 0x00c6, 0x080c, 0x749c, 0x005e, 0x01f8, 0x6013, 0x0000, 0x651a, - 0x601f, 0x0003, 0x00c6, 0x2560, 0x080c, 0x460d, 0x00ce, 0x080c, - 0x6127, 0x0086, 0x2041, 0x0000, 0x080c, 0x606d, 0x2c08, 0x080c, - 0x8ee4, 0x008e, 0x2009, 0x004c, 0x080c, 0x7518, 0xa085, 0x0001, - 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00c6, 0x0056, - 0x0126, 0x2091, 0x8000, 0x62a0, 0x00c6, 0x080c, 0x749c, 0x005e, - 0x0500, 0x6612, 0x651a, 0x601f, 0x0003, 0x2019, 0x0005, 0x00c6, - 0x2560, 0x080c, 0x460d, 0x00ce, 0x080c, 0x6127, 0x0086, 0x2041, - 0x0000, 0x080c, 0x606d, 0x2c08, 0x080c, 0x8ee4, 0x008e, 0x2009, - 0x004d, 0x080c, 0x7518, 0xa085, 0x0001, 0x012e, 0x005e, 0x00ce, + 0x8210, 0x1f04, 0x75c5, 0x015e, 0x000e, 0x6852, 0x000e, 0x684e, + 0x001e, 0x2168, 0x080c, 0x14af, 0x0418, 0x0016, 0x080c, 0x14af, + 0x00de, 0x080c, 0x793f, 0x00e0, 0x6837, 0x0103, 0x6944, 0xa184, + 0x00ff, 0xa0b6, 0x0002, 0x0180, 0xa086, 0x0028, 0x1118, 0x684b, + 0x001c, 0x0060, 0xd1dc, 0x0118, 0x684b, 0x0015, 0x0038, 0xd1d4, + 0x0118, 0x684b, 0x0007, 0x0010, 0x684b, 0x0000, 0x080c, 0x46a1, + 0x080c, 0x6d18, 0x00de, 0x0005, 0x2019, 0x0001, 0x080c, 0x68e5, + 0x6003, 0x0002, 0x080c, 0x5cc9, 0x080c, 0x5dc2, 0x0005, 0x080c, + 0x5cc9, 0x080c, 0x2563, 0x00d6, 0x6110, 0x2168, 0x080c, 0x7b8f, + 0x0150, 0x6837, 0x0103, 0x684b, 0x0029, 0x6847, 0x0000, 0x080c, + 0x46a1, 0x080c, 0x7d30, 0x00de, 0x080c, 0x6d18, 0x080c, 0x5dc2, + 0x0005, 0x684b, 0x0015, 0xd1fc, 0x0138, 0x684b, 0x0007, 0x8002, + 0x8000, 0x810a, 0xa189, 0x0000, 0x6962, 0x685e, 0x0005, 0xa182, + 0x0040, 0x0002, 0x7645, 0x7645, 0x7645, 0x7645, 0x7645, 0x7647, + 0x7645, 0x76e7, 0x76ef, 0x7645, 0x7645, 0x7645, 0x7645, 0x7645, + 0x7645, 0x7645, 0x7645, 0x7645, 0x7645, 0x080c, 0x1410, 0x0076, + 0x00f6, 0x00e6, 0x00d6, 0x2071, 0x908c, 0x6110, 0x2178, 0x7614, + 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, + 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0904, 0x76d8, 0xa694, 0xff00, + 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, + 0x0300, 0x0904, 0x76d6, 0xa686, 0x0100, 0x1140, 0x2001, 0x9099, + 0x2004, 0xa005, 0x1118, 0xc6c4, 0x7e46, 0x0c28, 0x080c, 0x1488, + 0x090c, 0x1410, 0x2d00, 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e, + 0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, + 0x6e46, 0xa68c, 0x0c00, 0x0120, 0x7318, 0x6b62, 0x731c, 0x6b5e, + 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0180, 0xa186, 0x0028, 0x1118, + 0x684b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038, + 0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010, 0x684b, 0x0000, 0x6f4e, + 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0160, 0x7328, + 0x732c, 0x6b56, 0x0036, 0x2308, 0x2019, 0x9098, 0xad90, 0x0019, + 0x080c, 0x794f, 0x003e, 0xd6cc, 0x01c8, 0x7124, 0x695a, 0xa192, + 0x0021, 0x1250, 0x2071, 0x9098, 0x831c, 0x2300, 0xae18, 0xad90, + 0x001d, 0x080c, 0x794f, 0x0050, 0x7838, 0xd0fc, 0x0120, 0x2009, + 0x0020, 0x695a, 0x0c78, 0x2d78, 0x080c, 0x78f4, 0xd6dc, 0x1110, + 0xa006, 0x0030, 0x2001, 0x0001, 0x2071, 0x908c, 0x7218, 0x731c, + 0x080c, 0x1716, 0x00de, 0x00ee, 0x00fe, 0x007e, 0x0005, 0x20e1, + 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x16d1, 0x0005, 0x00d6, + 0x6003, 0x0002, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0904, 0x778d, + 0xd1cc, 0x0904, 0x7766, 0x6948, 0x6838, 0xd0fc, 0x0590, 0x0016, + 0x684c, 0x0006, 0x6850, 0x0006, 0x684c, 0xd0ac, 0x0180, 0x6810, + 0x6914, 0xa115, 0x0160, 0x080c, 0x7621, 0x00f6, 0x6948, 0x2178, + 0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0x00fe, 0x6948, + 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0023, 0x0156, 0x21a8, + 0x2304, 0x2012, 0x8318, 0x8210, 0x1f04, 0x7720, 0x015e, 0x000e, + 0x6852, 0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x14af, 0x0804, + 0x778b, 0x0016, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6, + 0x0002, 0x01b0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c, 0x784b, + 0x001c, 0x00b8, 0xd1dc, 0x0128, 0x684b, 0x0015, 0x784b, 0x0015, + 0x0080, 0xd1d4, 0x0128, 0x684b, 0x0007, 0x784b, 0x0007, 0x0048, + 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, + 0x7621, 0x6860, 0x7862, 0x685c, 0x785e, 0x684c, 0x784e, 0x00fe, + 0x080c, 0x14af, 0x00de, 0x080c, 0x793f, 0x0428, 0x6837, 0x0103, + 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0180, 0xa086, 0x0028, + 0x1118, 0x684b, 0x001c, 0x00a8, 0xd1dc, 0x0118, 0x684b, 0x0015, + 0x0080, 0xd1d4, 0x0118, 0x684b, 0x0007, 0x0058, 0x684b, 0x0000, + 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, + 0x7621, 0x080c, 0x46a1, 0x080c, 0x6d18, 0x00de, 0x0005, 0x080c, + 0x5c37, 0x0010, 0x080c, 0x5cc9, 0x080c, 0x7b8f, 0x0198, 0x00d6, + 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0x8b0c, 0x210c, 0xd18c, + 0x1198, 0xd184, 0x1170, 0x6108, 0x694a, 0x6847, 0x0000, 0x080c, + 0x46a1, 0x00de, 0x080c, 0x6d18, 0x080c, 0x5d10, 0x080c, 0x5dc2, + 0x0005, 0x684b, 0x0004, 0x0c88, 0x684b, 0x0004, 0x0c70, 0xa182, + 0x0040, 0x0002, 0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x77cf, + 0x77cd, 0x77d2, 0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x77cd, + 0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x080c, 0x1410, 0x080c, + 0x6d18, 0x0005, 0x0006, 0x0026, 0xa016, 0x080c, 0x16d1, 0x002e, + 0x000e, 0x0005, 0xa182, 0x0085, 0x0002, 0x77e6, 0x77e4, 0x77e4, + 0x77e4, 0x77e4, 0x77e4, 0x77e4, 0x080c, 0x1410, 0x6003, 0x000b, + 0x6106, 0x080c, 0x589c, 0x0126, 0x2091, 0x8000, 0x080c, 0x5d10, + 0x012e, 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a, 0x0085, + 0x0a0c, 0x1410, 0xa08a, 0x008c, 0x1a0c, 0x1410, 0xa082, 0x0085, + 0x0072, 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c, 0x1410, + 0x080c, 0x5c37, 0x080c, 0x7d3c, 0x080c, 0x5d10, 0x0005, 0x7816, + 0x7818, 0x7818, 0x7816, 0x7816, 0x7816, 0x7816, 0x080c, 0x1410, + 0x080c, 0x5c37, 0x080c, 0x7d3c, 0x080c, 0x5d10, 0x0005, 0xa186, + 0x0013, 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x04aa, 0xa186, + 0x0027, 0x11e8, 0x080c, 0x5c37, 0x080c, 0x2563, 0x00d6, 0x6010, + 0x2068, 0x080c, 0x7b8f, 0x0150, 0x6837, 0x0103, 0x6847, 0x0000, + 0x684b, 0x0029, 0x080c, 0x46a1, 0x080c, 0x7d30, 0x00de, 0x080c, + 0x6d18, 0x080c, 0x5d10, 0x0005, 0x080c, 0x6d55, 0x0ce0, 0xa186, + 0x0014, 0x1dd0, 0x080c, 0x5c37, 0x00d6, 0x6010, 0x2068, 0x080c, + 0x7b8f, 0x0d60, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b, 0x0006, + 0x6850, 0xc0ec, 0x6852, 0x08f0, 0x7865, 0x7863, 0x7863, 0x7863, + 0x7863, 0x7863, 0x786e, 0x080c, 0x1410, 0x080c, 0x5c37, 0x6017, + 0x0014, 0x6003, 0x000c, 0x080c, 0x5d10, 0x0005, 0x080c, 0x5c37, + 0x6017, 0x0014, 0x6003, 0x000e, 0x080c, 0x5d10, 0x0005, 0xa182, + 0x008c, 0x1220, 0xa182, 0x0085, 0x0208, 0x001a, 0x080c, 0x6d55, + 0x0005, 0x7888, 0x7888, 0x7888, 0x7888, 0x788a, 0x78ad, 0x7888, + 0x080c, 0x1410, 0x00d6, 0x080c, 0x7d30, 0x080c, 0x7b8f, 0x01c8, + 0x6010, 0x2068, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0128, 0x684b, + 0x0006, 0xc0ec, 0x6852, 0x0048, 0xd0bc, 0x0118, 0x684b, 0x0002, + 0x0020, 0x684b, 0x0005, 0x080c, 0x7dce, 0x6847, 0x0000, 0x080c, + 0x46a1, 0x080c, 0x6d18, 0x00de, 0x0005, 0x00d6, 0x6010, 0x2068, + 0x080c, 0x7b8f, 0x01c8, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0128, + 0xc0ec, 0x6852, 0x684b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0x684b, + 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x7dce, 0x6847, 0x0000, + 0x080c, 0x46a1, 0x080c, 0x7d30, 0x00de, 0x080c, 0x6d18, 0x0005, + 0x0016, 0x00d6, 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0140, 0x6837, + 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x080c, 0x46a1, 0x00de, + 0x001e, 0xa186, 0x0013, 0x0148, 0xa186, 0x0014, 0x0130, 0xa186, + 0x0027, 0x0118, 0x080c, 0x6d55, 0x0030, 0x080c, 0x5c37, 0x080c, + 0x7d3c, 0x080c, 0x5d10, 0x0005, 0x0056, 0x0066, 0x00d6, 0x00f6, + 0x2029, 0x0001, 0xa182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, + 0x2130, 0x2069, 0x9098, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, + 0xaf90, 0x001d, 0x080c, 0x794f, 0xa6b2, 0x0020, 0x7804, 0xa06d, + 0x0110, 0x080c, 0x14af, 0x080c, 0x1488, 0x0500, 0x8528, 0x6837, + 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d, 0x1228, + 0x2608, 0xad90, 0x000f, 0x0459, 0x0088, 0xa6b2, 0x003c, 0x2009, + 0x003c, 0x2d78, 0xad90, 0x000f, 0x0411, 0x0c28, 0x00fe, 0x852f, + 0xa5ad, 0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0028, 0x00fe, 0x852f, + 0xa5ad, 0x0003, 0x7d36, 0x00de, 0x006e, 0x005e, 0x0005, 0x00f6, + 0x8dff, 0x0158, 0x6804, 0xa07d, 0x0130, 0x6807, 0x0000, 0x080c, + 0x46a1, 0x2f68, 0x0cb8, 0x080c, 0x46a1, 0x00fe, 0x0005, 0x0156, + 0xa184, 0x0001, 0x0108, 0x8108, 0x810c, 0x21a8, 0x2304, 0x8007, + 0x2012, 0x8318, 0x8210, 0x1f04, 0x7956, 0x015e, 0x0005, 0x0126, + 0x2091, 0x8000, 0x601c, 0xa084, 0x000f, 0x0013, 0x012e, 0x0005, + 0x797e, 0x7970, 0x7979, 0x7995, 0x7970, 0x7979, 0x7972, 0x7979, + 0x080c, 0x1410, 0x0036, 0x2019, 0x0010, 0x080c, 0x85f9, 0x003e, + 0x0005, 0xa006, 0x0005, 0xa085, 0x0001, 0x0005, 0x00d6, 0x6010, + 0x2068, 0x080c, 0x7b8f, 0x0178, 0xa00e, 0x2001, 0x0005, 0x080c, + 0x4773, 0x080c, 0x7dce, 0x080c, 0x46a1, 0x080c, 0x6d18, 0xa085, + 0x0001, 0x00de, 0x0005, 0xa006, 0x0ce0, 0x6000, 0xa08a, 0x0010, + 0x1a0c, 0x1410, 0x000b, 0x0005, 0x79ac, 0x79c7, 0x79ae, 0x79d6, + 0x79c4, 0x79ac, 0x7979, 0x797e, 0x797e, 0x7979, 0x7979, 0x7979, + 0x7979, 0x7979, 0x7979, 0x7979, 0x080c, 0x1410, 0x00d6, 0x6010, + 0x2068, 0x080c, 0x7b8f, 0x0110, 0x080c, 0x7dce, 0x00de, 0x6007, + 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x589c, 0x080c, + 0x5d10, 0xa085, 0x0001, 0x0005, 0x080c, 0x179e, 0x0c38, 0x00e6, + 0x2071, 0x8daa, 0x7024, 0xac06, 0x1110, 0x080c, 0x6862, 0x080c, + 0x677e, 0x00ee, 0x19d8, 0x080c, 0x7979, 0x0005, 0x0036, 0x00e6, + 0x2071, 0x8daa, 0x703c, 0xac06, 0x1138, 0x2019, 0x0000, 0x080c, + 0x68e5, 0x00ee, 0x003e, 0x0850, 0x080c, 0x6b33, 0x00ee, 0x003e, + 0x1928, 0x080c, 0x7979, 0x0005, 0x00c6, 0x601c, 0xa084, 0x000f, + 0x0013, 0x00ce, 0x0005, 0x7a01, 0x7a62, 0x7b28, 0x7a05, 0x7a01, + 0x7a01, 0x85ef, 0x6d18, 0x7a62, 0x080c, 0x7d69, 0x1110, 0x080c, + 0x6fb6, 0x0005, 0x6017, 0x0001, 0x0005, 0x6010, 0xa080, 0x0019, + 0x2c02, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x1410, 0x000b, 0x0005, + 0x7a20, 0x7a22, 0x7a40, 0x7a52, 0x7a5f, 0x7a20, 0x7a01, 0x7a01, + 0x7a01, 0x7a52, 0x7a52, 0x7a20, 0x7a20, 0x7a20, 0x7a20, 0x7a5c, + 0x080c, 0x1410, 0x00e6, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, + 0x2071, 0x8daa, 0x7024, 0xac06, 0x0180, 0x080c, 0x677e, 0x6007, + 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6017, 0x0014, 0x080c, + 0x589c, 0x080c, 0x5d10, 0x00ee, 0x0005, 0x6017, 0x0001, 0x0cd8, + 0x00d6, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x00de, 0x6007, + 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x589c, 0x080c, + 0x5d10, 0x0005, 0x00d6, 0x6017, 0x0001, 0x6010, 0x2068, 0x6850, + 0xc0b5, 0x6852, 0x00de, 0x0005, 0x080c, 0x6d18, 0x0005, 0x080c, + 0x179e, 0x08f0, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x1410, 0x000b, + 0x0005, 0x7a79, 0x7a02, 0x7a7b, 0x7a79, 0x7a7b, 0x7a79, 0x7a79, + 0x7a79, 0x79fc, 0x79fc, 0x7a79, 0x7a79, 0x7a79, 0x7a79, 0x7a79, + 0x7a79, 0x080c, 0x1410, 0x00d6, 0x6018, 0x2068, 0x6804, 0xa084, + 0x00ff, 0x00de, 0xa08a, 0x000c, 0x1a0c, 0x1410, 0x000b, 0x0005, + 0x7a94, 0x7ac2, 0x7a94, 0x7ac2, 0x7a94, 0x7ac2, 0x7a96, 0x7a9d, + 0x7a94, 0x7ac2, 0x7a94, 0x7aae, 0x080c, 0x1410, 0x6004, 0xa08e, + 0x0004, 0x0518, 0xa08e, 0x0002, 0x0500, 0x6004, 0x080c, 0x7d69, + 0x0904, 0x7b0b, 0xa08e, 0x0021, 0x0904, 0x7b0f, 0xa08e, 0x0022, + 0x0904, 0x7b0b, 0xa08e, 0x003d, 0x0904, 0x7b0f, 0xa08e, 0x0001, + 0x1150, 0x00d6, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x00de, + 0xa086, 0x0006, 0x0110, 0x080c, 0x2563, 0x080c, 0x6fb6, 0x080c, + 0x7d3c, 0x0005, 0x00c6, 0x00d6, 0x6104, 0xa186, 0x0016, 0x05a0, + 0xa186, 0x0002, 0x1500, 0x6018, 0x2068, 0x2001, 0x8b32, 0x2004, + 0xd0ac, 0x1904, 0x7b13, 0x68a0, 0xd0bc, 0x15e8, 0x6840, 0xa084, + 0x00ff, 0xa005, 0x0180, 0x8001, 0x6842, 0x6013, 0x0000, 0x601f, + 0x0007, 0x6017, 0x0398, 0x080c, 0x6cc2, 0x0128, 0x2d00, 0x601a, + 0x601f, 0x0001, 0x0088, 0x00de, 0x00ce, 0x080c, 0x6fb6, 0x080c, + 0x2563, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x2589, 0x012e, + 0x00ee, 0x080c, 0x7d3c, 0x0005, 0x2001, 0x0002, 0x080c, 0x42b9, + 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x58e2, 0x080c, 0x5d10, + 0x00de, 0x00ce, 0x0c80, 0x080c, 0x6fb6, 0x0804, 0x7abf, 0x080c, + 0x6fd3, 0x0804, 0x7abf, 0x00de, 0x00ce, 0x080c, 0x6fb6, 0x080c, + 0x2563, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x2589, 0x6013, + 0x0000, 0x601f, 0x0007, 0x6017, 0x0398, 0x012e, 0x00ee, 0x0005, + 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x1410, 0x000b, 0x0005, 0x7b3f, + 0x7b3f, 0x7b3f, 0x7b3f, 0x7b3f, 0x7b3f, 0x7b3f, 0x7b3f, 0x7b3f, + 0x7a01, 0x7b3f, 0x7a02, 0x7b41, 0x7a02, 0x7b4a, 0x7b3f, 0x080c, + 0x1410, 0x6007, 0x008b, 0x6003, 0x000d, 0x080c, 0x589c, 0x080c, + 0x5d10, 0x0005, 0x080c, 0x7d30, 0x080c, 0x7b8f, 0x0568, 0x080c, + 0x2563, 0x00d6, 0x04e1, 0x0168, 0x6010, 0x2068, 0x6837, 0x0103, + 0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x080c, + 0x46a1, 0x2c68, 0x080c, 0x6cc2, 0x0140, 0x6818, 0x601a, 0x00c6, + 0x2d60, 0x080c, 0x7d3c, 0x00ce, 0x0008, 0x2d60, 0x00de, 0x6013, + 0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, + 0x58e2, 0x080c, 0x5d10, 0x0010, 0x080c, 0x7d3c, 0x0005, 0xa284, + 0x0003, 0x1158, 0xa282, 0x9200, 0x0240, 0x2001, 0x8b16, 0x2004, + 0xa202, 0x1218, 0xa085, 0x0001, 0x0005, 0xa006, 0x0ce8, 0x0026, + 0x6210, 0x82ff, 0x002e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006, + 0x0126, 0x2091, 0x8000, 0x2061, 0x9200, 0x2071, 0x8b00, 0x7344, + 0x7064, 0xa302, 0x1290, 0x601c, 0xa206, 0x1148, 0x080c, 0x7d69, + 0x1110, 0x080c, 0x6fb6, 0x00c6, 0x080c, 0x6d18, 0x00ce, 0xace0, + 0x000c, 0x7058, 0xac02, 0x1208, 0x0c50, 0x012e, 0x000e, 0x003e, + 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0xa188, 0x8c34, + 0x210c, 0x81ff, 0x0170, 0x2061, 0x9200, 0x2071, 0x8b00, 0x0016, + 0x080c, 0x6cc2, 0x001e, 0x0138, 0x611a, 0x080c, 0x2563, 0x080c, + 0x6d18, 0xa006, 0x0010, 0xa085, 0x0001, 0x001e, 0x00ce, 0x00ee, + 0x0005, 0x00c6, 0x0056, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, + 0x6cc2, 0x005e, 0x0170, 0x6612, 0x651a, 0x601f, 0x0003, 0x2009, + 0x004b, 0x080c, 0x6d3f, 0xa085, 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00c6, 0x0056, 0x0126, 0x2091, 0x8000, - 0x62a0, 0x00c6, 0x080c, 0x749c, 0x005e, 0x0500, 0x6612, 0x651a, - 0x601f, 0x0003, 0x2019, 0x0005, 0x00c6, 0x2560, 0x080c, 0x460d, - 0x00ce, 0x080c, 0x6127, 0x0086, 0x2041, 0x0000, 0x080c, 0x606d, - 0x2c08, 0x080c, 0x8ee4, 0x008e, 0x2009, 0x004e, 0x080c, 0x7518, - 0xa085, 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, - 0x00c6, 0x0096, 0x0086, 0x0056, 0x0126, 0x2091, 0x8000, 0x62a0, - 0x00c6, 0x080c, 0x749c, 0x005e, 0x0904, 0x8426, 0x6612, 0x651a, - 0x601f, 0x0003, 0x00c6, 0x2560, 0x080c, 0x45af, 0x0118, 0x2001, - 0x83ec, 0x0028, 0x080c, 0x4581, 0x0160, 0x2001, 0x83f2, 0x0006, - 0xa00e, 0x2001, 0x0004, 0x080c, 0x492c, 0x080c, 0x4809, 0x000e, - 0x0807, 0x2019, 0x0004, 0x080c, 0x632b, 0x0036, 0x003e, 0x00ce, - 0x2041, 0x0001, 0x2608, 0x080c, 0x6140, 0x080c, 0x606d, 0x2c08, - 0x2648, 0x080c, 0x8ee4, 0x6018, 0xa080, 0x000f, 0x200c, 0x81ff, - 0x090c, 0x61d3, 0x2009, 0x0052, 0x080c, 0x7518, 0xa085, 0x0001, - 0x012e, 0x005e, 0x008e, 0x009e, 0x00ce, 0x0005, 0xa006, 0x0cc0, - 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x749c, 0x001e, - 0x0178, 0x660a, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, - 0x001f, 0x080c, 0x7518, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, - 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, - 0x749c, 0x001e, 0x0178, 0x660a, 0x611a, 0x601f, 0x0008, 0x2d00, - 0x6012, 0x2009, 0x0021, 0x080c, 0x7518, 0xa085, 0x0001, 0x012e, - 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, - 0x00c6, 0x080c, 0x749c, 0x001e, 0x0178, 0x660a, 0x611a, 0x601f, - 0x0001, 0x2d00, 0x6012, 0x2009, 0x003d, 0x080c, 0x7518, 0xa085, - 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, - 0x2091, 0x8000, 0x00c6, 0x080c, 0x749c, 0x001e, 0x0170, 0x611a, - 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x080c, 0x7518, - 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x0026, - 0x00d6, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0110, 0x8211, 0x6a3e, - 0x00de, 0x002e, 0x0005, 0x0006, 0x6013, 0x0000, 0x601f, 0x0007, - 0x2001, 0x94dd, 0x2004, 0x6016, 0x000e, 0x0005, 0x0066, 0x00c6, - 0x00d6, 0x2031, 0x9252, 0x2634, 0xd6e4, 0x0128, 0x6618, 0x2660, - 0x6e48, 0x080c, 0x453a, 0x00de, 0x00ce, 0x006e, 0x0005, 0x0006, - 0x0016, 0x6004, 0xa08e, 0x0002, 0x0140, 0xa08e, 0x0003, 0x0128, - 0xa08e, 0x0004, 0x0110, 0xa085, 0x0001, 0x001e, 0x000e, 0x0005, - 0x0006, 0x00d6, 0x6010, 0xa06d, 0x0128, 0x6838, 0xd0fc, 0x0110, - 0xa006, 0x0010, 0xa085, 0x0001, 0x00de, 0x000e, 0x0005, 0x00c6, - 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x749c, 0x001e, 0x0180, - 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x080c, 0x266c, 0x2009, - 0x0028, 0x080c, 0x7518, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, - 0xa006, 0x0cd8, 0xa186, 0x0015, 0x1178, 0x2011, 0x9220, 0x2204, - 0xa086, 0x0074, 0x1148, 0x080c, 0x7a64, 0x6003, 0x0001, 0x6007, - 0x0029, 0x080c, 0x603e, 0x0020, 0x080c, 0x7776, 0x080c, 0x74f2, - 0x0005, 0xa186, 0x0015, 0x11b0, 0x2011, 0x9220, 0x2204, 0xa086, - 0x0014, 0x1180, 0x00d6, 0x6018, 0x2068, 0x080c, 0x44c7, 0x00de, - 0x080c, 0x7a6e, 0x1138, 0x2001, 0x0006, 0x080c, 0x43e3, 0x080c, - 0x7598, 0x0020, 0x080c, 0x7776, 0x080c, 0x74f2, 0x0005, 0x6848, - 0xa086, 0x0005, 0x1108, 0x0009, 0x0005, 0x6850, 0xc0ad, 0x6852, - 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x2001, 0x94d9, 0x200c, - 0x8000, 0x2014, 0x2001, 0x0064, 0x080c, 0x5eaf, 0x2001, 0x94dd, - 0x82ff, 0x1110, 0x2011, 0x0002, 0x2202, 0x003e, 0x002e, 0x001e, - 0x000e, 0x0005, 0x0006, 0x2001, 0x94dd, 0x2003, 0x0028, 0x2001, - 0x94de, 0x2003, 0x07d0, 0x000e, 0x0005, 0x0066, 0x6000, 0xa0b2, - 0x0010, 0x1a0c, 0x13fe, 0x0013, 0x006e, 0x0005, 0x856e, 0x881c, - 0x8907, 0x856e, 0x856e, 0x856e, 0x856e, 0x856e, 0x85a6, 0x8973, - 0x856e, 0x856e, 0x856e, 0x856e, 0x856e, 0x856e, 0x080c, 0x13fe, - 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x13fe, 0x0013, 0x006e, - 0x0005, 0x8589, 0x8ce9, 0x8589, 0x8589, 0x8589, 0x8589, 0x8589, - 0x8589, 0x8cad, 0x8d31, 0x8589, 0x9105, 0x9135, 0x9105, 0x9135, - 0x8589, 0x080c, 0x13fe, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, - 0x13fe, 0x0013, 0x006e, 0x0005, 0x85a4, 0x8ab9, 0x8b64, 0x8b88, - 0x8bd3, 0x85a4, 0x85a4, 0x8c44, 0x897f, 0x8c87, 0x8c9a, 0x85a4, - 0x85a4, 0x85a4, 0x85a4, 0x85a4, 0x080c, 0x13fe, 0xa1b2, 0x003e, - 0x1a0c, 0x13fe, 0x2100, 0x0002, 0x85df, 0x86f0, 0x85df, 0x85df, - 0x85df, 0x86f7, 0x85df, 0x85df, 0x85df, 0x85df, 0x85df, 0x85df, - 0x85df, 0x85df, 0x85df, 0x85df, 0x85df, 0x85df, 0x85df, 0x85df, - 0x85df, 0x85df, 0x85df, 0x85e1, 0x860b, 0x8616, 0x865a, 0x8674, - 0x86aa, 0x86dd, 0x85df, 0x85df, 0x86fa, 0x85df, 0x85df, 0x8709, - 0x8710, 0x85df, 0x85df, 0x85df, 0x85df, 0x85df, 0x87ab, 0x85df, - 0x85df, 0x87b5, 0x85df, 0x85df, 0x875d, 0x85df, 0x85df, 0x080c, - 0x13fe, 0x080c, 0x470e, 0x6618, 0x00c6, 0x2660, 0x080c, 0x4443, - 0x00ce, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, - 0x0278, 0x080c, 0x8e28, 0x1904, 0x8654, 0x080c, 0x8dd3, 0x1120, - 0x6007, 0x0008, 0x0804, 0x86eb, 0x6007, 0x0009, 0x0804, 0x86eb, - 0x080c, 0x8fa4, 0x0128, 0x080c, 0x8e28, 0x0d78, 0x0804, 0x8654, - 0x6013, 0x1900, 0x0c88, 0x6106, 0x080c, 0x8d83, 0x6007, 0x0006, - 0x0804, 0x86eb, 0x6007, 0x0007, 0x0804, 0x86eb, 0x080c, 0x9150, - 0x1904, 0x87c6, 0x00d6, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, - 0x8637, 0xa686, 0x0006, 0x01a0, 0xa686, 0x0004, 0x0188, 0x080c, - 0x4dc5, 0x1160, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006, 0x0140, - 0xa686, 0x0004, 0x0128, 0xa686, 0x0005, 0x0110, 0x00de, 0x00e0, - 0x080c, 0x8e86, 0x11a0, 0xa686, 0x0006, 0x1150, 0x0026, 0x6218, - 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x26b1, 0x002e, - 0x080c, 0x44c7, 0x6007, 0x000a, 0x00de, 0x0804, 0x86eb, 0x6007, - 0x000b, 0x00de, 0x0804, 0x86eb, 0x080c, 0x266c, 0x6007, 0x0001, - 0x0804, 0x86eb, 0x080c, 0x9150, 0x1904, 0x87c6, 0x6618, 0x00d6, - 0x2668, 0x6e04, 0x00de, 0xa686, 0x0707, 0x0d70, 0x0026, 0x6218, - 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x26b1, 0x002e, - 0x6007, 0x000c, 0x0804, 0x86eb, 0x080c, 0x470e, 0x6618, 0xa6b0, - 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x02b0, 0xa6b4, - 0xff00, 0x8637, 0xa686, 0x0004, 0x0118, 0xa686, 0x0006, 0x1960, - 0x080c, 0x8e93, 0x1120, 0x6007, 0x000e, 0x0804, 0x86eb, 0x080c, - 0x266c, 0x6007, 0x000f, 0x0804, 0x86eb, 0x080c, 0x8fa4, 0x0160, - 0xa6b4, 0xff00, 0x8637, 0xa682, 0x0004, 0x0a04, 0x8654, 0xa682, - 0x0007, 0x0e30, 0x0804, 0x8654, 0x6013, 0x1900, 0x6007, 0x0009, - 0x0804, 0x86eb, 0x080c, 0x470e, 0x6618, 0xa6b0, 0x0001, 0x2634, - 0xa684, 0x00ff, 0xa082, 0x0006, 0x02c0, 0xa6b4, 0xff00, 0x8637, - 0xa686, 0x0004, 0x0120, 0xa686, 0x0006, 0x1904, 0x8654, 0x080c, - 0x8ebb, 0x1130, 0x080c, 0x8dd3, 0x1118, 0x6007, 0x0010, 0x0418, - 0x080c, 0x266c, 0x6007, 0x0011, 0x00f0, 0x080c, 0x8fa4, 0x0140, - 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0d48, 0x0804, 0x8654, - 0x6013, 0x1900, 0x6007, 0x0009, 0x0070, 0x7030, 0xa086, 0x6000, - 0x0140, 0x080c, 0x9150, 0x1904, 0x87c6, 0x080c, 0x87c9, 0x1904, - 0x8654, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x603e, 0x0005, - 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x603e, 0x0cc0, 0x6007, - 0x0005, 0x0cc0, 0x080c, 0x9150, 0x1904, 0x87c6, 0x080c, 0x87c9, - 0x1904, 0x8654, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x603e, - 0x0005, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x603e, 0x0005, - 0x080c, 0x9150, 0x1904, 0x87c6, 0x080c, 0x87c9, 0x1904, 0x8654, - 0x0016, 0x0026, 0x2011, 0x9791, 0x2214, 0xa286, 0xffff, 0x0190, - 0x2c08, 0x080c, 0x82de, 0x01d8, 0x2260, 0x2011, 0x9790, 0x2214, - 0x6008, 0xa206, 0x11a0, 0x6018, 0xa190, 0x0006, 0x2214, 0xa206, - 0x01e0, 0x0068, 0x2011, 0x9790, 0x2214, 0x2c08, 0x080c, 0x90ab, - 0x11a0, 0x2011, 0x9791, 0x2214, 0xa286, 0xffff, 0x01a0, 0x2160, - 0x6007, 0x0026, 0x6013, 0x1700, 0x2011, 0x9789, 0x2214, 0xa296, - 0xffff, 0x1160, 0x6007, 0x0025, 0x0048, 0x601c, 0xa086, 0x0007, - 0x1d70, 0x080c, 0x74f2, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, - 0x080c, 0x603e, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, - 0x43d1, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, - 0x9205, 0x2011, 0x9796, 0x080c, 0x7aee, 0x003e, 0x002e, 0x001e, - 0x015e, 0x0120, 0x6007, 0x0031, 0x0804, 0x86eb, 0x080c, 0x7910, - 0x080c, 0x4dc5, 0x1578, 0x0006, 0x0026, 0x0036, 0x2011, 0x9223, - 0x2204, 0x8000, 0x2012, 0xa084, 0x0007, 0x0190, 0x2001, 0x94d7, - 0x2003, 0xaaaa, 0x2001, 0x94d8, 0x2003, 0x0001, 0x2001, 0x9200, - 0x2003, 0x0001, 0x080c, 0x4d10, 0x003e, 0x002e, 0x000e, 0x0005, - 0x2001, 0x0001, 0x080c, 0x23ba, 0x080c, 0x4dd7, 0x1110, 0x080c, - 0x4d9a, 0x2011, 0x8036, 0x2019, 0x0005, 0x080c, 0x3698, 0x003e, - 0x002e, 0x000e, 0x0005, 0x6106, 0x0479, 0x6007, 0x002b, 0x0804, - 0x86eb, 0x6007, 0x002c, 0x0804, 0x86eb, 0x080c, 0x9150, 0x1170, - 0x0081, 0x1904, 0x8654, 0x6106, 0x0419, 0x1120, 0x6007, 0x002e, - 0x0804, 0x86eb, 0x6007, 0x002f, 0x0804, 0x86eb, 0x080c, 0x74f2, - 0x0005, 0x00d6, 0x0066, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, - 0x8637, 0xa686, 0x0006, 0x0128, 0xa686, 0x0004, 0x0110, 0xa085, - 0x0001, 0x006e, 0x00de, 0x0005, 0x00d6, 0x0439, 0x00de, 0x0005, - 0x00d6, 0x0481, 0x11e0, 0x680c, 0xa08c, 0xff00, 0x6824, 0xa084, - 0x00ff, 0xa115, 0x6212, 0xd1e4, 0x0118, 0x2009, 0x0001, 0x0060, - 0xd1ec, 0x0168, 0x6920, 0xa18c, 0x00ff, 0x6824, 0x080c, 0x240b, - 0x1130, 0x2110, 0x2009, 0x0000, 0x080c, 0x26b1, 0x0018, 0xa085, - 0x0001, 0x0008, 0xa006, 0x00de, 0x0005, 0x2069, 0x978d, 0x6800, - 0xa082, 0x0010, 0x1228, 0x6013, 0x0000, 0xa085, 0x0001, 0x0008, - 0xa006, 0x0005, 0x6013, 0x0000, 0x2069, 0x978c, 0x6808, 0xa084, - 0xff00, 0xa086, 0x0800, 0x0005, 0x6004, 0xa0b2, 0x003e, 0x1a0c, - 0x13fe, 0xa1b6, 0x0013, 0x1110, 0x2008, 0x0092, 0xa1b6, 0x0027, - 0x0120, 0xa1b6, 0x0014, 0x190c, 0x13fe, 0x2001, 0x0007, 0x080c, - 0x43f1, 0x080c, 0x6389, 0x080c, 0x849b, 0x080c, 0x6462, 0x0005, - 0x8875, 0x8877, 0x8875, 0x8875, 0x8875, 0x8877, 0x8885, 0x88e7, - 0x88b2, 0x88e7, 0x88c3, 0x88e7, 0x8885, 0x88e7, 0x88df, 0x88e7, - 0x88df, 0x88e7, 0x88e7, 0x8875, 0x8875, 0x8875, 0x8875, 0x8875, - 0x8875, 0x8875, 0x8875, 0x8875, 0x8875, 0x8875, 0x8875, 0x8875, - 0x88e7, 0x8875, 0x8875, 0x88e7, 0x8875, 0x88e7, 0x88e7, 0x8875, - 0x8875, 0x8875, 0x8875, 0x88e7, 0x88e7, 0x8875, 0x88e7, 0x88e7, - 0x8875, 0x887f, 0x8875, 0x8875, 0x8875, 0x8875, 0x8875, 0x8875, - 0x8875, 0x8875, 0x8875, 0x8875, 0x8875, 0x080c, 0x13fe, 0x080c, - 0x6389, 0x6003, 0x0002, 0x080c, 0x6462, 0x0804, 0x88ed, 0x2001, - 0x0000, 0x080c, 0x43d1, 0x0804, 0x88e7, 0x00f6, 0x2079, 0x9251, - 0x7804, 0x00fe, 0xd0ac, 0x1904, 0x88e7, 0x2001, 0x0000, 0x080c, - 0x43d1, 0x6018, 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x0904, - 0x88e7, 0x2001, 0x0002, 0x080c, 0x43e3, 0x080c, 0x6389, 0x601f, - 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x603e, 0x080c, - 0x6462, 0x00c6, 0x6118, 0x2160, 0x2009, 0x0001, 0x080c, 0x573d, - 0x00ce, 0x04d8, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa6b4, - 0xff00, 0x8637, 0xa686, 0x0006, 0x0550, 0xa686, 0x0004, 0x0538, - 0x2001, 0x0004, 0x0410, 0x2001, 0x9200, 0x2004, 0xa086, 0x0003, - 0x1110, 0x080c, 0x370a, 0x2001, 0x0006, 0x0401, 0x6618, 0x00d6, + 0x62a0, 0x00c6, 0x080c, 0x6cc2, 0x005e, 0x01f8, 0x6013, 0x0000, + 0x651a, 0x601f, 0x0003, 0x00c6, 0x2560, 0x080c, 0x44e6, 0x00ce, + 0x080c, 0x59d5, 0x0086, 0x2041, 0x0000, 0x080c, 0x5911, 0x2c08, + 0x080c, 0x878f, 0x008e, 0x2009, 0x004c, 0x080c, 0x6d3f, 0xa085, + 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00c6, + 0x0056, 0x0126, 0x2091, 0x8000, 0x62a0, 0x00c6, 0x080c, 0x6cc2, + 0x005e, 0x0500, 0x6612, 0x651a, 0x601f, 0x0003, 0x2019, 0x0005, + 0x00c6, 0x2560, 0x080c, 0x44e6, 0x00ce, 0x080c, 0x59d5, 0x0086, + 0x2041, 0x0000, 0x080c, 0x5911, 0x2c08, 0x080c, 0x878f, 0x008e, + 0x2009, 0x004d, 0x080c, 0x6d3f, 0xa085, 0x0001, 0x012e, 0x005e, + 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00c6, 0x0056, 0x0126, 0x2091, + 0x8000, 0x62a0, 0x00c6, 0x080c, 0x6cc2, 0x005e, 0x0500, 0x6612, + 0x651a, 0x601f, 0x0003, 0x2019, 0x0005, 0x00c6, 0x2560, 0x080c, + 0x44e6, 0x00ce, 0x080c, 0x59d5, 0x0086, 0x2041, 0x0000, 0x080c, + 0x5911, 0x2c08, 0x080c, 0x878f, 0x008e, 0x2009, 0x004e, 0x080c, + 0x6d3f, 0xa085, 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, + 0x0cd0, 0x00c6, 0x0096, 0x0086, 0x0056, 0x0126, 0x2091, 0x8000, + 0x62a0, 0x00c6, 0x080c, 0x6cc2, 0x005e, 0x0904, 0x7cc7, 0x6612, + 0x651a, 0x601f, 0x0003, 0x00c6, 0x2560, 0x080c, 0x4488, 0x0118, + 0x2001, 0x7c8d, 0x0028, 0x080c, 0x445a, 0x0160, 0x2001, 0x7c93, + 0x0006, 0xa00e, 0x2001, 0x0004, 0x080c, 0x4773, 0x080c, 0x46a1, + 0x000e, 0x0807, 0x2019, 0x0004, 0x080c, 0x5bd9, 0x0036, 0x003e, + 0x00ce, 0x2041, 0x0001, 0x2608, 0x080c, 0x59ee, 0x080c, 0x5911, + 0x2c08, 0x2648, 0x080c, 0x878f, 0x6018, 0xa080, 0x000f, 0x200c, + 0x81ff, 0x090c, 0x5a81, 0x2009, 0x0052, 0x080c, 0x6d3f, 0xa085, + 0x0001, 0x012e, 0x005e, 0x008e, 0x009e, 0x00ce, 0x0005, 0xa006, + 0x0cc0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x6cc2, + 0x001e, 0x0178, 0x660a, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, + 0x2009, 0x001f, 0x080c, 0x6d3f, 0xa085, 0x0001, 0x012e, 0x00ce, + 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, + 0x080c, 0x6cc2, 0x001e, 0x0178, 0x660a, 0x611a, 0x601f, 0x0008, + 0x2d00, 0x6012, 0x2009, 0x0021, 0x080c, 0x6d3f, 0xa085, 0x0001, + 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x00c6, 0x080c, 0x6cc2, 0x001e, 0x0178, 0x660a, 0x611a, + 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x003d, 0x080c, 0x6d3f, + 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x6cc2, 0x001e, 0x0170, + 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x080c, + 0x6d3f, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, + 0x0026, 0x00d6, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0110, 0x8211, + 0x6a3e, 0x00de, 0x002e, 0x0005, 0x0006, 0x6013, 0x0000, 0x601f, + 0x0007, 0x2001, 0x8da2, 0x2004, 0x6016, 0x000e, 0x0005, 0x0066, + 0x00c6, 0x00d6, 0x2031, 0x8b52, 0x2634, 0xd6e4, 0x0128, 0x6618, + 0x2660, 0x6e48, 0x080c, 0x4413, 0x00de, 0x00ce, 0x006e, 0x0005, + 0x0006, 0x0016, 0x6004, 0xa08e, 0x0002, 0x0140, 0xa08e, 0x0003, + 0x0128, 0xa08e, 0x0004, 0x0110, 0xa085, 0x0001, 0x001e, 0x000e, + 0x0005, 0x0006, 0x00d6, 0x6010, 0xa06d, 0x0128, 0x6838, 0xd0fc, + 0x0110, 0xa006, 0x0010, 0xa085, 0x0001, 0x00de, 0x000e, 0x0005, + 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x6cc2, 0x001e, + 0x0180, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x080c, 0x2563, + 0x2009, 0x0028, 0x080c, 0x6d3f, 0xa085, 0x0001, 0x012e, 0x00ce, + 0x0005, 0xa006, 0x0cd8, 0xa186, 0x0015, 0x1178, 0x2011, 0x8b20, + 0x2204, 0xa086, 0x0074, 0x1148, 0x080c, 0x72a4, 0x6003, 0x0001, + 0x6007, 0x0029, 0x080c, 0x58e2, 0x0020, 0x080c, 0x6fb6, 0x080c, + 0x6d18, 0x0005, 0xa186, 0x0015, 0x11b0, 0x2011, 0x8b20, 0x2204, + 0xa086, 0x0014, 0x1180, 0x00d6, 0x6018, 0x2068, 0x080c, 0x43a0, + 0x00de, 0x080c, 0x72ae, 0x1138, 0x2001, 0x0006, 0x080c, 0x42b9, + 0x080c, 0x6dc7, 0x0020, 0x080c, 0x6fb6, 0x080c, 0x6d18, 0x0005, + 0x6848, 0xa086, 0x0005, 0x1108, 0x0009, 0x0005, 0x6850, 0xc0ad, + 0x6852, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x2001, 0x8d9e, + 0x200c, 0x8000, 0x2014, 0x2001, 0x0064, 0x080c, 0x575a, 0x2001, + 0x8da2, 0x82ff, 0x1110, 0x2011, 0x0002, 0x2202, 0x003e, 0x002e, + 0x001e, 0x000e, 0x0005, 0x0006, 0x2001, 0x8da2, 0x2003, 0x0028, + 0x2001, 0x8da3, 0x2003, 0x07d0, 0x000e, 0x0005, 0x00d6, 0x6024, + 0xa06d, 0x0110, 0x080c, 0x149f, 0x00de, 0x0005, 0x0066, 0x6000, + 0xa0b2, 0x0010, 0x1a0c, 0x1410, 0x0013, 0x006e, 0x0005, 0x7e17, + 0x80cf, 0x81c5, 0x7e17, 0x7e17, 0x7e17, 0x7e17, 0x7e17, 0x7e4f, + 0x8231, 0x7e17, 0x7e17, 0x7e17, 0x7e17, 0x7e17, 0x7e17, 0x080c, + 0x1410, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x1410, 0x0013, + 0x006e, 0x0005, 0x7e32, 0x8594, 0x7e32, 0x7e32, 0x7e32, 0x7e32, + 0x7e32, 0x7e32, 0x8558, 0x85dc, 0x7e32, 0x89b0, 0x89e0, 0x89b0, + 0x89e0, 0x7e32, 0x080c, 0x1410, 0x0066, 0x6000, 0xa0b2, 0x0010, + 0x1a0c, 0x1410, 0x0013, 0x006e, 0x0005, 0x7e4d, 0x8364, 0x840f, + 0x8433, 0x847e, 0x7e4d, 0x7e4d, 0x84ef, 0x823d, 0x8532, 0x8545, + 0x7e4d, 0x7e4d, 0x7e4d, 0x7e4d, 0x7e4d, 0x080c, 0x1410, 0xa1b2, + 0x0040, 0x1a0c, 0x1410, 0x2100, 0x0002, 0x7e98, 0x7fa9, 0x7e98, + 0x7e98, 0x7e98, 0x7fb0, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, + 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, + 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e9a, 0x7ec4, 0x7ecf, 0x7f13, + 0x7f2d, 0x7f63, 0x7f96, 0x7e98, 0x7e98, 0x7fb3, 0x7e98, 0x7e98, + 0x7fc2, 0x7fc9, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x805e, + 0x7e98, 0x7e98, 0x8068, 0x7e98, 0x7e98, 0x8016, 0x7e98, 0x7e98, + 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, + 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, + 0x080c, 0x1410, 0x080c, 0x45e7, 0x6618, 0x00c6, 0x2660, 0x080c, + 0x4319, 0x00ce, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, + 0x0006, 0x0278, 0x080c, 0x86d3, 0x1904, 0x7f0d, 0x080c, 0x867e, + 0x1120, 0x6007, 0x0008, 0x0804, 0x7fa4, 0x6007, 0x0009, 0x0804, + 0x7fa4, 0x080c, 0x884f, 0x0128, 0x080c, 0x86d3, 0x0d78, 0x0804, + 0x7f0d, 0x6013, 0x1900, 0x0c88, 0x6106, 0x080c, 0x862e, 0x6007, + 0x0006, 0x0804, 0x7fa4, 0x6007, 0x0007, 0x0804, 0x7fa4, 0x080c, + 0x89fb, 0x1904, 0x8079, 0x00d6, 0x6618, 0x2668, 0x6e04, 0xa6b4, + 0xff00, 0x8637, 0xa686, 0x0006, 0x01a0, 0xa686, 0x0004, 0x0188, + 0x080c, 0x4c42, 0x1160, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006, + 0x0140, 0xa686, 0x0004, 0x0128, 0xa686, 0x0005, 0x0110, 0x00de, + 0x00e0, 0x080c, 0x8731, 0x11a0, 0xa686, 0x0006, 0x1150, 0x0026, + 0x6218, 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x25a8, + 0x002e, 0x080c, 0x43a0, 0x6007, 0x000a, 0x00de, 0x0804, 0x7fa4, + 0x6007, 0x000b, 0x00de, 0x0804, 0x7fa4, 0x080c, 0x2563, 0x6007, + 0x0001, 0x0804, 0x7fa4, 0x080c, 0x89fb, 0x1904, 0x8079, 0x6618, + 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa686, 0x0707, 0x0d70, 0x0026, + 0x6218, 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x25a8, + 0x002e, 0x6007, 0x000c, 0x0804, 0x7fa4, 0x080c, 0x45e7, 0x6618, + 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x02b0, + 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0004, 0x0118, 0xa686, 0x0006, + 0x1960, 0x080c, 0x873e, 0x1120, 0x6007, 0x000e, 0x0804, 0x7fa4, + 0x080c, 0x2563, 0x6007, 0x000f, 0x0804, 0x7fa4, 0x080c, 0x884f, + 0x0160, 0xa6b4, 0xff00, 0x8637, 0xa682, 0x0004, 0x0a04, 0x7f0d, + 0xa682, 0x0007, 0x0e30, 0x0804, 0x7f0d, 0x6013, 0x1900, 0x6007, + 0x0009, 0x0804, 0x7fa4, 0x080c, 0x45e7, 0x6618, 0xa6b0, 0x0001, + 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x02c0, 0xa6b4, 0xff00, + 0x8637, 0xa686, 0x0004, 0x0120, 0xa686, 0x0006, 0x1904, 0x7f0d, + 0x080c, 0x8766, 0x1130, 0x080c, 0x867e, 0x1118, 0x6007, 0x0010, + 0x0418, 0x080c, 0x2563, 0x6007, 0x0011, 0x00f0, 0x080c, 0x884f, + 0x0140, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0d48, 0x0804, + 0x7f0d, 0x6013, 0x1900, 0x6007, 0x0009, 0x0070, 0x7030, 0xa086, + 0x6000, 0x0140, 0x080c, 0x89fb, 0x1904, 0x8079, 0x080c, 0x807c, + 0x1904, 0x7f0d, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x58e2, + 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x58e2, 0x0cc0, + 0x6007, 0x0005, 0x0cc0, 0x080c, 0x89fb, 0x1904, 0x8079, 0x080c, + 0x807c, 0x1904, 0x7f0d, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, + 0x58e2, 0x0005, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x58e2, + 0x0005, 0x080c, 0x89fb, 0x1904, 0x8079, 0x080c, 0x807c, 0x1904, + 0x7f0d, 0x0016, 0x0026, 0x2011, 0x9091, 0x2214, 0xa286, 0xffff, + 0x0190, 0x2c08, 0x080c, 0x7b7f, 0x01d8, 0x2260, 0x2011, 0x9090, + 0x2214, 0x6008, 0xa206, 0x11a0, 0x6018, 0xa190, 0x0006, 0x2214, + 0xa206, 0x01e0, 0x0068, 0x2011, 0x9090, 0x2214, 0x2c08, 0x080c, + 0x8956, 0x11a0, 0x2011, 0x9091, 0x2214, 0xa286, 0xffff, 0x01a0, + 0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x2011, 0x9089, 0x2214, + 0xa296, 0xffff, 0x1160, 0x6007, 0x0025, 0x0048, 0x601c, 0xa086, + 0x0007, 0x1d70, 0x080c, 0x6d18, 0x2160, 0x6007, 0x0025, 0x6003, + 0x0001, 0x080c, 0x58e2, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, + 0x080c, 0x42a7, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, + 0x2019, 0x8b05, 0x2011, 0x9096, 0x080c, 0x7326, 0x003e, 0x002e, + 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804, 0x7fa4, 0x080c, + 0x715d, 0x080c, 0x4c42, 0x1548, 0x0006, 0x0026, 0x0036, 0x2011, + 0x8b23, 0x2204, 0x8000, 0x2012, 0xa084, 0x0007, 0x0190, 0x2001, + 0x8d9c, 0x2003, 0xaaaa, 0x2001, 0x8d9d, 0x2003, 0x0001, 0x2001, + 0x8b00, 0x2003, 0x0001, 0x080c, 0x4b8b, 0x003e, 0x002e, 0x000e, + 0x0005, 0x2001, 0x0001, 0x080c, 0x2298, 0x080c, 0x4c54, 0x1110, + 0x080c, 0x4c15, 0x003e, 0x002e, 0x000e, 0x0005, 0x6106, 0x0479, + 0x6007, 0x002b, 0x0804, 0x7fa4, 0x6007, 0x002c, 0x0804, 0x7fa4, + 0x080c, 0x89fb, 0x1170, 0x0081, 0x1904, 0x7f0d, 0x6106, 0x0419, + 0x1120, 0x6007, 0x002e, 0x0804, 0x7fa4, 0x6007, 0x002f, 0x0804, + 0x7fa4, 0x080c, 0x6d18, 0x0005, 0x00d6, 0x0066, 0x6618, 0x2668, + 0x6e04, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0128, 0xa686, + 0x0004, 0x0110, 0xa085, 0x0001, 0x006e, 0x00de, 0x0005, 0x00d6, + 0x0439, 0x00de, 0x0005, 0x00d6, 0x0481, 0x11e0, 0x680c, 0xa08c, + 0xff00, 0x6824, 0xa084, 0x00ff, 0xa115, 0x6212, 0xd1e4, 0x0118, + 0x2009, 0x0001, 0x0060, 0xd1ec, 0x0168, 0x6920, 0xa18c, 0x00ff, + 0x6824, 0x080c, 0x22e9, 0x1130, 0x2110, 0x2009, 0x0000, 0x080c, + 0x25a8, 0x0018, 0xa085, 0x0001, 0x0008, 0xa006, 0x00de, 0x0005, + 0x2069, 0x908d, 0x6800, 0xa082, 0x0010, 0x1228, 0x6013, 0x0000, + 0xa085, 0x0001, 0x0008, 0xa006, 0x0005, 0x6013, 0x0000, 0x2069, + 0x908c, 0x6808, 0xa084, 0xff00, 0xa086, 0x0800, 0x0005, 0x6004, + 0xa0b2, 0x0040, 0x1a0c, 0x1410, 0xa1b6, 0x0013, 0x1110, 0x2008, + 0x0092, 0xa1b6, 0x0027, 0x0120, 0xa1b6, 0x0014, 0x190c, 0x1410, + 0x2001, 0x0007, 0x080c, 0x42c7, 0x080c, 0x5c37, 0x080c, 0x7d3c, + 0x080c, 0x5d10, 0x0005, 0x812b, 0x812d, 0x812b, 0x812b, 0x812b, + 0x812d, 0x813b, 0x81a3, 0x816e, 0x81a3, 0x817f, 0x81a3, 0x813b, + 0x81a3, 0x819b, 0x81a3, 0x819b, 0x81a3, 0x81a3, 0x812b, 0x812b, + 0x812b, 0x812b, 0x812b, 0x812b, 0x812b, 0x812b, 0x812b, 0x812b, + 0x812b, 0x812b, 0x812b, 0x81a3, 0x812b, 0x812b, 0x81a3, 0x812b, + 0x81a3, 0x81a3, 0x812b, 0x812b, 0x812b, 0x812b, 0x81a3, 0x81a3, + 0x812b, 0x81a3, 0x81a3, 0x812b, 0x8135, 0x812b, 0x812b, 0x812b, + 0x812b, 0x812b, 0x812b, 0x812b, 0x812b, 0x812b, 0x812b, 0x812b, + 0x812b, 0x812b, 0x812b, 0x080c, 0x1410, 0x080c, 0x5c37, 0x6003, + 0x0002, 0x080c, 0x5d10, 0x0804, 0x81a9, 0x2001, 0x0000, 0x080c, + 0x42a7, 0x0804, 0x81a3, 0x00f6, 0x2079, 0x8b51, 0x7804, 0x00fe, + 0xd0ac, 0x1904, 0x81a3, 0x2001, 0x0000, 0x080c, 0x42a7, 0x6018, + 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x1138, 0x00f6, 0x2079, + 0x8b00, 0x7894, 0x8000, 0x7896, 0x00fe, 0x2001, 0x0002, 0x080c, + 0x42b9, 0x080c, 0x5c37, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, + 0x0002, 0x080c, 0x58e2, 0x080c, 0x5d10, 0x00c6, 0x6118, 0x2160, + 0x2009, 0x0001, 0x080c, 0x5619, 0x00ce, 0x04d8, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, - 0x0170, 0x2001, 0x0006, 0x0048, 0x2001, 0x0004, 0x0030, 0x2001, - 0x0006, 0x0061, 0x0020, 0x0018, 0x0010, 0x080c, 0x43f1, 0x080c, - 0x6389, 0x080c, 0x74f2, 0x080c, 0x6462, 0x0005, 0x0016, 0x00d6, - 0x6118, 0x2168, 0x6900, 0xd184, 0x0178, 0x6104, 0xa18e, 0x000a, - 0x1128, 0x699c, 0xd1a4, 0x1110, 0x2001, 0x0007, 0x2001, 0x0000, - 0x080c, 0x43d1, 0x080c, 0x2692, 0x00de, 0x001e, 0x0005, 0x00d6, - 0x6618, 0x2668, 0x6804, 0xa084, 0xff00, 0x8007, 0x00de, 0xa0b2, - 0x000c, 0x1a0c, 0x13fe, 0xa1b6, 0x0015, 0x1110, 0x003b, 0x0028, - 0xa1b6, 0x0016, 0x190c, 0x13fe, 0x04eb, 0x0005, 0x7805, 0x7805, - 0x7805, 0x7805, 0x7805, 0x7805, 0x7805, 0x892a, 0x7805, 0x7805, - 0x7805, 0x7805, 0x00f6, 0x2079, 0x9251, 0x7804, 0x00fe, 0xd0ac, - 0x1198, 0x2001, 0x0000, 0x080c, 0x43d1, 0x2001, 0x0002, 0x080c, - 0x43e3, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, - 0x603e, 0x080c, 0x6462, 0x00a8, 0x2011, 0x9783, 0x2204, 0x8211, - 0x220c, 0x080c, 0x240b, 0x1168, 0x00c6, 0x080c, 0x4434, 0x0120, - 0x00ce, 0x080c, 0x74f2, 0x0028, 0x080c, 0x41e0, 0x00ce, 0x080c, - 0x74f2, 0x0005, 0x7805, 0x7805, 0x7805, 0x7805, 0x7805, 0x7805, - 0x7805, 0x8966, 0x7805, 0x7805, 0x7805, 0x7805, 0x080c, 0x7a61, - 0x1138, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x603e, 0x0010, - 0x080c, 0x74f2, 0x0005, 0x6004, 0xa08a, 0x003e, 0x1a0c, 0x13fe, - 0x080c, 0x6389, 0x080c, 0x849b, 0x080c, 0x6462, 0x0005, 0xa182, - 0x0040, 0x0002, 0x8995, 0x8995, 0x8995, 0x8995, 0x8997, 0x8995, - 0x8995, 0x8995, 0x8995, 0x8995, 0x8995, 0x8995, 0x8995, 0x8995, - 0x8995, 0x8995, 0x8995, 0x8995, 0x8995, 0x080c, 0x13fe, 0x00d6, - 0x00e6, 0x00f6, 0x0156, 0x0046, 0x0026, 0x6106, 0x2071, 0x9780, - 0x7444, 0xa4a4, 0xf600, 0x0904, 0x8a0d, 0xa486, 0x2000, 0x01f0, - 0xa486, 0x0400, 0x01d8, 0xa486, 0x1000, 0x0178, 0xa486, 0x4000, - 0x01d8, 0xa486, 0x0200, 0x0120, 0x080c, 0x74f2, 0x0804, 0x8a67, - 0x6118, 0x2104, 0xc0fd, 0x200a, 0x0078, 0x2069, 0x9566, 0x6a00, - 0xd284, 0x0904, 0x8a79, 0xc2cd, 0x6a02, 0x0030, 0x2009, 0x0001, - 0x2011, 0x0200, 0x080c, 0x585b, 0x080c, 0x147c, 0x090c, 0x13fe, + 0x0550, 0xa686, 0x0004, 0x0538, 0x2001, 0x0004, 0x0410, 0x2001, + 0x8b00, 0x2004, 0xa086, 0x0003, 0x1110, 0x080c, 0x3689, 0x2001, + 0x0006, 0x0401, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa6b4, + 0xff00, 0x8637, 0xa686, 0x0006, 0x0170, 0x2001, 0x0006, 0x0048, + 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0061, 0x0020, 0x0018, + 0x0010, 0x080c, 0x42c7, 0x080c, 0x5c37, 0x080c, 0x6d18, 0x080c, + 0x5d10, 0x0005, 0x0016, 0x00d6, 0x6118, 0x2168, 0x6900, 0xd184, + 0x0188, 0x6104, 0xa18e, 0x000a, 0x1128, 0x699c, 0xd1a4, 0x1110, + 0x2001, 0x0007, 0x080c, 0x42b9, 0x2001, 0x0000, 0x080c, 0x42a7, + 0x080c, 0x2589, 0x00de, 0x001e, 0x0005, 0x00d6, 0x6618, 0x2668, + 0x6804, 0xa084, 0xff00, 0x8007, 0x00de, 0xa0b2, 0x000c, 0x1a0c, + 0x1410, 0xa1b6, 0x0015, 0x1110, 0x003b, 0x0028, 0xa1b6, 0x0016, + 0x190c, 0x1410, 0x04eb, 0x0005, 0x7045, 0x7045, 0x7045, 0x7045, + 0x7045, 0x7045, 0x7045, 0x81e8, 0x7045, 0x7045, 0x7045, 0x7045, + 0x00f6, 0x2079, 0x8b51, 0x7804, 0x00fe, 0xd0ac, 0x1198, 0x2001, + 0x0000, 0x080c, 0x42a7, 0x2001, 0x0002, 0x080c, 0x42b9, 0x601f, + 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x58e2, 0x080c, + 0x5d10, 0x00a8, 0x2011, 0x9083, 0x2204, 0x8211, 0x220c, 0x080c, + 0x22e9, 0x1168, 0x00c6, 0x080c, 0x430a, 0x0120, 0x00ce, 0x080c, + 0x6d18, 0x0028, 0x080c, 0x4118, 0x00ce, 0x080c, 0x6d18, 0x0005, + 0x7045, 0x7045, 0x7045, 0x7045, 0x7045, 0x7045, 0x7045, 0x8224, + 0x7045, 0x7045, 0x7045, 0x7045, 0x080c, 0x72a1, 0x1138, 0x6003, + 0x0001, 0x6007, 0x0001, 0x080c, 0x58e2, 0x0010, 0x080c, 0x6d18, + 0x0005, 0x6004, 0xa08a, 0x0040, 0x1a0c, 0x1410, 0x080c, 0x5c37, + 0x080c, 0x7d3c, 0x080c, 0x5d10, 0x0005, 0xa182, 0x0040, 0x0002, + 0x8253, 0x8253, 0x8253, 0x8253, 0x8255, 0x8253, 0x8253, 0x8253, + 0x8253, 0x8253, 0x8253, 0x8253, 0x8253, 0x8253, 0x8253, 0x8253, + 0x8253, 0x8253, 0x8253, 0x080c, 0x1410, 0x00d6, 0x00e6, 0x00f6, + 0x0156, 0x0046, 0x0026, 0x6106, 0x2071, 0x9080, 0x7444, 0xa4a4, + 0xff00, 0x0904, 0x82bd, 0xa486, 0x2000, 0x0180, 0xa486, 0x0400, + 0x0168, 0xa486, 0x1000, 0x0108, 0x0078, 0x2069, 0x8e2a, 0x6a00, + 0xd284, 0x0904, 0x8324, 0xc2cd, 0x6a02, 0x0030, 0x2009, 0x0001, + 0x2011, 0x0200, 0x080c, 0x5734, 0x080c, 0x1488, 0x090c, 0x1410, 0x6003, 0x0007, 0x2d00, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, 0x685e, 0x6008, 0x68b2, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x694a, 0x0016, 0xa084, 0xff00, 0x6846, - 0x684f, 0x0000, 0x6857, 0x0036, 0x080c, 0x4809, 0x001e, 0xa486, - 0x2000, 0x1130, 0x2019, 0x0017, 0x080c, 0x9071, 0x0804, 0x8a67, - 0xa486, 0x0400, 0x1130, 0x2019, 0x0002, 0x080c, 0x9033, 0x0804, - 0x8a67, 0xa486, 0x0200, 0x1110, 0x080c, 0x9020, 0xa486, 0x1000, - 0x1110, 0x080c, 0x905e, 0x0804, 0x8a67, 0x2069, 0x9566, 0x6a00, - 0xd284, 0x0904, 0x8ab6, 0xa284, 0x0300, 0x1904, 0x8ab0, 0x6804, - 0xa005, 0x0904, 0x8aa1, 0x2d78, 0x6003, 0x0007, 0x6018, 0x2004, - 0xd0fc, 0x1904, 0x8ab0, 0x080c, 0x145f, 0x0904, 0x8a6e, 0x7800, - 0xd08c, 0x1118, 0x7804, 0x8001, 0x7806, 0x6013, 0x0000, 0x6803, - 0x0000, 0x6837, 0x0116, 0x683b, 0x0000, 0x6008, 0x68b2, 0x2c00, - 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x6986, 0x6846, - 0x6853, 0x003d, 0x7244, 0xa294, 0x0003, 0xa286, 0x0002, 0x1118, - 0x684f, 0x0040, 0x0040, 0xa286, 0x0001, 0x1118, 0x684f, 0x0080, - 0x0010, 0x684f, 0x0000, 0x20a9, 0x000a, 0x2001, 0x9790, 0xad90, - 0x0015, 0x200c, 0x810f, 0x2112, 0x8000, 0x8210, 0x1f04, 0x8a59, - 0x200c, 0x6982, 0x8000, 0x200c, 0x697e, 0x080c, 0x4809, 0x002e, - 0x004e, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x0005, 0x6013, 0x0100, - 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x5ff8, 0x080c, 0x6462, - 0x0c70, 0x2069, 0x9792, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200, - 0x11a8, 0x2069, 0x9780, 0x686c, 0xa084, 0x00ff, 0x0016, 0x6110, - 0xa18c, 0x0700, 0xa10d, 0x6112, 0x001e, 0x6003, 0x0001, 0x6007, - 0x0043, 0x080c, 0x5ff8, 0x080c, 0x6462, 0x0888, 0x6013, 0x0200, - 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x5ff8, 0x080c, 0x6462, - 0x0830, 0x6013, 0x0300, 0x0010, 0x6013, 0x0100, 0x6003, 0x0001, - 0x6007, 0x0041, 0x080c, 0x5ff8, 0x080c, 0x6462, 0x0804, 0x8a67, - 0x6013, 0x0500, 0x0c98, 0x6013, 0x0600, 0x0818, 0x6013, 0x0200, - 0x0800, 0xa186, 0x0013, 0x1170, 0x6004, 0xa08a, 0x0040, 0x0a0c, - 0x13fe, 0xa08a, 0x0053, 0x1a0c, 0x13fe, 0xa082, 0x0040, 0x2008, - 0x0804, 0x8b24, 0xa186, 0x0047, 0x11b8, 0x2001, 0x0109, 0x2004, - 0xd084, 0x01f0, 0x0126, 0x2091, 0x2400, 0x0006, 0x0016, 0x0026, - 0x080c, 0x5ee3, 0x002e, 0x001e, 0x000e, 0x012e, 0x6000, 0xa086, - 0x0002, 0x1170, 0x0804, 0x8b64, 0xa186, 0x0027, 0x0120, 0xa186, - 0x0014, 0x190c, 0x13fe, 0x6004, 0xa082, 0x0040, 0x2008, 0x001a, - 0x080c, 0x7526, 0x0005, 0x8b06, 0x8b08, 0x8b08, 0x8b06, 0x8b06, - 0x8b06, 0x8b06, 0x8b06, 0x8b06, 0x8b06, 0x8b06, 0x8b06, 0x8b06, - 0x8b06, 0x8b06, 0x8b06, 0x8b06, 0x8b06, 0x8b06, 0x080c, 0x13fe, - 0x080c, 0x6389, 0x080c, 0x6462, 0x0036, 0x00d6, 0x6010, 0xa06d, - 0x0180, 0xad84, 0xf000, 0x0168, 0x2019, 0x0004, 0x080c, 0x9097, - 0x6013, 0x0000, 0x6014, 0xa005, 0x1110, 0x6017, 0x0014, 0x6003, - 0x0007, 0x00de, 0x003e, 0x0005, 0x0002, 0x8b38, 0x8b55, 0x8b41, - 0x8b5e, 0x8b38, 0x8b38, 0x8b38, 0x8b38, 0x8b38, 0x8b38, 0x8b38, - 0x8b38, 0x8b38, 0x8b38, 0x8b38, 0x8b38, 0x8b38, 0x8b38, 0x8b38, - 0x080c, 0x13fe, 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, - 0x200a, 0x080c, 0x6389, 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4, - 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, 0x080c, 0x7518, 0x0010, - 0x6003, 0x0002, 0x080c, 0x6462, 0x0005, 0x080c, 0x6389, 0x080c, - 0x5836, 0x080c, 0x74f2, 0x080c, 0x6462, 0x0005, 0x080c, 0x6389, - 0x2009, 0x0041, 0x0804, 0x8c44, 0xa182, 0x0040, 0x0002, 0x8b7a, - 0x8b7c, 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7d, 0x8b7a, - 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7a, - 0x8b7a, 0x8b7a, 0x080c, 0x13fe, 0x0005, 0x6003, 0x0004, 0x6110, - 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x16c6, 0x0005, - 0xa182, 0x0040, 0x0002, 0x8b9e, 0x8b9e, 0x8b9e, 0x8b9e, 0x8b9e, - 0x8b9e, 0x8b9e, 0x8b9e, 0x8b9e, 0x8ba0, 0x8bc0, 0x8b9e, 0x8b9e, - 0x8b9e, 0x8b9e, 0x8bc0, 0x8b9e, 0x8b9e, 0x8b9e, 0x080c, 0x13fe, - 0x080c, 0x641b, 0x080c, 0x651c, 0x6010, 0x00d6, 0x2068, 0x684c, - 0xd0fc, 0x0150, 0xa08c, 0x0003, 0xa18e, 0x0002, 0x0158, 0x2009, - 0x0041, 0x00de, 0x0804, 0x8c44, 0x6003, 0x0007, 0x080c, 0x5836, - 0x00de, 0x0005, 0x080c, 0x5836, 0x080c, 0x74f2, 0x00de, 0x0cc8, - 0x0036, 0x080c, 0x641b, 0x080c, 0x651c, 0x6010, 0x00d6, 0x2068, - 0x2019, 0x0004, 0x080c, 0x9097, 0x080c, 0x849b, 0x6017, 0x0028, - 0x00de, 0x003e, 0x0005, 0xa186, 0x0013, 0x1150, 0x6004, 0xa086, - 0x0042, 0x190c, 0x13fe, 0x080c, 0x6389, 0x080c, 0x6462, 0x0005, - 0xa186, 0x0027, 0x0118, 0xa186, 0x0014, 0x1180, 0x6004, 0xa086, - 0x0042, 0x190c, 0x13fe, 0x2001, 0x0007, 0x080c, 0x43f1, 0x080c, - 0x6389, 0x080c, 0x849b, 0x080c, 0x6462, 0x0005, 0xa182, 0x0040, - 0x0002, 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c, - 0x8c0e, 0x8c1a, 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c, - 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c, 0x080c, 0x13fe, 0x0036, 0x0046, - 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x16c6, 0x004e, - 0x003e, 0x0005, 0x6010, 0x00d6, 0x2068, 0x6810, 0x6a14, 0xa20d, - 0x1168, 0x684c, 0xd0fc, 0x0120, 0x2009, 0x0041, 0x00de, 0x00e0, - 0x6003, 0x0007, 0x080c, 0x5836, 0x00de, 0x0005, 0x6003, 0x0007, - 0x0021, 0x080c, 0x5838, 0x00de, 0x0005, 0xd2fc, 0x0140, 0x8002, - 0x8000, 0x8212, 0xa291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009, - 0x0015, 0x6a6a, 0x6866, 0x0005, 0xa182, 0x0040, 0x0002, 0x8c5a, - 0x8c5c, 0x8c68, 0x8c74, 0x8c5a, 0x8c5a, 0x8c5a, 0x8c83, 0x8c5a, - 0x8c5a, 0x8c5a, 0x8c5a, 0x8c5a, 0x8c5a, 0x8c5a, 0x8c5a, 0x8c5a, - 0x8c5a, 0x8c5a, 0x080c, 0x13fe, 0x6003, 0x0001, 0x6106, 0x080c, - 0x5ff8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6462, 0x012e, 0x0005, - 0x6003, 0x0001, 0x6106, 0x080c, 0x5ff8, 0x0126, 0x2091, 0x8000, - 0x080c, 0x6462, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10, - 0x080c, 0x1c88, 0x0126, 0x2091, 0x8000, 0x080c, 0x605b, 0x080c, - 0x651c, 0x012e, 0x0005, 0xa016, 0x080c, 0x16c6, 0x0005, 0x080c, - 0x6389, 0x6110, 0x81ff, 0x0148, 0x00d6, 0x2168, 0x0036, 0x2019, - 0x0029, 0x080c, 0x9097, 0x003e, 0x00de, 0x080c, 0x849b, 0x080c, - 0x6462, 0x0005, 0x080c, 0x641b, 0x6110, 0x81ff, 0x0148, 0x00d6, - 0x2168, 0x0036, 0x2019, 0x0029, 0x080c, 0x9097, 0x003e, 0x00de, - 0x080c, 0x849b, 0x080c, 0x651c, 0x0005, 0xa182, 0x0085, 0x0002, - 0x8cb9, 0x8cb7, 0x8cb7, 0x8cc5, 0x8cb7, 0x8cb7, 0x8cb7, 0x080c, - 0x13fe, 0x6003, 0x000b, 0x6106, 0x080c, 0x5ff8, 0x0126, 0x2091, - 0x8000, 0x080c, 0x6462, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c, - 0x9150, 0x0118, 0x080c, 0x74f2, 0x00c8, 0x2071, 0x9780, 0x7224, - 0x6212, 0x7220, 0x080c, 0x8f71, 0x0118, 0x6007, 0x0086, 0x0040, - 0x6007, 0x0087, 0x7224, 0xa296, 0xffff, 0x1110, 0x6007, 0x0086, - 0x6003, 0x0001, 0x080c, 0x5ff8, 0x080c, 0x6462, 0x00ee, 0x002e, - 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a, 0x0085, 0x0a0c, - 0x13fe, 0xa08a, 0x008c, 0x1a0c, 0x13fe, 0xa082, 0x0085, 0x00a2, - 0xa186, 0x0027, 0x0130, 0xa186, 0x0014, 0x0118, 0x080c, 0x7526, - 0x0050, 0x2001, 0x0007, 0x080c, 0x43f1, 0x080c, 0x6389, 0x080c, - 0x849b, 0x080c, 0x6462, 0x0005, 0x8d13, 0x8d15, 0x8d15, 0x8d13, - 0x8d13, 0x8d13, 0x8d13, 0x080c, 0x13fe, 0x080c, 0x6389, 0x080c, - 0x74f2, 0x080c, 0x6462, 0x0005, 0xa182, 0x0085, 0x0a0c, 0x13fe, - 0xa182, 0x008c, 0x1a0c, 0x13fe, 0xa182, 0x0085, 0x0002, 0x8d2e, - 0x8d2e, 0x8d2e, 0x8d30, 0x8d2e, 0x8d2e, 0x8d2e, 0x080c, 0x13fe, - 0x0005, 0xa186, 0x0013, 0x0148, 0xa186, 0x0014, 0x0130, 0xa186, - 0x0027, 0x0118, 0x080c, 0x7526, 0x0030, 0x080c, 0x6389, 0x080c, - 0x849b, 0x080c, 0x6462, 0x0005, 0x0036, 0x2019, 0x000b, 0x0031, - 0x601f, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, 0x0036, - 0x0086, 0x2091, 0x8000, 0x2c40, 0x080c, 0x724a, 0x1540, 0x080c, - 0x72e2, 0x1528, 0x6000, 0xa086, 0x0000, 0x0508, 0x601c, 0xa086, - 0x0007, 0x01e8, 0x00d6, 0x6000, 0xa086, 0x0004, 0x1140, 0x601f, - 0x0007, 0x2001, 0x94dd, 0x2004, 0x6016, 0x080c, 0x1788, 0x6010, - 0x2068, 0x080c, 0x82ee, 0x0110, 0x080c, 0x9097, 0x00de, 0x6013, - 0x0000, 0x601f, 0x0007, 0x2001, 0x94dd, 0x2004, 0x6016, 0x008e, - 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, 0x0036, 0x0156, 0x2079, - 0x9780, 0x7938, 0x783c, 0x080c, 0x240b, 0x1904, 0x8dce, 0x0016, - 0x00c6, 0x080c, 0x4434, 0x15c0, 0x2011, 0x9790, 0xac98, 0x000a, - 0x20a9, 0x0004, 0x080c, 0x7aee, 0x1578, 0x001e, 0x002e, 0x0026, - 0x0016, 0x2019, 0x0029, 0x080c, 0x73a2, 0x080c, 0x6127, 0x0086, - 0x2041, 0x0000, 0x080c, 0x606d, 0x008e, 0x001e, 0x0086, 0x2041, - 0x0000, 0x080c, 0x8ee4, 0x008e, 0x080c, 0x460d, 0x0026, 0x6204, - 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, 0x0118, 0xa286, 0x0004, - 0x1118, 0x62a0, 0x080c, 0x2704, 0x002e, 0x001e, 0x080c, 0x41e0, - 0x6612, 0x6516, 0xa006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e, - 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x2009, 0x9220, - 0x2104, 0xa086, 0x0074, 0x1904, 0x8e1e, 0x2069, 0x978e, 0x690c, - 0xa182, 0x0100, 0x0678, 0x6908, 0xa184, 0x8000, 0x05a0, 0x2001, - 0x94d7, 0x2004, 0xa005, 0x1118, 0xa184, 0x0800, 0x0560, 0x6910, - 0xa18a, 0x0001, 0x0610, 0x6914, 0x2069, 0x97ae, 0x6904, 0x81ff, - 0x1198, 0x690c, 0xa182, 0x0100, 0x02a8, 0x6908, 0x81ff, 0x1178, - 0x6910, 0xa18a, 0x0001, 0x0288, 0x6918, 0xa18a, 0x0001, 0x0298, - 0x00d0, 0x6013, 0x0100, 0x00a0, 0x6013, 0x0300, 0x0088, 0x6013, - 0x0500, 0x0070, 0x6013, 0x0700, 0x0058, 0x6013, 0x0900, 0x0040, - 0x6013, 0x0b00, 0x0028, 0x6013, 0x0f00, 0x0010, 0x6013, 0x2d00, - 0xa085, 0x0001, 0x0008, 0xa006, 0x001e, 0x00de, 0x00ce, 0x0005, - 0x00c6, 0x00d6, 0x0026, 0x0036, 0x0156, 0x6218, 0x2268, 0x6b04, - 0xa394, 0x00ff, 0xa286, 0x0006, 0x0190, 0xa286, 0x0004, 0x0178, - 0xa394, 0xff00, 0x8217, 0xa286, 0x0006, 0x0148, 0xa286, 0x0004, - 0x0130, 0x00c6, 0x2d60, 0x080c, 0x4443, 0x00ce, 0x04c0, 0x2011, - 0x9796, 0xad98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x7aee, 0x1580, - 0x2011, 0x979a, 0xad98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x7aee, - 0x1538, 0x0046, 0x0016, 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, - 0x2009, 0x9252, 0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, - 0x90d7, 0x6800, 0xc0e5, 0x6802, 0x2019, 0x0029, 0x080c, 0x6127, - 0x0086, 0x2041, 0x0000, 0x080c, 0x606d, 0x2c08, 0x080c, 0x8ee4, - 0x008e, 0x2001, 0x0007, 0x080c, 0x43f1, 0x001e, 0x004e, 0xa006, - 0x015e, 0x003e, 0x002e, 0x00de, 0x00ce, 0x0005, 0x00d6, 0x2069, - 0x978e, 0x6800, 0xa086, 0x0800, 0x0118, 0x6013, 0x0000, 0x0008, - 0xa006, 0x00de, 0x0005, 0x00c6, 0x00f6, 0x0016, 0x0026, 0x0036, - 0x0156, 0x2079, 0x978c, 0x7930, 0x7834, 0x080c, 0x240b, 0x11a0, - 0x080c, 0x4434, 0x1188, 0x2011, 0x9790, 0xac98, 0x000a, 0x20a9, - 0x0004, 0x080c, 0x7aee, 0x1140, 0x2011, 0x9794, 0xac98, 0x0006, - 0x20a9, 0x0004, 0x080c, 0x7aee, 0x015e, 0x003e, 0x002e, 0x001e, - 0x00fe, 0x00ce, 0x0005, 0x00c6, 0x0006, 0x0016, 0x0026, 0x0036, - 0x0156, 0x2011, 0x9783, 0x2204, 0x8211, 0x220c, 0x080c, 0x240b, - 0x11a0, 0x080c, 0x4434, 0x1188, 0x2011, 0x9796, 0xac98, 0x000a, - 0x20a9, 0x0004, 0x080c, 0x7aee, 0x1140, 0x2011, 0x979a, 0xac98, - 0x0006, 0x20a9, 0x0004, 0x080c, 0x7aee, 0x015e, 0x003e, 0x002e, - 0x001e, 0x000e, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0076, 0x0066, - 0x0056, 0x0046, 0x0026, 0x0126, 0x2091, 0x8000, 0x2029, 0x94ee, - 0x252c, 0x2021, 0x94f4, 0x2424, 0x2061, 0x9900, 0x2071, 0x9200, - 0x7644, 0x7064, 0x8001, 0xa602, 0x1a04, 0x8f44, 0x2100, 0xac06, - 0x05d0, 0x080c, 0x90ee, 0x05b8, 0x671c, 0xa786, 0x0001, 0x0904, - 0x8f56, 0xa786, 0x0007, 0x0578, 0x2500, 0xac06, 0x0560, 0x2400, - 0xac06, 0x0548, 0x080c, 0x90fe, 0x1530, 0x88ff, 0x0118, 0x6020, - 0xa906, 0x1508, 0x00d6, 0x6000, 0xa086, 0x0004, 0x1120, 0x0016, - 0x080c, 0x1788, 0x001e, 0x6010, 0x2068, 0x080c, 0x82ee, 0x0180, - 0xa786, 0x0003, 0x1510, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, - 0x0016, 0x080c, 0x8527, 0x080c, 0x4809, 0x001e, 0x080c, 0x848f, - 0x00de, 0x080c, 0x849b, 0xace0, 0x000c, 0x2001, 0x9216, 0x2004, - 0xac02, 0x1210, 0x0804, 0x8ef6, 0x012e, 0x002e, 0x004e, 0x005e, - 0x006e, 0x007e, 0x00ce, 0x00ee, 0x0005, 0xa786, 0x0006, 0x19d8, - 0xa386, 0x0005, 0x0d40, 0x080c, 0x9097, 0x0c10, 0x080c, 0x90fe, - 0x1d10, 0xa180, 0x0001, 0x2004, 0xa086, 0x0018, 0x19e0, 0x6000, - 0xa086, 0x0002, 0x19c0, 0x080c, 0x84b7, 0x0130, 0x080c, 0x84c8, - 0x1990, 0x080c, 0x7776, 0x0010, 0x080c, 0x2692, 0x080c, 0x849b, - 0x0850, 0x00c6, 0x00e6, 0x0016, 0x2c08, 0x2170, 0x080c, 0x90ab, - 0x001e, 0x0120, 0x601c, 0xa084, 0x000f, 0x001b, 0x00ee, 0x00ce, - 0x0005, 0x8f89, 0x8f89, 0x8f89, 0x8f89, 0x8f89, 0x8f89, 0x8f8b, - 0x8f89, 0xa006, 0x0005, 0x0046, 0x0016, 0x7018, 0xa080, 0x0028, - 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, 0x2009, 0x0020, 0x080c, - 0x90d7, 0x001e, 0x004e, 0x0036, 0x2019, 0x0002, 0x080c, 0x8d4e, - 0x003e, 0xa085, 0x0001, 0x0005, 0x2001, 0x0001, 0x080c, 0x43d1, - 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x9205, - 0x2011, 0x9796, 0x080c, 0x7aee, 0x003e, 0x002e, 0x001e, 0x015e, - 0xa005, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0076, 0x0066, 0x0026, - 0x0126, 0x2091, 0x8000, 0x2061, 0x9900, 0x2079, 0x0001, 0x8fff, - 0x0904, 0x9014, 0x2071, 0x9200, 0x7644, 0x7064, 0x8001, 0xa602, - 0x1a04, 0x9014, 0x88ff, 0x0128, 0x2800, 0xac06, 0x15a0, 0x2079, - 0x0000, 0x080c, 0x90ee, 0x0578, 0x2400, 0xac06, 0x0560, 0x671c, - 0xa786, 0x0006, 0x1540, 0xa786, 0x0007, 0x0528, 0x88ff, 0x1140, - 0x6018, 0xa206, 0x1500, 0x85ff, 0x0118, 0x6020, 0xa106, 0x11d8, - 0x00d6, 0x6000, 0xa086, 0x0004, 0x1140, 0x601f, 0x0007, 0x2001, - 0x94dd, 0x2004, 0x6016, 0x080c, 0x1788, 0x6010, 0x2068, 0x080c, - 0x82ee, 0x0120, 0x0046, 0x080c, 0x9097, 0x004e, 0x00de, 0x080c, - 0x849b, 0x88ff, 0x1190, 0xace0, 0x000c, 0x2001, 0x9216, 0x2004, - 0xac02, 0x1210, 0x0804, 0x8fc7, 0xa006, 0x012e, 0x002e, 0x006e, - 0x007e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0xa8c5, 0x0001, 0x0ca8, - 0x0086, 0x0056, 0x2041, 0x0000, 0x2029, 0x0001, 0x2c20, 0x2019, - 0x0002, 0x6218, 0x080c, 0x724a, 0x080c, 0x72e2, 0x080c, 0x8fba, - 0x005e, 0x008e, 0x0005, 0x0026, 0x0046, 0x0056, 0x0086, 0x00c6, - 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, - 0x0036, 0x080c, 0x4434, 0x1170, 0x2c10, 0x2041, 0x0000, 0x2508, - 0x0056, 0x2029, 0x0001, 0x080c, 0x724a, 0x080c, 0x72e2, 0x080c, - 0x8fba, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0x903f, 0x015e, - 0x00ce, 0x008e, 0x005e, 0x004e, 0x002e, 0x0005, 0x0086, 0x0056, - 0x6218, 0x2041, 0x0000, 0x2029, 0x0001, 0x2019, 0x0048, 0x080c, - 0x724a, 0x080c, 0x72e2, 0x2c20, 0x080c, 0x8fba, 0x005e, 0x008e, - 0x0005, 0x0026, 0x0046, 0x0056, 0x0086, 0x00c6, 0x0156, 0x2c20, - 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x0036, 0x080c, 0x4434, - 0x1150, 0x2c10, 0x2041, 0x0000, 0x2828, 0x080c, 0x724a, 0x080c, - 0x72e2, 0x080c, 0x8fba, 0x003e, 0x001e, 0x8108, 0x1f04, 0x907c, - 0x015e, 0x00ce, 0x008e, 0x005e, 0x004e, 0x002e, 0x0005, 0x0016, - 0x00f6, 0x8dff, 0x0168, 0x6800, 0xa07d, 0x0138, 0x6803, 0x0000, - 0x6b52, 0x080c, 0x4809, 0x2f68, 0x0cb0, 0x6b52, 0x080c, 0x4809, - 0x00fe, 0x001e, 0x0005, 0x00e6, 0x0046, 0x0036, 0x2061, 0x9900, - 0x2071, 0x9200, 0x7444, 0x7064, 0x8001, 0xa402, 0x12d8, 0x2100, - 0xac06, 0x0168, 0x6000, 0xa086, 0x0000, 0x0148, 0x6008, 0xa206, - 0x1130, 0x6018, 0xa1a0, 0x0006, 0x2424, 0xa406, 0x0140, 0xace0, - 0x000c, 0x2001, 0x9216, 0x2004, 0xac02, 0x1220, 0x0c08, 0xa085, - 0x0001, 0x0008, 0xa006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x00d6, - 0x0006, 0x080c, 0x147c, 0x000e, 0x090c, 0x13fe, 0x6837, 0x010d, - 0x685e, 0x6956, 0x6c46, 0x684f, 0x0000, 0xa006, 0x68b2, 0x6802, - 0x683a, 0x685a, 0x080c, 0x4809, 0x00de, 0x0005, 0x6700, 0xa786, - 0x0000, 0x0158, 0xa786, 0x0001, 0x0140, 0xa786, 0x000a, 0x0128, - 0xa786, 0x0009, 0x0110, 0xa085, 0x0001, 0x0005, 0x00e6, 0x6018, - 0x2070, 0x70a0, 0xa206, 0x00ee, 0x0005, 0xa186, 0x0013, 0x1128, - 0x6004, 0xa082, 0x0085, 0x2008, 0x00c2, 0xa186, 0x0027, 0x1178, - 0x080c, 0x6389, 0x0036, 0x00d6, 0x6010, 0x2068, 0x2019, 0x0004, - 0x080c, 0x9097, 0x00de, 0x003e, 0x080c, 0x6462, 0x0005, 0xa186, - 0x0014, 0x0d70, 0x080c, 0x7526, 0x0005, 0x912e, 0x912c, 0x912c, - 0x912c, 0x912c, 0x912c, 0x912e, 0x080c, 0x13fe, 0x080c, 0x6389, - 0x6003, 0x000c, 0x080c, 0x6462, 0x0005, 0xa182, 0x008c, 0x1220, - 0xa182, 0x0085, 0x0208, 0x001a, 0x080c, 0x7526, 0x0005, 0x9146, - 0x9146, 0x9146, 0x9146, 0x9148, 0x914d, 0x9146, 0x080c, 0x13fe, - 0x00d6, 0x080c, 0x74f2, 0x00de, 0x0005, 0x080c, 0x74f2, 0x0005, - 0x00e6, 0x6018, 0x2070, 0x7000, 0xd0ec, 0x00ee, 0x0005, 0x0126, - 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0x9240, 0xd5a4, 0x0118, - 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0118, 0x7030, 0x8000, 0x7032, - 0xd5ac, 0x0118, 0x2071, 0x924a, 0x0451, 0x00ee, 0x000e, 0x012e, - 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0x9240, - 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0118, 0x7030, - 0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071, 0x924a, 0x0081, 0x00ee, - 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, - 0x2071, 0x9242, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e04, - 0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x0005, - 0x00e6, 0x2071, 0x9240, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, - 0x9244, 0x0c69, 0x00ee, 0x0005, 0x0001, 0x0002, 0x0004, 0x0008, - 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, - 0x1000, 0x2000, 0x4000, 0x8000, 0x448c + 0x684f, 0x0000, 0x6857, 0x0036, 0x080c, 0x46a1, 0x001e, 0xa486, + 0x2000, 0x1130, 0x2019, 0x0017, 0x080c, 0x891c, 0x0804, 0x8312, + 0xa486, 0x0400, 0x1130, 0x2019, 0x0002, 0x080c, 0x88de, 0x0804, + 0x8312, 0xa486, 0x0200, 0x1110, 0x080c, 0x88cb, 0xa486, 0x1000, + 0x1110, 0x080c, 0x8909, 0x0804, 0x8312, 0x2069, 0x8e2a, 0x6a00, + 0xd284, 0x0904, 0x8361, 0xa284, 0x0300, 0x1904, 0x835b, 0x6804, + 0xa005, 0x0904, 0x834c, 0x2d78, 0x6003, 0x0007, 0x080c, 0x146f, + 0x0904, 0x8319, 0x7800, 0xd08c, 0x1118, 0x7804, 0x8001, 0x7806, + 0x6013, 0x0000, 0x6803, 0x0000, 0x6837, 0x0116, 0x683b, 0x0000, + 0x6008, 0x68b2, 0x2c00, 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007, + 0x7130, 0x6986, 0x6846, 0x6853, 0x003d, 0x7244, 0xa294, 0x0003, + 0xa286, 0x0002, 0x1118, 0x684f, 0x0040, 0x0040, 0xa286, 0x0001, + 0x1118, 0x684f, 0x0080, 0x0010, 0x684f, 0x0000, 0x20a9, 0x000a, + 0x2001, 0x9090, 0xad90, 0x0015, 0x200c, 0x810f, 0x2112, 0x8000, + 0x8210, 0x1f04, 0x8304, 0x200c, 0x6982, 0x8000, 0x200c, 0x697e, + 0x080c, 0x46a1, 0x002e, 0x004e, 0x015e, 0x00fe, 0x00ee, 0x00de, + 0x0005, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, + 0x589c, 0x080c, 0x5d10, 0x0c70, 0x2069, 0x9092, 0x2d04, 0xa084, + 0xff00, 0xa086, 0x1200, 0x11a8, 0x2069, 0x9080, 0x686c, 0xa084, + 0x00ff, 0x0016, 0x6110, 0xa18c, 0x0700, 0xa10d, 0x6112, 0x001e, + 0x6003, 0x0001, 0x6007, 0x0043, 0x080c, 0x589c, 0x080c, 0x5d10, + 0x0888, 0x6013, 0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, + 0x589c, 0x080c, 0x5d10, 0x0830, 0x6013, 0x0300, 0x0010, 0x6013, + 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x589c, 0x080c, + 0x5d10, 0x0804, 0x8312, 0x6013, 0x0500, 0x0c98, 0x6013, 0x0600, + 0x0818, 0x6013, 0x0200, 0x0800, 0xa186, 0x0013, 0x1170, 0x6004, + 0xa08a, 0x0040, 0x0a0c, 0x1410, 0xa08a, 0x0053, 0x1a0c, 0x1410, + 0xa082, 0x0040, 0x2008, 0x0804, 0x83cf, 0xa186, 0x0047, 0x11b8, + 0x2001, 0x0109, 0x2004, 0xd084, 0x01f0, 0x0126, 0x2091, 0x2400, + 0x0006, 0x0016, 0x0026, 0x080c, 0x578e, 0x002e, 0x001e, 0x000e, + 0x012e, 0x6000, 0xa086, 0x0002, 0x1170, 0x0804, 0x840f, 0xa186, + 0x0027, 0x0120, 0xa186, 0x0014, 0x190c, 0x1410, 0x6004, 0xa082, + 0x0040, 0x2008, 0x001a, 0x080c, 0x6d55, 0x0005, 0x83b1, 0x83b3, + 0x83b3, 0x83b1, 0x83b1, 0x83b1, 0x83b1, 0x83b1, 0x83b1, 0x83b1, + 0x83b1, 0x83b1, 0x83b1, 0x83b1, 0x83b1, 0x83b1, 0x83b1, 0x83b1, + 0x83b1, 0x080c, 0x1410, 0x080c, 0x5c37, 0x080c, 0x5d10, 0x0036, + 0x00d6, 0x6010, 0xa06d, 0x0180, 0xad84, 0xf000, 0x0168, 0x2019, + 0x0004, 0x080c, 0x8942, 0x6013, 0x0000, 0x6014, 0xa005, 0x1110, + 0x6017, 0x0014, 0x6003, 0x0007, 0x00de, 0x003e, 0x0005, 0x0002, + 0x83e3, 0x8400, 0x83ec, 0x8409, 0x83e3, 0x83e3, 0x83e3, 0x83e3, + 0x83e3, 0x83e3, 0x83e3, 0x83e3, 0x83e3, 0x83e3, 0x83e3, 0x83e3, + 0x83e3, 0x83e3, 0x83e3, 0x080c, 0x1410, 0x6010, 0xa088, 0x0013, + 0x2104, 0xa085, 0x0400, 0x200a, 0x080c, 0x5c37, 0x6010, 0xa080, + 0x0013, 0x2004, 0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, + 0x080c, 0x6d3f, 0x0010, 0x6003, 0x0002, 0x080c, 0x5d10, 0x0005, + 0x080c, 0x5c37, 0x080c, 0x570f, 0x080c, 0x6d18, 0x080c, 0x5d10, + 0x0005, 0x080c, 0x5c37, 0x2009, 0x0041, 0x0804, 0x84ef, 0xa182, + 0x0040, 0x0002, 0x8425, 0x8427, 0x8425, 0x8425, 0x8425, 0x8425, + 0x8425, 0x8428, 0x8425, 0x8425, 0x8425, 0x8425, 0x8425, 0x8425, + 0x8425, 0x8425, 0x8425, 0x8425, 0x8425, 0x080c, 0x1410, 0x0005, + 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, + 0x080c, 0x16d1, 0x0005, 0xa182, 0x0040, 0x0002, 0x8449, 0x8449, + 0x8449, 0x8449, 0x8449, 0x8449, 0x8449, 0x8449, 0x8449, 0x844b, + 0x846b, 0x8449, 0x8449, 0x8449, 0x8449, 0x846b, 0x8449, 0x8449, + 0x8449, 0x080c, 0x1410, 0x080c, 0x5cc9, 0x080c, 0x5dc2, 0x6010, + 0x00d6, 0x2068, 0x684c, 0xd0fc, 0x0150, 0xa08c, 0x0003, 0xa18e, + 0x0002, 0x0158, 0x2009, 0x0041, 0x00de, 0x0804, 0x84ef, 0x6003, + 0x0007, 0x080c, 0x570f, 0x00de, 0x0005, 0x080c, 0x570f, 0x080c, + 0x6d18, 0x00de, 0x0cc8, 0x0036, 0x080c, 0x5cc9, 0x080c, 0x5dc2, + 0x6010, 0x00d6, 0x2068, 0x2019, 0x0004, 0x080c, 0x8942, 0x080c, + 0x7d3c, 0x6017, 0x0028, 0x00de, 0x003e, 0x0005, 0xa186, 0x0013, + 0x1150, 0x6004, 0xa086, 0x0042, 0x190c, 0x1410, 0x080c, 0x5c37, + 0x080c, 0x5d10, 0x0005, 0xa186, 0x0027, 0x0118, 0xa186, 0x0014, + 0x1180, 0x6004, 0xa086, 0x0042, 0x190c, 0x1410, 0x2001, 0x0007, + 0x080c, 0x42c7, 0x080c, 0x5c37, 0x080c, 0x7d3c, 0x080c, 0x5d10, + 0x0005, 0xa182, 0x0040, 0x0002, 0x84b7, 0x84b7, 0x84b7, 0x84b7, + 0x84b7, 0x84b7, 0x84b7, 0x84b9, 0x84c5, 0x84b7, 0x84b7, 0x84b7, + 0x84b7, 0x84b7, 0x84b7, 0x84b7, 0x84b7, 0x84b7, 0x84b7, 0x080c, + 0x1410, 0x0036, 0x0046, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, + 0x080c, 0x16d1, 0x004e, 0x003e, 0x0005, 0x6010, 0x00d6, 0x2068, + 0x6810, 0x6a14, 0xa20d, 0x1168, 0x684c, 0xd0fc, 0x0120, 0x2009, + 0x0041, 0x00de, 0x00e0, 0x6003, 0x0007, 0x080c, 0x570f, 0x00de, + 0x0005, 0x6003, 0x0007, 0x0021, 0x080c, 0x5711, 0x00de, 0x0005, + 0xd2fc, 0x0140, 0x8002, 0x8000, 0x8212, 0xa291, 0x0000, 0x2009, + 0x0009, 0x0010, 0x2009, 0x0015, 0x6a6a, 0x6866, 0x0005, 0xa182, + 0x0040, 0x0002, 0x8505, 0x8507, 0x8513, 0x851f, 0x8505, 0x8505, + 0x8505, 0x852e, 0x8505, 0x8505, 0x8505, 0x8505, 0x8505, 0x8505, + 0x8505, 0x8505, 0x8505, 0x8505, 0x8505, 0x080c, 0x1410, 0x6003, + 0x0001, 0x6106, 0x080c, 0x589c, 0x0126, 0x2091, 0x8000, 0x080c, + 0x5d10, 0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x589c, + 0x0126, 0x2091, 0x8000, 0x080c, 0x5d10, 0x012e, 0x0005, 0x6003, + 0x0003, 0x6106, 0x2c10, 0x080c, 0x1bc8, 0x0126, 0x2091, 0x8000, + 0x080c, 0x58ff, 0x080c, 0x5dc2, 0x012e, 0x0005, 0xa016, 0x080c, + 0x16d1, 0x0005, 0x080c, 0x5c37, 0x6110, 0x81ff, 0x0148, 0x00d6, + 0x2168, 0x0036, 0x2019, 0x0029, 0x080c, 0x8942, 0x003e, 0x00de, + 0x080c, 0x7d3c, 0x080c, 0x5d10, 0x0005, 0x080c, 0x5cc9, 0x6110, + 0x81ff, 0x0148, 0x00d6, 0x2168, 0x0036, 0x2019, 0x0029, 0x080c, + 0x8942, 0x003e, 0x00de, 0x080c, 0x7d3c, 0x080c, 0x5dc2, 0x0005, + 0xa182, 0x0085, 0x0002, 0x8564, 0x8562, 0x8562, 0x8570, 0x8562, + 0x8562, 0x8562, 0x080c, 0x1410, 0x6003, 0x000b, 0x6106, 0x080c, + 0x589c, 0x0126, 0x2091, 0x8000, 0x080c, 0x5d10, 0x012e, 0x0005, + 0x0026, 0x00e6, 0x080c, 0x89fb, 0x0118, 0x080c, 0x6d18, 0x00c8, + 0x2071, 0x9080, 0x7224, 0x6212, 0x7220, 0x080c, 0x881c, 0x0118, + 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0xa296, 0xffff, + 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x080c, 0x589c, 0x080c, + 0x5d10, 0x00ee, 0x002e, 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, + 0xa08a, 0x0085, 0x0a0c, 0x1410, 0xa08a, 0x008c, 0x1a0c, 0x1410, + 0xa082, 0x0085, 0x00a2, 0xa186, 0x0027, 0x0130, 0xa186, 0x0014, + 0x0118, 0x080c, 0x6d55, 0x0050, 0x2001, 0x0007, 0x080c, 0x42c7, + 0x080c, 0x5c37, 0x080c, 0x7d3c, 0x080c, 0x5d10, 0x0005, 0x85be, + 0x85c0, 0x85c0, 0x85be, 0x85be, 0x85be, 0x85be, 0x080c, 0x1410, + 0x080c, 0x5c37, 0x080c, 0x6d18, 0x080c, 0x5d10, 0x0005, 0xa182, + 0x0085, 0x0a0c, 0x1410, 0xa182, 0x008c, 0x1a0c, 0x1410, 0xa182, + 0x0085, 0x0002, 0x85d9, 0x85d9, 0x85d9, 0x85db, 0x85d9, 0x85d9, + 0x85d9, 0x080c, 0x1410, 0x0005, 0xa186, 0x0013, 0x0148, 0xa186, + 0x0014, 0x0130, 0xa186, 0x0027, 0x0118, 0x080c, 0x6d55, 0x0030, + 0x080c, 0x5c37, 0x080c, 0x7d3c, 0x080c, 0x5d10, 0x0005, 0x0036, + 0x2019, 0x000b, 0x0031, 0x601f, 0x0006, 0x6003, 0x0007, 0x003e, + 0x0005, 0x0126, 0x0036, 0x0086, 0x2091, 0x8000, 0x2c40, 0x080c, + 0x6a17, 0x1540, 0x080c, 0x6aaf, 0x1528, 0x6000, 0xa086, 0x0000, + 0x0508, 0x601c, 0xa086, 0x0007, 0x01e8, 0x00d6, 0x6000, 0xa086, + 0x0004, 0x1140, 0x601f, 0x0007, 0x2001, 0x8da2, 0x2004, 0x6016, + 0x080c, 0x179e, 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0110, 0x080c, + 0x8942, 0x00de, 0x6013, 0x0000, 0x601f, 0x0007, 0x2001, 0x8da2, + 0x2004, 0x6016, 0x008e, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, + 0x0036, 0x0156, 0x2079, 0x9080, 0x7938, 0x783c, 0x080c, 0x22e9, + 0x1904, 0x8679, 0x0016, 0x00c6, 0x080c, 0x430a, 0x15c0, 0x2011, + 0x9090, 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x7326, 0x1578, + 0x001e, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, 0x6b6f, + 0x080c, 0x59d5, 0x0086, 0x2041, 0x0000, 0x080c, 0x5911, 0x008e, + 0x001e, 0x0086, 0x2041, 0x0000, 0x080c, 0x878f, 0x008e, 0x080c, + 0x44e6, 0x0026, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, + 0x0118, 0xa286, 0x0004, 0x1118, 0x62a0, 0x080c, 0x25fb, 0x002e, + 0x001e, 0x080c, 0x4118, 0x6612, 0x6516, 0xa006, 0x0010, 0x00ce, + 0x001e, 0x015e, 0x003e, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, + 0x0016, 0x2009, 0x8b20, 0x2104, 0xa086, 0x0074, 0x1904, 0x86c9, + 0x2069, 0x908e, 0x690c, 0xa182, 0x0100, 0x0678, 0x6908, 0xa184, + 0x8000, 0x05a0, 0x2001, 0x8d9c, 0x2004, 0xa005, 0x1118, 0xa184, + 0x0800, 0x0560, 0x6910, 0xa18a, 0x0001, 0x0610, 0x6914, 0x2069, + 0x90ae, 0x6904, 0x81ff, 0x1198, 0x690c, 0xa182, 0x0100, 0x02a8, + 0x6908, 0x81ff, 0x1178, 0x6910, 0xa18a, 0x0001, 0x0288, 0x6918, + 0xa18a, 0x0001, 0x0298, 0x00d0, 0x6013, 0x0100, 0x00a0, 0x6013, + 0x0300, 0x0088, 0x6013, 0x0500, 0x0070, 0x6013, 0x0700, 0x0058, + 0x6013, 0x0900, 0x0040, 0x6013, 0x0b00, 0x0028, 0x6013, 0x0f00, + 0x0010, 0x6013, 0x2d00, 0xa085, 0x0001, 0x0008, 0xa006, 0x001e, + 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x0026, 0x0036, 0x0156, + 0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff, 0xa286, 0x0006, 0x0190, + 0xa286, 0x0004, 0x0178, 0xa394, 0xff00, 0x8217, 0xa286, 0x0006, + 0x0148, 0xa286, 0x0004, 0x0130, 0x00c6, 0x2d60, 0x080c, 0x4319, + 0x00ce, 0x04c0, 0x2011, 0x9096, 0xad98, 0x000a, 0x20a9, 0x0004, + 0x080c, 0x7326, 0x1580, 0x2011, 0x909a, 0xad98, 0x0006, 0x20a9, + 0x0004, 0x080c, 0x7326, 0x1538, 0x0046, 0x0016, 0x6aa0, 0xa294, + 0x00ff, 0x8227, 0xa006, 0x2009, 0x8b52, 0x210c, 0xd1a4, 0x0138, + 0x2009, 0x0029, 0x080c, 0x8982, 0x6800, 0xc0e5, 0x6802, 0x2019, + 0x0029, 0x080c, 0x59d5, 0x0086, 0x2041, 0x0000, 0x080c, 0x5911, + 0x2c08, 0x080c, 0x878f, 0x008e, 0x2001, 0x0007, 0x080c, 0x42c7, + 0x001e, 0x004e, 0xa006, 0x015e, 0x003e, 0x002e, 0x00de, 0x00ce, + 0x0005, 0x00d6, 0x2069, 0x908e, 0x6800, 0xa086, 0x0800, 0x0118, + 0x6013, 0x0000, 0x0008, 0xa006, 0x00de, 0x0005, 0x00c6, 0x00f6, + 0x0016, 0x0026, 0x0036, 0x0156, 0x2079, 0x908c, 0x7930, 0x7834, + 0x080c, 0x22e9, 0x11a0, 0x080c, 0x430a, 0x1188, 0x2011, 0x9090, + 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x7326, 0x1140, 0x2011, + 0x9094, 0xac98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x7326, 0x015e, + 0x003e, 0x002e, 0x001e, 0x00fe, 0x00ce, 0x0005, 0x00c6, 0x0006, + 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, 0x9083, 0x2204, 0x8211, + 0x220c, 0x080c, 0x22e9, 0x11a0, 0x080c, 0x430a, 0x1188, 0x2011, + 0x9096, 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x7326, 0x1140, + 0x2011, 0x909a, 0xac98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x7326, + 0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00ce, 0x0005, 0x00e6, + 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0126, 0x2091, + 0x8000, 0x2029, 0x8db3, 0x252c, 0x2021, 0x8db9, 0x2424, 0x2061, + 0x9200, 0x2071, 0x8b00, 0x7644, 0x7064, 0x8001, 0xa602, 0x1a04, + 0x87ef, 0x2100, 0xac06, 0x05d0, 0x080c, 0x8999, 0x05b8, 0x671c, + 0xa786, 0x0001, 0x0904, 0x8801, 0xa786, 0x0007, 0x0578, 0x2500, + 0xac06, 0x0560, 0x2400, 0xac06, 0x0548, 0x080c, 0x89a9, 0x1530, + 0x88ff, 0x0118, 0x6020, 0xa906, 0x1508, 0x00d6, 0x6000, 0xa086, + 0x0004, 0x1120, 0x0016, 0x080c, 0x179e, 0x001e, 0x6010, 0x2068, + 0x080c, 0x7b8f, 0x0180, 0xa786, 0x0003, 0x1510, 0x6837, 0x0103, + 0x6b4a, 0x6847, 0x0000, 0x0016, 0x080c, 0x7dc8, 0x080c, 0x46a1, + 0x001e, 0x080c, 0x7d30, 0x00de, 0x080c, 0x7d3c, 0xace0, 0x000c, + 0x2001, 0x8b16, 0x2004, 0xac02, 0x1210, 0x0804, 0x87a1, 0x012e, + 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00ee, 0x0005, + 0xa786, 0x0006, 0x19d8, 0xa386, 0x0005, 0x0d40, 0x080c, 0x8942, + 0x0c10, 0x080c, 0x89a9, 0x1d10, 0xa180, 0x0001, 0x2004, 0xa086, + 0x0018, 0x19e0, 0x6000, 0xa086, 0x0002, 0x19c0, 0x080c, 0x7d58, + 0x0130, 0x080c, 0x7d69, 0x1990, 0x080c, 0x6fb6, 0x0010, 0x080c, + 0x2589, 0x080c, 0x7d3c, 0x0850, 0x00c6, 0x00e6, 0x0016, 0x2c08, + 0x2170, 0x080c, 0x8956, 0x001e, 0x0120, 0x601c, 0xa084, 0x000f, + 0x001b, 0x00ee, 0x00ce, 0x0005, 0x8834, 0x8834, 0x8834, 0x8834, + 0x8834, 0x8834, 0x8836, 0x8834, 0xa006, 0x0005, 0x0046, 0x0016, + 0x7018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, + 0x2009, 0x0020, 0x080c, 0x8982, 0x001e, 0x004e, 0x0036, 0x2019, + 0x0002, 0x080c, 0x85f9, 0x003e, 0xa085, 0x0001, 0x0005, 0x2001, + 0x0001, 0x080c, 0x42a7, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, + 0x0004, 0x2019, 0x8b05, 0x2011, 0x9096, 0x080c, 0x7326, 0x003e, + 0x002e, 0x001e, 0x015e, 0xa005, 0x0005, 0x00f6, 0x00e6, 0x00c6, + 0x0076, 0x0066, 0x0026, 0x0126, 0x2091, 0x8000, 0x2061, 0x9200, + 0x2079, 0x0001, 0x8fff, 0x0904, 0x88bf, 0x2071, 0x8b00, 0x7644, + 0x7064, 0x8001, 0xa602, 0x1a04, 0x88bf, 0x88ff, 0x0128, 0x2800, + 0xac06, 0x15a0, 0x2079, 0x0000, 0x080c, 0x8999, 0x0578, 0x2400, + 0xac06, 0x0560, 0x671c, 0xa786, 0x0006, 0x1540, 0xa786, 0x0007, + 0x0528, 0x88ff, 0x1140, 0x6018, 0xa206, 0x1500, 0x85ff, 0x0118, + 0x6020, 0xa106, 0x11d8, 0x00d6, 0x6000, 0xa086, 0x0004, 0x1140, + 0x601f, 0x0007, 0x2001, 0x8da2, 0x2004, 0x6016, 0x080c, 0x179e, + 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0120, 0x0046, 0x080c, 0x8942, + 0x004e, 0x00de, 0x080c, 0x7d3c, 0x88ff, 0x1190, 0xace0, 0x000c, + 0x2001, 0x8b16, 0x2004, 0xac02, 0x1210, 0x0804, 0x8872, 0xa006, + 0x012e, 0x002e, 0x006e, 0x007e, 0x00ce, 0x00ee, 0x00fe, 0x0005, + 0xa8c5, 0x0001, 0x0ca8, 0x0086, 0x0056, 0x2041, 0x0000, 0x2029, + 0x0001, 0x2c20, 0x2019, 0x0002, 0x6218, 0x080c, 0x6a17, 0x080c, + 0x6aaf, 0x080c, 0x8865, 0x005e, 0x008e, 0x0005, 0x0026, 0x0046, + 0x0056, 0x0086, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, + 0x2009, 0x0000, 0x0016, 0x0036, 0x080c, 0x430a, 0x1170, 0x2c10, + 0x2041, 0x0000, 0x2508, 0x0056, 0x2029, 0x0001, 0x080c, 0x6a17, + 0x080c, 0x6aaf, 0x080c, 0x8865, 0x005e, 0x003e, 0x001e, 0x8108, + 0x1f04, 0x88ea, 0x015e, 0x00ce, 0x008e, 0x005e, 0x004e, 0x002e, + 0x0005, 0x0086, 0x0056, 0x6218, 0x2041, 0x0000, 0x2029, 0x0001, + 0x2019, 0x0048, 0x080c, 0x6a17, 0x080c, 0x6aaf, 0x2c20, 0x080c, + 0x8865, 0x005e, 0x008e, 0x0005, 0x0026, 0x0046, 0x0056, 0x0086, + 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, + 0x0036, 0x080c, 0x430a, 0x1150, 0x2c10, 0x2041, 0x0000, 0x2828, + 0x080c, 0x6a17, 0x080c, 0x6aaf, 0x080c, 0x8865, 0x003e, 0x001e, + 0x8108, 0x1f04, 0x8927, 0x015e, 0x00ce, 0x008e, 0x005e, 0x004e, + 0x002e, 0x0005, 0x0016, 0x00f6, 0x8dff, 0x0168, 0x6800, 0xa07d, + 0x0138, 0x6803, 0x0000, 0x6b52, 0x080c, 0x46a1, 0x2f68, 0x0cb0, + 0x6b52, 0x080c, 0x46a1, 0x00fe, 0x001e, 0x0005, 0x00e6, 0x0046, + 0x0036, 0x2061, 0x9200, 0x2071, 0x8b00, 0x7444, 0x7064, 0x8001, + 0xa402, 0x12d8, 0x2100, 0xac06, 0x0168, 0x6000, 0xa086, 0x0000, + 0x0148, 0x6008, 0xa206, 0x1130, 0x6018, 0xa1a0, 0x0006, 0x2424, + 0xa406, 0x0140, 0xace0, 0x000c, 0x2001, 0x8b16, 0x2004, 0xac02, + 0x1220, 0x0c08, 0xa085, 0x0001, 0x0008, 0xa006, 0x003e, 0x004e, + 0x00ee, 0x0005, 0x00d6, 0x0006, 0x080c, 0x1488, 0x000e, 0x090c, + 0x1410, 0x6837, 0x010d, 0x685e, 0x6956, 0x6c46, 0x684f, 0x0000, + 0xa006, 0x68b2, 0x6802, 0x683a, 0x685a, 0x080c, 0x46a1, 0x00de, + 0x0005, 0x6700, 0xa786, 0x0000, 0x0158, 0xa786, 0x0001, 0x0140, + 0xa786, 0x000a, 0x0128, 0xa786, 0x0009, 0x0110, 0xa085, 0x0001, + 0x0005, 0x00e6, 0x6018, 0x2070, 0x70a0, 0xa206, 0x00ee, 0x0005, + 0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x00c2, + 0xa186, 0x0027, 0x1178, 0x080c, 0x5c37, 0x0036, 0x00d6, 0x6010, + 0x2068, 0x2019, 0x0004, 0x080c, 0x8942, 0x00de, 0x003e, 0x080c, + 0x5d10, 0x0005, 0xa186, 0x0014, 0x0d70, 0x080c, 0x6d55, 0x0005, + 0x89d9, 0x89d7, 0x89d7, 0x89d7, 0x89d7, 0x89d7, 0x89d9, 0x080c, + 0x1410, 0x080c, 0x5c37, 0x6003, 0x000c, 0x080c, 0x5d10, 0x0005, + 0xa182, 0x008c, 0x1220, 0xa182, 0x0085, 0x0208, 0x001a, 0x080c, + 0x6d55, 0x0005, 0x89f1, 0x89f1, 0x89f1, 0x89f1, 0x89f3, 0x89f8, + 0x89f1, 0x080c, 0x1410, 0x00d6, 0x080c, 0x6d18, 0x00de, 0x0005, + 0x080c, 0x6d18, 0x0005, 0x00e6, 0x6018, 0x2070, 0x7000, 0xd0ec, + 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, + 0x8b40, 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0118, + 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071, 0x8b4a, 0x0451, + 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, + 0x8000, 0x2071, 0x8b40, 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, + 0xd5b4, 0x0118, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071, + 0x8b4a, 0x0081, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, + 0x00e6, 0x2091, 0x8000, 0x2071, 0x8b42, 0x0021, 0x00ee, 0x000e, + 0x012e, 0x0005, 0x2e04, 0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04, + 0x8000, 0x2072, 0x0005, 0x00e6, 0x2071, 0x8b40, 0x0c99, 0x00ee, + 0x0005, 0x00e6, 0x2071, 0x8b44, 0x0c69, 0x00ee, 0x0005, 0x0001, + 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, + 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x2854 }; diff -ur --new-file old/linux/drivers/scsi/qlogicpti.c new/linux/drivers/scsi/qlogicpti.c --- old/linux/drivers/scsi/qlogicpti.c Tue Dec 21 07:06:42 1999 +++ new/linux/drivers/scsi/qlogicpti.c Thu Jan 27 17:58:15 2000 @@ -781,7 +781,7 @@ struct sbus_dev *sdev = qpti->sdev; #define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN) - qpti->res_cpu = sbus_alloc_consistant(sdev, + qpti->res_cpu = sbus_alloc_consistent(sdev, QSIZE(RES_QUEUE_LEN), &qpti->res_dvma); if (qpti->res_cpu == NULL || @@ -790,12 +790,12 @@ return -1; } - qpti->req_cpu = sbus_alloc_consistant(sdev, + qpti->req_cpu = sbus_alloc_consistent(sdev, QSIZE(QLOGICPTI_REQ_QUEUE_LEN), &qpti->req_dvma); if (qpti->req_cpu == NULL || qpti->req_dvma == 0) { - sbus_free_consistant(sdev, QSIZE(RES_QUEUE_LEN), + sbus_free_consistent(sdev, QSIZE(RES_QUEUE_LEN), qpti->res_cpu, qpti->res_dvma); printk("QPTI: Cannot map request queue.\n"); return -1; @@ -917,10 +917,10 @@ fail_unmap_queues: #define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN) - sbus_free_consistant(qpti->sdev, + sbus_free_consistent(qpti->sdev, QSIZE(RES_QUEUE_LEN), qpti->res_cpu, qpti->res_dvma); - sbus_free_consistant(qpti->sdev, + sbus_free_consistent(qpti->sdev, QSIZE(QLOGICPTI_REQ_QUEUE_LEN), qpti->req_cpu, qpti->req_dvma); #undef QSIZE @@ -958,10 +958,10 @@ free_irq(qpti->irq, qpti); #define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN) - sbus_free_consistant(qpti->sdev, + sbus_free_consistent(qpti->sdev, QSIZE(RES_QUEUE_LEN), qpti->res_cpu, qpti->res_dvma); - sbus_free_consistant(qpti->sdev, + sbus_free_consistent(qpti->sdev, QSIZE(QLOGICPTI_REQ_QUEUE_LEN), qpti->req_cpu, qpti->req_dvma); #undef QSIZE @@ -1046,8 +1046,8 @@ if (n > 4) n = 4; for (i = 0; i < n; i++, sg++) { - ds[i].d_base = sg->dvma_address; - ds[i].d_count = sg->dvma_length; + ds[i].d_base = sg_dma_address(sg); + ds[i].d_count = sg_dma_len(sg); } sg_count -= 4; while (sg_count > 0) { @@ -1069,8 +1069,8 @@ if (n > 7) n = 7; for (i = 0; i < n; i++, sg++) { - ds[i].d_base = sg->dvma_address; - ds[i].d_count = sg->dvma_length; + ds[i].d_base = sg_dma_address(sg); + ds[i].d_count = sg_dma_len(sg); } sg_count -= n; } diff -ur --new-file old/linux/drivers/scsi/scsi.c new/linux/drivers/scsi/scsi.c --- old/linux/drivers/scsi/scsi.c Fri Jan 21 00:15:22 2000 +++ new/linux/drivers/scsi/scsi.c Tue Jan 25 19:41:46 2000 @@ -86,44 +86,11 @@ * Definitions and constants. */ -/* - * PAGE_SIZE must be a multiple of the sector size (512). True - * for all reasonably recent architectures (even the VAX...). - */ -#define SECTOR_SIZE 512 -#define SECTORS_PER_PAGE (PAGE_SIZE/SECTOR_SIZE) - -#if SECTORS_PER_PAGE <= 8 -typedef unsigned char FreeSectorBitmap; -#elif SECTORS_PER_PAGE <= 32 -typedef unsigned int FreeSectorBitmap; -#else -#error You lose. -#endif - #define MIN_RESET_DELAY (2*HZ) /* Do not call reset on error if we just did a reset within 15 sec. */ #define MIN_RESET_PERIOD (15*HZ) -/* The following devices are known not to tolerate a lun != 0 scan for - * one reason or another. Some will respond to all luns, others will - * lock up. - */ - -#define BLIST_NOLUN 0x001 -#define BLIST_FORCELUN 0x002 -#define BLIST_BORKEN 0x004 -#define BLIST_KEY 0x008 -#define BLIST_SINGLELUN 0x010 -#define BLIST_NOTQ 0x020 -#define BLIST_SPARSELUN 0x040 -#define BLIST_MAX5LUN 0x080 -#define BLIST_ISDISK 0x100 -#define BLIST_ISROM 0x200 -#define BLIST_GHOST 0x400 - - /* * Data declarations. @@ -139,12 +106,6 @@ static unsigned long serial_number = 0; static Scsi_Cmnd *scsi_bh_queue_head = NULL; static Scsi_Cmnd *scsi_bh_queue_tail = NULL; -static FreeSectorBitmap *dma_malloc_freelist = NULL; -static int need_isa_bounce_buffers; -static unsigned int dma_sectors = 0; -unsigned int scsi_dma_free_sectors = 0; -unsigned int scsi_need_isa_buffer = 0; -static unsigned char **dma_malloc_pages = NULL; /* * Note - the initial logging level can be set here to log events at boot time. @@ -173,12 +134,7 @@ /* * Function prototypes. */ -static void resize_dma_pool(void); -static void print_inquiry(unsigned char *data); extern void scsi_times_out(Scsi_Cmnd * SCpnt); -static int scan_scsis_single(int channel, int dev, int lun, int *max_scsi_dev, - int *sparse_lun, Scsi_Device ** SDpnt, Scsi_Cmnd * SCpnt, - struct Scsi_Host *shpnt, char *scsi_result); void scsi_build_commandblocks(Scsi_Device * SDpnt); static int scsi_unregister_device(struct Scsi_Device_Template *tpnt); @@ -189,140 +145,40 @@ extern void scsi_old_done(Scsi_Cmnd * SCpnt); extern void scsi_old_times_out(Scsi_Cmnd * SCpnt); -struct dev_info { - const char *vendor; - const char *model; - const char *revision; /* Latest revision known to be bad. Not used yet */ - unsigned flags; -}; /* - * This is what was previously known as the blacklist. The concept - * has been expanded so that we can specify other types of things we - * need to be aware of. - */ -static struct dev_info device_list[] = -{ - {"Aashima", "IMAGERY 2400SP", "1.03", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ - {"CHINON", "CD-ROM CDS-431", "H42", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ - {"CHINON", "CD-ROM CDS-535", "Q14", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ - {"DENON", "DRD-25X", "V", BLIST_NOLUN}, /* Locks up if probed for lun != 0 */ - {"HITACHI", "DK312C", "CM81", BLIST_NOLUN}, /* Responds to all lun - dtg */ - {"HITACHI", "DK314C", "CR21", BLIST_NOLUN}, /* responds to all lun */ - {"IMS", "CDD521/10", "2.06", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */ - {"MAXTOR", "XT-3280", "PR02", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */ - {"MAXTOR", "XT-4380S", "B3C", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */ - {"MAXTOR", "MXT-1240S", "I1.2", BLIST_NOLUN}, /* Locks up when LUN>0 polled */ - {"MAXTOR", "XT-4170S", "B5A", BLIST_NOLUN}, /* Locks-up sometimes when LUN>0 polled. */ - {"MAXTOR", "XT-8760S", "B7B", BLIST_NOLUN}, /* guess what? */ - {"MEDIAVIS", "RENO CD-ROMX2A", "2.03", BLIST_NOLUN}, /*Responds to all lun */ - {"MICROP", "4110", "*", BLIST_NOTQ}, /* Buggy Tagged Queuing */ - {"NEC", "CD-ROM DRIVE:841", "1.0", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */ - {"PHILIPS", "PCA80SC", "V4-2", BLIST_NOLUN}, /* Responds to all lun */ - {"RODIME", "RO3000S", "2.33", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ - {"SANYO", "CRD-250S", "1.20", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1 - * for aha152x controller, which causes - * SCSI code to reset bus.*/ - {"SEAGATE", "ST157N", "\004|j", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1 - * for aha152x controller, which causes - * SCSI code to reset bus.*/ - {"SEAGATE", "ST296", "921", BLIST_NOLUN}, /* Responds to all lun */ - {"SEAGATE", "ST1581", "6538", BLIST_NOLUN}, /* Responds to all lun */ - {"SONY", "CD-ROM CDU-541", "4.3d", BLIST_NOLUN}, - {"SONY", "CD-ROM CDU-55S", "1.0i", BLIST_NOLUN}, - {"SONY", "CD-ROM CDU-561", "1.7x", BLIST_NOLUN}, - {"SONY", "CD-ROM CDU-8012", "*", BLIST_NOLUN}, - {"TANDBERG", "TDC 3600", "U07", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ - {"TEAC", "CD-R55S", "1.0H", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ - {"TEAC", "CD-ROM", "1.06", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1 - * for seagate controller, which causes - * SCSI code to reset bus.*/ - {"TEAC", "MT-2ST/45S2-27", "RV M", BLIST_NOLUN}, /* Responds to all lun */ - {"TEXEL", "CD-ROM", "1.06", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1 - * for seagate controller, which causes - * SCSI code to reset bus.*/ - {"QUANTUM", "LPS525S", "3110", BLIST_NOLUN}, /* Locks sometimes if polled for lun != 0 */ - {"QUANTUM", "PD1225S", "3110", BLIST_NOLUN}, /* Locks sometimes if polled for lun != 0 */ - {"QUANTUM", "FIREBALL ST4.3S", "0F0C", BLIST_NOLUN}, /* Locks up when polled for lun != 0 */ - {"MEDIAVIS", "CDR-H93MV", "1.31", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ - {"SANKYO", "CP525", "6.64", BLIST_NOLUN}, /* causes failed REQ SENSE, extra reset */ - {"HP", "C1750A", "3226", BLIST_NOLUN}, /* scanjet iic */ - {"HP", "C1790A", "", BLIST_NOLUN}, /* scanjet iip */ - {"HP", "C2500A", "", BLIST_NOLUN}, /* scanjet iicx */ - {"YAMAHA", "CDR100", "1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ - {"YAMAHA", "CDR102", "1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 - * extra reset */ - {"RELISYS", "Scorpio", "*", BLIST_NOLUN}, /* responds to all LUN */ - {"MICROTEK", "ScanMaker II", "5.61", BLIST_NOLUN}, /* responds to all LUN */ - -/* - * Other types of devices that have special flags. - */ - {"SONY", "CD-ROM CDU-8001", "*", BLIST_BORKEN}, - {"TEXEL", "CD-ROM", "1.06", BLIST_BORKEN}, - {"IOMEGA", "Io20S *F", "*", BLIST_KEY}, - {"INSITE", "Floptical F*8I", "*", BLIST_KEY}, - {"INSITE", "I325VM", "*", BLIST_KEY}, - {"NRC", "MBR-7", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, - {"NRC", "MBR-7.4", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, - {"REGAL", "CDC-4X", "*", BLIST_MAX5LUN | BLIST_SINGLELUN}, - {"NAKAMICH", "MJ-4.8S", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, - {"NAKAMICH", "MJ-5.16S", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, - {"PIONEER", "CD-ROM DRM-600", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, - {"PIONEER", "CD-ROM DRM-602X", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, - {"PIONEER", "CD-ROM DRM-604X", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, - {"EMULEX", "MD21/S2 ESDI", "*", BLIST_SINGLELUN}, - {"CANON", "IPUBJD", "*", BLIST_SPARSELUN}, - {"nCipher", "Fastness Crypto", "*", BLIST_FORCELUN}, - {"NEC", "PD-1 ODX654P", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, - {"MATSHITA", "PD-1", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, - {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN}, - {"CREATIVE","DVD-RAM RAM","*", BLIST_GHOST}, - {"MATSHITA","PD-2 LF-D100","*", BLIST_GHOST}, - {"HITACHI", "GF-1050","*", BLIST_GHOST}, /* Hitachi SCSI DVD-RAM */ - {"TOSHIBA","CDROM","*", BLIST_ISROM}, - {"TOSHIBA","DVD-RAM SD-W1101","*", BLIST_GHOST}, - {"TOSHIBA","DVD-RAM SD-W1111","*", BLIST_GHOST}, - - /* - * Must be at end of list... - */ - {NULL, NULL, NULL} -}; - -static int get_device_flags(unsigned char *response_data) -{ - int i = 0; - unsigned char *pnt; - for (i = 0; 1; i++) { - if (device_list[i].vendor == NULL) - return 0; - pnt = &response_data[8]; - while (*pnt && *pnt == ' ') - pnt++; - if (memcmp(device_list[i].vendor, pnt, - strlen(device_list[i].vendor))) - continue; - pnt = &response_data[16]; - while (*pnt && *pnt == ' ') - pnt++; - if (memcmp(device_list[i].model, pnt, - strlen(device_list[i].model))) - continue; - return device_list[i].flags; - } - return 0; -} - - -static void scan_scsis_done(Scsi_Cmnd * SCpnt) -{ - - SCSI_LOG_MLCOMPLETE(1, printk("scan_scsis_done(%p, %06x)\n", SCpnt->host, SCpnt->result)); - SCpnt->request.rq_status = RQ_SCSI_DONE; - - if (SCpnt->request.sem != NULL) - up(SCpnt->request.sem); + * Function: scsi_get_request_handler() + * + * Purpose: Selects queue handler function for a device. + * + * Arguments: SDpnt - device for which we need a handler function. + * + * Returns: Nothing + * + * Lock status: No locking assumed or required. + * + * Notes: Most devices will end up using scsi_request_fn for the + * handler function (at least as things are done now). + * The "block" feature basically ensures that only one of + * the blocked hosts is active at one time, mainly to work around + * buggy DMA chipsets where the memory gets starved. + * For this case, we have a special handler function, which + * does some checks and ultimately calls scsi_request_fn. + * + * As a future enhancement, it might be worthwhile to add support + * for stacked handlers - there might get to be too many permutations + * otherwise. Then again, we might just have one handler that does + * all of the special cases (a little bit slower), and those devices + * that don't need the special case code would directly call + * scsi_request_fn. + * + * As it stands, I can think of a number of special cases that + * we might need to handle. This would not only include the blocked + * case, but single_lun (for changers), and any special handling + * we might need for a spun-down disk to spin it back up again. + */ +request_fn_proc * scsi_get_request_handler(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt) { + return scsi_request_fn; } #ifdef MODULE @@ -349,43 +205,24 @@ #endif -#ifdef CONFIG_SCSI_MULTI_LUN -static int max_scsi_luns = 8; -#else -static int max_scsi_luns = 1; -#endif - -#ifdef MODULE - -MODULE_PARM(max_scsi_luns, "i"); -MODULE_PARM_DESC(max_scsi_luns, "last scsi LUN (should be between 1 and 8)"); - -#else - -static int __init scsi_luns_setup(char *str) +/* + * Issue a command and wait for it to complete + */ + +static void scsi_wait_done(Scsi_Cmnd * SCpnt) { - int tmp; + struct request *req; - if (get_option(&str, &tmp) == 1) { - max_scsi_luns = tmp; - return 1; - } else { - printk("scsi_luns_setup : usage max_scsi_luns=n " - "(n should be between 1 and 8)\n"); - return 0; + req = &SCpnt->request; + req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ + + if (req->sem != NULL) { + up(req->sem); } } -__setup("max_scsi_luns=", scsi_luns_setup); - -#endif - -/* - * Issue a command and wait for it to complete - */ - void scsi_wait_cmd (Scsi_Cmnd * SCpnt, const void *cmnd , - void *buffer, unsigned bufflen, void (*done)(Scsi_Cmnd *), + void *buffer, unsigned bufflen, int timeout, int retries) { DECLARE_MUTEX_LOCKED(sem); @@ -393,595 +230,13 @@ SCpnt->request.sem = &sem; SCpnt->request.rq_status = RQ_SCSI_BUSY; scsi_do_cmd (SCpnt, (void *) cmnd, - buffer, bufflen, done, timeout, retries); + buffer, bufflen, scsi_wait_done, timeout, retries); down (&sem); SCpnt->request.sem = NULL; } /* - * Detecting SCSI devices : - * We scan all present host adapter's busses, from ID 0 to ID (max_id). - * We use the INQUIRY command, determine device type, and pass the ID / - * lun address of all sequential devices to the tape driver, all random - * devices to the disk driver. - */ -static void scan_scsis(struct Scsi_Host *shpnt, - unchar hardcoded, - unchar hchannel, - unchar hid, - unchar hlun) -{ - int channel; - int dev; - int lun; - int max_dev_lun; - Scsi_Cmnd *SCpnt; - unsigned char *scsi_result; - unsigned char scsi_result0[256]; - Scsi_Device *SDpnt; - Scsi_Device *SDtail; - int sparse_lun; - - scsi_result = NULL; - SCpnt = (Scsi_Cmnd *) scsi_init_malloc(sizeof(Scsi_Cmnd), - GFP_ATOMIC | GFP_DMA); - if (SCpnt) { - SDpnt = (Scsi_Device *) scsi_init_malloc(sizeof(Scsi_Device), - GFP_ATOMIC); - if (SDpnt) { - /* - * Register the queue for the device. All I/O requests will come - * in through here. We also need to register a pointer to - * ourselves, since the queue handler won't know what device - * the queue actually represents. We could look it up, but it - * is pointless work. - */ - blk_init_queue(&SDpnt->request_queue, scsi_request_fn); - blk_queue_headactive(&SDpnt->request_queue, 0); - SDpnt->request_queue.queuedata = (void *) SDpnt; - /* Make sure we have something that is valid for DMA purposes */ - scsi_result = ((!shpnt->unchecked_isa_dma) - ? &scsi_result0[0] : scsi_init_malloc(512, GFP_DMA)); - } - } - if (scsi_result == NULL) { - printk("Unable to obtain scsi_result buffer\n"); - goto leave; - } - /* - * We must chain ourself in the host_queue, so commands can time out - */ - SCpnt->next = NULL; - SDpnt->device_queue = SCpnt; - SDpnt->host = shpnt; - SDpnt->online = TRUE; - - initialize_merge_fn(SDpnt); - - /* - * Initialize the object that we will use to wait for command blocks. - */ - init_waitqueue_head(&SDpnt->scpnt_wait); - - /* - * Next, hook the device to the host in question. - */ - SDpnt->prev = NULL; - SDpnt->next = NULL; - if (shpnt->host_queue != NULL) { - SDtail = shpnt->host_queue; - while (SDtail->next != NULL) - SDtail = SDtail->next; - - SDtail->next = SDpnt; - SDpnt->prev = SDtail; - } else { - shpnt->host_queue = SDpnt; - } - - /* - * We need to increment the counter for this one device so we can track when - * things are quiet. - */ - atomic_inc(&shpnt->host_active); - atomic_inc(&SDpnt->device_active); - - if (hardcoded == 1) { - Scsi_Device *oldSDpnt = SDpnt; - struct Scsi_Device_Template *sdtpnt; - channel = hchannel; - if (channel > shpnt->max_channel) - goto leave; - dev = hid; - if (dev >= shpnt->max_id) - goto leave; - lun = hlun; - if (lun >= shpnt->max_lun) - goto leave; - scan_scsis_single(channel, dev, lun, &max_dev_lun, &sparse_lun, - &SDpnt, SCpnt, shpnt, scsi_result); - if (SDpnt != oldSDpnt) { - - /* it could happen the blockdevice hasn't yet been inited */ - for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next) - if (sdtpnt->init && sdtpnt->dev_noticed) - (*sdtpnt->init) (); - - for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next) { - if (sdtpnt->attach) { - (*sdtpnt->attach) (oldSDpnt); - if (oldSDpnt->attached) { - scsi_build_commandblocks(oldSDpnt); - if (0 == oldSDpnt->has_cmdblocks) { - printk("scan_scsis: DANGER, no command blocks\n"); - /* What to do now ?? */ - } - } - } - } - resize_dma_pool(); - - for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next) { - if (sdtpnt->finish && sdtpnt->nr_dev) { - (*sdtpnt->finish) (); - } - } - } - } else { - /* Actual LUN. PC ordering is 0->n IBM/spec ordering is n->0 */ - int order_dev; - - for (channel = 0; channel <= shpnt->max_channel; channel++) { - for (dev = 0; dev < shpnt->max_id; ++dev) { - if (shpnt->reverse_ordering) - /* Shift to scanning 15,14,13... or 7,6,5,4, */ - order_dev = shpnt->max_id - dev - 1; - else - order_dev = dev; - - if (shpnt->this_id != order_dev) { - - /* - * We need the for so our continue, etc. work fine. We put this in - * a variable so that we can override it during the scan if we - * detect a device *KNOWN* to have multiple logical units. - */ - max_dev_lun = (max_scsi_luns < shpnt->max_lun ? - max_scsi_luns : shpnt->max_lun); - sparse_lun = 0; - for (lun = 0; lun < max_dev_lun; ++lun) { - if (!scan_scsis_single(channel, order_dev, lun, &max_dev_lun, - &sparse_lun, &SDpnt, SCpnt, shpnt, - scsi_result) - && !sparse_lun) - break; /* break means don't probe further for luns!=0 */ - } /* for lun ends */ - } /* if this_id != id ends */ - } /* for dev ends */ - } /* for channel ends */ - } /* if/else hardcoded */ - - /* - * We need to decrement the counter for this one device - * so we know when everything is quiet. - */ - atomic_dec(&shpnt->host_active); - atomic_dec(&SDpnt->device_active); - - leave: - - { /* Unchain SCpnt from host_queue */ - Scsi_Device *prev, *next; - Scsi_Device *dqptr; - - for (dqptr = shpnt->host_queue; dqptr != SDpnt; dqptr = dqptr->next) - continue; - if (dqptr) { - prev = dqptr->prev; - next = dqptr->next; - if (prev) - prev->next = next; - else - shpnt->host_queue = next; - if (next) - next->prev = prev; - } - } - - /* Last device block does not exist. Free memory. */ - if (SDpnt != NULL) - scsi_init_free((char *) SDpnt, sizeof(Scsi_Device)); - - if (SCpnt != NULL) - scsi_init_free((char *) SCpnt, sizeof(Scsi_Cmnd)); - - /* If we allocated a buffer so we could do DMA, free it now */ - if (scsi_result != &scsi_result0[0] && scsi_result != NULL) { - scsi_init_free(scsi_result, 512); - } { - Scsi_Device *sdev; - Scsi_Cmnd *scmd; - - SCSI_LOG_SCAN_BUS(4, printk("Host status for host %p:\n", shpnt)); - for (sdev = shpnt->host_queue; sdev; sdev = sdev->next) { - SCSI_LOG_SCAN_BUS(4, printk("Device %d %p: ", sdev->id, sdev)); - for (scmd = sdev->device_queue; scmd; scmd = scmd->next) { - SCSI_LOG_SCAN_BUS(4, printk("%p ", scmd)); - } - SCSI_LOG_SCAN_BUS(4, printk("\n")); - } - } -} - -/* - * The worker for scan_scsis. - * Returning 0 means Please don't ask further for lun!=0, 1 means OK go on. - * Global variables used : scsi_devices(linked list) - */ -int scan_scsis_single(int channel, int dev, int lun, int *max_dev_lun, - int *sparse_lun, Scsi_Device ** SDpnt2, Scsi_Cmnd * SCpnt, - struct Scsi_Host *shpnt, char *scsi_result) -{ - unsigned char scsi_cmd[12]; - struct Scsi_Device_Template *sdtpnt; - Scsi_Device *SDtail, *SDpnt = *SDpnt2; - int bflags, type = -1; - static int ghost_channel=-1, ghost_dev=-1; - int org_lun = lun; - - SDpnt->host = shpnt; - SDpnt->id = dev; - SDpnt->lun = lun; - SDpnt->channel = channel; - SDpnt->online = TRUE; - - - if ((channel == ghost_channel) && (dev == ghost_dev) && (lun == 1)) { - SDpnt->lun = 0; - } else { - ghost_channel = ghost_dev = -1; - } - - - /* Some low level driver could use device->type (DB) */ - SDpnt->type = -1; - - /* - * Assume that the device will have handshaking problems, and then fix this - * field later if it turns out it doesn't - */ - SDpnt->borken = 1; - SDpnt->was_reset = 0; - SDpnt->expecting_cc_ua = 0; - SDpnt->starved = 0; - - scsi_cmd[0] = TEST_UNIT_READY; - scsi_cmd[1] = lun << 5; - scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[4] = scsi_cmd[5] = 0; - - SCpnt->host = SDpnt->host; - SCpnt->device = SDpnt; - SCpnt->target = SDpnt->id; - SCpnt->lun = SDpnt->lun; - SCpnt->channel = SDpnt->channel; - - scsi_wait_cmd (SCpnt, (void *) scsi_cmd, - (void *) NULL, - 0, scan_scsis_done, SCSI_TIMEOUT + 4 * HZ, 5); - - SCSI_LOG_SCAN_BUS(3, printk("scsi: scan_scsis_single id %d lun %d. Return code 0x%08x\n", - dev, lun, SCpnt->result)); - SCSI_LOG_SCAN_BUS(3, print_driverbyte(SCpnt->result)); - SCSI_LOG_SCAN_BUS(3, print_hostbyte(SCpnt->result)); - SCSI_LOG_SCAN_BUS(3, printk("\n")); - - if (SCpnt->result) { - if (((driver_byte(SCpnt->result) & DRIVER_SENSE) || - (status_byte(SCpnt->result) & CHECK_CONDITION)) && - ((SCpnt->sense_buffer[0] & 0x70) >> 4) == 7) { - if (((SCpnt->sense_buffer[2] & 0xf) != NOT_READY) && - ((SCpnt->sense_buffer[2] & 0xf) != UNIT_ATTENTION) && - ((SCpnt->sense_buffer[2] & 0xf) != ILLEGAL_REQUEST || lun > 0)) - return 1; - } else - return 0; - } - SCSI_LOG_SCAN_BUS(3, printk("scsi: performing INQUIRY\n")); - /* - * Build an INQUIRY command block. - */ - scsi_cmd[0] = INQUIRY; - scsi_cmd[1] = (lun << 5) & 0xe0; - scsi_cmd[2] = 0; - scsi_cmd[3] = 0; - scsi_cmd[4] = 255; - scsi_cmd[5] = 0; - SCpnt->cmd_len = 0; - - scsi_wait_cmd (SCpnt, (void *) scsi_cmd, - (void *) scsi_result, - 256, scan_scsis_done, SCSI_TIMEOUT, 3); - - SCSI_LOG_SCAN_BUS(3, printk("scsi: INQUIRY %s with code 0x%x\n", - SCpnt->result ? "failed" : "successful", SCpnt->result)); - - if (SCpnt->result) - return 0; /* assume no peripheral if any sort of error */ - - /* - * Check the peripheral qualifier field - this tells us whether LUNS - * are supported here or not. - */ - if ((scsi_result[0] >> 5) == 3) { - return 0; /* assume no peripheral if any sort of error */ - } - - /* - * Get any flags for this device. - */ - bflags = get_device_flags (scsi_result); - - - /* The Toshiba ROM was "gender-changed" here as an inline hack. - This is now much more generic. - This is a mess: What we really want is to leave the scsi_result - alone, and just change the SDpnt structure. And the SDpnt is what - we want print_inquiry to print. -- REW - */ - if (bflags & BLIST_ISDISK) { - scsi_result[0] = TYPE_DISK; - scsi_result[1] |= 0x80; /* removable */ - } - - if (bflags & BLIST_ISROM) { - scsi_result[0] = TYPE_ROM; - scsi_result[1] |= 0x80; /* removable */ - } - - if (bflags & BLIST_GHOST) { - if ((ghost_channel == channel) && (ghost_dev == dev) && (org_lun == 1)) { - lun=1; - } else { - ghost_channel = channel; - ghost_dev = dev; - scsi_result[0] = TYPE_MOD; - scsi_result[1] |= 0x80; /* removable */ - } - } - - - memcpy(SDpnt->vendor, scsi_result + 8, 8); - memcpy(SDpnt->model, scsi_result + 16, 16); - memcpy(SDpnt->rev, scsi_result + 32, 4); - - SDpnt->removable = (0x80 & scsi_result[1]) >> 7; - SDpnt->online = TRUE; - SDpnt->lockable = SDpnt->removable; - SDpnt->changed = 0; - SDpnt->access_count = 0; - SDpnt->busy = 0; - SDpnt->has_cmdblocks = 0; - /* - * Currently, all sequential devices are assumed to be tapes, all random - * devices disk, with the appropriate read only flags set for ROM / WORM - * treated as RO. - */ - switch (type = (scsi_result[0] & 0x1f)) { - case TYPE_TAPE: - case TYPE_DISK: - case TYPE_MOD: - case TYPE_PROCESSOR: - case TYPE_SCANNER: - case TYPE_MEDIUM_CHANGER: - case TYPE_ENCLOSURE: - SDpnt->writeable = 1; - break; - case TYPE_WORM: - case TYPE_ROM: - SDpnt->writeable = 0; - break; - default: - printk("scsi: unknown type %d\n", type); - } - - SDpnt->device_blocked = FALSE; - SDpnt->device_busy = 0; - SDpnt->single_lun = 0; - SDpnt->soft_reset = - (scsi_result[7] & 1) && ((scsi_result[3] & 7) == 2); - SDpnt->random = (type == TYPE_TAPE) ? 0 : 1; - SDpnt->type = (type & 0x1f); - - print_inquiry(scsi_result); - - for (sdtpnt = scsi_devicelist; sdtpnt; - sdtpnt = sdtpnt->next) - if (sdtpnt->detect) - SDpnt->attached += - (*sdtpnt->detect) (SDpnt); - - SDpnt->scsi_level = scsi_result[2] & 0x07; - if (SDpnt->scsi_level >= 2 || - (SDpnt->scsi_level == 1 && - (scsi_result[3] & 0x0f) == 1)) - SDpnt->scsi_level++; - - /* - * Accommodate drivers that want to sleep when they should be in a polling - * loop. - */ - SDpnt->disconnect = 0; - - - /* - * Set the tagged_queue flag for SCSI-II devices that purport to support - * tagged queuing in the INQUIRY data. - */ - SDpnt->tagged_queue = 0; - if ((SDpnt->scsi_level >= SCSI_2) && - (scsi_result[7] & 2) && - !(bflags & BLIST_NOTQ)) { - SDpnt->tagged_supported = 1; - SDpnt->current_tag = 0; - } - /* - * Some revisions of the Texel CD ROM drives have handshaking problems when - * used with the Seagate controllers. Before we know what type of device - * we're talking to, we assume it's borken and then change it here if it - * turns out that it isn't a TEXEL drive. - */ - if ((bflags & BLIST_BORKEN) == 0) - SDpnt->borken = 0; - - /* - * If we want to only allow I/O to one of the luns attached to this device - * at a time, then we set this flag. - */ - if (bflags & BLIST_SINGLELUN) - SDpnt->single_lun = 1; - - /* - * These devices need this "key" to unlock the devices so we can use it - */ - if ((bflags & BLIST_KEY) != 0) { - printk("Unlocked floptical drive.\n"); - SDpnt->lockable = 0; - scsi_cmd[0] = MODE_SENSE; - scsi_cmd[1] = (lun << 5) & 0xe0; - scsi_cmd[2] = 0x2e; - scsi_cmd[3] = 0; - scsi_cmd[4] = 0x2a; - scsi_cmd[5] = 0; - SCpnt->cmd_len = 0; - scsi_wait_cmd (SCpnt, (void *) scsi_cmd, - (void *) scsi_result, 0x2a, - scan_scsis_done, SCSI_TIMEOUT, 3); - } - /* - * Detach the command from the device. It was just a temporary to be used while - * scanning the bus - the real ones will be allocated later. - */ - SDpnt->device_queue = NULL; - - /* - * This device was already hooked up to the host in question, - * so at this point we just let go of it and it should be fine. We do need to - * allocate a new one and attach it to the host so that we can further scan the bus. - */ - SDpnt = (Scsi_Device *) scsi_init_malloc(sizeof(Scsi_Device), GFP_ATOMIC); - *SDpnt2 = SDpnt; - if (!SDpnt) { - printk("scsi: scan_scsis_single: Cannot malloc\n"); - return 0; - } - /* - * Register the queue for the device. All I/O requests will come - * in through here. We also need to register a pointer to - * ourselves, since the queue handler won't know what device - * the queue actually represents. We could look it up, but it - * is pointless work. - */ - blk_init_queue(&SDpnt->request_queue, scsi_request_fn); - blk_queue_headactive(&SDpnt->request_queue, 0); - SDpnt->request_queue.queuedata = (void *) SDpnt; - SDpnt->host = shpnt; - initialize_merge_fn(SDpnt); - - /* - * And hook up our command block to the new device we will be testing - * for. - */ - SDpnt->device_queue = SCpnt; - SDpnt->online = TRUE; - - /* - * Initialize the object that we will use to wait for command blocks. - */ - init_waitqueue_head(&SDpnt->scpnt_wait); - - /* - * Since we just found one device, there had damn well better be one in the list - * already. - */ - if (shpnt->host_queue == NULL) - panic("scan_scsis_single: Host queue == NULL\n"); - - SDtail = shpnt->host_queue; - while (SDtail->next) { - SDtail = SDtail->next; - } - - /* Add this device to the linked list at the end */ - SDtail->next = SDpnt; - SDpnt->prev = SDtail; - SDpnt->next = NULL; - - /* - * Some scsi devices cannot be polled for lun != 0 due to firmware bugs - */ - if (bflags & BLIST_NOLUN) - return 0; /* break; */ - - /* - * If this device is known to support sparse multiple units, override the - * other settings, and scan all of them. - */ - if (bflags & BLIST_SPARSELUN) { - *max_dev_lun = 8; - *sparse_lun = 1; - return 1; - } - /* - * If this device is known to support multiple units, override the other - * settings, and scan all of them. - */ - if (bflags & BLIST_FORCELUN) { - *max_dev_lun = 8; - return 1; - } - /* - * REGAL CDC-4X: avoid hang after LUN 4 - */ - if (bflags & BLIST_MAX5LUN) { - *max_dev_lun = 5; - return 1; - } - - /* - * If this device is Ghosted, scan upto two luns. (It physically only - * has one). -- REW - */ - if (bflags & BLIST_GHOST) { - *max_dev_lun = 2; - return 1; - } - - - /* - * We assume the device can't handle lun!=0 if: - it reports scsi-0 (ANSI - * SCSI Revision 0) (old drives like MAXTOR XT-3280) or - it reports scsi-1 - * (ANSI SCSI Revision 1) and Response Data Format 0 - */ - if (((scsi_result[2] & 0x07) == 0) - || - ((scsi_result[2] & 0x07) == 1 && - (scsi_result[3] & 0x0f) == 0)) - return 0; - return 1; -} - -/* - * Flag bits for the internal_timeout array - */ -#define NORMAL_TIMEOUT 0 -#define IN_ABORT 1 -#define IN_RESET 2 -#define IN_RESET2 4 -#define IN_RESET3 8 - - -/* * This lock protects the freelist for all devices on the system. * We could make this finer grained by having a single lock per * device if it is ever found that there is excessive contention @@ -990,11 +245,6 @@ static spinlock_t device_request_lock = SPIN_LOCK_UNLOCKED; /* - * Used for access to internal allocator used for DMA safe buffers. - */ -static spinlock_t allocator_request_lock = SPIN_LOCK_UNLOCKED; - -/* * Used to protect insertion into and removal from the queue of * commands to be processed by the bottom half handler. */ @@ -1465,7 +715,8 @@ * the completion function for the high level driver. */ - memcpy((void *) SCpnt->data_cmnd, (const void *) cmnd, 12); + memcpy((void *) SCpnt->data_cmnd, (const void *) cmnd, + sizeof(SCpnt->data_cmnd)); SCpnt->reset_chain = NULL; SCpnt->serial_number = 0; SCpnt->serial_number_at_timeout = 0; @@ -1477,7 +728,8 @@ SCpnt->done = done; SCpnt->timeout_per_command = timeout; - memcpy((void *) SCpnt->cmnd, (const void *) cmnd, 12); + memcpy((void *) SCpnt->cmnd, (const void *) cmnd, + sizeof(SCpnt->cmnd)); /* Zero the sense buffer. Some host adapters automatically request * sense on error. 0 is not a valid sense code. */ @@ -1820,127 +1072,6 @@ static void scsi_unregister_host(Scsi_Host_Template *); #endif -/* - * Function: scsi_malloc - * - * Purpose: Allocate memory from the DMA-safe pool. - * - * Arguments: len - amount of memory we need. - * - * Lock status: No locks assumed to be held. This function is SMP-safe. - * - * Returns: Pointer to memory block. - * - * Notes: Prior to the new queue code, this function was not SMP-safe. - * This function can only allocate in units of sectors - * (i.e. 512 bytes). - * - * We cannot use the normal system allocator becuase we need - * to be able to guarantee that we can process a complete disk - * I/O request without touching the system allocator. Think - * about it - if the system were heavily swapping, and tried to - * write out a block of memory to disk, and the SCSI code needed - * to allocate more memory in order to be able to write the - * data to disk, you would wedge the system. - */ -void *scsi_malloc(unsigned int len) -{ - unsigned int nbits, mask; - unsigned long flags; - - int i, j; - if (len % SECTOR_SIZE != 0 || len > PAGE_SIZE) - return NULL; - - nbits = len >> 9; - mask = (1 << nbits) - 1; - - spin_lock_irqsave(&allocator_request_lock, flags); - - for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++) - for (j = 0; j <= SECTORS_PER_PAGE - nbits; j++) { - if ((dma_malloc_freelist[i] & (mask << j)) == 0) { - dma_malloc_freelist[i] |= (mask << j); - scsi_dma_free_sectors -= nbits; -#ifdef DEBUG - SCSI_LOG_MLQUEUE(3, printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9))); - printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9)); -#endif - spin_unlock_irqrestore(&allocator_request_lock, flags); - return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9)); - } - } - spin_unlock_irqrestore(&allocator_request_lock, flags); - return NULL; /* Nope. No more */ -} - -/* - * Function: scsi_free - * - * Purpose: Free memory into the DMA-safe pool. - * - * Arguments: ptr - data block we are freeing. - * len - size of block we are freeing. - * - * Lock status: No locks assumed to be held. This function is SMP-safe. - * - * Returns: Nothing - * - * Notes: This function *must* only be used to free memory - * allocated from scsi_malloc(). - * - * Prior to the new queue code, this function was not SMP-safe. - * This function can only allocate in units of sectors - * (i.e. 512 bytes). - */ -int scsi_free(void *obj, unsigned int len) -{ - unsigned int page, sector, nbits, mask; - unsigned long flags; - -#ifdef DEBUG - unsigned long ret = 0; - -#ifdef __mips__ - __asm__ __volatile__("move\t%0,$31":"=r"(ret)); -#else - ret = __builtin_return_address(0); -#endif - printk("scsi_free %p %d\n", obj, len); - SCSI_LOG_MLQUEUE(3, printk("SFree: %p %d\n", obj, len)); -#endif - - spin_lock_irqsave(&allocator_request_lock, flags); - - for (page = 0; page < dma_sectors / SECTORS_PER_PAGE; page++) { - unsigned long page_addr = (unsigned long) dma_malloc_pages[page]; - if ((unsigned long) obj >= page_addr && - (unsigned long) obj < page_addr + PAGE_SIZE) { - sector = (((unsigned long) obj) - page_addr) >> 9; - - nbits = len >> 9; - mask = (1 << nbits) - 1; - - if ((mask << sector) >= (1 << SECTORS_PER_PAGE)) - panic("scsi_free:Bad memory alignment"); - - if ((dma_malloc_freelist[page] & - (mask << sector)) != (mask << sector)) { -#ifdef DEBUG - printk("scsi_free(obj=%p, len=%d) called from %08lx\n", - obj, len, ret); -#endif - panic("scsi_free:Trying to free unused memory"); - } - scsi_dma_free_sectors += nbits; - dma_malloc_freelist[page] &= ~(mask << sector); - spin_unlock_irqrestore(&allocator_request_lock, flags); - return 0; - } - } - panic("scsi_free:Bad offset"); -} - int scsi_loadable_module_flag; /* Set after we scan builtin drivers */ @@ -2124,7 +1255,7 @@ /* * This should build the DMA pool. */ - resize_dma_pool(); + scsi_resize_dma_pool(); /* * OK, now we finish the initialization by doing spin-up, read @@ -2140,47 +1271,6 @@ } #endif /* MODULE */ /* } */ -static void print_inquiry(unsigned char *data) -{ - int i; - - printk(" Vendor: "); - for (i = 8; i < 16; i++) { - if (data[i] >= 0x20 && i < data[4] + 5) - printk("%c", data[i]); - else - printk(" "); - } - - printk(" Model: "); - for (i = 16; i < 32; i++) { - if (data[i] >= 0x20 && i < data[4] + 5) - printk("%c", data[i]); - else - printk(" "); - } - - printk(" Rev: "); - for (i = 32; i < 36; i++) { - if (data[i] >= 0x20 && i < data[4] + 5) - printk("%c", data[i]); - else - printk(" "); - } - - printk("\n"); - - i = data[0] & 0x1f; - - printk(" Type: %s ", - i < MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] : "Unknown "); - printk(" ANSI SCSI revision: %02x", data[2] & 0x07); - if ((data[2] & 0x07) == 1 && (data[3] & 0x0f) == 1) - printk(" CCS\n"); - else - printk("\n"); -} - #ifdef CONFIG_PROC_FS static int scsi_proc_info(char *buffer, char **start, off_t offset, int length) { @@ -2475,217 +1565,6 @@ } #endif -/* - * Function: resize_dma_pool - * - * Purpose: Ensure that the DMA pool is sufficiently large to be - * able to guarantee that we can always process I/O requests - * without calling the system allocator. - * - * Arguments: None. - * - * Lock status: No locks assumed to be held. This function is SMP-safe. - * - * Returns: Nothing - * - * Notes: Prior to the new queue code, this function was not SMP-safe. - * Go through the device list and recompute the most appropriate - * size for the dma pool. Then grab more memory (as required). - */ -static void resize_dma_pool(void) -{ - int i, k; - unsigned long size; - unsigned long flags; - struct Scsi_Host *shpnt; - struct Scsi_Host *host = NULL; - Scsi_Device *SDpnt; - FreeSectorBitmap *new_dma_malloc_freelist = NULL; - unsigned int new_dma_sectors = 0; - unsigned int new_need_isa_buffer = 0; - unsigned char **new_dma_malloc_pages = NULL; - int out_of_space = 0; - - spin_lock_irqsave(&allocator_request_lock, flags); - - if (!scsi_hostlist) { - /* - * Free up the DMA pool. - */ - if (scsi_dma_free_sectors != dma_sectors) - panic("SCSI DMA pool memory leak %d %d\n", scsi_dma_free_sectors, dma_sectors); - - for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++) - scsi_init_free(dma_malloc_pages[i], PAGE_SIZE); - if (dma_malloc_pages) - scsi_init_free((char *) dma_malloc_pages, - (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages)); - dma_malloc_pages = NULL; - if (dma_malloc_freelist) - scsi_init_free((char *) dma_malloc_freelist, - (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_freelist)); - dma_malloc_freelist = NULL; - dma_sectors = 0; - scsi_dma_free_sectors = 0; - spin_unlock_irqrestore(&allocator_request_lock, flags); - return; - } - /* Next, check to see if we need to extend the DMA buffer pool */ - - new_dma_sectors = 2 * SECTORS_PER_PAGE; /* Base value we use */ - - if (__pa(high_memory) - 1 > ISA_DMA_THRESHOLD) - need_isa_bounce_buffers = 1; - else - need_isa_bounce_buffers = 0; - - if (scsi_devicelist) - for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) - new_dma_sectors += SECTORS_PER_PAGE; /* Increment for each host */ - - for (host = scsi_hostlist; host; host = host->next) { - for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) { - /* - * sd and sr drivers allocate scatterlists. - * sr drivers may allocate for each command 1x2048 or 2x1024 extra - * buffers for 2k sector size and 1k fs. - * sg driver allocates buffers < 4k. - * st driver does not need buffers from the dma pool. - * estimate 4k buffer/command for devices of unknown type (should panic). - */ - if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM || - SDpnt->type == TYPE_DISK || SDpnt->type == TYPE_MOD) { - new_dma_sectors += ((host->sg_tablesize * - sizeof(struct scatterlist) + 511) >> 9) * - SDpnt->queue_depth; - if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM) - new_dma_sectors += (2048 >> 9) * SDpnt->queue_depth; - } else if (SDpnt->type == TYPE_SCANNER || - SDpnt->type == TYPE_PROCESSOR || - SDpnt->type == TYPE_MEDIUM_CHANGER || - SDpnt->type == TYPE_ENCLOSURE) { - new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth; - } else { - if (SDpnt->type != TYPE_TAPE) { - printk("resize_dma_pool: unknown device type %d\n", SDpnt->type); - new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth; - } - } - - if (host->unchecked_isa_dma && - need_isa_bounce_buffers && - SDpnt->type != TYPE_TAPE) { - new_dma_sectors += (PAGE_SIZE >> 9) * host->sg_tablesize * - SDpnt->queue_depth; - new_need_isa_buffer++; - } - } - } - -#ifdef DEBUG_INIT - printk("resize_dma_pool: needed dma sectors = %d\n", new_dma_sectors); -#endif - - /* limit DMA memory to 32MB: */ - new_dma_sectors = (new_dma_sectors + 15) & 0xfff0; - - /* - * We never shrink the buffers - this leads to - * race conditions that I would rather not even think - * about right now. - */ -#if 0 /* Why do this? No gain and risks out_of_space */ - if (new_dma_sectors < dma_sectors) - new_dma_sectors = dma_sectors; -#endif - if (new_dma_sectors <= dma_sectors) { - spin_unlock_irqrestore(&allocator_request_lock, flags); - return; /* best to quit while we are in front */ - } - - for (k = 0; k < 20; ++k) { /* just in case */ - out_of_space = 0; - size = (new_dma_sectors / SECTORS_PER_PAGE) * - sizeof(FreeSectorBitmap); - new_dma_malloc_freelist = (FreeSectorBitmap *) - scsi_init_malloc(size, GFP_ATOMIC); - if (new_dma_malloc_freelist) { - size = (new_dma_sectors / SECTORS_PER_PAGE) * - sizeof(*new_dma_malloc_pages); - new_dma_malloc_pages = (unsigned char **) - scsi_init_malloc(size, GFP_ATOMIC); - if (!new_dma_malloc_pages) { - size = (new_dma_sectors / SECTORS_PER_PAGE) * - sizeof(FreeSectorBitmap); - scsi_init_free((char *) new_dma_malloc_freelist, size); - out_of_space = 1; - } - } else - out_of_space = 1; - - if ((!out_of_space) && (new_dma_sectors > dma_sectors)) { - for (i = dma_sectors / SECTORS_PER_PAGE; - i < new_dma_sectors / SECTORS_PER_PAGE; i++) { - new_dma_malloc_pages[i] = (unsigned char *) - scsi_init_malloc(PAGE_SIZE, GFP_ATOMIC | GFP_DMA); - if (!new_dma_malloc_pages[i]) - break; - } - if (i != new_dma_sectors / SECTORS_PER_PAGE) { /* clean up */ - int k = i; - - out_of_space = 1; - for (i = 0; i < k; ++i) - scsi_init_free(new_dma_malloc_pages[i], PAGE_SIZE); - } - } - if (out_of_space) { /* try scaling down new_dma_sectors request */ - printk("scsi::resize_dma_pool: WARNING, dma_sectors=%u, " - "wanted=%u, scaling\n", dma_sectors, new_dma_sectors); - if (new_dma_sectors < (8 * SECTORS_PER_PAGE)) - break; /* pretty well hopeless ... */ - new_dma_sectors = (new_dma_sectors * 3) / 4; - new_dma_sectors = (new_dma_sectors + 15) & 0xfff0; - if (new_dma_sectors <= dma_sectors) - break; /* stick with what we have got */ - } else - break; /* found space ... */ - } /* end of for loop */ - if (out_of_space) { - spin_unlock_irqrestore(&allocator_request_lock, flags); - scsi_need_isa_buffer = new_need_isa_buffer; /* some useful info */ - printk(" WARNING, not enough memory, pool not expanded\n"); - return; - } - /* When we dick with the actual DMA list, we need to - * protect things - */ - if (dma_malloc_freelist) { - size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(FreeSectorBitmap); - memcpy(new_dma_malloc_freelist, dma_malloc_freelist, size); - scsi_init_free((char *) dma_malloc_freelist, size); - } - dma_malloc_freelist = new_dma_malloc_freelist; - - if (dma_malloc_pages) { - size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages); - memcpy(new_dma_malloc_pages, dma_malloc_pages, size); - scsi_init_free((char *) dma_malloc_pages, size); - } - scsi_dma_free_sectors += new_dma_sectors - dma_sectors; - dma_malloc_pages = new_dma_malloc_pages; - dma_sectors = new_dma_sectors; - scsi_need_isa_buffer = new_need_isa_buffer; - - spin_unlock_irqrestore(&allocator_request_lock, flags); - -#ifdef DEBUG_INIT - printk("resize_dma_pool: dma free sectors = %d\n", scsi_dma_free_sectors); - printk("resize_dma_pool: dma sectors = %d\n", dma_sectors); - printk("resize_dma_pool: need isa buffers = %d\n", scsi_need_isa_buffer); -#endif -} - #ifdef CONFIG_MODULES /* a big #ifdef block... */ /* @@ -2819,7 +1698,7 @@ * Now that we have all of the devices, resize the DMA pool, * as required. */ if (!out_of_space) - resize_dma_pool(); + scsi_resize_dma_pool(); /* This does any final handling that is required. */ @@ -3037,7 +1916,7 @@ * do the right thing and free everything. */ if (!scsi_hosts) - resize_dma_pool(); + scsi_resize_dma_pool(); printk("scsi : %d host%s.\n", next_scsi_host, (next_scsi_host == 1) ? "" : "s"); @@ -3049,7 +1928,6 @@ (scsi_memory_upper_value - scsi_init_memory_start) / 1024); #endif - /* There were some hosts that were loaded at boot time, so we cannot do any more than this */ if (tpnt->present) @@ -3132,7 +2010,7 @@ if (tpnt->finish && tpnt->nr_dev) (*tpnt->finish) (); if (!out_of_space) - resize_dma_pool(); + scsi_resize_dma_pool(); MOD_INC_USE_COUNT; if (out_of_space) { @@ -3362,6 +2240,11 @@ int has_space = 0; struct proc_dir_entry *generic; + if( scsi_init_minimal_dma_pool() != 0 ) + { + return 1; + } + /* * This makes /proc/scsi and /proc/scsi/scsi visible. */ @@ -3382,39 +2265,6 @@ scsi_loadable_module_flag = 1; - dma_sectors = PAGE_SIZE / SECTOR_SIZE; - scsi_dma_free_sectors = dma_sectors; - /* - * Set up a minimal DMA buffer list - this will be used during scan_scsis - * in some cases. - */ - - /* One bit per sector to indicate free/busy */ - size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(FreeSectorBitmap); - dma_malloc_freelist = (FreeSectorBitmap *) - scsi_init_malloc(size, GFP_ATOMIC); - if (dma_malloc_freelist) { - /* One pointer per page for the page list */ - dma_malloc_pages = (unsigned char **) scsi_init_malloc( - (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages), - GFP_ATOMIC); - if (dma_malloc_pages) { - dma_malloc_pages[0] = (unsigned char *) - scsi_init_malloc(PAGE_SIZE, GFP_ATOMIC | GFP_DMA); - if (dma_malloc_pages[0]) - has_space = 1; - } - } - if (!has_space) { - if (dma_malloc_freelist) { - scsi_init_free((char *) dma_malloc_freelist, size); - if (dma_malloc_pages) - scsi_init_free((char *) dma_malloc_pages, - (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages)); - } - printk("scsi::init_module: failed, out of memory\n"); - return 1; - } /* * This is where the processing takes place for most everything * when commands are completed. @@ -3437,7 +2287,7 @@ /* * Free up the DMA pool. */ - resize_dma_pool(); + scsi_resize_dma_pool(); } @@ -3491,7 +2341,7 @@ SDpnt->device_queue = SCpnt; - blk_init_queue(&SDpnt->request_queue, scsi_request_fn); + blk_init_queue(&SDpnt->request_queue, scsi_get_request_handler(SDpnt, SDpnt->host)); blk_queue_headactive(&SDpnt->request_queue, 0); SDpnt->request_queue.queuedata = (void *) SDpnt; @@ -3519,7 +2369,7 @@ */ void scsi_free_host_dev(Scsi_Device * SDpnt) { - if( SDpnt->id != SDpnt->host->this_id ) + if( (unsigned char) SDpnt->id != (unsigned char) SDpnt->host->this_id ) { panic("Attempt to delete wrong device\n"); } diff -ur --new-file old/linux/drivers/scsi/scsi.h new/linux/drivers/scsi/scsi.h --- old/linux/drivers/scsi/scsi.h Fri Jan 21 01:07:11 2000 +++ new/linux/drivers/scsi/scsi.h Fri Jan 28 17:02:51 2000 @@ -365,90 +365,120 @@ * Initializes all SCSI devices. This scans all scsi busses. */ -extern int scsi_dev_init(void); - - - -void *scsi_malloc(unsigned int); -int scsi_free(void *, unsigned int); extern unsigned int scsi_logging_level; /* What do we log? */ extern unsigned int scsi_dma_free_sectors; /* How much room do we have left */ extern unsigned int scsi_need_isa_buffer; /* True if some devices need indirection * buffers */ -extern void scsi_make_blocked_list(void); extern volatile int in_scan_scsis; extern const unsigned char scsi_command_size[8]; + /* * These are the error handling functions defined in scsi_error.c */ +extern void scsi_times_out(Scsi_Cmnd * SCpnt); extern void scsi_add_timer(Scsi_Cmnd * SCset, int timeout, void (*complete) (Scsi_Cmnd *)); -extern void scsi_done(Scsi_Cmnd * SCpnt); extern int scsi_delete_timer(Scsi_Cmnd * SCset); extern void scsi_error_handler(void *host); -extern int scsi_retry_command(Scsi_Cmnd *); -extern void scsi_finish_command(Scsi_Cmnd *); extern int scsi_sense_valid(Scsi_Cmnd *); extern int scsi_decide_disposition(Scsi_Cmnd * SCpnt); extern int scsi_block_when_processing_errors(Scsi_Device *); extern void scsi_sleep(int); + +/* + * Prototypes for functions in scsicam.c + */ extern int scsi_partsize(struct buffer_head *bh, unsigned long capacity, unsigned int *cyls, unsigned int *hds, unsigned int *secs); /* + * Prototypes for functions in scsi_dma.c + */ +void scsi_resize_dma_pool(void); +int scsi_init_minimal_dma_pool(void); +void *scsi_malloc(unsigned int); +int scsi_free(void *, unsigned int); + +/* * Prototypes for functions in scsi_merge.c */ extern void recount_segments(Scsi_Cmnd * SCpnt); +extern void initialize_merge_fn(Scsi_Device * SDpnt); + +/* + * Prototypes for functions in scsi_queue.c + */ +extern int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason); /* * Prototypes for functions in scsi_lib.c */ -extern void initialize_merge_fn(Scsi_Device * SDpnt); -extern void scsi_request_fn(request_queue_t * q); +extern void scsi_maybe_unblock_host(Scsi_Device * SDpnt); +extern void scsi_blocked_request_fn(request_queue_t * q); +extern Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt, int uptodate, + int sectors); +extern struct Scsi_Device_Template *scsi_get_request_dev(struct request *); +extern int scsi_init_cmd_errh(Scsi_Cmnd * SCpnt); +extern int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int); +extern void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, + int block_sectors); extern void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt); +extern void scsi_request_fn(request_queue_t * q); -extern int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int); -extern int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt); /* * Prototypes for functions in scsi.c */ - -/* - * scsi_abort aborts the current command that is executing on host host. - * The error code, if non zero is returned in the host byte, otherwise - * DID_ABORT is returned in the hostbyte. - */ - +extern int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt); +extern void scsi_bottom_half_handler(void); +extern void scsi_build_commandblocks(Scsi_Device * SDpnt); +extern void scsi_done(Scsi_Cmnd * SCpnt); +extern void scsi_finish_command(Scsi_Cmnd *); +extern int scsi_retry_command(Scsi_Cmnd *); +extern Scsi_Cmnd *scsi_allocate_device(Scsi_Device *, int, int); +extern void scsi_release_command(Scsi_Cmnd *); extern void scsi_do_cmd(Scsi_Cmnd *, const void *cmnd, void *buffer, unsigned bufflen, void (*done) (struct scsi_cmnd *), int timeout, int retries); - extern void scsi_wait_cmd(Scsi_Cmnd *, const void *cmnd, void *buffer, unsigned bufflen, - void (*done) (struct scsi_cmnd *), int timeout, int retries); +extern int scsi_dev_init(void); -extern Scsi_Cmnd *scsi_allocate_device(Scsi_Device *, int, int); - -extern void scsi_release_command(Scsi_Cmnd *); +/* + * Prototypes for functions/data in hosts.c + */ extern int max_scsi_hosts; +/* + * Prototypes for functions in scsi_proc.c + */ extern void proc_print_scsidevice(Scsi_Device *, char *, int *, int); extern struct proc_dir_entry *proc_scsi; +/* + * Prototypes for functions in constants.c + */ extern void print_command(unsigned char *); extern void print_sense(const char *, Scsi_Cmnd *); extern void print_driverbyte(int scsiresult); extern void print_hostbyte(int scsiresult); +extern void print_status (int status); /* * The scsi_device struct contains what we know about each given scsi * device. + * + * FIXME(eric) - one of the great regrets that I have is that I failed to define + * these structure elements as something like sdev_foo instead of foo. This would + * make it so much easier to grep through sources and so forth. I propose that + * all new elements that get added to these structures follow this convention. + * As time goes on and as people have the stomach for it, it should be possible to + * go back and retrofit at least some of the elements here with with the prefix. */ struct scsi_device { @@ -538,6 +568,14 @@ } Scsi_Pointer; +/* + * FIXME(eric) - one of the great regrets that I have is that I failed to define + * these structure elements as something like sc_foo instead of foo. This would + * make it so much easier to grep through sources and so forth. I propose that + * all new elements that get added to these structures follow this convention. + * As time goes on and as people have the stomach for it, it should be possible to + * go back and retrofit at least some of the elements here with with the prefix. + */ struct scsi_cmnd { /* private: */ /* @@ -593,14 +631,14 @@ unsigned char old_cmd_len; /* These elements define the operation we are about to perform */ - unsigned char cmnd[12]; + unsigned char cmnd[MAX_COMMAND_SIZE]; unsigned request_bufflen; /* Actual request size */ struct timer_list eh_timeout; /* Used to time out the command. */ void *request_buffer; /* Actual requested buffer */ /* These elements define the operation we ultimately want to perform */ - unsigned char data_cmnd[12]; + unsigned char data_cmnd[MAX_COMMAND_SIZE]; unsigned short old_use_sg; /* We save use_sg here when requesting * sense info */ unsigned short use_sg; /* Number of pieces of scatter-gather */ @@ -667,29 +705,15 @@ }; /* - * Flag bits for the internal_timeout array + * Flag bit for the internal_timeout array */ #define NORMAL_TIMEOUT 0 -#define IN_ABORT 1 -#define IN_RESET 2 -#define IN_RESET2 4 -#define IN_RESET3 8 /* * Definitions and prototypes used for scsi mid-level queue. */ #define SCSI_MLQUEUE_HOST_BUSY 0x1055 #define SCSI_MLQUEUE_DEVICE_BUSY 0x1056 - -extern int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason); - -extern Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt, int uptodate, - int sectors); - -extern void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, - int block_sectors); - -extern struct Scsi_Device_Template *scsi_get_request_dev(struct request *); #define SCSI_SLEEP(QUEUE, CONDITION) { \ if (CONDITION) { \ diff -ur --new-file old/linux/drivers/scsi/scsi_debug.c new/linux/drivers/scsi/scsi_debug.c --- old/linux/drivers/scsi/scsi_debug.c Fri Jan 7 20:55:28 2000 +++ new/linux/drivers/scsi/scsi_debug.c Fri Jan 21 18:48:12 2000 @@ -544,18 +544,6 @@ return 0; } -static void sd_test_done(Scsi_Cmnd * SCpnt) -{ - struct request *req; - - req = &SCpnt->request; - req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ - - if (req->sem != NULL) { - up(req->sem); - } -} - static void scsi_debug_send_self_command(struct Scsi_Host * shpnt) { static unsigned char cmd[6] = @@ -575,7 +563,7 @@ printk("Sending command\n"); scsi_wait_cmd (scp, (void *) cmd, (void *) NULL, - 0, sd_test_done, 100, 3); + 0, 100, 3); printk("Releasing command\n"); scsi_release_command(scp); diff -ur --new-file old/linux/drivers/scsi/scsi_dma.c new/linux/drivers/scsi/scsi_dma.c --- old/linux/drivers/scsi/scsi_dma.c Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/scsi/scsi_dma.c Thu Jan 27 17:58:15 2000 @@ -0,0 +1,449 @@ +/* + * scsi_dma.c Copyright (C) 2000 Eric Youngdale + * + * mid-level SCSI DMA bounce buffer allocator + * + */ + +#define __NO_VERSION__ +#include +#include +#include + + +#include "scsi.h" +#include "hosts.h" +#include "constants.h" + +#ifdef CONFIG_KMOD +#include +#endif + +/* + * PAGE_SIZE must be a multiple of the sector size (512). True + * for all reasonably recent architectures (even the VAX...). + */ +#define SECTOR_SIZE 512 +#define SECTORS_PER_PAGE (PAGE_SIZE/SECTOR_SIZE) + +#if SECTORS_PER_PAGE <= 8 +typedef unsigned char FreeSectorBitmap; +#elif SECTORS_PER_PAGE <= 32 +typedef unsigned int FreeSectorBitmap; +#else +#error You lose. +#endif + +/* + * Used for access to internal allocator used for DMA safe buffers. + */ +static spinlock_t allocator_request_lock = SPIN_LOCK_UNLOCKED; + +static FreeSectorBitmap *dma_malloc_freelist = NULL; +static int need_isa_bounce_buffers; +static unsigned int dma_sectors = 0; +unsigned int scsi_dma_free_sectors = 0; +unsigned int scsi_need_isa_buffer = 0; +static unsigned char **dma_malloc_pages = NULL; + +/* + * Function: scsi_malloc + * + * Purpose: Allocate memory from the DMA-safe pool. + * + * Arguments: len - amount of memory we need. + * + * Lock status: No locks assumed to be held. This function is SMP-safe. + * + * Returns: Pointer to memory block. + * + * Notes: Prior to the new queue code, this function was not SMP-safe. + * This function can only allocate in units of sectors + * (i.e. 512 bytes). + * + * We cannot use the normal system allocator becuase we need + * to be able to guarantee that we can process a complete disk + * I/O request without touching the system allocator. Think + * about it - if the system were heavily swapping, and tried to + * write out a block of memory to disk, and the SCSI code needed + * to allocate more memory in order to be able to write the + * data to disk, you would wedge the system. + */ +void *scsi_malloc(unsigned int len) +{ + unsigned int nbits, mask; + unsigned long flags; + + int i, j; + if (len % SECTOR_SIZE != 0 || len > PAGE_SIZE) + return NULL; + + nbits = len >> 9; + mask = (1 << nbits) - 1; + + spin_lock_irqsave(&allocator_request_lock, flags); + + for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++) + for (j = 0; j <= SECTORS_PER_PAGE - nbits; j++) { + if ((dma_malloc_freelist[i] & (mask << j)) == 0) { + dma_malloc_freelist[i] |= (mask << j); + scsi_dma_free_sectors -= nbits; +#ifdef DEBUG + SCSI_LOG_MLQUEUE(3, printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9))); + printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9)); +#endif + spin_unlock_irqrestore(&allocator_request_lock, flags); + return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9)); + } + } + spin_unlock_irqrestore(&allocator_request_lock, flags); + return NULL; /* Nope. No more */ +} + +/* + * Function: scsi_free + * + * Purpose: Free memory into the DMA-safe pool. + * + * Arguments: ptr - data block we are freeing. + * len - size of block we are freeing. + * + * Lock status: No locks assumed to be held. This function is SMP-safe. + * + * Returns: Nothing + * + * Notes: This function *must* only be used to free memory + * allocated from scsi_malloc(). + * + * Prior to the new queue code, this function was not SMP-safe. + * This function can only allocate in units of sectors + * (i.e. 512 bytes). + */ +int scsi_free(void *obj, unsigned int len) +{ + unsigned int page, sector, nbits, mask; + unsigned long flags; + +#ifdef DEBUG + unsigned long ret = 0; + +#ifdef __mips__ + __asm__ __volatile__("move\t%0,$31":"=r"(ret)); +#else + ret = __builtin_return_address(0); +#endif + printk("scsi_free %p %d\n", obj, len); + SCSI_LOG_MLQUEUE(3, printk("SFree: %p %d\n", obj, len)); +#endif + + spin_lock_irqsave(&allocator_request_lock, flags); + + for (page = 0; page < dma_sectors / SECTORS_PER_PAGE; page++) { + unsigned long page_addr = (unsigned long) dma_malloc_pages[page]; + if ((unsigned long) obj >= page_addr && + (unsigned long) obj < page_addr + PAGE_SIZE) { + sector = (((unsigned long) obj) - page_addr) >> 9; + + nbits = len >> 9; + mask = (1 << nbits) - 1; + + if ((mask << sector) >= (1 << SECTORS_PER_PAGE)) + panic("scsi_free:Bad memory alignment"); + + if ((dma_malloc_freelist[page] & + (mask << sector)) != (mask << sector)) { +#ifdef DEBUG + printk("scsi_free(obj=%p, len=%d) called from %08lx\n", + obj, len, ret); +#endif + panic("scsi_free:Trying to free unused memory"); + } + scsi_dma_free_sectors += nbits; + dma_malloc_freelist[page] &= ~(mask << sector); + spin_unlock_irqrestore(&allocator_request_lock, flags); + return 0; + } + } + panic("scsi_free:Bad offset"); +} + + +/* + * Function: scsi_resize_dma_pool + * + * Purpose: Ensure that the DMA pool is sufficiently large to be + * able to guarantee that we can always process I/O requests + * without calling the system allocator. + * + * Arguments: None. + * + * Lock status: No locks assumed to be held. This function is SMP-safe. + * + * Returns: Nothing + * + * Notes: Prior to the new queue code, this function was not SMP-safe. + * Go through the device list and recompute the most appropriate + * size for the dma pool. Then grab more memory (as required). + */ +void scsi_resize_dma_pool(void) +{ + int i, k; + unsigned long size; + unsigned long flags; + struct Scsi_Host *shpnt; + struct Scsi_Host *host = NULL; + Scsi_Device *SDpnt; + FreeSectorBitmap *new_dma_malloc_freelist = NULL; + unsigned int new_dma_sectors = 0; + unsigned int new_need_isa_buffer = 0; + unsigned char **new_dma_malloc_pages = NULL; + int out_of_space = 0; + + spin_lock_irqsave(&allocator_request_lock, flags); + + if (!scsi_hostlist) { + /* + * Free up the DMA pool. + */ + if (scsi_dma_free_sectors != dma_sectors) + panic("SCSI DMA pool memory leak %d %d\n", scsi_dma_free_sectors, dma_sectors); + + for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++) + free_pages((unsigned long) dma_malloc_pages[i], 0); + if (dma_malloc_pages) + kfree((char *) dma_malloc_pages); + dma_malloc_pages = NULL; + if (dma_malloc_freelist) + kfree((char *) dma_malloc_freelist); + dma_malloc_freelist = NULL; + dma_sectors = 0; + scsi_dma_free_sectors = 0; + spin_unlock_irqrestore(&allocator_request_lock, flags); + return; + } + /* Next, check to see if we need to extend the DMA buffer pool */ + + new_dma_sectors = 2 * SECTORS_PER_PAGE; /* Base value we use */ + + if (__pa(high_memory) - 1 > ISA_DMA_THRESHOLD) + need_isa_bounce_buffers = 1; + else + need_isa_bounce_buffers = 0; + + if (scsi_devicelist) + for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) + new_dma_sectors += SECTORS_PER_PAGE; /* Increment for each host */ + + for (host = scsi_hostlist; host; host = host->next) { + for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) { + /* + * sd and sr drivers allocate scatterlists. + * sr drivers may allocate for each command 1x2048 or 2x1024 extra + * buffers for 2k sector size and 1k fs. + * sg driver allocates buffers < 4k. + * st driver does not need buffers from the dma pool. + * estimate 4k buffer/command for devices of unknown type (should panic). + */ + if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM || + SDpnt->type == TYPE_DISK || SDpnt->type == TYPE_MOD) { + int nents = host->sg_tablesize; +#ifdef DMA_CHUNK_SIZE + /* If the architecture does DMA sg merging, make sure + we count with at least 64 entries even for HBAs + which handle very few sg entries. */ + if (nents < 64) nents = 64; +#endif + new_dma_sectors += ((nents * + sizeof(struct scatterlist) + 511) >> 9) * + SDpnt->queue_depth; + if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM) + new_dma_sectors += (2048 >> 9) * SDpnt->queue_depth; + } else if (SDpnt->type == TYPE_SCANNER || + SDpnt->type == TYPE_PROCESSOR || + SDpnt->type == TYPE_MEDIUM_CHANGER || + SDpnt->type == TYPE_ENCLOSURE) { + new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth; + } else { + if (SDpnt->type != TYPE_TAPE) { + printk("resize_dma_pool: unknown device type %d\n", SDpnt->type); + new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth; + } + } + + if (host->unchecked_isa_dma && + need_isa_bounce_buffers && + SDpnt->type != TYPE_TAPE) { + new_dma_sectors += (PAGE_SIZE >> 9) * host->sg_tablesize * + SDpnt->queue_depth; + new_need_isa_buffer++; + } + } + } + +#ifdef DEBUG_INIT + printk("resize_dma_pool: needed dma sectors = %d\n", new_dma_sectors); +#endif + + /* limit DMA memory to 32MB: */ + new_dma_sectors = (new_dma_sectors + 15) & 0xfff0; + + /* + * We never shrink the buffers - this leads to + * race conditions that I would rather not even think + * about right now. + */ +#if 0 /* Why do this? No gain and risks out_of_space */ + if (new_dma_sectors < dma_sectors) + new_dma_sectors = dma_sectors; +#endif + if (new_dma_sectors <= dma_sectors) { + spin_unlock_irqrestore(&allocator_request_lock, flags); + return; /* best to quit while we are in front */ + } + + for (k = 0; k < 20; ++k) { /* just in case */ + out_of_space = 0; + size = (new_dma_sectors / SECTORS_PER_PAGE) * + sizeof(FreeSectorBitmap); + new_dma_malloc_freelist = (FreeSectorBitmap *) + kmalloc(size, GFP_ATOMIC); + if (new_dma_malloc_freelist) { + memset(new_dma_malloc_freelist, 0, size); + size = (new_dma_sectors / SECTORS_PER_PAGE) * + sizeof(*new_dma_malloc_pages); + new_dma_malloc_pages = (unsigned char **) + kmalloc(size, GFP_ATOMIC); + if (!new_dma_malloc_pages) { + size = (new_dma_sectors / SECTORS_PER_PAGE) * + sizeof(FreeSectorBitmap); + kfree((char *) new_dma_malloc_freelist); + out_of_space = 1; + } else { + memset(new_dma_malloc_pages, 0, size); + } + } else + out_of_space = 1; + + if ((!out_of_space) && (new_dma_sectors > dma_sectors)) { + for (i = dma_sectors / SECTORS_PER_PAGE; + i < new_dma_sectors / SECTORS_PER_PAGE; i++) { + new_dma_malloc_pages[i] = (unsigned char *) + __get_free_pages(GFP_ATOMIC | GFP_DMA, 0); + if (!new_dma_malloc_pages[i]) + break; + } + if (i != new_dma_sectors / SECTORS_PER_PAGE) { /* clean up */ + int k = i; + + out_of_space = 1; + for (i = 0; i < k; ++i) + free_pages((unsigned long) new_dma_malloc_pages[i], 0); + } + } + if (out_of_space) { /* try scaling down new_dma_sectors request */ + printk("scsi::resize_dma_pool: WARNING, dma_sectors=%u, " + "wanted=%u, scaling\n", dma_sectors, new_dma_sectors); + if (new_dma_sectors < (8 * SECTORS_PER_PAGE)) + break; /* pretty well hopeless ... */ + new_dma_sectors = (new_dma_sectors * 3) / 4; + new_dma_sectors = (new_dma_sectors + 15) & 0xfff0; + if (new_dma_sectors <= dma_sectors) + break; /* stick with what we have got */ + } else + break; /* found space ... */ + } /* end of for loop */ + if (out_of_space) { + spin_unlock_irqrestore(&allocator_request_lock, flags); + scsi_need_isa_buffer = new_need_isa_buffer; /* some useful info */ + printk(" WARNING, not enough memory, pool not expanded\n"); + return; + } + /* When we dick with the actual DMA list, we need to + * protect things + */ + if (dma_malloc_freelist) { + size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(FreeSectorBitmap); + memcpy(new_dma_malloc_freelist, dma_malloc_freelist, size); + kfree((char *) dma_malloc_freelist); + } + dma_malloc_freelist = new_dma_malloc_freelist; + + if (dma_malloc_pages) { + size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages); + memcpy(new_dma_malloc_pages, dma_malloc_pages, size); + kfree((char *) dma_malloc_pages); + } + scsi_dma_free_sectors += new_dma_sectors - dma_sectors; + dma_malloc_pages = new_dma_malloc_pages; + dma_sectors = new_dma_sectors; + scsi_need_isa_buffer = new_need_isa_buffer; + + spin_unlock_irqrestore(&allocator_request_lock, flags); + +#ifdef DEBUG_INIT + printk("resize_dma_pool: dma free sectors = %d\n", scsi_dma_free_sectors); + printk("resize_dma_pool: dma sectors = %d\n", dma_sectors); + printk("resize_dma_pool: need isa buffers = %d\n", scsi_need_isa_buffer); +#endif +} + +/* + * Function: scsi_init_minimal_dma_pool + * + * Purpose: Allocate a minimal (1-page) DMA pool. + * + * Arguments: None. + * + * Lock status: No locks assumed to be held. This function is SMP-safe. + * + * Returns: Nothing + * + * Notes: + */ +int scsi_init_minimal_dma_pool(void) +{ + unsigned long size; + unsigned long flags; + int has_space = 0; + + spin_lock_irqsave(&allocator_request_lock, flags); + + dma_sectors = PAGE_SIZE / SECTOR_SIZE; + scsi_dma_free_sectors = dma_sectors; + /* + * Set up a minimal DMA buffer list - this will be used during scan_scsis + * in some cases. + */ + + /* One bit per sector to indicate free/busy */ + size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(FreeSectorBitmap); + dma_malloc_freelist = (FreeSectorBitmap *) + kmalloc(size, GFP_ATOMIC); + if (dma_malloc_freelist) { + memset(dma_malloc_freelist, 0, size); + /* One pointer per page for the page list */ + dma_malloc_pages = (unsigned char **) kmalloc( + (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages), + GFP_ATOMIC); + if (dma_malloc_pages) { + memset(dma_malloc_pages, 0, size); + dma_malloc_pages[0] = (unsigned char *) + __get_free_pages(GFP_ATOMIC | GFP_DMA, 0); + if (dma_malloc_pages[0]) + has_space = 1; + } + } + if (!has_space) { + if (dma_malloc_freelist) { + kfree((char *) dma_malloc_freelist); + if (dma_malloc_pages) + kfree((char *) dma_malloc_pages); + } + spin_unlock_irqrestore(&allocator_request_lock, flags); + printk("scsi::init_module: failed, out of memory\n"); + return 1; + } + + spin_unlock_irqrestore(&allocator_request_lock, flags); + return 0; +} diff -ur --new-file old/linux/drivers/scsi/scsi_ioctl.c new/linux/drivers/scsi/scsi_ioctl.c --- old/linux/drivers/scsi/scsi_ioctl.c Fri Jan 7 20:55:28 2000 +++ new/linux/drivers/scsi/scsi_ioctl.c Fri Jan 21 18:48:12 2000 @@ -90,18 +90,6 @@ * The output area is then filled in starting from the command byte. */ -static void scsi_ioctl_done(Scsi_Cmnd * SCpnt) -{ - struct request *req; - - req = &SCpnt->request; - req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ - - if (req->sem != NULL) { - up(req->sem); - } -} - static int ioctl_internal_command(Scsi_Device * dev, char *cmd, int timeout, int retries) { @@ -117,7 +105,7 @@ return -EINTR; } - scsi_wait_cmd(SCpnt, cmd, NULL, 0, scsi_ioctl_done, timeout, retries); + scsi_wait_cmd(SCpnt, cmd, NULL, 0, timeout, retries); SCSI_LOG_IOCTL(2, printk("Ioctl returned 0x%x\n", SCpnt->result)); @@ -201,7 +189,7 @@ int scsi_ioctl_send_command(Scsi_Device * dev, Scsi_Ioctl_Command * sic) { char *buf; - unsigned char cmd[12]; + unsigned char cmd[MAX_COMMAND_SIZE]; char *cmd_in; Scsi_Cmnd *SCpnt; Scsi_Device *SDpnt; @@ -300,8 +288,7 @@ return -EINTR; } - scsi_wait_cmd(SCpnt, cmd, buf, needed, scsi_ioctl_done, - timeout, retries); + scsi_wait_cmd(SCpnt, cmd, buf, needed, timeout, retries); /* * If there was an error condition, pass the info back to the user. @@ -358,7 +345,7 @@ int scsi_ioctl(Scsi_Device * dev, int cmd, void *arg) { int result; - char scsi_cmd[12]; + char scsi_cmd[MAX_COMMAND_SIZE]; /* No idea how this happens.... */ if (!dev) diff -ur --new-file old/linux/drivers/scsi/scsi_lib.c new/linux/drivers/scsi/scsi_lib.c --- old/linux/drivers/scsi/scsi_lib.c Fri Jan 21 00:15:22 2000 +++ new/linux/drivers/scsi/scsi_lib.c Fri Jan 21 18:48:12 2000 @@ -51,6 +51,13 @@ */ /* + * For hosts that request single-file access to the ISA bus, this is a pointer to + * the currently active host. + */ +volatile struct Scsi_Host *host_active = NULL; + + +/* * Function: scsi_insert_special_cmd() * * Purpose: Insert pre-formed command into request queue. @@ -184,6 +191,7 @@ return 1; } + /* * Function: scsi_queue_next_request() * @@ -202,6 +210,23 @@ * If SCpnt is NULL, it means that the previous command * was completely finished, and we should simply start * a new command, if possible. + * + * This is where a lot of special case code has begun to + * accumulate. It doesn't really affect readability or + * anything, but it might be considered architecturally + * inelegant. If more of these special cases start to + * accumulate, I am thinking along the lines of implementing + * an atexit() like technology that gets run when commands + * complete. I am not convinced that it is worth the + * added overhead, however. Right now as things stand, + * there are simple conditional checks, and most hosts + * would skip past. + * + * Another possible solution would be to tailor different + * handler functions, sort of like what we did in scsi_merge.c. + * This is probably a better solution, but the number of different + * permutations grows as 2**N, and if too many more special cases + * get added, we start to get screwed. */ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) { diff -ur --new-file old/linux/drivers/scsi/scsi_merge.c new/linux/drivers/scsi/scsi_merge.c --- old/linux/drivers/scsi/scsi_merge.c Sat Jan 8 21:57:44 2000 +++ new/linux/drivers/scsi/scsi_merge.c Thu Jan 27 17:58:15 2000 @@ -5,6 +5,7 @@ * Initial versions: Eric Youngdale (eric@andante.org). * Based upon conversations with large numbers * of people at Linux Expo. + * Support for dynamic DMA mapping: Jakub Jelinek (jakub@redhat.com). */ /* @@ -55,6 +56,7 @@ #include #include #include +#include #include "scsi.h" #include "hosts.h" @@ -303,6 +305,10 @@ SHpnt->unchecked_isa_dma, NULL); } +#define MERGEABLE_BUFFERS(X,Y) \ +(((((long)(X)->b_data+(X)->b_size)|((long)(Y)->b_data)) & \ + (DMA_CHUNK_SIZE - 1)) == 0) + /* * Function: __scsi_merge_fn() * @@ -369,7 +375,7 @@ */ if (dma_host && virt_to_phys(req->bhtail->b_data) - 1 == ISA_DMA_THRESHOLD) { - goto new_segment; + goto new_end_segment; } if (CONTIGUOUS_BUFFERS(req->bhtail, bh)) { #ifdef DMA_SEGMENT_SIZE_LIMITED @@ -377,9 +383,8 @@ && virt_to_phys(bh->b_data) - 1 >= ISA_DMA_THRESHOLD ) { segment_size = 0; count = __count_segments(req, use_clustering, dma_host, &segment_size); - if( segment_size + bh->b_size > PAGE_SIZE ) - { - goto new_segment; + if( segment_size + bh->b_size > PAGE_SIZE ) { + goto new_end_segment; } } #endif @@ -389,8 +394,17 @@ return 1; } } + new_end_segment: +#ifdef DMA_CHUNK_SIZE + if (MERGEABLE_BUFFERS(req->bhtail, bh)) + goto new_mergeable; +#endif goto new_segment; - } else if (req->sector - count == sector) { + } else { + if (req->sector - count != sector) { + /* Attempt to merge sector that doesn't belong */ + BUG(); + } if (use_clustering) { /* * See if we can do this without creating another @@ -400,7 +414,7 @@ */ if (dma_host && virt_to_phys(bh->b_data) - 1 == ISA_DMA_THRESHOLD) { - goto new_segment; + goto new_start_segment; } if (CONTIGUOUS_BUFFERS(bh, req->bh)) { #ifdef DMA_SEGMENT_SIZE_LIMITED @@ -409,7 +423,7 @@ segment_size = bh->b_size; count = __count_segments(req, use_clustering, dma_host, &segment_size); if( count != req->nr_segments ) { - goto new_segment; + goto new_start_segment; } } #endif @@ -419,10 +433,41 @@ return 1; } } + new_start_segment: +#ifdef DMA_CHUNK_SIZE + if (MERGEABLE_BUFFERS(bh, req->bh)) + goto new_mergeable; +#endif goto new_segment; - } else { - panic("Attempt to merge sector that doesn't belong"); } +#ifdef DMA_CHUNK_SIZE + new_mergeable: + /* + * pci_map_sg will be able to merge these two + * into a single hardware sg entry, check if + * we'll have enough memory for the sg list. + * scsi.c allocates for this purpose + * min(64,sg_tablesize) entries. + */ + if (req->nr_segments >= 64 && + req->nr_segments >= SHpnt->sg_tablesize) + return 0; + req->nr_segments++; + return 1; + new_segment: + /* + * pci_map_sg won't be able to map these two + * into a single hardware sg entry, so we have to + * check if things fit into sg_tablesize. + */ + if (req->nr_hw_segments >= SHpnt->sg_tablesize || + (req->nr_segments >= 64 && + req->nr_segments >= SHpnt->sg_tablesize)) + return 0; + req->nr_hw_segments++; + req->nr_segments++; + return 1; +#else new_segment: if (req->nr_segments < SHpnt->sg_tablesize) { /* @@ -434,6 +479,7 @@ } else { return 0; } +#endif } /* @@ -464,8 +510,10 @@ return ret; \ } +/* Version with use_clustering 0 and dma_host 1 is not necessary, + * since the only use of dma_host above is protected by use_clustering. + */ MERGEFCT(scsi_merge_fn_, 0, 0) -MERGEFCT(scsi_merge_fn_d, 0, 1) MERGEFCT(scsi_merge_fn_c, 1, 0) MERGEFCT(scsi_merge_fn_dc, 1, 1) /* @@ -513,6 +561,18 @@ SDpnt = (Scsi_Device *) q->queuedata; SHpnt = SDpnt->host; +#ifdef DMA_CHUNK_SIZE + /* If it would not fit into prepared memory space for sg chain, + * then don't allow the merge. + */ + if (req->nr_segments + next->nr_segments - 1 > 64 && + req->nr_segments + next->nr_segments - 1 > SHpnt->sg_tablesize) { + return 0; + } + if (req->nr_hw_segments + next->nr_hw_segments - 1 > SHpnt->sg_tablesize) { + return 0; + } +#else /* * If the two requests together are too large (even assuming that we * can merge the boundary requests into one segment, then don't @@ -521,6 +581,7 @@ if (req->nr_segments + next->nr_segments - 1 > SHpnt->sg_tablesize) { return 0; } +#endif /* * The main question is whether the two segments at the boundaries * would be considered one or two. @@ -560,10 +621,32 @@ * This one is OK. Let it go. */ req->nr_segments += next->nr_segments - 1; +#ifdef DMA_CHUNK_SIZE + req->nr_hw_segments += next->nr_hw_segments - 1; +#endif return 1; } } dont_combine: +#ifdef DMA_CHUNK_SIZE + if (req->nr_segments + next->nr_segments > 64 && + req->nr_segments + next->nr_segments > SHpnt->sg_tablesize) { + return 0; + } + /* If dynamic DMA mapping can merge last segment in req with + * first segment in next, then the check for hw segments was + * done above already, so we can always merge. + */ + if (MERGEABLE_BUFFERS (req->bhtail, next->bh)) { + req->nr_hw_segments += next->nr_hw_segments - 1; + } else if (req->nr_hw_segments + next->nr_hw_segments > SHpnt->sg_tablesize) { + return 0; + } else { + req->nr_hw_segments += next->nr_hw_segments; + } + req->nr_segments += next->nr_segments; + return 1; +#else /* * We know that the two requests at the boundary should not be combined. * Make sure we can fix something that is the sum of the two. @@ -579,6 +662,7 @@ req->nr_segments += next->nr_segments; return 1; } +#endif } /* @@ -609,8 +693,10 @@ return ret; \ } +/* Version with use_clustering 0 and dma_host 1 is not necessary, + * since the only use of dma_host above is protected by use_clustering. + */ MERGEREQFCT(scsi_merge_requests_fn_, 0, 0) -MERGEREQFCT(scsi_merge_requests_fn_d, 0, 1) MERGEREQFCT(scsi_merge_requests_fn_c, 1, 0) MERGEREQFCT(scsi_merge_requests_fn_dc, 1, 1) /* @@ -737,7 +823,7 @@ * Next, walk the list, and fill in the addresses and sizes of * each segment. */ - memset(sgpnt, 0, SCpnt->sglist_len); + memset(sgpnt, 0, SCpnt->use_sg * sizeof(struct scatterlist)); SCpnt->request_buffer = (char *) sgpnt; SCpnt->request_bufflen = 0; bhprev = NULL; @@ -983,9 +1069,10 @@ * If the host has already selected a merge manager, then don't * pick a new one. */ - if (q->merge_fn != NULL) { +#if 0 + if (q->merge_fn != NULL) return; - } +#endif /* * If this host has an unlimited tablesize, then don't bother with a * merge manager. The whole point of the operation is to make sure @@ -1002,8 +1089,8 @@ q->merge_requests_fn = scsi_merge_requests_fn_; SDpnt->scsi_init_io_fn = scsi_init_io_v; } else if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma != 0) { - q->merge_fn = scsi_merge_fn_d; - q->merge_requests_fn = scsi_merge_requests_fn_d; + q->merge_fn = scsi_merge_fn_; + q->merge_requests_fn = scsi_merge_requests_fn_; SDpnt->scsi_init_io_fn = scsi_init_io_vd; } else if (CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma == 0) { q->merge_fn = scsi_merge_fn_c; diff -ur --new-file old/linux/drivers/scsi/scsi_obsolete.c new/linux/drivers/scsi/scsi_obsolete.c --- old/linux/drivers/scsi/scsi_obsolete.c Fri Jan 7 20:55:28 2000 +++ new/linux/drivers/scsi/scsi_obsolete.c Fri Jan 21 18:48:12 2000 @@ -132,7 +132,6 @@ /* * Flag bits for the internal_timeout array */ -#define NORMAL_TIMEOUT 0 #define IN_ABORT 1 #define IN_RESET 2 #define IN_RESET2 4 diff -ur --new-file old/linux/drivers/scsi/scsi_scan.c new/linux/drivers/scsi/scsi_scan.c --- old/linux/drivers/scsi/scsi_scan.c Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/scsi/scsi_scan.c Fri Jan 21 18:48:12 2000 @@ -0,0 +1,820 @@ +/* + * scsi_scan.c Copyright (C) 2000 Eric Youngdale + * + * Bus scan logic. + * + * This used to live in scsi.c, but that file was just a laundry basket + * full of misc stuff. This got separated out in order to make things + * clearer. + */ + +#define __NO_VERSION__ +#include +#include +#include + +#include + +#include "scsi.h" +#include "hosts.h" +#include "constants.h" + +#ifdef CONFIG_KMOD +#include +#endif + +/* The following devices are known not to tolerate a lun != 0 scan for + * one reason or another. Some will respond to all luns, others will + * lock up. + */ + +#define BLIST_NOLUN 0x001 +#define BLIST_FORCELUN 0x002 +#define BLIST_BORKEN 0x004 +#define BLIST_KEY 0x008 +#define BLIST_SINGLELUN 0x010 +#define BLIST_NOTQ 0x020 +#define BLIST_SPARSELUN 0x040 +#define BLIST_MAX5LUN 0x080 +#define BLIST_ISDISK 0x100 +#define BLIST_ISROM 0x200 +#define BLIST_GHOST 0x400 + +static void print_inquiry(unsigned char *data); +static int scan_scsis_single(int channel, int dev, int lun, int *max_scsi_dev, + int *sparse_lun, Scsi_Device ** SDpnt, Scsi_Cmnd * SCpnt, + struct Scsi_Host *shpnt, char *scsi_result); + +struct dev_info { + const char *vendor; + const char *model; + const char *revision; /* Latest revision known to be bad. Not used yet */ + unsigned flags; +}; + +/* + * This is what was previously known as the blacklist. The concept + * has been expanded so that we can specify other types of things we + * need to be aware of. + */ +static struct dev_info device_list[] = +{ + {"Aashima", "IMAGERY 2400SP", "1.03", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ + {"CHINON", "CD-ROM CDS-431", "H42", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ + {"CHINON", "CD-ROM CDS-535", "Q14", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ + {"DENON", "DRD-25X", "V", BLIST_NOLUN}, /* Locks up if probed for lun != 0 */ + {"HITACHI", "DK312C", "CM81", BLIST_NOLUN}, /* Responds to all lun - dtg */ + {"HITACHI", "DK314C", "CR21", BLIST_NOLUN}, /* responds to all lun */ + {"IMS", "CDD521/10", "2.06", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */ + {"MAXTOR", "XT-3280", "PR02", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */ + {"MAXTOR", "XT-4380S", "B3C", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */ + {"MAXTOR", "MXT-1240S", "I1.2", BLIST_NOLUN}, /* Locks up when LUN>0 polled */ + {"MAXTOR", "XT-4170S", "B5A", BLIST_NOLUN}, /* Locks-up sometimes when LUN>0 polled. */ + {"MAXTOR", "XT-8760S", "B7B", BLIST_NOLUN}, /* guess what? */ + {"MEDIAVIS", "RENO CD-ROMX2A", "2.03", BLIST_NOLUN}, /*Responds to all lun */ + {"MICROP", "4110", "*", BLIST_NOTQ}, /* Buggy Tagged Queuing */ + {"NEC", "CD-ROM DRIVE:841", "1.0", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */ + {"PHILIPS", "PCA80SC", "V4-2", BLIST_NOLUN}, /* Responds to all lun */ + {"RODIME", "RO3000S", "2.33", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ + {"SANYO", "CRD-250S", "1.20", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1 + * for aha152x controller, which causes + * SCSI code to reset bus.*/ + {"SEAGATE", "ST157N", "\004|j", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1 + * for aha152x controller, which causes + * SCSI code to reset bus.*/ + {"SEAGATE", "ST296", "921", BLIST_NOLUN}, /* Responds to all lun */ + {"SEAGATE", "ST1581", "6538", BLIST_NOLUN}, /* Responds to all lun */ + {"SONY", "CD-ROM CDU-541", "4.3d", BLIST_NOLUN}, + {"SONY", "CD-ROM CDU-55S", "1.0i", BLIST_NOLUN}, + {"SONY", "CD-ROM CDU-561", "1.7x", BLIST_NOLUN}, + {"SONY", "CD-ROM CDU-8012", "*", BLIST_NOLUN}, + {"TANDBERG", "TDC 3600", "U07", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ + {"TEAC", "CD-R55S", "1.0H", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ + {"TEAC", "CD-ROM", "1.06", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1 + * for seagate controller, which causes + * SCSI code to reset bus.*/ + {"TEAC", "MT-2ST/45S2-27", "RV M", BLIST_NOLUN}, /* Responds to all lun */ + {"TEXEL", "CD-ROM", "1.06", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1 + * for seagate controller, which causes + * SCSI code to reset bus.*/ + {"QUANTUM", "LPS525S", "3110", BLIST_NOLUN}, /* Locks sometimes if polled for lun != 0 */ + {"QUANTUM", "PD1225S", "3110", BLIST_NOLUN}, /* Locks sometimes if polled for lun != 0 */ + {"QUANTUM", "FIREBALL ST4.3S", "0F0C", BLIST_NOLUN}, /* Locks up when polled for lun != 0 */ + {"MEDIAVIS", "CDR-H93MV", "1.31", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ + {"SANKYO", "CP525", "6.64", BLIST_NOLUN}, /* causes failed REQ SENSE, extra reset */ + {"HP", "C1750A", "3226", BLIST_NOLUN}, /* scanjet iic */ + {"HP", "C1790A", "", BLIST_NOLUN}, /* scanjet iip */ + {"HP", "C2500A", "", BLIST_NOLUN}, /* scanjet iicx */ + {"YAMAHA", "CDR100", "1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ + {"YAMAHA", "CDR102", "1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 + * extra reset */ + {"RELISYS", "Scorpio", "*", BLIST_NOLUN}, /* responds to all LUN */ + {"MICROTEK", "ScanMaker II", "5.61", BLIST_NOLUN}, /* responds to all LUN */ + +/* + * Other types of devices that have special flags. + */ + {"SONY", "CD-ROM CDU-8001", "*", BLIST_BORKEN}, + {"TEXEL", "CD-ROM", "1.06", BLIST_BORKEN}, + {"IOMEGA", "Io20S *F", "*", BLIST_KEY}, + {"INSITE", "Floptical F*8I", "*", BLIST_KEY}, + {"INSITE", "I325VM", "*", BLIST_KEY}, + {"NRC", "MBR-7", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, + {"NRC", "MBR-7.4", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, + {"REGAL", "CDC-4X", "*", BLIST_MAX5LUN | BLIST_SINGLELUN}, + {"NAKAMICH", "MJ-4.8S", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, + {"NAKAMICH", "MJ-5.16S", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, + {"PIONEER", "CD-ROM DRM-600", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, + {"PIONEER", "CD-ROM DRM-602X", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, + {"PIONEER", "CD-ROM DRM-604X", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, + {"EMULEX", "MD21/S2 ESDI", "*", BLIST_SINGLELUN}, + {"CANON", "IPUBJD", "*", BLIST_SPARSELUN}, + {"nCipher", "Fastness Crypto", "*", BLIST_FORCELUN}, + {"NEC", "PD-1 ODX654P", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, + {"MATSHITA", "PD-1", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, + {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN}, + {"CREATIVE","DVD-RAM RAM","*", BLIST_GHOST}, + {"MATSHITA","PD-2 LF-D100","*", BLIST_GHOST}, + {"HITACHI", "GF-1050","*", BLIST_GHOST}, /* Hitachi SCSI DVD-RAM */ + {"TOSHIBA","CDROM","*", BLIST_ISROM}, + {"TOSHIBA","DVD-RAM SD-W1101","*", BLIST_GHOST}, + {"TOSHIBA","DVD-RAM SD-W1111","*", BLIST_GHOST}, + + /* + * Must be at end of list... + */ + {NULL, NULL, NULL} +}; + +#ifdef CONFIG_SCSI_MULTI_LUN +static int max_scsi_luns = 8; +#else +static int max_scsi_luns = 1; +#endif + +#ifdef MODULE + +MODULE_PARM(max_scsi_luns, "i"); +MODULE_PARM_DESC(max_scsi_luns, "last scsi LUN (should be between 1 and 8)"); + +#else + +static int __init scsi_luns_setup(char *str) +{ + int tmp; + + if (get_option(&str, &tmp) == 1) { + max_scsi_luns = tmp; + return 1; + } else { + printk("scsi_luns_setup : usage max_scsi_luns=n " + "(n should be between 1 and 8)\n"); + return 0; + } +} + +__setup("max_scsi_luns=", scsi_luns_setup); + +#endif + +static void print_inquiry(unsigned char *data) +{ + int i; + + printk(" Vendor: "); + for (i = 8; i < 16; i++) { + if (data[i] >= 0x20 && i < data[4] + 5) + printk("%c", data[i]); + else + printk(" "); + } + + printk(" Model: "); + for (i = 16; i < 32; i++) { + if (data[i] >= 0x20 && i < data[4] + 5) + printk("%c", data[i]); + else + printk(" "); + } + + printk(" Rev: "); + for (i = 32; i < 36; i++) { + if (data[i] >= 0x20 && i < data[4] + 5) + printk("%c", data[i]); + else + printk(" "); + } + + printk("\n"); + + i = data[0] & 0x1f; + + printk(" Type: %s ", + i < MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] : "Unknown "); + printk(" ANSI SCSI revision: %02x", data[2] & 0x07); + if ((data[2] & 0x07) == 1 && (data[3] & 0x0f) == 1) + printk(" CCS\n"); + else + printk("\n"); +} + +static int get_device_flags(unsigned char *response_data) +{ + int i = 0; + unsigned char *pnt; + for (i = 0; 1; i++) { + if (device_list[i].vendor == NULL) + return 0; + pnt = &response_data[8]; + while (*pnt && *pnt == ' ') + pnt++; + if (memcmp(device_list[i].vendor, pnt, + strlen(device_list[i].vendor))) + continue; + pnt = &response_data[16]; + while (*pnt && *pnt == ' ') + pnt++; + if (memcmp(device_list[i].model, pnt, + strlen(device_list[i].model))) + continue; + return device_list[i].flags; + } + return 0; +} + +/* + * Detecting SCSI devices : + * We scan all present host adapter's busses, from ID 0 to ID (max_id). + * We use the INQUIRY command, determine device type, and pass the ID / + * lun address of all sequential devices to the tape driver, all random + * devices to the disk driver. + */ +void scan_scsis(struct Scsi_Host *shpnt, + unchar hardcoded, + unchar hchannel, + unchar hid, + unchar hlun) +{ + int channel; + int dev; + int lun; + int max_dev_lun; + Scsi_Cmnd *SCpnt; + unsigned char *scsi_result; + unsigned char scsi_result0[256]; + Scsi_Device *SDpnt; + Scsi_Device *SDtail; + int sparse_lun; + + scsi_result = NULL; + SCpnt = (Scsi_Cmnd *) kmalloc(sizeof(Scsi_Cmnd), + GFP_ATOMIC | GFP_DMA); + if (SCpnt) { + memset(SCpnt, 0, sizeof(Scsi_Cmnd)); + SDpnt = (Scsi_Device *) kmalloc(sizeof(Scsi_Device), + GFP_ATOMIC); + if (SDpnt) { + memset(SDpnt, 0, sizeof(Scsi_Device)); + /* + * Register the queue for the device. All I/O requests will come + * in through here. We also need to register a pointer to + * ourselves, since the queue handler won't know what device + * the queue actually represents. We could look it up, but it + * is pointless work. + */ + blk_init_queue(&SDpnt->request_queue, scsi_get_request_handler(SDpnt, shpnt)); + blk_queue_headactive(&SDpnt->request_queue, 0); + SDpnt->request_queue.queuedata = (void *) SDpnt; + /* Make sure we have something that is valid for DMA purposes */ + scsi_result = ((!shpnt->unchecked_isa_dma) + ? &scsi_result0[0] : kmalloc(512, GFP_DMA)); + } + } + if (scsi_result == NULL) { + printk("Unable to obtain scsi_result buffer\n"); + goto leave; + } + /* + * We must chain ourself in the host_queue, so commands can time out + */ + SCpnt->next = NULL; + SDpnt->device_queue = SCpnt; + SDpnt->host = shpnt; + SDpnt->online = TRUE; + + initialize_merge_fn(SDpnt); + + /* + * Initialize the object that we will use to wait for command blocks. + */ + init_waitqueue_head(&SDpnt->scpnt_wait); + + /* + * Next, hook the device to the host in question. + */ + SDpnt->prev = NULL; + SDpnt->next = NULL; + if (shpnt->host_queue != NULL) { + SDtail = shpnt->host_queue; + while (SDtail->next != NULL) + SDtail = SDtail->next; + + SDtail->next = SDpnt; + SDpnt->prev = SDtail; + } else { + shpnt->host_queue = SDpnt; + } + + /* + * We need to increment the counter for this one device so we can track when + * things are quiet. + */ + atomic_inc(&shpnt->host_active); + atomic_inc(&SDpnt->device_active); + + if (hardcoded == 1) { + Scsi_Device *oldSDpnt = SDpnt; + struct Scsi_Device_Template *sdtpnt; + channel = hchannel; + if (channel > shpnt->max_channel) + goto leave; + dev = hid; + if (dev >= shpnt->max_id) + goto leave; + lun = hlun; + if (lun >= shpnt->max_lun) + goto leave; + scan_scsis_single(channel, dev, lun, &max_dev_lun, &sparse_lun, + &SDpnt, SCpnt, shpnt, scsi_result); + if (SDpnt != oldSDpnt) { + + /* it could happen the blockdevice hasn't yet been inited */ + for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next) + if (sdtpnt->init && sdtpnt->dev_noticed) + (*sdtpnt->init) (); + + for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next) { + if (sdtpnt->attach) { + (*sdtpnt->attach) (oldSDpnt); + if (oldSDpnt->attached) { + scsi_build_commandblocks(oldSDpnt); + if (0 == oldSDpnt->has_cmdblocks) { + printk("scan_scsis: DANGER, no command blocks\n"); + /* What to do now ?? */ + } + } + } + } + scsi_resize_dma_pool(); + + for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next) { + if (sdtpnt->finish && sdtpnt->nr_dev) { + (*sdtpnt->finish) (); + } + } + } + } else { + /* Actual LUN. PC ordering is 0->n IBM/spec ordering is n->0 */ + int order_dev; + + for (channel = 0; channel <= shpnt->max_channel; channel++) { + for (dev = 0; dev < shpnt->max_id; ++dev) { + if (shpnt->reverse_ordering) + /* Shift to scanning 15,14,13... or 7,6,5,4, */ + order_dev = shpnt->max_id - dev - 1; + else + order_dev = dev; + + if (shpnt->this_id != order_dev) { + + /* + * We need the for so our continue, etc. work fine. We put this in + * a variable so that we can override it during the scan if we + * detect a device *KNOWN* to have multiple logical units. + */ + max_dev_lun = (max_scsi_luns < shpnt->max_lun ? + max_scsi_luns : shpnt->max_lun); + sparse_lun = 0; + for (lun = 0; lun < max_dev_lun; ++lun) { + if (!scan_scsis_single(channel, order_dev, lun, &max_dev_lun, + &sparse_lun, &SDpnt, SCpnt, shpnt, + scsi_result) + && !sparse_lun) + break; /* break means don't probe further for luns!=0 */ + } /* for lun ends */ + } /* if this_id != id ends */ + } /* for dev ends */ + } /* for channel ends */ + } /* if/else hardcoded */ + + /* + * We need to decrement the counter for this one device + * so we know when everything is quiet. + */ + atomic_dec(&shpnt->host_active); + atomic_dec(&SDpnt->device_active); + + leave: + + { /* Unchain SCpnt from host_queue */ + Scsi_Device *prev, *next; + Scsi_Device *dqptr; + + for (dqptr = shpnt->host_queue; dqptr != SDpnt; dqptr = dqptr->next) + continue; + if (dqptr) { + prev = dqptr->prev; + next = dqptr->next; + if (prev) + prev->next = next; + else + shpnt->host_queue = next; + if (next) + next->prev = prev; + } + } + + /* Last device block does not exist. Free memory. */ + if (SDpnt != NULL) + kfree((char *) SDpnt); + + if (SCpnt != NULL) + kfree((char *) SCpnt); + + /* If we allocated a buffer so we could do DMA, free it now */ + if (scsi_result != &scsi_result0[0] && scsi_result != NULL) { + kfree(scsi_result); + } { + Scsi_Device *sdev; + Scsi_Cmnd *scmd; + + SCSI_LOG_SCAN_BUS(4, printk("Host status for host %p:\n", shpnt)); + for (sdev = shpnt->host_queue; sdev; sdev = sdev->next) { + SCSI_LOG_SCAN_BUS(4, printk("Device %d %p: ", sdev->id, sdev)); + for (scmd = sdev->device_queue; scmd; scmd = scmd->next) { + SCSI_LOG_SCAN_BUS(4, printk("%p ", scmd)); + } + SCSI_LOG_SCAN_BUS(4, printk("\n")); + } + } +} + +/* + * The worker for scan_scsis. + * Returning 0 means Please don't ask further for lun!=0, 1 means OK go on. + * Global variables used : scsi_devices(linked list) + */ +int scan_scsis_single(int channel, int dev, int lun, int *max_dev_lun, + int *sparse_lun, Scsi_Device ** SDpnt2, Scsi_Cmnd * SCpnt, + struct Scsi_Host *shpnt, char *scsi_result) +{ + unsigned char scsi_cmd[MAX_COMMAND_SIZE]; + struct Scsi_Device_Template *sdtpnt; + Scsi_Device *SDtail, *SDpnt = *SDpnt2; + int bflags, type = -1; + static int ghost_channel=-1, ghost_dev=-1; + int org_lun = lun; + + SDpnt->host = shpnt; + SDpnt->id = dev; + SDpnt->lun = lun; + SDpnt->channel = channel; + SDpnt->online = TRUE; + + + if ((channel == ghost_channel) && (dev == ghost_dev) && (lun == 1)) { + SDpnt->lun = 0; + } else { + ghost_channel = ghost_dev = -1; + } + + + /* Some low level driver could use device->type (DB) */ + SDpnt->type = -1; + + /* + * Assume that the device will have handshaking problems, and then fix this + * field later if it turns out it doesn't + */ + SDpnt->borken = 1; + SDpnt->was_reset = 0; + SDpnt->expecting_cc_ua = 0; + SDpnt->starved = 0; + + scsi_cmd[0] = TEST_UNIT_READY; + scsi_cmd[1] = lun << 5; + scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[4] = scsi_cmd[5] = 0; + + SCpnt->host = SDpnt->host; + SCpnt->device = SDpnt; + SCpnt->target = SDpnt->id; + SCpnt->lun = SDpnt->lun; + SCpnt->channel = SDpnt->channel; + + scsi_wait_cmd (SCpnt, (void *) scsi_cmd, + (void *) NULL, + 0, SCSI_TIMEOUT + 4 * HZ, 5); + + SCSI_LOG_SCAN_BUS(3, printk("scsi: scan_scsis_single id %d lun %d. Return code 0x%08x\n", + dev, lun, SCpnt->result)); + SCSI_LOG_SCAN_BUS(3, print_driverbyte(SCpnt->result)); + SCSI_LOG_SCAN_BUS(3, print_hostbyte(SCpnt->result)); + SCSI_LOG_SCAN_BUS(3, printk("\n")); + + if (SCpnt->result) { + if (((driver_byte(SCpnt->result) & DRIVER_SENSE) || + (status_byte(SCpnt->result) & CHECK_CONDITION)) && + ((SCpnt->sense_buffer[0] & 0x70) >> 4) == 7) { + if (((SCpnt->sense_buffer[2] & 0xf) != NOT_READY) && + ((SCpnt->sense_buffer[2] & 0xf) != UNIT_ATTENTION) && + ((SCpnt->sense_buffer[2] & 0xf) != ILLEGAL_REQUEST || lun > 0)) + return 1; + } else + return 0; + } + SCSI_LOG_SCAN_BUS(3, printk("scsi: performing INQUIRY\n")); + /* + * Build an INQUIRY command block. + */ + scsi_cmd[0] = INQUIRY; + scsi_cmd[1] = (lun << 5) & 0xe0; + scsi_cmd[2] = 0; + scsi_cmd[3] = 0; + scsi_cmd[4] = 255; + scsi_cmd[5] = 0; + SCpnt->cmd_len = 0; + + scsi_wait_cmd (SCpnt, (void *) scsi_cmd, + (void *) scsi_result, + 256, SCSI_TIMEOUT, 3); + + SCSI_LOG_SCAN_BUS(3, printk("scsi: INQUIRY %s with code 0x%x\n", + SCpnt->result ? "failed" : "successful", SCpnt->result)); + + if (SCpnt->result) + return 0; /* assume no peripheral if any sort of error */ + + /* + * Check the peripheral qualifier field - this tells us whether LUNS + * are supported here or not. + */ + if ((scsi_result[0] >> 5) == 3) { + return 0; /* assume no peripheral if any sort of error */ + } + + /* + * Get any flags for this device. + */ + bflags = get_device_flags (scsi_result); + + + /* The Toshiba ROM was "gender-changed" here as an inline hack. + This is now much more generic. + This is a mess: What we really want is to leave the scsi_result + alone, and just change the SDpnt structure. And the SDpnt is what + we want print_inquiry to print. -- REW + */ + if (bflags & BLIST_ISDISK) { + scsi_result[0] = TYPE_DISK; + scsi_result[1] |= 0x80; /* removable */ + } + + if (bflags & BLIST_ISROM) { + scsi_result[0] = TYPE_ROM; + scsi_result[1] |= 0x80; /* removable */ + } + + if (bflags & BLIST_GHOST) { + if ((ghost_channel == channel) && (ghost_dev == dev) && (org_lun == 1)) { + lun=1; + } else { + ghost_channel = channel; + ghost_dev = dev; + scsi_result[0] = TYPE_MOD; + scsi_result[1] |= 0x80; /* removable */ + } + } + + + memcpy(SDpnt->vendor, scsi_result + 8, 8); + memcpy(SDpnt->model, scsi_result + 16, 16); + memcpy(SDpnt->rev, scsi_result + 32, 4); + + SDpnt->removable = (0x80 & scsi_result[1]) >> 7; + SDpnt->online = TRUE; + SDpnt->lockable = SDpnt->removable; + SDpnt->changed = 0; + SDpnt->access_count = 0; + SDpnt->busy = 0; + SDpnt->has_cmdblocks = 0; + /* + * Currently, all sequential devices are assumed to be tapes, all random + * devices disk, with the appropriate read only flags set for ROM / WORM + * treated as RO. + */ + switch (type = (scsi_result[0] & 0x1f)) { + case TYPE_TAPE: + case TYPE_DISK: + case TYPE_MOD: + case TYPE_PROCESSOR: + case TYPE_SCANNER: + case TYPE_MEDIUM_CHANGER: + case TYPE_ENCLOSURE: + SDpnt->writeable = 1; + break; + case TYPE_WORM: + case TYPE_ROM: + SDpnt->writeable = 0; + break; + default: + printk("scsi: unknown type %d\n", type); + } + + SDpnt->device_blocked = FALSE; + SDpnt->device_busy = 0; + SDpnt->single_lun = 0; + SDpnt->soft_reset = + (scsi_result[7] & 1) && ((scsi_result[3] & 7) == 2); + SDpnt->random = (type == TYPE_TAPE) ? 0 : 1; + SDpnt->type = (type & 0x1f); + + print_inquiry(scsi_result); + + for (sdtpnt = scsi_devicelist; sdtpnt; + sdtpnt = sdtpnt->next) + if (sdtpnt->detect) + SDpnt->attached += + (*sdtpnt->detect) (SDpnt); + + SDpnt->scsi_level = scsi_result[2] & 0x07; + if (SDpnt->scsi_level >= 2 || + (SDpnt->scsi_level == 1 && + (scsi_result[3] & 0x0f) == 1)) + SDpnt->scsi_level++; + + /* + * Accommodate drivers that want to sleep when they should be in a polling + * loop. + */ + SDpnt->disconnect = 0; + + + /* + * Set the tagged_queue flag for SCSI-II devices that purport to support + * tagged queuing in the INQUIRY data. + */ + SDpnt->tagged_queue = 0; + if ((SDpnt->scsi_level >= SCSI_2) && + (scsi_result[7] & 2) && + !(bflags & BLIST_NOTQ)) { + SDpnt->tagged_supported = 1; + SDpnt->current_tag = 0; + } + /* + * Some revisions of the Texel CD ROM drives have handshaking problems when + * used with the Seagate controllers. Before we know what type of device + * we're talking to, we assume it's borken and then change it here if it + * turns out that it isn't a TEXEL drive. + */ + if ((bflags & BLIST_BORKEN) == 0) + SDpnt->borken = 0; + + /* + * If we want to only allow I/O to one of the luns attached to this device + * at a time, then we set this flag. + */ + if (bflags & BLIST_SINGLELUN) + SDpnt->single_lun = 1; + + /* + * These devices need this "key" to unlock the devices so we can use it + */ + if ((bflags & BLIST_KEY) != 0) { + printk("Unlocked floptical drive.\n"); + SDpnt->lockable = 0; + scsi_cmd[0] = MODE_SENSE; + scsi_cmd[1] = (lun << 5) & 0xe0; + scsi_cmd[2] = 0x2e; + scsi_cmd[3] = 0; + scsi_cmd[4] = 0x2a; + scsi_cmd[5] = 0; + SCpnt->cmd_len = 0; + scsi_wait_cmd (SCpnt, (void *) scsi_cmd, + (void *) scsi_result, 0x2a, + SCSI_TIMEOUT, 3); + } + /* + * Detach the command from the device. It was just a temporary to be used while + * scanning the bus - the real ones will be allocated later. + */ + SDpnt->device_queue = NULL; + + /* + * This device was already hooked up to the host in question, + * so at this point we just let go of it and it should be fine. We do need to + * allocate a new one and attach it to the host so that we can further scan the bus. + */ + SDpnt = (Scsi_Device *) kmalloc(sizeof(Scsi_Device), GFP_ATOMIC); + *SDpnt2 = SDpnt; + if (!SDpnt) { + printk("scsi: scan_scsis_single: Cannot malloc\n"); + return 0; + } + memset(SDpnt, 0, sizeof(Scsi_Device)); + + /* + * Register the queue for the device. All I/O requests will come + * in through here. We also need to register a pointer to + * ourselves, since the queue handler won't know what device + * the queue actually represents. We could look it up, but it + * is pointless work. + */ + blk_init_queue(&SDpnt->request_queue, scsi_get_request_handler(SDpnt, shpnt)); + blk_queue_headactive(&SDpnt->request_queue, 0); + SDpnt->request_queue.queuedata = (void *) SDpnt; + SDpnt->host = shpnt; + initialize_merge_fn(SDpnt); + + /* + * And hook up our command block to the new device we will be testing + * for. + */ + SDpnt->device_queue = SCpnt; + SDpnt->online = TRUE; + + /* + * Initialize the object that we will use to wait for command blocks. + */ + init_waitqueue_head(&SDpnt->scpnt_wait); + + /* + * Since we just found one device, there had damn well better be one in the list + * already. + */ + if (shpnt->host_queue == NULL) + panic("scan_scsis_single: Host queue == NULL\n"); + + SDtail = shpnt->host_queue; + while (SDtail->next) { + SDtail = SDtail->next; + } + + /* Add this device to the linked list at the end */ + SDtail->next = SDpnt; + SDpnt->prev = SDtail; + SDpnt->next = NULL; + + /* + * Some scsi devices cannot be polled for lun != 0 due to firmware bugs + */ + if (bflags & BLIST_NOLUN) + return 0; /* break; */ + + /* + * If this device is known to support sparse multiple units, override the + * other settings, and scan all of them. + */ + if (bflags & BLIST_SPARSELUN) { + *max_dev_lun = 8; + *sparse_lun = 1; + return 1; + } + /* + * If this device is known to support multiple units, override the other + * settings, and scan all of them. + */ + if (bflags & BLIST_FORCELUN) { + *max_dev_lun = 8; + return 1; + } + /* + * REGAL CDC-4X: avoid hang after LUN 4 + */ + if (bflags & BLIST_MAX5LUN) { + *max_dev_lun = 5; + return 1; + } + + /* + * If this device is Ghosted, scan upto two luns. (It physically only + * has one). -- REW + */ + if (bflags & BLIST_GHOST) { + *max_dev_lun = 2; + return 1; + } + + + /* + * We assume the device can't handle lun!=0 if: - it reports scsi-0 (ANSI + * SCSI Revision 0) (old drives like MAXTOR XT-3280) or - it reports scsi-1 + * (ANSI SCSI Revision 1) and Response Data Format 0 + */ + if (((scsi_result[2] & 0x07) == 0) + || + ((scsi_result[2] & 0x07) == 1 && + (scsi_result[3] & 0x0f) == 0)) + return 0; + return 1; +} + diff -ur --new-file old/linux/drivers/scsi/sd.c new/linux/drivers/scsi/sd.c --- old/linux/drivers/scsi/sd.c Wed Jan 19 03:54:21 2000 +++ new/linux/drivers/scsi/sd.c Fri Jan 21 18:48:12 2000 @@ -640,17 +640,6 @@ return retval; } -static void sd_init_done(Scsi_Cmnd * SCpnt) -{ - struct request *req; - - req = &SCpnt->request; - req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ - - if (req->sem != NULL) { - up(req->sem); - } -} static int sd_init_onedisk(int i) { unsigned char cmd[10]; @@ -698,7 +687,7 @@ SCpnt->sense_buffer[2] = 0; scsi_wait_cmd (SCpnt, (void *) cmd, (void *) buffer, - 0/*512*/, sd_init_done, SD_TIMEOUT, MAX_RETRIES); + 0/*512*/, SD_TIMEOUT, MAX_RETRIES); the_result = SCpnt->result; retries++; @@ -724,7 +713,7 @@ SCpnt->sense_buffer[2] = 0; scsi_wait_cmd(SCpnt, (void *) cmd, (void *) buffer, - 512, sd_init_done, SD_TIMEOUT, MAX_RETRIES); + 512, SD_TIMEOUT, MAX_RETRIES); } spintime = 1; spintime_value = jiffies; @@ -754,7 +743,7 @@ SCpnt->sense_buffer[2] = 0; scsi_wait_cmd(SCpnt, (void *) cmd, (void *) buffer, - 8, sd_init_done, SD_TIMEOUT, MAX_RETRIES); + 8, SD_TIMEOUT, MAX_RETRIES); the_result = SCpnt->result; retries--; @@ -905,7 +894,7 @@ /* same code as READCAPA !! */ scsi_wait_cmd(SCpnt, (void *) cmd, (void *) buffer, - 512, sd_init_done, SD_TIMEOUT, MAX_RETRIES); + 512, SD_TIMEOUT, MAX_RETRIES); the_result = SCpnt->result; diff -ur --new-file old/linux/drivers/scsi/sr.c new/linux/drivers/scsi/sr.c --- old/linux/drivers/scsi/sr.c Fri Jan 7 20:55:28 2000 +++ new/linux/drivers/scsi/sr.c Fri Jan 21 18:48:12 2000 @@ -456,18 +456,6 @@ } -static void sr_init_done(Scsi_Cmnd * SCpnt) -{ - struct request *req; - - req = &SCpnt->request; - req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ - - if (req->sem != NULL) { - up(req->sem); - } -} - void get_sectorsize(int i) { unsigned char cmd[10]; @@ -494,7 +482,7 @@ /* Do the command and wait.. */ scsi_wait_cmd(SCpnt, (void *) cmd, (void *) buffer, - 512, sr_init_done, SR_TIMEOUT, MAX_RETRIES); + 512, SR_TIMEOUT, MAX_RETRIES); the_result = SCpnt->result; retries--; @@ -671,11 +659,11 @@ /* do the locking and issue the command */ SCpnt->request.rq_dev = cdi->dev; - /* scsi_do_cmd sets the command length */ + /* scsi_wait_cmd sets the command length */ SCpnt->cmd_len = 0; scsi_wait_cmd(SCpnt, (void *) cgc->cmd, (void *) buffer, cgc->buflen, - sr_init_done, SR_TIMEOUT, MAX_RETRIES); + SR_TIMEOUT, MAX_RETRIES); if ((cgc->stat = SCpnt->result)) cgc->sense = (struct request_sense *) SCpnt->sense_buffer; diff -ur --new-file old/linux/drivers/scsi/sr_ioctl.c new/linux/drivers/scsi/sr_ioctl.c --- old/linux/drivers/scsi/sr_ioctl.c Sun Dec 19 00:36:40 1999 +++ new/linux/drivers/scsi/sr_ioctl.c Fri Jan 21 18:48:12 2000 @@ -30,23 +30,6 @@ /* In fact, it is very slow if it has to spin up first */ #define IOCTL_TIMEOUT 30*HZ -static void sr_ioctl_done(Scsi_Cmnd * SCpnt) -{ - struct request *req; - - req = &SCpnt->request; - req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ - - if (SCpnt->buffer && req->buffer && SCpnt->buffer != req->buffer) { - memcpy(req->buffer, SCpnt->buffer, SCpnt->bufflen); - scsi_free(SCpnt->buffer, (SCpnt->bufflen + 511) & ~511); - SCpnt->buffer = req->buffer; - } - if (req->sem != NULL) { - up(req->sem); - } -} - /* We do our own retries because we want to know what the specific error code is. Normally the UNIT_ATTENTION code will automatically clear after one error */ @@ -55,6 +38,7 @@ { Scsi_Cmnd *SCpnt; Scsi_Device *SDev; + struct request *req; int result, err = 0, retries = 0; char *bounce_buffer; @@ -79,7 +63,14 @@ scsi_wait_cmd(SCpnt, (void *) sr_cmd, (void *) buffer, buflength, - sr_ioctl_done, IOCTL_TIMEOUT, IOCTL_RETRIES); + IOCTL_TIMEOUT, IOCTL_RETRIES); + + req = &SCpnt->request; + if (SCpnt->buffer && req->buffer && SCpnt->buffer != req->buffer) { + memcpy(req->buffer, SCpnt->buffer, SCpnt->bufflen); + scsi_free(SCpnt->buffer, (SCpnt->bufflen + 511) & ~511); + SCpnt->buffer = req->buffer; + } result = SCpnt->result; @@ -262,14 +253,14 @@ int sr_select_speed(struct cdrom_device_info *cdi, int speed) { - u_char sr_cmd[12]; + u_char sr_cmd[MAX_COMMAND_SIZE]; if (speed == 0) speed = 0xffff; /* set to max */ else speed *= 177; /* Nx to kbyte/s */ - memset(sr_cmd, 0, 12); + memset(sr_cmd, 0, MAX_COMMAND_SIZE); sr_cmd[0] = GPCMD_SET_SPEED; /* SET CD SPEED */ sr_cmd[1] = (scsi_CDs[MINOR(cdi->dev)].device->lun) << 5; sr_cmd[2] = (speed >> 8) & 0xff; /* MSB for speed (in kbytes/sec) */ @@ -370,14 +361,14 @@ int sr_read_cd(int minor, unsigned char *dest, int lba, int format, int blksize) { - unsigned char cmd[12]; + unsigned char cmd[MAX_COMMAND_SIZE]; #ifdef DEBUG printk("sr%d: sr_read_cd lba=%d format=%d blksize=%d\n", minor, lba, format, blksize); #endif - memset(cmd, 0, 12); + memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = GPCMD_READ_CD; /* READ_CD */ cmd[1] = (scsi_CDs[minor].device->lun << 5) | ((format & 7) << 2); cmd[2] = (unsigned char) (lba >> 24) & 0xff; @@ -408,7 +399,7 @@ int sr_read_sector(int minor, int lba, int blksize, unsigned char *dest) { - unsigned char cmd[12]; /* the scsi-command */ + unsigned char cmd[MAX_COMMAND_SIZE]; /* the scsi-command */ int rc; /* we try the READ CD command first... */ @@ -429,7 +420,7 @@ printk("sr%d: sr_read_sector lba=%d blksize=%d\n", minor, lba, blksize); #endif - memset(cmd, 0, 12); + memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = GPCMD_READ_10; cmd[1] = (scsi_CDs[minor].device->lun << 5); cmd[2] = (unsigned char) (lba >> 24) & 0xff; diff -ur --new-file old/linux/drivers/scsi/sr_vendor.c new/linux/drivers/scsi/sr_vendor.c --- old/linux/drivers/scsi/sr_vendor.c Mon Dec 13 08:04:20 1999 +++ new/linux/drivers/scsi/sr_vendor.c Fri Jan 21 18:48:12 2000 @@ -106,7 +106,7 @@ int sr_set_blocklength(int minor, int blocklength) { unsigned char *buffer; /* the buffer for the ioctl */ - unsigned char cmd[12]; /* the scsi-command */ + unsigned char cmd[MAX_COMMAND_SIZE]; /* the scsi-command */ struct ccs_modesel_head *modesel; int rc, density = 0; @@ -122,7 +122,7 @@ #ifdef DEBUG printk("sr%d: MODE SELECT 0x%x/%d\n", minor, density, blocklength); #endif - memset(cmd, 0, 12); + memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = MODE_SELECT; cmd[1] = (scsi_CDs[minor].device->lun << 5) | (1 << 4); cmd[4] = 12; @@ -153,7 +153,7 @@ { unsigned long sector; unsigned char *buffer; /* the buffer for the ioctl */ - unsigned char cmd[12]; /* the scsi-command */ + unsigned char cmd[MAX_COMMAND_SIZE]; /* the scsi-command */ int rc, no_multi, minor; minor = MINOR(cdi->dev); @@ -171,7 +171,7 @@ switch (VENDOR_ID) { case VENDOR_SCSI3: - memset(cmd, 0, 12); + memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = READ_TOC; cmd[1] = (scsi_CDs[minor].device->lun << 5); cmd[8] = 12; @@ -196,7 +196,7 @@ #ifdef CONFIG_BLK_DEV_SR_VENDOR case VENDOR_NEC:{ unsigned long min, sec, frame; - memset(cmd, 0, 12); + memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = 0xde; cmd[1] = (scsi_CDs[minor].device->lun << 5) | 0x03; cmd[2] = 0xb0; @@ -221,7 +221,7 @@ /* we request some disc information (is it a XA-CD ?, * where starts the last session ?) */ - memset(cmd, 0, 12); + memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = 0xc7; cmd[1] = (scsi_CDs[minor].device->lun << 5) | 3; rc = sr_do_ioctl(minor, cmd, buffer, 4, 1); @@ -244,7 +244,7 @@ } case VENDOR_WRITER: - memset(cmd, 0, 12); + memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = READ_TOC; cmd[1] = (scsi_CDs[minor].device->lun << 5); cmd[8] = 0x04; diff -ur --new-file old/linux/drivers/sgi/char/graphics.c new/linux/drivers/sgi/char/graphics.c --- old/linux/drivers/sgi/char/graphics.c Fri Jan 7 20:43:09 2000 +++ new/linux/drivers/sgi/char/graphics.c Mon Jan 24 20:04:37 2000 @@ -254,15 +254,7 @@ */ static struct vm_operations_struct graphics_mmap = { - NULL, /* no special mmap-open */ - NULL, /* no special mmap-close */ - NULL, /* no special mmap-unmap */ - NULL, /* no special mmap-protect */ - NULL, /* no special mmap-sync */ - NULL, /* no special mmap-advise */ - sgi_graphics_nopage, /* our magic no-page fault handler */ - NULL, /* no special mmap-wppage */ - NULL /* no special mmap-swapout */ + nopage: sgi_graphics_nopage, /* our magic no-page fault handler */ }; int diff -ur --new-file old/linux/drivers/sgi/char/shmiq.c new/linux/drivers/sgi/char/shmiq.c --- old/linux/drivers/sgi/char/shmiq.c Fri Jan 7 20:43:09 2000 +++ new/linux/drivers/sgi/char/shmiq.c Mon Jan 24 20:04:37 2000 @@ -296,15 +296,7 @@ } static struct vm_operations_struct qcntl_mmap = { - NULL, /* no special mmap-open */ - NULL, /* no special mmap-close */ - NULL, /* no special mmap-unmap */ - NULL, /* no special mmap-protect */ - NULL, /* no special mmap-sync */ - NULL, /* no special mmap-advise */ - shmiq_nopage, /* our magic no-page fault handler */ - NULL, /* no special mmap-wppage */ - NULL /* no special mmap-swapout */ + nopage: shmiq_nopage, /* our magic no-page fault handler */ }; static int diff -ur --new-file old/linux/drivers/sound/ad1848.c new/linux/drivers/sound/ad1848.c --- old/linux/drivers/sound/ad1848.c Sat Oct 2 16:49:29 1999 +++ new/linux/drivers/sound/ad1848.c Sat Jan 22 21:31:10 2000 @@ -71,7 +71,8 @@ #define MD_4232 5 #define MD_C930 6 #define MD_IWAVE 7 -#define MD_4235 8 /* Crystal Audio CS4235 */ +#define MD_4235 8 /* Crystal Audio CS4235 */ +#define MD_1845_SSCAPE 9 /* Ensoniq Soundscape PNP*/ /* Mixer parameters */ int recmask; @@ -100,6 +101,7 @@ static int nr_ad1848_devs = 0; int deskpro_xl = 0; +int deskpro_m = 0; #ifdef CONFIG_SOUND_SPRO int soundpro = 1; #else @@ -117,7 +119,7 @@ #endif -static int ad_format_mask[9 /*devc->model */ ] = +static int ad_format_mask[10 /*devc->model */ ] = { 0, AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW, @@ -127,7 +129,8 @@ AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM, AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM, AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM, - AFMT_U8 | AFMT_S16_LE /* CS4235 */ + AFMT_U8 | AFMT_S16_LE /* CS4235 */, + AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW /* Ensoniq Soundscape*/ }; static ad1848_info adev_info[MAX_AUDIO_DEV]; @@ -140,7 +143,7 @@ static struct { unsigned char flags; #define CAP_F_TIMER 0x01 -} capabilities [9 /*devc->model */ ] = { +} capabilities [10 /*devc->model */ ] = { {0} ,{0} /* MD_1848 */ ,{CAP_F_TIMER} /* MD_4231 */ @@ -149,7 +152,8 @@ ,{CAP_F_TIMER} /* MD_4232 */ ,{0} /* MD_C930 */ ,{CAP_F_TIMER} /* MD_IWAVE */ - ,{0} /* MD_4235 */ + ,{0} /* MD_4235 */ + ,{CAP_F_TIMER} /* MD_1845_SSCAPE */ }; static int ad1848_open(int dev, int mode); @@ -231,7 +235,7 @@ while (timeout > 0 && (ad_read(devc, 11) & 0x20)) timeout--; if (ad_read(devc, 11) & 0x20) - if (devc->model != MD_1845) + if ( (devc->model != MD_1845) || (devc->model != MD_1845_SSCAPE)) printk(KERN_WARNING "ad1848: Auto calibration timed out(3).\n"); } @@ -555,6 +559,7 @@ case MD_4231: case MD_4231A: case MD_1845: + case MD_1845_SSCAPE: devc->supported_devices = MODE2_MIXER_DEVICES; break; @@ -751,7 +756,7 @@ if (arg <= 0) return portc->speed; - if (devc->model == MD_1845) /* AD1845 has different timer than others */ + if (devc->model == MD_1845 || devc->model == MD_1845_SSCAPE) /* AD1845 has different timer than others */ { if (arg < 4000) arg = 4000; @@ -1087,7 +1092,7 @@ ad_enter_MCE(devc); /* Enables changes to the format select reg */ - if (devc->model == MD_1845) /* Use alternate speed select registers */ + if (devc->model == MD_1845 || devc->model == MD_1845_SSCAPE) /* Use alternate speed select registers */ { fs &= 0xf0; /* Mask off the rate select bits */ @@ -1157,7 +1162,7 @@ ad_enter_MCE(devc); /* Enables changes to the format select reg */ - if (devc->model == MD_1845) /* Use alternate speed select registers */ + if ((devc->model == MD_1845) || (devc->model == MD_1845_SSCAPE)) /* Use alternate speed select registers */ { fs &= 0xf0; /* Mask off the rate select bits */ @@ -1193,7 +1198,7 @@ while (timeout < 10000 && inb(devc->base) == 0x80) timeout++; - if (devc->model != MD_1848 && devc->model != MD_1845) + if (devc->model != MD_1848 && devc->model != MD_1845 && devc->model != MD_1845_SSCAPE) { /* * CS4231 compatible devices don't have separate sampling rate selection @@ -1405,13 +1410,17 @@ if (devc->model > MD_1848) { - ad_write(devc, 12, ad_read(devc, 12) | 0x40); /* Mode2 = enabled */ + if (devc->model == MD_1845_SSCAPE) + ad_write(devc, 12, ad_read(devc, 12) | 0x50); + else + ad_write(devc, 12, ad_read(devc, 12) | 0x40); /* Mode2 = enabled */ if (devc->model == MD_IWAVE) ad_write(devc, 12, 0x6c); /* Select codec mode 3 */ - for (i = 16; i < 32; i++) - ad_write(devc, i, init_values[i]); + if (devc-> model != MD_1845_SSCAPE) + for (i = 16; i < 32; i++) + ad_write(devc, i, init_values[i]); if (devc->model == MD_IWAVE) ad_write(devc, 16, 0x30); /* Playback and capture counters enabled */ @@ -1423,7 +1432,7 @@ else ad_write(devc, 9, ad_read(devc, 9) | 0x04); /* Single DMA mode */ - if (devc->model == MD_1845) + if (devc->model == MD_1845 || devc->model == MD_1845_SSCAPE) ad_write(devc, 27, ad_read(devc, 27) | 0x08); /* Alternate freq select enabled */ if (devc->model == MD_IWAVE) @@ -1462,6 +1471,7 @@ int interwave = 0; int ad1847_flag = 0; int cs4248_flag = 0; + int sscape_flag = 0; int i; @@ -1474,6 +1484,13 @@ interwave = 1; *ad_flags = 0; } + + if (*ad_flags == 0x87654321) + { + sscape_flag = 1; + *ad_flags = 0; + } + if (*ad_flags == 0x12345677) { cs4248_flag = 1; @@ -1821,6 +1838,9 @@ devc->chip_name = "AD1847"; + if (sscape_flag == 1) + devc->model = MD_1845_SSCAPE; + return 1; } @@ -1979,7 +1999,7 @@ switch (cmd) { case AD1848_SET_XTAL: /* Change clock frequency of AD1845 (only ) */ - if (devc->model != MD_1845) + if (devc->model != MD_1845 || devc->model != MD_1845_SSCAPE) return -EINVAL; ad_enter_MCE(devc); ad_write(devc, 29, (ad_read(devc, 29) & 0x1f) | (arg << 5)); @@ -2146,6 +2166,34 @@ /* * Experimental initialization sequence for the integrated sound system + * of the Compaq Deskpro M. + */ + +static int init_deskpro_m(struct address_info *hw_config) +{ + unsigned char tmp; + + if ((tmp = inb(0xc44)) == 0xff) + { + DDB(printk("init_deskpro_m: Dead port 0xc44\n")); + return 0; + } + + outb(0x10, 0xc44); + outb(0x40, 0xc45); + outb(0x00, 0xc46); + outb(0xe8, 0xc47); + outb(0x14, 0xc44); + outb(0x40, 0xc45); + outb(0x00, 0xc46); + outb(0xe8, 0xc47); + outb(0x10, 0xc44); + + return 1; +} + +/* + * Experimental initialization sequence for the integrated sound system * of Compaq Deskpro XL. */ @@ -2370,6 +2418,12 @@ return 0; } + if (deskpro_m) /* Compaq Deskpro M */ + { + if (!init_deskpro_m(hw_config)) + return 0; + } + /* * Check if the IO port returns valid signature. The original MS Sound * system returns 0x04 while some cards (AudioTrix Pro for example) @@ -2558,7 +2612,7 @@ * the timer divider. */ - if (devc->model == MD_1845) + if (devc->model == MD_1845 || devc->model == MD_1845_SSCAPE) xtal_nsecs = 10050; else if (ad_read(devc, 8) & 0x01) xtal_nsecs = 9920; @@ -2659,6 +2713,7 @@ MODULE_PARM(dma2, "i"); /* Second DMA channel */ MODULE_PARM(type, "i"); /* Card type */ MODULE_PARM(deskpro_xl, "i"); /* Special magic for Deskpro XL boxen */ +MODULE_PARM(deskpro_m, "i"); /* Special magic for Deskpro M box */ MODULE_PARM(soundpro, "i"); /* More special magic for SoundPro chips */ int io = -1; diff -ur --new-file old/linux/drivers/sound/audio.c new/linux/drivers/sound/audio.c --- old/linux/drivers/sound/audio.c Wed Jun 2 08:25:48 1999 +++ new/linux/drivers/sound/audio.c Wed Jan 26 22:25:50 2000 @@ -228,7 +228,7 @@ { /* Handle nonblocking mode */ if ((file->f_flags & O_NONBLOCK) && err == -EAGAIN) - return p; /* No more space. Return # of accepted bytes */ + return p? p : -EAGAIN; /* No more space. Return # of accepted bytes */ return err; } l = c; @@ -308,11 +308,11 @@ * Nonblocking mode handling. Return current # of bytes */ - if ((file->f_flags & O_NONBLOCK) && buf_no == -EAGAIN) - return p; - if (p > 0) /* Avoid throwing away data */ return p; /* Return it instead */ + + if ((file->f_flags & O_NONBLOCK) && buf_no == -EAGAIN) + return -EAGAIN; return buf_no; } diff -ur --new-file old/linux/drivers/sound/cmpci.c new/linux/drivers/sound/cmpci.c --- old/linux/drivers/sound/cmpci.c Thu Jan 20 19:44:46 2000 +++ new/linux/drivers/sound/cmpci.c Wed Jan 26 22:25:50 2000 @@ -2315,7 +2315,7 @@ #ifdef CONFIG_SOUND_CMPCI_REAR static int rear_out = 1; #else -static int read_out = 0; +static int rear_out = 0; #endif int __init init_cmpci(void) @@ -2377,6 +2377,7 @@ s->iobase = pcidev->resource[0].start; s->iosynth = 0x388; s->iomidi = 0x330; + spin_lock_init(&s->lock); if (s->iobase == 0) continue; s->irq = pcidev->irq; diff -ur --new-file old/linux/drivers/sound/dmasound.c new/linux/drivers/sound/dmasound.c --- old/linux/drivers/sound/dmasound.c Tue Oct 12 19:00:58 1999 +++ new/linux/drivers/sound/dmasound.c Wed Jan 26 21:45:20 2000 @@ -2891,10 +2891,13 @@ * Amiga */ +#define StopDMA() custom.aud[0].audvol = custom.aud[1].audvol = 0; \ + custom.aud[2].audvol = custom.aud[3].audvol = 0; \ + custom.dmacon = AMI_AUDIO_OFF; static void *AmiAlloc(unsigned int size, int flags) { - return(amiga_chip_alloc((long)size)); + return amiga_chip_alloc((long)size, "dmasound"); } static void AmiFree(void *obj, unsigned int size) @@ -2905,7 +2908,7 @@ static int __init AmiIrqInit(void) { /* turn off DMA for audio channels */ - custom.dmacon = AMI_AUDIO_OFF; + StopDMA(); /* Register interrupt handler. */ if (request_irq(IRQ_AMIGA_AUD0, ami_sq_interrupt, 0, @@ -2918,7 +2921,7 @@ static void AmiIrqCleanUp(void) { /* turn off DMA for audio channels */ - custom.dmacon = AMI_AUDIO_OFF; + StopDMA(); /* release the interrupt */ free_irq(IRQ_AMIGA_AUD0, ami_sq_interrupt); } @@ -2927,7 +2930,7 @@ static void AmiSilence(void) { /* turn off DMA for audio channels */ - custom.dmacon = AMI_AUDIO_OFF; + StopDMA(); } @@ -3008,6 +3011,15 @@ custom.aud[0].audvol = sound.volume_left; sound.volume_right = VOLUME_VOXWARE_TO_AMI((volume & 0xff00) >> 8); custom.aud[1].audvol = sound.volume_right; + if (sound.hard.size == 16) { + if (sound.volume_left == 64 && sound.volume_right == 64) { + custom.aud[2].audvol = 1; + custom.aud[3].audvol = 1; + } else { + custom.aud[2].audvol = 0; + custom.aud[3].audvol = 0; + } + } return(VOLUME_AMI_TO_VOXWARE(sound.volume_left) | (VOLUME_AMI_TO_VOXWARE(sound.volume_right) << 8)); } @@ -3047,6 +3059,9 @@ ch0 = start; ch1 = start; } + + custom.aud[0].audvol = sound.volume_left; + custom.aud[1].audvol = sound.volume_right; if (sound.hard.size == 8) { custom.aud[0].audlc = (u_short *)ZTWO_PADDR(ch0); custom.aud[0].audlen = size; @@ -3070,8 +3085,11 @@ custom.aud[3].audlc = (u_short *)ZTWO_PADDR(ch3); custom.aud[3].audlen = size; custom.dmacon = AMI_AUDIO_14; - } else + } else { + custom.aud[2].audvol = 0; + custom.aud[3].audvol = 0; custom.dmacon = AMI_AUDIO_8; + } } sq.front = (sq.front+1) % sq.max_count; sq.active |= AMI_PLAY_LOADED; @@ -3118,6 +3136,8 @@ { int minframes = 1; + custom.intena = IF_AUD0; + if (!sq.active) { /* Playing was interrupted and sq_reset() has already cleared * the sq variables, so better don't do anything here. @@ -3141,7 +3161,9 @@ if (!sq.active) /* No frame is playing, disable audio DMA */ - custom.dmacon = AMI_AUDIO_OFF; + StopDMA(); + + custom.intena = IF_SETCLR | IF_AUD0; if (sq.count >= minframes) /* Try to play the next frame */ diff -ur --new-file old/linux/drivers/sound/esssolo1.c new/linux/drivers/sound/esssolo1.c --- old/linux/drivers/sound/esssolo1.c Mon Jan 17 18:43:57 2000 +++ new/linux/drivers/sound/esssolo1.c Tue Jan 25 20:41:20 2000 @@ -71,6 +71,7 @@ /*****************************************************************************/ +#include #include #include #include diff -ur --new-file old/linux/drivers/sound/msnd_pinnacle.c new/linux/drivers/sound/msnd_pinnacle.c --- old/linux/drivers/sound/msnd_pinnacle.c Thu Jan 20 19:44:46 2000 +++ new/linux/drivers/sound/msnd_pinnacle.c Sat Jan 22 21:31:10 2000 @@ -46,6 +46,7 @@ # include #endif #include +#include #include "sound_config.h" #include "sound_firmware.h" #ifdef MSND_CLASSIC diff -ur --new-file old/linux/drivers/sound/soundcard.c new/linux/drivers/sound/soundcard.c --- old/linux/drivers/sound/soundcard.c Sun Nov 21 20:13:56 1999 +++ new/linux/drivers/sound/soundcard.c Thu Jan 27 15:32:14 2000 @@ -164,7 +164,7 @@ #define MODULEPROCSTRING "Driver compiled into kernel" #endif - down(&uts_sem); + down_read(&uts_sem); len = sprintf(buffer, "OSS/Free:" SOUND_VERSION_STRING "\n" "Load type: " MODULEPROCSTRING "\n" @@ -172,7 +172,7 @@ "Config options: %x\n\nInstalled drivers: \n", system_utsname.sysname, system_utsname.nodename, system_utsname.release, system_utsname.version, system_utsname.machine, SELECTED_SOUND_OPTIONS); - up(&uts_sem); + up_read(&uts_sem); for (i = 0; (i < num_sound_drivers) && (pos <= offset + length); i++) { if (!sound_drivers[i].card_type) diff -ur --new-file old/linux/drivers/usb/Config.in new/linux/drivers/usb/Config.in --- old/linux/drivers/usb/Config.in Fri Jan 21 00:00:16 2000 +++ new/linux/drivers/usb/Config.in Thu Jan 27 16:40:16 2000 @@ -9,7 +9,7 @@ comment 'USB Controllers' dep_tristate ' UHCI (Intel PIIX4, VIA, ...) support' CONFIG_USB_UHCI $CONFIG_USB - dep_tristate ' OHCI-HCD (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI_HCD $CONFIG_USB + dep_tristate ' OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB comment 'Miscellaneous USB options' bool ' Preliminary USB device filesystem' CONFIG_USB_DEVICEFS @@ -22,17 +22,19 @@ dep_tristate ' USB Serial Converter support' CONFIG_USB_SERIAL $CONFIG_USB if [ "$CONFIG_USB_SERIAL" != "n" ]; then bool ' USB Generic Serial Driver' CONFIG_USB_SERIAL_GENERIC - bool ' USB ConnectTech WhiteHEAT Serial Driver' CONFIG_USB_SERIAL_WHITEHEAT bool ' USB Handspring Visor Driver' CONFIG_USB_SERIAL_VISOR - bool ' USB Belkin Single Port Serial Driver' CONFIG_USB_SERIAL_BELKIN - bool ' USB Peracom Single Port Serial Driver' CONFIG_USB_SERIAL_PERACOM + bool ' USB ConnectTech WhiteHEAT Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_WHITEHEAT + bool ' USB FTDI Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_FTDI + bool ' USB Belkin Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_BELKIN + bool ' USB Peracom Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_PERACOM fi dep_tristate ' USB CPiA Camera support' CONFIG_USB_CPIA $CONFIG_USB + dep_tristate ' USB IBM (Xirlink) C-it Camera support' CONFIG_USB_IBMCAM $CONFIG_USB dep_tristate ' USB OV511 Camera support' CONFIG_USB_OV511 $CONFIG_USB dep_tristate ' USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB - dep_tristate ' USB SCSI (mass storage) support' CONFIG_USB_SCSI $CONFIG_USB - if [ "$CONFIG_USB_SCSI" != "n" ]; then - bool ' USB SCSI verbose debug' CONFIG_USB_SCSI_DEBUG + dep_tristate ' USB Mass Storage support' CONFIG_USB_STORAGE $CONFIG_USB + if [ "$CONFIG_USB_STORAGE" != "n" ]; then + bool ' USB Mass Storage verbose debug' CONFIG_USB_STORAGE_DEBUG fi dep_tristate ' USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT dep_tristate ' DABUSB driver' CONFIG_USB_DABUSB $CONFIG_USB @@ -48,7 +50,12 @@ dep_tristate ' Keyboard support' CONFIG_INPUT_KEYBDEV $CONFIG_USB dep_tristate ' Mouse support' CONFIG_INPUT_MOUSEDEV $CONFIG_USB if [ "$CONFIG_INPUT_MOUSEDEV" != "n" ]; then - bool ' Mix all mice into one device' CONFIG_INPUT_MOUSEDEV_MIX + bool ' Mix all mice into one device' CONFIG_INPUT_MOUSEDEV_MIX + bool ' Support for digitizers' CONFIG_INPUT_MOUSEDEV_DIGITIZER + if [ "$CONFIG_INPUT_MOUSEDEV_DIGITIZER" != "n" ]; then + int ' Horizontal screen resolution' CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024 + int ' Vertical screen resolution' CONFIG_INPUT_MOUSEDEV_SCREEN_Y 768 + fi fi dep_tristate ' Joystick support' CONFIG_INPUT_JOYDEV $CONFIG_USB dep_tristate ' Event interface support' CONFIG_INPUT_EVDEV $CONFIG_USB diff -ur --new-file old/linux/drivers/usb/Makefile new/linux/drivers/usb/Makefile --- old/linux/drivers/usb/Makefile Fri Jan 21 00:00:16 2000 +++ new/linux/drivers/usb/Makefile Thu Jan 27 16:40:16 2000 @@ -21,19 +21,17 @@ # Multipart objects. -list-multi := usbcore.o usb-uhci.o usb-ohci-hcd.o +list-multi := usbcore.o usbcore-objs := usb.o usb-debug.o usb-core.o hub.o -usb-uhci-objs := uhci.o uhci-debug.o -usb-ohci-hcd-objs := ohci-hcd.o -usb-scsi-objs := usb_scsi.o +usb-storage-objs := usb_storage.o # Optional parts of multipart objects. ifeq ($(CONFIG_USB_DEVICEFS),y) usbcore-objs += devio.o inode.o drivers.o devices.o endif -ifeq ($(CONFIG_USB_SCSI_DEBUG),y) - usb-scsi-objs += usb_scsi_debug.o +ifeq ($(CONFIG_USB_STORAGE_DEBUG),y) + usb-storage-objs += usb_storage_debug.o endif # Object file lists. @@ -47,7 +45,7 @@ obj-$(CONFIG_USB) += usbcore.o obj-$(CONFIG_USB_UHCI) += usb-uhci.o -obj-$(CONFIG_USB_OHCI_HCD) += usb-ohci-hcd.o +obj-$(CONFIG_USB_OHCI) += usb-ohci.o obj-$(CONFIG_USB_MOUSE) += usbmouse.o input.o obj-$(CONFIG_USB_HID) += hid.o input.o @@ -65,8 +63,9 @@ obj-$(CONFIG_USB_SERIAL) += usb-serial.o obj-$(CONFIG_USB_AUDIO) += audio.o obj-$(CONFIG_USB_CPIA) += cpia.o +obj-$(CONFIG_USB_IBMCAM) += ibmcam.o obj-$(CONFIG_USB_DC2XX) += dc2xx.o -obj-$(CONFIG_USB_SCSI) += usb-scsi.o +obj-$(CONFIG_USB_STORAGE) += usb-storage.o obj-$(CONFIG_USB_USS720) += uss720.o obj-$(CONFIG_USB_DABUSB) += dabusb.o obj-$(CONFIG_USB_OV511) += ov511.o @@ -106,11 +105,5 @@ usbcore.o: $(usbcore-objs) $(LD) -r -o $@ $(usbcore-objs) -usb-uhci.o: $(usb-uhci-objs) - $(LD) -r -o $@ $(usb-uhci-objs) - -usb-ohci-hcd.o: $(usb-ohci-hcd-objs) - $(LD) -r -o $@ $(usb-ohci-hcd-objs) - -usb-scsi.o: $(usb-scsi-objs) - $(LD) -r -o $@ $(usb-scsi-objs) +usb-storage.o: $(usb-storage-objs) + $(LD) -r -o $@ $(usb-storage-objs) diff -ur --new-file old/linux/drivers/usb/audio.c new/linux/drivers/usb/audio.c --- old/linux/drivers/usb/audio.c Fri Jan 7 20:43:09 2000 +++ new/linux/drivers/usb/audio.c Tue Jan 25 20:37:21 2000 @@ -3129,10 +3129,12 @@ static void usb_audio_featureunit(struct consmixstate *state, unsigned char *ftr) { - struct usb_device *dev = state->s->usbdev; struct mixerchannel *ch; unsigned short chftr, mchftr; +#if 0 + struct usb_device *dev = state->s->usbdev; unsigned char data[1]; +#endif usb_audio_recurseunit(state, ftr[4]); if (state->nrchannels == 0) { diff -ur --new-file old/linux/drivers/usb/bitstream.h new/linux/drivers/usb/bitstream.h --- old/linux/drivers/usb/bitstream.h Sat Dec 18 01:49:45 1999 +++ new/linux/drivers/usb/bitstream.h Thu Jan 1 01:00:00 1970 @@ -1,1508 +0,0 @@ -static unsigned char bitstream[] = { -0x00,0x09,0x0F,0xF0,0x0F,0xF0,0x0F,0xF0, -0x0F,0xF0,0x00,0x00,0x01,0x61,0x00,0x0D, -0x64,0x61,0x62,0x75,0x73,0x62,0x74,0x72, -0x2E,0x6E,0x63,0x64,0x00,0x62,0x00,0x0B, -0x73,0x31,0x30,0x78,0x6C,0x76,0x71,0x31, -0x30,0x30,0x00,0x63,0x00,0x0B,0x31,0x39, -0x39,0x39,0x2F,0x30,0x39,0x2F,0x32,0x34, -0x00,0x64,0x00,0x09,0x31,0x30,0x3A,0x34, -0x32,0x3A,0x34,0x36,0x00,0x65,0x00,0x00, -0x2E,0xC0,0xFF,0x20,0x17,0x5F,0x9F,0x5B, -0xFE,0xFB,0xBB,0xB7,0xBB,0xBB,0xFB,0xBF, -0xAF,0xEF,0xFB,0xDF,0xB7,0xFB,0xFB,0x7F, -0xBF,0xB7,0xEF,0xF2,0xFF,0xFB,0xFE,0xFF, -0xFF,0xEF,0xFF,0xFE,0xFF,0xBF,0xFF,0xFF, -0xFF,0xFF,0xAF,0xFF,0xFA,0xFF,0xFF,0xFF, -0xC9,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFB,0xFF,0xA3,0xFF,0xFB, -0xFE,0xFF,0xBF,0xEF,0xE3,0xFE,0xFF,0xBF, -0xE3,0xFE,0xFF,0xBF,0x6F,0xFB,0xF6,0xFF, -0xBF,0xFF,0x47,0xFF,0xFF,0x9F,0xEE,0xF9, -0xFE,0xCF,0x9F,0xEF,0xFB,0xCF,0x9B,0xEE, -0xF8,0xFE,0xEF,0x8F,0xEE,0xFB,0xFE,0x0B, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xBF,0xFF,0xFF,0xFB,0xFF,0xFF, -0xBF,0xFF,0xFF,0xFC,0x17,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0x7F, -0xFF,0xFF,0xFB,0xFF,0xFF,0x7F,0xFF,0xFF, -0xFC,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x5F,0xFF, -0xFF,0xFD,0xFF,0xFF,0xDB,0xFF,0xFD,0xFF, -0x77,0xFF,0xFD,0xFF,0xFF,0xDF,0xFE,0xFD, -0xFF,0xFF,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFD,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1, -0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xE3,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF, -0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0x67,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0x7F,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF, -0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0x2F,0xFF, -0xF3,0xFD,0xFF,0x7F,0xDE,0xF7,0xFD,0xFF, -0x7F,0xF7,0x7D,0xFF,0x7F,0xDF,0xF7,0xBD, -0xFF,0x7F,0xFF,0x1F,0xFF,0xEF,0xFB,0xFE, -0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xEF,0xFB, -0xFE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFF, -0x3F,0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F, -0x9F,0xE7,0xFA,0x7F,0x9F,0xE7,0xF9,0xFE, -0x7F,0x9F,0xE7,0xFF,0xFC,0x7F,0xBF,0xBF, -0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xB7, -0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, -0xFF,0xE0,0xFD,0xF9,0xFE,0x7F,0x9F,0xE7, -0xF9,0xFE,0x7F,0x9D,0xF9,0xFE,0x7D,0x9D, -0xE7,0xF9,0xFE,0x7F,0x9F,0xED,0xED,0xFF, -0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F, -0xDF,0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF, -0x7F,0xDF,0xFF,0x9B,0xFF,0xEF,0xFB,0xFE, -0xFB,0xBF,0xEF,0xBB,0xFE,0xFF,0xAF,0xBB, -0xBE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFF, -0xB7,0xBF,0xDB,0xF6,0xBD,0xBF,0x6B,0xDB, -0xF6,0xF9,0xBF,0x5B,0xD6,0xF9,0xBF,0x6F, -0xDB,0xF6,0xFD,0xBF,0xFF,0x0E,0xFF,0xFF, -0xFF,0xFF,0x5F,0xFF,0xF7,0xFF,0xFF,0x7F, -0xF7,0xBD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xDF,0x9F,0xFF,0xFF,0xFF,0xFE,0xFF, -0xFF,0xEF,0xFE,0xFE,0xFF,0xFF,0x77,0xFF, -0xFB,0xFB,0xFF,0xFF,0xFF,0xFF,0xF8,0x3F, -0xFF,0xFD,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xF4,0x7F,0xFF,0xFE,0xFD, -0xBE,0xFF,0xDF,0xFE,0xFF,0xFF,0xEF,0x7F, -0xFF,0xCF,0xFF,0xCF,0xFF,0xFF,0xFF,0xDF, -0xE6,0xFF,0xFF,0x7F,0xDF,0xF7,0xDD,0x7F, -0x7F,0xDF,0xF7,0xFF,0x7F,0xDF,0xD7,0xFD, -0xFF,0x7F,0xDF,0xF7,0xFF,0xCD,0xFF,0xF2, -0xFF,0xFF,0x4F,0x7F,0xF4,0xFF,0xFF,0xFF, -0xE7,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xBB,0xFF,0xEF,0xFF,0xFE,0xFF, -0xFF,0xFF,0xEF,0xFF,0xFF,0xEF,0xFF,0xFB, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x65, -0xEF,0xFF,0xFF,0x7F,0xFF,0xFD,0xEF,0xFF, -0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFE,0xCF,0xDF,0xFE,0xFF, -0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xF3,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFE,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBF,0xFF, -0xFF,0xFF,0xE3,0x7F,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xEF,0xEB,0xFF,0xFE,0xBF,0xFF, -0xEB,0xFF,0xFC,0x7F,0xFF,0xFF,0xFF,0xEE, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF, -0xD6,0xFF,0xFD,0xBF,0xFF,0xFB,0xFF,0xFE, -0xFD,0xFF,0xFF,0xFD,0xEF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xDE,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xBF,0xFF,0xFD,0xFF,0x7F,0xBF, -0xFF,0x5F,0xDF,0xFF,0xFF,0xBF,0x77,0xFF, -0xFF,0xFF,0x7F,0xD7,0xFF,0xFF,0xFF,0xFF, -0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xDF,0xEF, -0xFF,0xFF,0xFE,0xFB,0xFF,0xFF,0xDF,0xBF, -0xFF,0xFF,0xFF,0xFF,0xED,0xFF,0xB7,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xAF,0x7F,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xDF,0xBF,0xDF,0xF3,0xFD,0xFB,0xFF,0x5B, -0xFD,0xFF,0xBF,0xEF,0xF7,0xFF,0xFF,0x7D, -0xFF,0xFF,0xFF,0xFF,0xF8,0x3B,0xFF,0xBF, -0x6F,0xFF,0xFE,0xFF,0xBF,0xFF,0xEB,0x7D, -0xFF,0xEF,0xFB,0xFE,0xFF,0xFF,0xFF,0xFF, -0xFF,0xF2,0x7F,0xFC,0xFF,0x3F,0xDF,0xED, -0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0x5F,0xF7, -0xB5,0xFF,0xEF,0xFF,0xFF,0xFF,0xE0,0x3F, -0x9F,0x9E,0xFF,0xFF,0xEF,0xFF,0xDF,0xFF, -0xBF,0x5F,0xBF,0xCF,0xF3,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0x69,0xAF,0x33,0xFD,0xFF, -0xFB,0xFF,0xFF,0xFF,0xFF,0xFC,0xFF,0x7F, -0xD9,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xF5, -0xA3,0xDF,0x6E,0xDE,0xFF,0xFF,0xBD,0xFF, -0xFF,0xFE,0xFF,0xFF,0xFF,0xFE,0xE7,0xFD, -0xFF,0xFF,0xFF,0xF9,0xEF,0xC6,0xFE,0xB7, -0xAD,0xE5,0xF9,0xFF,0xFF,0xFF,0xCF,0xFF, -0xFF,0xFF,0xCD,0xFB,0x7F,0xFF,0xFF,0xFF, -0xF9,0xF6,0x0F,0xDF,0xEC,0xCF,0x7F,0xFF, -0xFB,0x7F,0xFF,0xFF,0xFF,0xFD,0xFF,0xFE, -0xF9,0xFD,0x7F,0xFF,0x7F,0xFF,0xF9,0x5B, -0xFF,0x73,0xDC,0xFD,0x7B,0xDF,0xFF,0xFF, -0xFF,0x7B,0xFF,0xFF,0xF7,0x53,0xD6,0xFF, -0xFF,0xFF,0xFF,0xD8,0x9F,0xFE,0xFF,0xEF, -0x7F,0xEE,0xFF,0xFF,0xFF,0xFB,0xED,0xED, -0xFD,0xFF,0xFE,0xFF,0xFF,0xFB,0x7F,0xFF, -0xE2,0x7F,0xFF,0x6F,0xD8,0x57,0xF7,0xFF, -0xFF,0xFF,0xDF,0xFF,0xE8,0xFF,0xFF,0xFD, -0xFF,0xFF,0xFC,0x7F,0xFF,0xE4,0xFF,0xFB, -0xEF,0xFB,0xFE,0xDF,0xB7,0xED,0xFF,0xFE, -0xDF,0x7F,0xFF,0xFE,0x7F,0xB7,0xFF,0xFF, -0xFF,0xFF,0x89,0xFF,0xFF,0xCF,0xF3,0xFE, -0x7F,0xFF,0xEF,0xFF,0xFE,0x7E,0x7F,0xFB, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF1, -0xFF,0xEB,0x7A,0xD5,0xBF,0x6F,0xDB,0xBE, -0xFD,0xB7,0xD8,0xF6,0xE5,0xBF,0x6F,0xFB, -0xFE,0xF5,0xBD,0x7E,0x06,0xFF,0xDF,0xF7, -0xFB,0xF6,0xFF,0x3F,0xFF,0xDB,0xFF,0xFF, -0x6F,0xFB,0xF7,0xFF,0xFF,0xFF,0xFB,0xFE, -0xF7,0xAF,0xFF,0xB7,0xED,0xEF,0xF7,0xFE, -0xFF,0xFF,0xDF,0xFF,0xFE,0xFF,0xEF,0xFF, -0xFF,0xFF,0xFF,0xBF,0xF7,0xFC,0x1F,0xEE, -0xFB,0xFE,0xBD,0xFF,0x7F,0x5F,0xD7,0xFD, -0xFB,0x43,0xFF,0xFF,0xFD,0xFF,0x5F,0xFF, -0xF7,0xFF,0xF9,0x3F,0xFF,0xCF,0xF3,0xFD, -0xF7,0x7E,0xEF,0xA7,0xF9,0xFE,0x8F,0xA7, -0xE9,0xF3,0x7E,0x9F,0xFB,0xF8,0xFF,0xFF, -0x3F,0xFD,0x7F,0x5F,0xDF,0xFD,0xFF,0xFF, -0x5F,0xFF,0xFD,0x5F,0xFF,0xFF,0x7F,0xFD, -0x7F,0xFD,0x9F,0xFF,0xE0,0xFF,0xFA,0xF8, -0xBE,0x6F,0x9F,0xE6,0xF8,0xBE,0x3F,0x9A, -0xF9,0xBE,0x6F,0x9F,0xE2,0xF9,0xFE,0x6F, -0x9F,0xF9,0xFF,0xF5,0xFD,0x7F,0xCF,0xDF, -0xFD,0xFD,0x7F,0xFF,0xF5,0xFF,0xFF,0xFF, -0xF7,0xF5,0xFD,0x0F,0xDB,0xFF,0xD3,0xFF, -0xEB,0xFA,0xFF,0xFF,0xBF,0xFF,0xFA,0xFF, -0xFF,0xCB,0xFB,0xFE,0xFF,0xFF,0xEB,0xFA, -0xFE,0xFF,0xFF,0xB7,0xFF,0xFF,0xFF,0xFF, -0xBF,0xFF,0xDF,0xF5,0xFF,0xFF,0xD7,0xFF, -0xFF,0xFF,0xDF,0xD7,0xF5,0xFF,0x7F,0xFE, -0x4F,0xFF,0xFD,0xFF,0x7F,0x7F,0xFF,0xAD, -0xEB,0xFB,0xFF,0xAD,0xFF,0xFF,0xFF,0xFF, -0xAF,0xEB,0xFB,0xFF,0xFC,0x0D,0xFF,0xFF, -0xDF,0xD2,0xFD,0xFF,0xFF,0xFD,0xF6,0xFF, -0xFF,0x7F,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF, -0xFF,0xFB,0x3F,0x7D,0xEB,0x32,0xFE,0xBF, -0x2F,0xEB,0xFA,0xAE,0xBD,0xE0,0xFA,0x7E, -0xBF,0xAD,0xEB,0xFA,0xFE,0xBF,0xF5,0x7F, -0xFF,0xDE,0xFE,0xE3,0xFB,0xFF,0xFF,0xFF, -0xDF,0xEF,0x4F,0xDF,0xFF,0x7F,0xDF,0xFF, -0xF7,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0xEF, -0xFB,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xDF, -0xED,0xFB,0xDF,0xFF,0xBF,0xFF,0xFF,0xFF, -0x81,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF, -0xFF,0xFF,0xFE,0xDD,0xFE,0xEF,0xFD,0xFF, -0xFF,0xFB,0xFE,0xF7,0xFF,0x93,0xFD,0xFB, -0x7E,0xFF,0xFE,0x87,0xE9,0xFF,0x7F,0xB3, -0x9F,0xFE,0xFE,0xFF,0xAF,0xFD,0xFE,0x7E, -0x3F,0xFE,0x67,0xFF,0xFF,0xF7,0xFF,0xFF, -0xFC,0xF7,0xDF,0xFD,0xFF,0x7F,0xFF,0xFF, -0x7F,0x6D,0xFF,0xFF,0xFE,0xFF,0xFF,0x2F, -0xFF,0xBF,0xFF,0xFF,0xEE,0xFF,0xBE,0xFF, -0xFF,0xFE,0xFF,0xEF,0xFF,0xFF,0xFE,0xFF, -0xEF,0xFF,0xFF,0xFA,0x5F,0xFF,0xFF,0xFB, -0xFF,0xFF,0xEF,0xFF,0xFB,0xFE,0xFD,0xFF, -0xFE,0xFF,0xFB,0xFF,0xFF,0xFF,0x7F,0xFF, -0xFE,0xBF,0xDF,0xFF,0xFB,0xFF,0xFF,0xF7, -0xFC,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F, -0xFF,0xFF,0xFF,0xFF,0xFF,0xF2,0x7F,0xFF, -0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF, -0xF3,0xFF,0xFF,0xFF,0xEF,0xFB,0xFF,0xFF, -0xFF,0xDF,0xE2,0xFF,0xFF,0xFB,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFB,0xE7,0xFF,0xFD, -0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xED, -0xEF,0xFD,0xFF,0xFF,0xDF,0xD7,0xF5,0xFD, -0x7F,0x5D,0xFD,0xFF,0x7F,0xDF,0x97,0xF4, -0xFD,0x7B,0x5F,0xFF,0xC9,0xFF,0xFB,0xFE, -0xFF,0xBF,0xFF,0x5F,0xFF,0xFF,0xF7,0xFF, -0xEF,0xFD,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xF7,0xFF,0xD7,0xFD,0x7D,0x7F,0xFF, -0xFF,0xFF,0xFF,0xEF,0xDF,0xF7,0xFD,0xFF, -0xBB,0xFF,0xFF,0x7F,0xFF,0xFE,0xE3,0xFF, -0xF9,0xFE,0x7F,0xBF,0xEF,0xFB,0xFE,0xFF, -0xBF,0xF9,0xFE,0xFF,0x9F,0xEF,0xF9,0xFE, -0xFF,0xBF,0xF3,0xDA,0xFF,0x37,0xCD,0xF3, -0x7C,0xDF,0x37,0xCD,0xF3,0x7F,0x37,0xCD, -0xF3,0x7C,0xDF,0x37,0xCC,0xF3,0x7F,0x5A, -0xBD,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,0xFD, -0xBF,0x6F,0xDE,0xFD,0xBF,0x6F,0xDB,0xF6, -0xFD,0xBF,0x6F,0xFE,0xF1,0x6F,0xEB,0x7A, -0xDE,0xB7,0xAD,0xEB,0x7A,0xDE,0xB7,0xAF, -0x7A,0xDE,0xB7,0xAD,0xEB,0x7A,0xDE,0xB7, -0xFF,0x7E,0xFF,0xFE,0xCD,0xB3,0x6C,0xDB, -0x36,0xCD,0xB3,0x6C,0xDE,0xCD,0xB3,0x6C, -0xDB,0x36,0xCD,0xB3,0x6C,0xDF,0xC9,0xBF, -0xF7,0xBD,0xEF,0x7A,0x9E,0xA7,0xA9,0xEA, -0x7A,0xB7,0xBD,0xEA,0x7B,0xDE,0xA7,0xBD, -0xCA,0x72,0x8D,0x91,0xFF,0xEF,0xFB,0xFE, -0xFF,0xBF,0xEF,0xFB,0xFE,0xF7,0xEF,0xFB, -0xFE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFE, -0x87,0xFF,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6, -0xFD,0xBF,0x6F,0xF6,0xFD,0xBF,0x6F,0xDB, -0xF6,0xFD,0xBF,0x6F,0xFE,0x4F,0xFF,0xBF, -0xEF,0xBB,0xEE,0xFB,0xBE,0xEF,0xBB,0xEF, -0xBE,0xEF,0xBB,0xEE,0xFB,0xBE,0xEF,0xBB, -0xEF,0xFC,0x5F,0xFF,0xFF,0xFF,0x3F,0xCF, -0xF3,0xFC,0xFF,0x3F,0xCF,0xFC,0xFF,0x3F, -0xCF,0xF3,0xFC,0xFF,0x3F,0xCF,0xFD,0x9F, -0xFE,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF, -0xEB,0xFE,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF, -0xAF,0xEB,0xFF,0xE1,0x6F,0xFD,0xFF,0x7F, -0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFD,0xFF, -0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF, -0x7A,0xBF,0xFB,0xFE,0xDF,0xB7,0xED,0xFB, -0x7E,0xDF,0xB7,0xFB,0x7E,0xDF,0xB7,0xED, -0xFB,0x7E,0xDF,0xB7,0xFF,0xC9,0xFF,0xFF, -0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, -0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEE, -0xFB,0xFE,0xBB,0xFF,0xFE,0xFF,0xBF,0xEF, -0xFB,0xFE,0xFF,0xBF,0xEF,0xFE,0xFF,0xBF, -0xEF,0xFB,0xFE,0xFF,0x3F,0xCF,0xFF,0xE7, -0xFE,0xFF,0xF5,0xFD,0x77,0x5D,0xD7,0x35, -0xDD,0x77,0xD7,0xF5,0xCD,0x7B,0x5D,0xD7, -0xF5,0xDD,0x77,0xFE,0x27,0xFF,0xFF,0x8B, -0xE2,0xF8,0xBE,0x2F,0x8B,0xE2,0xF9,0xAF, -0x8B,0xE2,0xF8,0xBE,0x2F,0x8B,0xE2,0xF9, -0xFE,0x1F,0xFF,0x5F,0xD7,0xF5,0xFD,0x7F, -0x5F,0xD7,0xF5,0xFF,0x5F,0xD7,0xF5,0xFD, -0x7F,0x5F,0xD7,0xF5,0xFF,0xFA,0x3F,0xFE, -0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,0xEB, -0xEC,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF, -0xEB,0xFF,0xFE,0x7F,0xFD,0x7F,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6, -0xFF,0xFA,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF, -0xF7,0xFC,0xFF,0xDF,0xF7,0xFD,0xFF,0x7F, -0xDF,0xF7,0xFD,0xFF,0xF5,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0x02,0xFF,0xFE,0xBF,0xAB,0xEB,0xFA, -0xBE,0xBF,0x23,0xEB,0xDE,0x1F,0xAF,0xEA, -0xFA,0xFE,0xAF,0xAF,0xEB,0xFD,0x97,0xFF, -0xF3,0xFC,0x7B,0x1F,0xCF,0xF1,0xFC,0x7F, -0x1F,0xF1,0xFC,0x77,0x1F,0xCD,0xF1,0xFC, -0xFF,0x1F,0xFE,0x87,0xFF,0xAF,0xEF,0xFA, -0xFE,0xFF,0xAF,0xEF,0xFA,0xFD,0xBF,0x2B, -0xFB,0x7E,0xBF,0xBF,0xEB,0xFB,0xFB,0xFB, -0xDF,0xFF,0xFB,0xF7,0xFF,0xFF,0x7F,0xF7, -0xF7,0xFF,0xFD,0xDF,0xFE,0xFC,0xDF,0xFF, -0xDF,0xFF,0xFD,0xFF,0xDA,0xBF,0xFF,0xBB, -0xEF,0xFB,0xF9,0xFF,0xBE,0xEF,0xFB,0xFB, -0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, -0xFF,0xF7,0x7F,0xFD,0xD7,0xFF,0xFF,0x7F, -0xFF,0xFF,0xFF,0xFE,0xF7,0xFF,0xFE,0xFF, -0xF7,0xFF,0xFF,0x7F,0xFF,0xFF,0xEC,0xFF, -0xFF,0xFE,0xDF,0xBF,0xFF,0xFB,0xFE,0xFF, -0xBB,0x68,0xAE,0x1F,0xAE,0xFB,0xFB,0xFF, -0xFF,0xBF,0xFF,0xD5,0xFF,0x7F,0xFF,0xFF, -0xF7,0xFE,0xFE,0xFF,0xBF,0xEF,0x9F,0xFD, -0x7F,0xFF,0xCB,0xFF,0xFF,0xDF,0xFF,0xFF, -0xBB,0xF7,0xBF,0xFF,0xFF,0xFF,0xFF,0xDF, -0xFF,0xBF,0xFB,0xFF,0xFF,0xFF,0xDE,0x3F, -0xFF,0xFF,0xFF,0xFF,0xFF,0xA7,0xFF,0xFF, -0xFF,0xFF,0xEF,0xFF,0x7F,0xFB,0xFD,0xFB, -0x7F,0xFF,0xFF,0xFF,0xFF,0xCF,0xF3,0x7C, -0xFF,0x7F,0x8D,0x7F,0xFF,0xFF,0xFF,0xFF, -0xFB,0xFF,0xF7,0xFB,0xFE,0xFD,0xFF,0xFF, -0xFF,0xFF,0xF7,0xFD,0xFF,0x7F,0xFD,0x1F, -0xFD,0xFF,0xFF,0xFF,0xFF,0xBF,0xDF,0xFF, -0xFF,0xFE,0x5C,0xFF,0x6D,0xFF,0x7F,0xAB, -0xE7,0xF1,0xFF,0xFD,0x9F,0xFF,0xFF,0xAD, -0xEB,0x7A,0x3F,0x1F,0xFF,0xFF,0xFE,0xBF, -0xAF,0xF3,0xDE,0xF5,0xFF,0x8F,0xFB,0xDF, -0xE6,0x7F,0xFF,0xDF,0xF3,0xFD,0xFF,0x7E, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xF7,0xF3, -0x7F,0xDF,0xF7,0xEF,0xFF,0xF6,0x3F,0x9F, -0xDF,0xFF,0xFF,0xEE,0xFF,0xFF,0xEF,0xFB, -0xFF,0xFF,0xF9,0xFB,0xFE,0x4F,0xBF,0xEF, -0xBB,0xFF,0x69,0xAF,0xAF,0xFC,0xFF,0x3F, -0xDD,0xFF,0xFC,0xBF,0x8F,0xFF,0xFD,0xF3, -0xBF,0xED,0x9E,0xFC,0xBF,0x6F,0xF5,0xD3, -0xDF,0xFF,0xDB,0xD6,0xF5,0xEF,0xFD,0xFE, -0xFF,0xB9,0xFF,0x1F,0xD2,0xA9,0xAF,0xFF, -0xDB,0xF7,0xBF,0xEF,0x46,0xFF,0xFF,0xAD, -0xEB,0x7A,0xDF,0xEF,0xF7,0xFF,0x7F,0xF7, -0x9F,0xED,0xFF,0x7F,0xFF,0xAD,0xEB,0x7F, -0xF5,0x6F,0xFF,0xFD,0xFB,0xD6,0xF4,0xF7, -0xFB,0xF9,0x7E,0x7F,0xFF,0x5F,0xC2,0xFE, -0xBF,0xFD,0xFB,0x33,0xDF,0xF9,0x5B,0xFF, -0xFF,0xDD,0x67,0x7D,0xCF,0xEF,0xDB,0xEC, -0xFF,0x77,0xDD,0xF7,0xFD,0xFF,0xFF,0xDE, -0xA7,0xBF,0xD4,0x9F,0xFF,0xFF,0xBF,0xEF, -0xFE,0xFF,0xDF,0xEF,0xBB,0xFF,0xFF,0xEF, -0xEB,0xFA,0xFF,0xEF,0xBD,0xFB,0xFF,0xE2, -0x7F,0xFF,0xDF,0xDF,0xF7,0xFD,0xBF,0xBB, -0x73,0xF7,0xFD,0x7F,0xDF,0xDE,0xF7,0xBF, -0xEA,0xDB,0xF6,0xFF,0xD6,0xFF,0xFF,0x66, -0xFF,0xBE,0xFF,0xBF,0x6B,0xD9,0xF6,0xDF, -0xFF,0xFB,0x7E,0x7F,0xB7,0x7E,0xFF,0xFE, -0xFF,0xCD,0xFF,0xFE,0x7F,0xFF,0xFC,0xFD, -0x3F,0xFB,0xFB,0xF7,0xFF,0xFF,0xFB,0xF6, -0x7D,0xFE,0x7F,0xFF,0xFC,0xFF,0xB9,0xFF, -0xF9,0xFA,0xFE,0xBF,0xAF,0x5B,0xD6,0xED, -0xAD,0x7B,0xF6,0xF9,0xBF,0xEF,0xF8,0xFA, -0xFE,0xBF,0xFE,0xE6,0xFF,0xFF,0xF7,0xFD, -0xFF,0x7F,0xBF,0xEF,0xF3,0xFF,0xFF,0x6F, -0xF7,0xFE,0xFF,0xFF,0xF7,0xFD,0xFE,0xF7, -0xEF,0xFF,0xFB,0xEF,0xFB,0x7E,0xDE,0xFE, -0xFF,0xBF,0xFF,0xFE,0xFF,0xFF,0xFB,0xFF, -0xFF,0xEF,0xFB,0x6F,0xFC,0x1F,0xFE,0xE7, -0xFF,0xFF,0xFF,0xEF,0xFF,0xD3,0xB4,0xBB, -0xFF,0xFF,0xFD,0xBF,0x6F,0xE3,0xFE,0xFF, -0xBF,0xFC,0xBF,0xF7,0xCF,0xF7,0xFD,0xFF, -0x2F,0xDF,0xAB,0xEA,0xFF,0xDF,0xE7,0xEA, -0x9A,0xAF,0xEF,0xFB,0xFE,0xFF,0xF5,0x3F, -0xFD,0x7E,0xFF,0xD7,0xF5,0xFB,0xFF,0xFD, -0xF7,0xFF,0x7F,0xFE,0xF7,0xFD,0xFF,0xD7, -0xFF,0xD7,0x7F,0xEE,0x7F,0xFA,0x79,0xFE, -0x2F,0x8B,0xE6,0xF9,0xFE,0x3F,0x9E,0xF9, -0xBE,0x2F,0x0B,0xE7,0xF9,0xFE,0x2F,0x9F, -0xFD,0xFF,0xFE,0x7D,0x7F,0x5F,0xD7,0xFF, -0xFF,0x7F,0xFF,0xFD,0xFF,0x7F,0x5F,0x97, -0xFF,0xFD,0x7F,0x5F,0xFF,0xE3,0xFF,0xFF, -0xFA,0xFE,0xBF,0xAF,0xFB,0xFB,0xFF,0xFF, -0xCF,0xEB,0xFE,0xBF,0xAF,0xFF,0xFA,0xFE, -0xBF,0xFF,0x87,0xFF,0xFF,0xF5,0xFF,0xFF, -0xFF,0xFF,0xFD,0xFF,0x7F,0xFF,0xFF,0xFF, -0xFB,0xFF,0xFF,0xF5,0xFF,0xFF,0xFE,0x0F, -0xFF,0xFD,0xEB,0xFF,0xFF,0xF7,0xFF,0xEF, -0x7B,0xDF,0xFE,0xFF,0xFF,0xDF,0xF7,0xFD, -0xEB,0x7F,0xDF,0xFF,0x5F,0xFF,0xFF,0xFF, -0xFF,0xFD,0xBF,0xFF,0x7E,0xFA,0xBF,0xC7, -0xDB,0xF7,0xBD,0x3F,0xFB,0xFF,0xF6,0xFF, -0xFA,0xAF,0xFF,0xEB,0xFA,0xFE,0x3F,0x2F, -0xEA,0xFA,0x3E,0xAD,0xC9,0xBA,0xF6,0xAD, -0xAF,0xEB,0xFA,0xF6,0xBF,0xFE,0x7F,0xFF, -0xFF,0xFD,0xFF,0xF1,0x7F,0x3F,0xCF,0xF1, -0xEF,0xFF,0x7F,0xFF,0xBC,0xDF,0xDF,0xF7, -0xDD,0xFF,0xE0,0x7F,0xFF,0xFF,0xFE,0xFF, -0xFA,0xEC,0xBB,0x7F,0x5F,0xFF,0xFB,0xEC, -0xFF,0xEF,0xB7,0xFF,0xF7,0xFF,0xFF,0xB5, -0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xEE,0xDF, -0x5F,0xDF,0xDE,0xFF,0xAE,0xE7,0x77,0xFF, -0xFF,0xDF,0xF7,0xFF,0xE3,0xFF,0xFA,0xBB, -0xFE,0xFF,0xAF,0xFD,0xFB,0xFE,0xBF,0xAB, -0xF9,0xFE,0xFF,0xBF,0x7F,0xBF,0xFE,0xBD, -0xFE,0xD7,0xFF,0x9F,0xFD,0xFF,0xBE,0xEF, -0xFF,0xEE,0xFD,0xBB,0x5B,0xEF,0xFF,0x7F, -0xEF,0xFF,0xEF,0xFF,0x7F,0xFF,0x4F,0xFF, -0xEF,0xFB,0xBC,0xFC,0xFF,0xFF,0xFF,0xFE, -0xFE,0xFD,0xFA,0xFE,0xFB,0xFF,0xFD,0xF3, -0xFB,0xFF,0xF8,0x5F,0xFF,0xFF,0xD7,0xF5, -0xFD,0xDF,0xEF,0xFF,0xF3,0xDC,0x5F,0xCE, -0xF5,0xBD,0xFF,0xFF,0xD7,0xFF,0xFF,0xF9, -0x3F,0xFF,0xDF,0xF7,0xFF,0xFE,0xFF,0xFD, -0xFF,0xFB,0xFF,0xF7,0xB9,0x7D,0xFE,0xDF, -0xFF,0xFF,0xFF,0xFF,0xF9,0x7F,0xFF,0xFE, -0xFF,0xFF,0x7F,0xFF,0xFE,0xFF,0xFF,0xF7, -0xF6,0xFF,0xBF,0xF1,0xF8,0xFF,0xFF,0xFF, -0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF, -0xFF,0xFF,0xFF,0xFF,0xEF,0xEF,0xFF,0xFF, -0x9B,0xFB,0x7F,0xFF,0xFF,0xFF,0xC1,0xFF, -0xDF,0xFF,0x3F,0x5F,0xD7,0xBF,0xEF,0xBB, -0xDE,0xEE,0xFF,0x7F,0xDF,0xFF,0xFE,0xF5, -0x7F,0xDF,0xFF,0x99,0xFF,0xFF,0xFA,0xFF, -0xBF,0xFD,0xEB,0x7A,0xFF,0xB7,0xFE,0xFE, -0xFF,0xFF,0xEF,0xFF,0xFF,0xFD,0xBF,0xFF, -0x97,0xFF,0xFD,0xF7,0xFF,0x7F,0xF7,0xFF, -0xFF,0xFD,0x5F,0xFE,0xF3,0xF9,0xDF,0xDF, -0xFF,0xFF,0xFC,0xFF,0xFF,0x83,0xFF,0xFF, -0xFE,0xFF,0x9E,0xEC,0xFB,0xEE,0xFF,0x9F, -0xBF,0xEF,0xFF,0xFE,0xED,0x7B,0xFF,0xFF, -0xFF,0xF1,0x5A,0xFF,0xFF,0xFD,0xFF,0x7C, -0x69,0x3B,0xDF,0xFF,0x7F,0x1F,0xDF,0xFF, -0xFD,0xBA,0xFF,0xFF,0xFB,0xFF,0x5B,0xBD, -0xFF,0xFF,0xFF,0xFF,0xD7,0xB6,0xED,0xE9, -0xFF,0xD6,0xBD,0x6F,0x5F,0xFB,0xFF,0xEF, -0xFF,0x5F,0xFE,0xF6,0x6F,0xFF,0xFF,0xFF, -0xFF,0xF7,0xEB,0x7A,0xDF,0xFF,0x9F,0x7F, -0x7F,0xFF,0xB7,0xFF,0xFF,0xFE,0xDF,0xFF, -0x6C,0xFF,0xFB,0xFF,0xBB,0x6F,0xEB,0xFE, -0xCC,0xF7,0xA5,0xFA,0x5C,0xF5,0x75,0xBB, -0xB7,0xDF,0xFE,0x6F,0x5F,0xC5,0xBF,0xFD, -0x7B,0xFE,0xFF,0x95,0xE7,0x29,0xCF,0x4F, -0xF5,0x91,0xEE,0x6B,0xDF,0xEF,0xFD,0x54, -0xF5,0xBD,0xB1,0xFF,0xEF,0xEE,0xFB,0xBE, -0xBF,0xAF,0xFE,0xDE,0xBD,0x6F,0xDA,0xF2, -0xFF,0xAF,0xBE,0xFF,0xFF,0xFD,0x7E,0xA7, -0xFF,0xF7,0xFF,0xBF,0xEF,0x7B,0xF6,0xFD, -0xBD,0x4A,0xF2,0x85,0x85,0xBF,0x5B,0xFE, -0xB5,0xFD,0xFA,0xFF,0x4F,0xFF,0xFE,0xDF, -0xFF,0xED,0xFF,0xBF,0xFF,0xBF,0x7F,0xFE, -0xFF,0xB7,0x6D,0xFF,0xF7,0xBF,0xBF,0xEF, -0xFD,0x1F,0xFF,0xFE,0x7D,0xFF,0x67,0xFF, -0xFF,0xFF,0x3F,0x7F,0xFE,0xBF,0xFF,0xE7, -0xDF,0xE7,0xFF,0xEF,0x6B,0xFC,0x1F,0xFF, -0xBF,0xEF,0xFB,0xFE,0xDE,0xBF,0xAF,0xFA, -0xFF,0xB6,0xEF,0xF9,0xFE,0xFF,0x8F,0xEF, -0xDB,0xEF,0xAB,0x6F,0xFB,0xFE,0xFF,0xFF, -0xEF,0xFD,0xFF,0x7F,0xFF,0xFF,0xDE,0xFF, -0xFF,0xEF,0xFF,0xFF,0xFF,0x3F,0xFF,0x6C, -0xFF,0xBF,0xFB,0xFF,0xFE,0xFF,0xFB,0xFE, -0xDF,0xFF,0xFF,0xEF,0xFF,0xFF,0xBF,0xFF, -0xFF,0xFE,0xFB,0xFF,0xD5,0x7F,0xFF,0xFF, -0xEF,0xFB,0xFF,0xFF,0xBF,0xEF,0x43,0xB5, -0xFD,0x6F,0xCF,0xD6,0xBE,0x3F,0x7F,0xDB, -0xFE,0xC3,0xFF,0xFD,0xFF,0xAF,0xEB,0xFB, -0xFC,0xFF,0x3E,0xEF,0xE8,0xFA,0xBD,0xCD, -0xAA,0xFE,0xFE,0x7D,0xCF,0xFF,0xB7,0xFF, -0xF7,0xFF,0xFF,0xFF,0xFD,0xFF,0x75,0xCD, -0x52,0xD7,0xFD,0xFB,0xF7,0xDD,0xFB,0xEF, -0xEB,0xFF,0xFF,0x4F,0xFF,0xBF,0x9F,0xE7, -0xF9,0xFC,0x7F,0x8B,0xC3,0xF9,0xAF,0x8F, -0xE7,0xE9,0xBE,0x7F,0x9F,0xE6,0xF9,0xFC, -0x5F,0xFF,0xFF,0xF7,0xFD,0xFF,0x7A,0x5F, -0xD7,0xED,0xFF,0xFF,0xD7,0xFF,0xDD,0x7F, -0xE7,0xFF,0xFC,0xFF,0xFC,0x3F,0xFF,0xFF, -0xFF,0xFB,0xFF,0xFE,0xBF,0xAF,0xFF,0xFD, -0xFF,0xEF,0xFF,0xEB,0xFF,0xFF,0xFF,0xFF, -0xFF,0xF7,0x7F,0xFF,0x7F,0xDF,0xFF,0xFD, -0xFD,0x7F,0xFE,0xF7,0xFD,0x7F,0xDF,0xFF, -0xFD,0xFF,0xFF,0xDF,0xFB,0xFF,0xEE,0xFF, -0xFB,0xFF,0xF7,0xFD,0xFF,0x7A,0xDF,0xF5, -0xFD,0xFA,0xDF,0xF7,0xFC,0xFF,0x7F,0xDF, -0xBF,0xED,0xFF,0xC9,0xFF,0xDF,0xFF,0xBF, -0x2F,0xFB,0xFF,0xBC,0xAD,0xFF,0xF7,0xFF, -0xFF,0xEF,0xD3,0xFF,0x7D,0xBF,0x6F,0xFF, -0xFA,0xFF,0xFE,0xBF,0xAE,0xEA,0xFA,0xBE, -0xAD,0xA5,0xEB,0xCE,0xBF,0xA7,0xEB,0x5A, -0xDE,0xBD,0xAF,0x6B,0xFD,0x57,0xFF,0xFF, -0xF4,0x7F,0x1F,0x7F,0xFD,0xFF,0x7F,0x36, -0xF0,0xDF,0x79,0xFF,0xFF,0xFF,0xF7,0xFD, -0xBF,0xFF,0x87,0xFF,0xFB,0xF3,0xFC,0xFF, -0xFF,0xFF,0xFF,0x7E,0xFF,0xBF,0xDF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,0xF8,0x9F, -0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFD, -0xF7,0xFC,0xBD,0xFF,0xFE,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFB,0xF9,0xBF,0xFF,0xFF,0xEB, -0xE2,0xFE,0xFF,0xBF,0xEF,0xA9,0xBA,0x2F, -0xEB,0xF9,0xFE,0x77,0xDF,0xF7,0xFF,0xFF, -0xF9,0x7F,0xFF,0xFF,0x7F,0xEF,0xD7,0xFF, -0xFD,0xFF,0xFB,0xF5,0xFF,0xBF,0x6F,0xDF, -0xFF,0xFF,0xFD,0xFF,0xFF,0xF0,0xFF,0xFF, -0xFF,0x3F,0xCF,0xFF,0xBA,0xEE,0x9B,0xBF, -0xEE,0xD7,0xFE,0xCD,0xEF,0xFF,0xDF,0xBF, -0xFF,0xFF,0xC5,0xFF,0xFF,0xFD,0x7F,0x4F, -0xFD,0xF6,0xD9,0xFF,0x4F,0xD6,0xFD,0xBF, -0x6E,0xFF,0xFF,0xF4,0x7F,0xFF,0x7F,0x8B, -0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xF9,0xFE, -0x37,0xFF,0xD9,0xFB,0xF5,0xAF,0xFD,0xFF, -0xFF,0xFB,0xFF,0xFF,0x07,0xFF,0xFF,0xFF, -0xFB,0xF7,0xFF,0xFD,0xFF,0x7C,0xFA,0x7E, -0x4F,0xFC,0xDF,0x1D,0xC7,0xFF,0xFF,0xFF, -0xFF,0xAE,0xFF,0xFF,0xFF,0xFF,0xFD,0xFB, -0xFF,0xFF,0xFE,0xFE,0xFC,0xFF,0x7F,0x7F, -0xBF,0xEF,0xFE,0xFF,0xFF,0xFF,0x5F,0xFD, -0xFF,0xFF,0xFF,0xFD,0x6F,0x5A,0xD7,0x7B, -0xBE,0x5F,0xFE,0x39,0xFF,0xF7,0xFF,0xF7, -0xFD,0xFE,0xAA,0x1F,0xFF,0xFF,0xFF,0xFF, -0xFE,0xFE,0xAB,0xAF,0xFD,0xFE,0xBF,0xFF, -0xF7,0xFF,0x7F,0xFE,0x8F,0xE3,0xFB,0xEE, -0x7F,0xFF,0xFF,0xFF,0xFF,0xEB,0xFB,0xFF, -0xFD,0xBF,0xEF,0xDF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFB,0xE4,0x3F,0xFF,0xDF, -0xFF,0xFF,0xFF,0xFF,0xF3,0xEF,0xBB,0xFB, -0xBF,0xEF,0xBB,0xFF,0xD7,0xBF,0xFF,0xFF, -0xFF,0x29,0xAF,0xF7,0xFF,0xFF,0xFB,0xFF, -0xFB,0xE6,0xFF,0x0F,0xFB,0x3F,0xDF,0x0F, -0xFF,0xAF,0xFF,0xFF,0xFF,0xF5,0xC3,0xDF, -0x5F,0xFF,0xFF,0xFF,0xFE,0x6B,0xCA,0xBE, -0xBC,0xFF,0x9F,0xF2,0xBF,0xFF,0xFE,0xFA, -0xFF,0xFF,0xEF,0x16,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFC,0xDF,0x97,0xFD,0x79,0xFF,0x37, -0xE7,0x7F,0xFF,0xFF,0xB5,0xFF,0xFF,0xF6, -0x2F,0xFF,0xFD,0xFB,0xFE,0xFF,0xFF,0xFD, -0x5F,0x57,0x5F,0xFF,0xDB,0x52,0xDF,0xFF, -0xFD,0xBF,0xFF,0xFF,0xFC,0xDB,0xFF,0x7B, -0xB5,0xFD,0x7F,0xFF,0x71,0x9C,0x6E,0xFF, -0xF6,0x35,0xA5,0x9B,0xFF,0xFF,0xFD,0xFF, -0xFF,0xDB,0x9E,0x7F,0xFE,0xEF,0xFB,0xFF, -0xFF,0xBD,0xEF,0xFF,0xDE,0xB7,0xF9,0x4B, -0xFF,0xF5,0xEF,0xFF,0xFF,0xFF,0xE8,0x7E, -0xFF,0xEA,0xDF,0xF7,0xFF,0xFD,0x69,0x5B, -0xFC,0x9F,0xEF,0x78,0xD6,0xFF,0xEB,0xEF, -0xFF,0xFF,0xFF,0xE8,0xFF,0xFF,0xED,0xFF, -0xFF,0xFF,0xFF,0xE3,0xF9,0xF6,0xBF,0xFF, -0xFF,0xFE,0xDF,0xFF,0x7F,0xFF,0xFF,0xFF, -0xD1,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF, -0xE7,0xF9,0xFF,0xBF,0x7F,0xD9,0xFF,0xFD, -0xFE,0x7F,0xFF,0xFE,0xFF,0xF9,0xFF,0xFB, -0xD6,0xDF,0xBF,0xEF,0x5B,0xD6,0xFF,0xBF, -0xFB,0xF6,0xFF,0xBF,0xEF,0xF8,0xF6,0xDD, -0xBE,0xFE,0x16,0xFF,0xBF,0xEF,0xFF,0xFE, -0xFF,0xBF,0xEF,0xFF,0xFF,0xFF,0x6F,0xFB, -0xFF,0xFF,0xFF,0x6F,0xF3,0xFF,0xF7,0xEF, -0xFB,0xFF,0xBF,0xFF,0xEF,0xFE,0xFF,0xBF, -0xFF,0xFF,0xFF,0xBE,0xBF,0xFF,0xEF,0xFF, -0x7F,0xEF,0xFF,0xFD,0x17,0xFB,0x7B,0xFF, -0xFF,0xFD,0x7F,0xDB,0xF6,0xF4,0x7F,0xFA, -0xFE,0xF5,0xBF,0xEB,0xE3,0xF7,0xFF,0xFF, -0xE9,0xBF,0xFF,0xAF,0xF7,0xFD,0xF3,0x7E, -0x8F,0xA3,0xEA,0xFF,0xCB,0xF3,0xEE,0xFF, -0xBF,0xEF,0xF7,0xF9,0xFF,0xFE,0x7F,0xFF, -0xFF,0xFF,0xFF,0xF5,0xFB,0xF6,0xFF,0xF5, -0x2F,0xFE,0xFB,0xD7,0xBF,0xFF,0xBE,0xDF, -0x9F,0xFF,0xF0,0xFF,0xFF,0xF9,0xFE,0x7F, -0x8F,0xA3,0xF8,0xFE,0x6F,0x9F,0xF9,0xF6, -0x2F,0x9F,0xE7,0xF9,0xFE,0x2F,0x9F,0xE1, -0xFF,0xFF,0xFF,0x7F,0xDF,0xF7,0xF5,0xFD, -0x7F,0x7F,0xF5,0xFF,0x9F,0x5F,0xFB,0xFE, -0xFF,0x7F,0xFF,0xFF,0xCB,0xFF,0xFF,0xFB, -0xFE,0xFF,0xBF,0xAF,0xFB,0xFE,0xFF,0xDF, -0xFE,0xFE,0xBF,0xF7,0xFF,0xFF,0xFF,0xFF, -0xFF,0xC7,0xFF,0xFF,0xFD,0xFF,0x7F,0xDD, -0xF7,0xFD,0xFF,0xFF,0xD7,0xFF,0xFD,0x7F, -0xFF,0xFB,0xFD,0xFF,0xFF,0xFE,0xEF,0x7F, -0xFD,0xEF,0xFB,0xFE,0xFB,0xFD,0xFF,0x7F, -0xDF,0xFD,0xFF,0x7A,0xDF,0xF7,0xFD,0xFF, -0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xD3,0xF7, -0xFF,0xFF,0x6F,0xDB,0xFF,0xFF,0xEF,0xCB, -0xF4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, -0x29,0xFF,0xE8,0xDA,0x76,0x9F,0xAF,0x6A, -0xDA,0xFE,0x35,0xEB,0xDA,0xD6,0xBF,0xAB, -0xEB,0x7A,0xDE,0xBF,0xD7,0x7F,0xFF,0xFE, -0xFF,0xBF,0xEF,0xFD,0xDF,0x77,0xBF,0xFD, -0x37,0xEF,0xFF,0xEF,0xFF,0x3F,0xFF,0xFF, -0xFF,0xFE,0x7F,0xFF,0xFF,0xFF,0xF7,0x7E, -0xDF,0xFF,0xFF,0xFF,0xFA,0xB7,0x7F,0xFF, -0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x89,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0x9F,0xFB,0xFF,0xFF,0xFF,0xE7,0xFF, -0xFF,0xFF,0xFF,0xAA,0xFF,0xAB,0xFB,0xFA, -0xEF,0xBF,0xFF,0xDF,0xFA,0x7B,0xB9,0xFE, -0xFE,0xFF,0xFD,0xFF,0xF7,0xFE,0x3F,0xFF, -0xB7,0xFF,0xF7,0xEE,0xFF,0x7F,0xEF,0xFF, -0xFF,0x7F,0xFF,0x1F,0xFB,0xFF,0xBF,0xFB, -0xFE,0xFF,0xBD,0xFF,0xFF,0x2F,0xFF,0xBF, -0xFF,0x7F,0xDF,0xFA,0xFF,0xFF,0xFC,0xEE, -0xF5,0xF3,0xBE,0xFB,0x0F,0xEF,0xF3,0xBE, -0xEF,0xFC,0x5F,0xFF,0x5A,0xFF,0xF7,0xDF, -0xFF,0xFF,0xFE,0xD5,0xFC,0x5F,0xFB,0xF2, -0xFF,0xFF,0x2F,0xBB,0xF3,0xFF,0xFF,0xBF, -0xFF,0xEF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF, -0xBF,0xFF,0xFF,0xFD,0x7B,0xFF,0xDF,0xB9, -0xFF,0xFB,0xFF,0xD8,0x7F,0xFF,0xFF,0xFF, -0xFB,0xFF,0xFC,0x7F,0x1F,0xBF,0xE0,0xDF, -0xF7,0xEF,0xFF,0xFD,0x7F,0xFE,0xDF,0xFF, -0xE0,0xFF,0xFF,0xFD,0xEF,0xFB,0xFF,0xFE, -0xF7,0xDF,0xFF,0xEB,0x5F,0xFF,0xF7,0xFF, -0xFF,0xFF,0xFF,0xBF,0xFF,0xFD,0xFF,0xFD, -0xFF,0xFF,0xFF,0xF7,0xFD,0xFF,0x3B,0xDC, -0xFD,0x6D,0x7B,0x5F,0x57,0xF5,0xFD,0x7F, -0x5F,0xFF,0xB1,0xFF,0xEB,0xFF,0xFF,0xFF, -0xFB,0xFB,0xFE,0xFF,0xBF,0xFB,0xBE,0xFF, -0xBF,0xEF,0xFB,0xFE,0xFF,0xAF,0xFE,0xF7, -0xDF,0xDF,0xFF,0xFF,0xFF,0x7F,0xCF,0xF3, -0xF8,0xFF,0xD7,0xFB,0xFF,0x5F,0xBF,0xF7, -0xFB,0xFF,0x7F,0xFE,0x23,0xFF,0xFF,0xFE, -0x7F,0xF3,0xFF,0xFB,0xFE,0xFF,0xFF,0xF3, -0xFF,0xFF,0xF5,0xF9,0xFF,0x3F,0xFF,0xFF, -0xF0,0x9A,0xFF,0xBE,0x7F,0xFF,0xFC,0xF9, -0xFF,0xFD,0xAF,0xEB,0xFE,0xBF,0xFF,0xCF, -0xF3,0xFE,0x7F,0xFF,0xFF,0x5B,0xBD,0xFF, -0xBC,0xEB,0xFF,0xD7,0xD4,0xAF,0xAF,0xFD, -0xFF,0xCF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7, -0xFD,0xFE,0xFF,0x6F,0xFF,0xFB,0xFF,0xFF, -0xFF,0xFD,0x7F,0x5E,0xFD,0xBF,0xDB,0xF6, -0xFD,0xBF,0x6F,0xFB,0xEE,0xFD,0xFF,0x7A, -0xFF,0xFA,0xFB,0xFF,0x3F,0xFB,0xB7,0x5F, -0xD6,0xF7,0x1F,0x71,0xDC,0x77,0x1D,0xC7, -0x31,0xDC,0x77,0xDF,0xF9,0xBF,0xF5,0x5B, -0xF4,0xD7,0x9D,0xAE,0xFF,0xBF,0xFD,0xBF, -0xDB,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,0xFE, -0x3D,0x81,0xFF,0xEB,0xFE,0xFE,0xFE,0xFF, -0xEB,0x7A,0xDF,0x7D,0x77,0x7D,0xF5,0x79, -0xDF,0x57,0xDD,0xF5,0x7D,0x7E,0xE6,0xFF, -0xD6,0x3F,0xBF,0x7F,0xFF,0xD4,0xF5,0x3F, -0xBF,0xFB,0xBE,0xEF,0xB3,0xEE,0xFB,0x9E, -0xEF,0xBB,0xFE,0x8B,0xFF,0xFE,0xDF,0xB7, -0xED,0xFF,0xF7,0xFD,0xFE,0xFF,0xEF,0xBB, -0xEE,0xFF,0xBE,0xEF,0xBB,0xEE,0xEB,0xFC, -0x1F,0xFF,0xFF,0xFD,0xFF,0xE7,0xFF,0xF7, -0xFD,0xFF,0xEF,0xFE,0xFF,0xBF,0xEF,0xFB, -0xFE,0xFF,0xBF,0xEB,0xFA,0x1F,0xFF,0xB7, -0xEF,0x5B,0xFE,0xFF,0xAF,0xEB,0xDD,0xE7, -0xDE,0x77,0x9D,0xE7,0x79,0xDE,0x77,0x9D, -0xBF,0xE6,0x6F,0xFF,0xFE,0xFF,0xBF,0xEF, -0xFB,0xFE,0xFD,0xBF,0x6F,0xF6,0xFD,0xBF, -0x6F,0xDB,0xF6,0xFD,0xBF,0xFF,0x7E,0xFF, -0xFF,0xFB,0xFE,0xFE,0xFF,0xEF,0xFB,0xFD, -0xEF,0x7E,0xF7,0xBD,0xEF,0x7B,0xDE,0xF7, -0xBD,0xEF,0xFF,0xD5,0xFF,0xBF,0xFF,0xEF, -0xFE,0xFF,0xFC,0x3F,0x0F,0xE7,0xFE,0x7F, -0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7,0xFE, -0xF3,0xFF,0xFE,0xDF,0xAD,0xDF,0x67,0xEE, -0xFB,0xBF,0xEF,0xFE,0xFF,0xBF,0xEF,0xFB, -0xFE,0xFF,0xBF,0xEF,0xFF,0x23,0xFF,0xFF, -0xFF,0xFF,0x7F,0xFF,0xF3,0xBC,0xDB,0xFE, -0xFB,0xFF,0xFB,0xBE,0xF7,0xFB,0xFF,0x7F, -0xDF,0xFF,0xCF,0xFB,0xFF,0x9F,0xE3,0xF9, -0xBE,0x3F,0x8F,0xE7,0x79,0xFF,0x9D,0xE7, -0xF9,0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x5F, -0xFF,0xCF,0xF7,0xFF,0xFF,0xFF,0xDF,0xF7, -0xFE,0x7F,0xE7,0xF9,0xFE,0x7F,0xFF,0xFF, -0xFB,0xFE,0xFF,0xFF,0xBF,0xFF,0xBF,0xBF, -0xFF,0xFE,0xFF,0xBF,0xEF,0xFF,0xFD,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFD,0xFF, -0xFF,0x3F,0xFF,0xBF,0xFF,0xF7,0xFF,0xFF, -0x7F,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xE8,0xEF,0xFF, -0x5F,0xF7,0xBF,0xF9,0xFE,0xDF,0xB7,0xFD, -0xFF,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7, -0xFD,0xFF,0xDD,0xFF,0xF2,0xFF,0xBF,0xFF, -0xFF,0xBF,0xFF,0xFF,0x2F,0xF2,0xFF,0xBF, -0x2F,0x7B,0xD2,0xF7,0xBF,0x2F,0xFF,0xBB, -0xFF,0xEE,0x8F,0xAF,0xEB,0xFA,0xFE,0x3F, -0xA7,0x69,0xCE,0x8F,0xA4,0xEA,0xFA,0xEE, -0xB7,0xAE,0xEB,0xFD,0xC7,0xFF,0xF7,0xF7, -0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3E,0xF3, -0x74,0xFF,0x3F,0x4F,0xFF,0xE7,0xFF,0x3F, -0xFE,0xA7,0xFF,0xFF,0xDF,0xF7,0xB7,0xFF, -0xF7,0xFF,0xBA,0xEF,0x37,0xEB,0xFB,0xFE, -0xBF,0xFB,0xFE,0xF3,0xFF,0xF9,0xDF,0xFF, -0xBF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF, -0xFD,0xDF,0xFF,0xFD,0xFF,0xFF,0xFB,0xFE, -0xFD,0xFF,0xFB,0xBF,0xFE,0x3F,0xED,0xFF, -0xDF,0xBE,0x3D,0xA7,0xFB,0xFA,0x3F,0xE6, -0xE1,0xFE,0xFE,0x3F,0xEF,0xE3,0xDF,0xF5, -0x7F,0xFE,0xFF,0x7E,0xFF,0xFF,0xFF,0xFF, -0xEF,0x6F,0xF6,0xFF,0x7D,0xEF,0xD7,0xDE, -0xFF,0x7D,0xEF,0xFF,0xF2,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0x7B,0xDE,0xFB,0xE6,0xEE, -0xEF,0x37,0x6E,0xF3,0x7E,0xEB,0x37,0xEF, -0xFF,0xC1,0xFF,0xFE,0xFF,0xF7,0xEF,0xFF, -0xFF,0xFF,0xBF,0x3F,0xD2,0xDF,0xBF,0x2F, -0x7B,0xE2,0xFF,0xFE,0x3B,0xBD,0xDB,0xFF, -0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFE, -0xFF,0xFB,0xFF,0xFF,0xBF,0xFF,0xFB,0xDF, -0xFF,0xBF,0xFF,0xB7,0xFF,0xFF,0xBF,0xEF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF, -0x7F,0xFF,0x1F,0xEF,0xF1,0xFD,0xFF,0xF6, -0xAF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF, -0xFF,0xFF,0xFE,0x9F,0xFF,0xFF,0xFF,0x77, -0xEF,0xF7,0xFB,0xFF,0xFE,0x5F,0xFF,0xFF, -0xBF,0xCF,0xFB,0xF7,0xDD,0xF7,0xF5,0xFF, -0x5F,0xD5,0xF5,0xFD,0x7F,0x5F,0xD7,0xF5, -0xFF,0xFB,0x0F,0xFF,0xFF,0xA9,0xEA,0x7A, -0xFF,0xAF,0x8F,0xFE,0xDF,0xAF,0xEF,0xFB, -0xFE,0xFF,0xBF,0xEF,0xFB,0xDF,0xE5,0x5F, -0xFF,0xFF,0xFF,0xFF,0xFF,0xBD,0x57,0xFF, -0xFF,0x6F,0x77,0xBF,0xF7,0xFB,0xFF,0x7F, -0xBF,0xF7,0xFF,0xFC,0xBF,0xFF,0x9F,0xFF, -0xFF,0xEF,0xFF,0xFE,0xFF,0xFF,0xFF,0x1F, -0xCF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFF,0xFB, -0x65,0xAF,0xF3,0x7C,0xFF,0x3F,0xDF,0xFF, -0xFD,0xE9,0xFE,0x7F,0xE7,0xFF,0xFE,0x7F, -0xFF,0xFF,0xFF,0xFF,0xFD,0xE3,0xDF,0xFB, -0xDB,0xF6,0xFD,0xEF,0x5B,0xFB,0xFF,0xDF, -0xFC,0xFF,0x3F,0xDF,0xF3,0xFD,0xFF,0x7F, -0xDF,0xEF,0x66,0xFF,0xDF,0xAD,0xEB,0x7A, -0xDE,0xF7,0xF7,0xE7,0xD9,0xFD,0x9F,0x67, -0xD9,0xF6,0x7D,0x9F,0xE7,0xDF,0xF5,0x47, -0xFD,0x65,0x5B,0xD6,0xF4,0xFE,0xFF,0xEF, -0xFF,0x6D,0xF6,0xDD,0xB7,0x6D,0xDB,0x76, -0xDC,0xB7,0x7D,0xFA,0x9B,0xF6,0x6D,0x9D, -0x67,0x59,0xDF,0xF7,0xDD,0xFF,0xEB,0xFE, -0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,0xE3, -0xD1,0x9F,0xFF,0xBD,0xBF,0xEF,0xFE,0xF7, -0xBF,0xBF,0xF7,0xD7,0x7F,0xDD,0xF7,0x9D, -0xDF,0x7F,0xDF,0xF7,0xFF,0xE0,0x7F,0xFD, -0xC1,0xDF,0xF7,0xFD,0xC7,0x7F,0x7F,0xFB, -0xFF,0xBB,0xEC,0xFB,0x3E,0xFF,0xBF,0xEC, -0xFB,0xFF,0xD8,0x7F,0xBF,0x6C,0xFF,0xBE, -0xFF,0xBF,0xED,0xFF,0xEF,0xFE,0xFB,0xBF, -0xEF,0xFB,0xFE,0xFF,0xBF,0xEE,0xFF,0xC5, -0xFF,0xAF,0x6F,0xFF,0xFC,0xFD,0x3F,0xE7, -0xFF,0xFE,0xFF,0xEF,0xFB,0xFE,0xFF,0xBF, -0xEF,0xFB,0xFE,0xBF,0x89,0xFE,0xFA,0xBA, -0xFE,0xBF,0xAF,0xFB,0xF6,0xF5,0xD9,0x7D, -0x97,0x65,0xD9,0x74,0x5D,0x97,0x65,0xD3, -0xFE,0xD6,0xFF,0xBF,0xF7,0xFD,0xFF,0x7F, -0xBF,0xCF,0xFB,0xFE,0xFF,0xEF,0xFB,0xFE, -0xFF,0xBF,0xEF,0xFB,0xFF,0xF6,0x8F,0xFB, -0xFF,0xEF,0xFB,0x7E,0xDB,0xFE,0xFF,0xBE, -0xEF,0xEE,0xFB,0xBE,0xEF,0xBB,0xEE,0xFB, -0xBE,0xFF,0xFF,0xDF,0xFF,0x43,0xFF,0xFF, -0xFB,0xEF,0x5F,0xB7,0xFE,0x7F,0xE7,0xF9, -0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0xF9, -0xBF,0xFE,0xAF,0x77,0xFD,0xFF,0x2F,0xAF, -0xA7,0xFE,0xFF,0xEF,0xFB,0xFE,0xFF,0xBF, -0xEF,0xFB,0xFE,0xFF,0xF1,0x7F,0xEF,0xDF, -0xFF,0x97,0xF5,0xEF,0xFF,0xDF,0xFF,0xFF, -0xBF,0xFF,0xBF,0xFF,0xFF,0xFE,0xFF,0xFF, -0xFF,0xE0,0xFF,0xFF,0xF9,0xFE,0x2F,0x8B, -0xE3,0xF8,0xBE,0x77,0x9F,0xF9,0xDA,0x77, -0x9D,0xE7,0x79,0xDE,0x77,0x9F,0xDD,0xFF, -0xFD,0xFD,0x7F,0x5F,0xD7,0xFD,0xFF,0x7F, -0xE7,0xFE,0x7F,0x97,0xE7,0xFB,0xFE,0xFF, -0xBF,0xEF,0xFF,0xAB,0xFF,0xEF,0xFA,0xFE, -0xBF,0xAF,0xFF,0xFA,0xFF,0xFF,0xDF,0xFF, -0xFB,0xFF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF, -0x67,0xFF,0xF7,0xF5,0xFF,0xFF,0xFF,0xDF, -0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xBD, -0xEB,0xFF,0xFF,0xF7,0xAD,0xEB,0xFF,0xDF, -0xFD,0xFF,0x3F,0xDF,0xF7,0xFD,0xFF,0x7F, -0xDF,0xFF,0x5F,0xFF,0xF7,0xFF,0xFF,0xFD, -0xBF,0xFF,0xCB,0xF4,0xFF,0x7F,0xD3,0xF7, -0xFD,0x3F,0x7F,0xD3,0xF7,0xFF,0xFC,0x3F, -0xFF,0xEA,0xFA,0xBE,0xAF,0xAB,0xEB,0xBA, -0xF4,0x95,0x6B,0x52,0xD4,0xAD,0x2F,0x4A, -0xD2,0xF6,0xBF,0xD2,0x7F,0xF7,0x3F,0xFF, -0xFF,0xF3,0x7F,0xFF,0xFF,0xF7,0xFF,0xBA, -0xDF,0xFB,0xFD,0xFF,0xBF,0xFF,0xFB,0xFF, -0xF8,0x7F,0xEA,0xFF,0xFE,0xFE,0xDF,0xFF, -0xF7,0xFF,0x7F,0xBB,0xFF,0xFF,0xBF,0xDF, -0xFB,0xFF,0xFF,0xBF,0xFF,0xB1,0x7F,0xFF, -0xFB,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF, -0xCF,0xFE,0xFF,0xFF,0xEF,0xFF,0xF7,0xFF, -0xFF,0xFF,0xF1,0xFF,0x69,0xBE,0xFA,0xBF, -0xAF,0xE2,0xFF,0xFE,0xFD,0xAF,0xF3,0xFE, -0xFF,0xBF,0xEF,0xFB,0xFC,0xFF,0xFF,0x07, -0xFD,0x95,0xDB,0xDF,0x7F,0xDF,0xAF,0xFF, -0xF7,0xAF,0x36,0xFE,0xBF,0x65,0xEB,0xF6, -0xFE,0x9F,0x6F,0xFE,0x07,0xFF,0xCF,0xFF, -0xF8,0xFE,0xFF,0xCF,0xFF,0xF6,0xFA,0xE7, -0xFB,0xFE,0xFF,0xBB,0xED,0xF9,0xFF,0xFF, -0xFF,0x5F,0xFF,0xFF,0xFF,0x75,0xFF,0xEF, -0x7E,0xFD,0xE0,0xE8,0x5E,0xD3,0xE5,0xF9, -0x3E,0x5F,0xD7,0xF7,0xFF,0xFA,0x2F,0xFB, -0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0x7F, -0x7F,0xD7,0xF5,0x7D,0x5F,0x57,0xD5,0xF5, -0xEF,0xFF,0xF3,0x7F,0xFC,0x7F,0xFF,0xC7, -0xF1,0xFF,0xFF,0x1F,0xCF,0xB0,0xFF,0x3F, -0xCF,0xF3,0xFC,0xFF,0x3F,0xCE,0xFF,0xE4, -0xFF,0xDF,0x7F,0xFE,0xF7,0xBB,0xFF,0xFF, -0xDF,0xEF,0xEE,0xFF,0xBF,0xEF,0xFB,0xFE, -0xBF,0xBF,0xEF,0xFF,0xD1,0xFF,0xFF,0xFF, -0xFD,0xFB,0xFF,0xFD,0xFF,0xFB,0x9F,0xE9, -0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0xBF, -0xFF,0xB3,0xFF,0xFF,0xF7,0xFF,0xFF,0xAF, -0xF7,0xFF,0xB6,0x3F,0xEB,0xFA,0xFE,0xBF, -0xAF,0xEB,0xFA,0xFE,0xBF,0xFE,0xA7,0xFF, -0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF, -0xFE,0x9F,0xF7,0xF9,0xFF,0x7F,0x9F,0xE7, -0xFF,0xFF,0xFE,0xAF,0x6F,0xFF,0xFF,0xFF, -0x9F,0xFF,0xDF,0xFF,0x7D,0x5F,0xDD,0xFF, -0xFB,0xBF,0xE7,0xBB,0xFF,0xFB,0xDF,0x6D, -0x5F,0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xEB,0xF7,0xFF,0xE7,0xEF,0xF7,0xFF,0xFF, -0x7F,0xFF,0xF7,0xFF,0xFC,0x8F,0xFF,0xEF, -0xFD,0xFE,0xFF,0xBE,0xF4,0xF2,0x7D,0xD7, -0xCF,0xFF,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xCF,0x6B,0xFF,0xBF,0x3F,0xFB,0xF2, -0xFC,0x7F,0xEB,0xFF,0x9F,0xFA,0xFF,0xFF, -0x3F,0xFF,0xF3,0xFF,0xFF,0xFD,0x70,0xF7, -0xFF,0xFF,0xBF,0xFF,0xFB,0xD7,0xFE,0xF5, -0x77,0xFF,0x15,0xDD,0x77,0xFD,0xFF,0x7F, -0xDF,0xF7,0xFB,0xCD,0xBF,0xFF,0xFD,0xFF, -0xFF,0xDF,0x37,0xCD,0xF9,0xEC,0xFE,0xEF, -0xBB,0xF4,0xFB,0x3F,0x4F,0xB3,0xFF,0xFD, -0xCB,0xFF,0xE9,0x7E,0x54,0x9F,0xE5,0x4B, -0xB7,0xFF,0xDD,0x7D,0xC7,0x71,0xDD,0x77, -0x5D,0xD7,0x75,0xCD,0x7F,0xD6,0xFF,0xD3, -0xF6,0xF9,0x3F,0x6D,0x95,0xAF,0x7F,0xFE, -0xFF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, -0xFE,0xF6,0xC7,0xFF,0xAD,0x7B,0xCA,0xFF, -0xBF,0xBF,0xEF,0xFD,0xE3,0xDF,0xB7,0xED, -0xFB,0x7E,0xDF,0x37,0xED,0xE3,0xFB,0xDF, -0xFF,0x52,0x5C,0x15,0xFD,0xCF,0x7F,0xDF, -0xFE,0xEF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEC, -0x7B,0xFE,0xFF,0xFE,0x3E,0x7F,0xDA,0xF7, -0xFD,0xFF,0x7F,0xFF,0xFF,0xFB,0xEF,0xBB, -0x6F,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFF, -0xF7,0x7D,0xFF,0xD8,0xFF,0xFD,0xBF,0x7F, -0xFB,0xFF,0xFF,0x9F,0xFB,0xFE,0x7F,0x9F, -0xE7,0xF9,0xFE,0x7F,0x9F,0xEA,0x7F,0xF6, -0xBF,0xBD,0x6A,0x5A,0xF6,0xE5,0xBF,0x77, -0x5F,0x6D,0xDD,0x77,0x5D,0xD7,0x75,0xDD, -0x77,0xFF,0xA5,0xBF,0xCF,0xFB,0xFF,0xFF, -0xBF,0xCF,0xFB,0xFD,0xFF,0xBF,0xF3,0xFE, -0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFD,0xAB, -0xFF,0xBF,0xBF,0xFF,0xFB,0xFF,0x7F,0xEF, -0xFF,0xBE,0xFB,0xEE,0xFB,0xBE,0xEF,0xBB, -0xEE,0xFB,0xBF,0xFF,0xB5,0xFF,0xD0,0xBC, -0xFD,0x2F,0x4B,0xF7,0xFF,0xFF,0x9F,0xF9, -0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x9F, -0xFA,0x8F,0xFD,0xAB,0xFA,0xDA,0xBF,0xAF, -0xB3,0xFD,0xFF,0xBF,0xFB,0xFE,0xFF,0xBF, -0xEF,0xFB,0xFE,0xF7,0xBF,0xFF,0x9F,0xFF, -0x77,0xF7,0xBD,0xFD,0x77,0xDF,0xFF,0x7E, -0xDF,0xED,0xBB,0xFE,0xFF,0xBE,0xEF,0xFB, -0xFE,0xFF,0xFA,0x3F,0xFF,0xBE,0x6F,0x8F, -0xE6,0xF9,0xFE,0x7F,0x9F,0xC7,0xFE,0x7F, -0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7,0xFB, -0x7F,0xFF,0x7F,0xCF,0xFF,0xFD,0xFF,0xFF, -0xDF,0xFB,0xAF,0xBF,0xEF,0xFF,0xFE,0xFF, -0x9F,0xEF,0xFB,0xFF,0xFC,0xFF,0xFB,0xFE, -0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xF7, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xF5,0xFF,0xFF,0xFF,0x3F,0xDF,0xF7, -0xFF,0xFF,0x7F,0xEF,0xFE,0xFF,0xBF,0xFF, -0xFB,0xFF,0xFF,0xBF,0xEF,0xFF,0xB3,0x7F, -0xFF,0x7B,0x5E,0xF7,0xFD,0xFF,0x7B,0x7F, -0xF7,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F, -0xDF,0xF7,0xFF,0x17,0xFF,0xFF,0xFF,0x7F, -0xFF,0xFF,0xDD,0xF6,0xFC,0xBF,0xCB,0xF2, -0xBC,0xBF,0x2F,0xCB,0xF2,0xFC,0xBF,0xFE, -0x8F,0xFF,0xFA,0x7E,0xBF,0xA7,0xEB,0xDA, -0xFC,0xBF,0xAF,0x7A,0xFE,0xBF,0xAF,0xEA, -0xFA,0xFE,0xBF,0xAF,0xF4,0xDF,0xFE,0xFF, -0xF3,0x3C,0x7F,0x3E,0xFF,0xCF,0xF8,0xBF, -0x8F,0xE3,0xF8,0xFE,0x3F,0x8F,0xE7,0xE8, -0xFF,0xFC,0x9F,0xFF,0xFF,0xCF,0xEB,0xB3, -0xE7,0xFB,0x7B,0xF3,0xFE,0xFF,0xCF,0xDB, -0xFB,0xFB,0xBF,0x6F,0x6F,0xDF,0xEC,0x7F, -0xFF,0xFF,0xF7,0xFD,0xFD,0xFF,0xFF,0xFF, -0xFF,0xB2,0xBF,0xFF,0xDE,0xFD,0xBD,0xEF, -0xFB,0xF6,0xDF,0xEA,0xE7,0xDB,0xFE,0xBB, -0xFF,0xEB,0xFB,0xBF,0x9F,0x8F,0xE8,0xFE, -0x3F,0x8F,0xA3,0xF8,0xFE,0x3F,0x8F,0xFF, -0xF8,0x7E,0xFD,0xFD,0x7F,0xFF,0xFB,0xCD, -0xFF,0xFD,0xFF,0x5F,0xEF,0xFD,0xFF,0xFF, -0xDF,0xF7,0xFD,0xFF,0xBE,0x90,0xFF,0xFF, -0xEE,0xFF,0x3F,0xBF,0xF3,0xBB,0xFE,0xB7, -0xAB,0xFA,0xFE,0xAF,0xAD,0xEA,0xFA,0xDE, -0xAB,0xFF,0x63,0xFF,0xFE,0xF2,0xFF,0xB3, -0xFF,0xDF,0xEE,0x7D,0xFF,0x03,0xF1,0xF4, -0x3F,0x1F,0xC3,0xF1,0xEC,0x7F,0xFE,0x6F, -0xFF,0xFB,0xFB,0xFF,0x9F,0xFF,0xBF,0xFF, -0x7B,0x5F,0xFD,0xFF,0xDF,0xF7,0xFD,0xFD, -0x7F,0x7F,0xDF,0xFE,0xCF,0xFB,0xFF,0xFF, -0xAF,0xFB,0xFF,0x1F,0xEF,0xA5,0xFD,0xBF, -0xDF,0xFB,0x7D,0xFF,0xBF,0xDF,0xFB,0xFF, -0xFD,0x3B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, -0xAF,0xF3,0xFF,0xFB,0x7F,0xBF,0xD7,0xFB, -0xBF,0x7F,0xBB,0xF7,0xFF,0xF8,0x7F,0xFF, -0xFA,0x5F,0xD7,0xFF,0xDF,0x7F,0xEF,0xFF, -0xFF,0x7F,0xDB,0xF7,0xFD,0xFF,0x7F,0xDF, -0xB7,0xFB,0xEC,0xFF,0xFF,0xF7,0xBF,0xEF, -0xFD,0xFC,0xFB,0xFF,0xEF,0xF0,0xFE,0x3F, -0x8F,0xE3,0xF8,0xFE,0x3F,0x8F,0xEF,0x8D, -0xFF,0xFF,0xEF,0x7F,0xBF,0xFF,0xFB,0xFF, -0xDB,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xEF,0xD8,0xFF,0x2E,0x7F, -0xBE,0xEF,0xFE,0x6E,0xFF,0xBF,0xF9,0xFF, -0xFF,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFC,0x66,0xBE,0x47,0xF3,0x7F,0xDF,0xFE, -0x87,0x9F,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xD6,0x6F,0x7C, -0xFB,0x4F,0xD2,0xFF,0xFD,0x2B,0xFE,0xFF, -0xFF,0xFD,0x5F,0xD7,0xD5,0xF5,0x7D,0xFF, -0xFF,0xFF,0xBF,0x9B,0xFF,0xFF,0xDF,0xB7, -0xFF,0xFF,0xDF,0xFF,0x3F,0xCF,0xFE,0x7F, -0xBF,0xEF,0xFB,0xFC,0xFF,0x3F,0xFF,0xD9, -0xBF,0xFE,0x97,0xEC,0x8F,0xB7,0xFE,0x9B, -0x7D,0xFD,0xB7,0xDD,0x77,0x1D,0xC7,0x71, -0xDD,0x77,0x5D,0xD7,0xF3,0x6F,0xFD,0x3F, -0x73,0xDD,0xAF,0xFD,0x7A,0xFF,0xFF,0xAF, -0xFE,0xFD,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF, -0xEF,0x66,0x7F,0xFF,0xFF,0xBF,0xBF,0xFF, -0xFB,0xFF,0xF7,0xDF,0xFD,0xFB,0x7D,0xDF, -0xB7,0xCD,0xF3,0x7C,0x5F,0x3F,0x91,0x3F, -0xFF,0x3D,0xEF,0x7B,0xFF,0xFC,0xFF,0xCA, -0xEF,0xFE,0xFF,0xBD,0xEF,0xFB,0x1E,0xE7, -0xBB,0xEC,0x7F,0xB3,0xFF,0xFD,0x9F,0xFF, -0xFF,0xFE,0xFF,0xFF,0x7F,0xBF,0xFB,0xFE, -0xFF,0xBF,0xEF,0xFB,0xEE,0xFB,0xBF,0xDF, -0x67,0xFF,0xFF,0xBF,0xEF,0xDB,0xFF,0xBC, -0xFE,0x7F,0xFB,0xFF,0x9F,0xEF,0xF9,0xFE, -0x7F,0x9F,0xE7,0xF9,0xFE,0x87,0xFF,0xEE, -0xFB,0xBE,0xE5,0xBF,0xEF,0xF9,0xD7,0x65, -0xF7,0xDD,0xE7,0x7D,0xDF,0x77,0x5D,0xD7, -0x7F,0xF8,0x9B,0xFE,0xFF,0xBF,0xEF,0xFB, -0xFF,0xFF,0xBF,0xEF,0xFB,0xFF,0x7F,0xCF, -0xF3,0xFC,0xFF,0xBF,0xEF,0xFF,0xDB,0x3F, -0xEF,0xFB,0xFE,0xFF,0xDF,0xFF,0xFE,0xFB, -0xBB,0xEF,0xBF,0xEF,0xBB,0xEE,0xFB,0xBE, -0xEF,0xBB,0xFF,0xFC,0x7F,0xFD,0x3B,0x5B, -0xD6,0xE5,0xFD,0x4F,0xC3,0xFB,0xFF,0xBF, -0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFF, -0xB4,0xFF,0xFA,0xBC,0x8F,0xB2,0xE9,0xD2, -0x2E,0xCF,0xFB,0xFF,0xBF,0xEF,0xFB,0xFE, -0xFF,0xBF,0xEF,0xFB,0xFF,0xEC,0xFF,0xFD, -0xFD,0x7F,0xDF,0xF7,0xE4,0xDF,0x5F,0xFF, -0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xC3,0xFF,0xEF,0xE6,0xF8,0xFE, -0x3F,0x8B,0x83,0xF9,0xFE,0x7F,0xE7,0xF9, -0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x17, -0xFD,0xFF,0xFF,0xFF,0x7F,0x5F,0xF7,0x2C, -0xFF,0xFF,0xFF,0xFE,0x7F,0xFF,0xE7,0xF9, -0xFE,0x7F,0x9F,0xFE,0x2F,0xFF,0xFF,0xEF, -0xFF,0xFE,0xBF,0xEF,0xAD,0xFF,0xFF,0x7F, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFE,0xDF,0xFF,0xDF,0xFF,0xFD,0xFD,0x7F, -0xDF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0x3F,0xFE, -0xF7,0xFD,0xEF,0x7A,0xFF,0xB1,0xBD,0xFF, -0x7F,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7,0xFD, -0xFF,0x7F,0xF3,0x27,0xFF,0xDF,0xFF,0xDD, -0xFF,0xFC,0x9B,0xFF,0xCB,0xFC,0xBF,0x2F, -0xCB,0xF2,0xFC,0xBF,0x2F,0xC9,0xFF,0xDE, -0xFF,0xDF,0xAF,0xEB,0xDA,0xFE,0xBB,0xAF, -0xEB,0xF8,0xF7,0xAF,0xE8,0xFA,0xFE,0xBF, -0xAF,0xEB,0xF2,0xFF,0xFD,0xFF,0xFF,0xEF, -0xBD,0xD7,0xBF,0xFF,0xFF,0xDE,0x8F,0xB8, -0xDE,0x37,0x8D,0xA3,0x78,0xDA,0x3F,0x8F, -0xFF,0xA1,0xFF,0xFF,0xFB,0xFB,0xFF,0xFF, -0xFF,0xFF,0xA7,0xBD,0xFB,0x76,0xFD,0xBF, -0xEF,0xDB,0xFE,0xBB,0xBF,0xFE,0x27,0x7F, -0xFF,0xFE,0xFE,0xFD,0xF5,0xFF,0xEF,0xF5, -0xDF,0x1F,0xE7,0xFD,0xFF,0x7F,0xDF,0xF7, -0xFD,0xFF,0xFF,0xCD,0xFD,0xAE,0xFF,0xFA, -0x3E,0x3F,0xAB,0xFD,0xF8,0x7E,0x8F,0xE3, -0xF8,0xFE,0x3E,0x8F,0xE3,0xF8,0xFF,0xFE, -0x1F,0xEF,0xDF,0xBF,0xFE,0xDE,0xDF,0xD9, -0xFF,0xDF,0xBC,0xFF,0xFF,0x7F,0xFF,0xEF, -0xFD,0x7F,0xDF,0xF7,0xF9,0x3F,0xFE,0xFF, -0xFF,0x6F,0xFE,0xDE,0xBF,0xF7,0xED,0xEA, -0xFD,0x8F,0x83,0xF8,0xEA,0x3F,0x8F,0xEF, -0xFF,0xF4,0x7F,0xFF,0xEF,0xEF,0x7B,0xF3, -0xF1,0x5F,0xFF,0xFF,0xF1,0x3B,0x7F,0xDF, -0xF7,0xFD,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF, -0xFF,0xFF,0xF7,0xFF,0x6F,0xFF,0x7F,0xFF, -0xFF,0xF7,0xDE,0xF7,0xBF,0xEF,0xFB,0xF7, -0xFD,0xFF,0xFF,0xF5,0xFA,0xFF,0xFF,0xFB, -0xE7,0xFF,0xF3,0xF8,0x7F,0xF3,0xDF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0xEF, -0xBB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, -0xFF,0x7F,0xFF,0x9F,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xCF,0xFF,0x37,0xFF,0xFF, -0x7F,0xDF,0x77,0x5D,0xE7,0xFC,0xFF,0xBF, -0xF7,0xF5,0xFB,0xFF,0xFF,0xD7,0xF5,0xFB, -0xFF,0xFF,0x45,0xFD,0x7F,0xEA,0xFD,0xBE, -0xBF,0xDF,0xF7,0xFF,0xFF,0xDB,0xFB,0xFE, -0xFF,0xBF,0xEF,0xFF,0xFF,0xFF,0xFB,0x5F, -0x7F,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFE,0xFF,0xEF,0xFD,0xFF,0x7F,0xDF, -0xFF,0xEF,0xFB,0xF8,0x0F,0xF3,0xFF,0xF9, -0x2E,0xFB,0xFE,0xFC,0xF3,0xEF,0xFF,0xFF, -0xBF,0xFF,0xFB,0xE7,0xFF,0xFE,0x7E,0xFF, -0xC0,0x6B,0xCF,0xFF,0x34,0xDF,0xF1,0xFD, -0xFF,0xEF,0xFF,0xFF,0xFF,0xDF,0xF7,0xFD, -0xCF,0x7F,0x9C,0xFD,0xFD,0x6C,0xF7,0xFF, -0xF6,0xFD,0xEB,0x2B,0x9F,0xFF,0xFC,0xFE, -0x7E,0xFF,0xFF,0xFF,0xFF,0xD7,0xF3,0xF7, -0xFF,0xFB,0xE1,0xBF,0xFF,0xEB,0x7A,0xDE, -0xD7,0xFB,0xFF,0xF9,0xFE,0xFF,0xFF,0xF3, -0xDE,0x7F,0xFD,0xE7,0x7F,0xFF,0xFD,0xBB, -0xFF,0xFF,0x7E,0xCC,0xF6,0xAF,0x5F,0x7F, -0xFE,0xF4,0x7D,0xF7,0xFD,0xBB,0x6E,0xDB, -0xB7,0xFF,0xF7,0xDF,0x66,0xFF,0xFF,0xF7, -0x3D,0xCF,0xDE,0xBD,0xFF,0xFF,0xDE,0xDB, -0x8D,0xF7,0x7E,0xDF,0xB7,0xEF,0x7F,0xFF, -0xF6,0x87,0xFF,0xFF,0xEF,0xFE,0xDE,0xBF, -0xFF,0xFF,0xFF,0xBB,0xEF,0xFD,0xFF,0x7B, -0xDE,0xF7,0x3F,0xFF,0xBF,0xFB,0xDB,0xFF, -0xF2,0xB6,0xFD,0xBD,0x7F,0xE7,0xFF,0xFF, -0xFF,0x6F,0xF7,0xFF,0xFF,0xFF,0xFE,0x77, -0xFF,0xBF,0xF8,0xAF,0xFF,0xDF,0xBF,0xFF, -0xBF,0x7F,0xFB,0xFF,0xFF,0xFF,0xDB,0xFE, -0xFF,0xBF,0xFF,0xFA,0xFF,0xFD,0xFF,0xF6, -0x7F,0xFF,0x9F,0xFF,0xFF,0x3F,0xEF,0xF8, -0xEE,0x7E,0x9F,0xBA,0xFE,0xBF,0x8F,0xEF, -0xFE,0xFE,0xF9,0xFF,0xFA,0x7F,0xFE,0x7E, -0xBF,0xAF,0xFB,0x96,0xFD,0x9F,0xEF,0x5E, -0x65,0xBE,0xEF,0x5B,0xB6,0xFF,0xBE,0xE3, -0xFF,0xB5,0xBF,0xFF,0xFD,0xFF,0x7F,0xFF, -0xEF,0xDF,0xFE,0xFF,0xBF,0xFB,0xFE,0xFF, -0xBF,0xCF,0xFF,0xFF,0xFF,0xFD,0x9B,0xFF, -0xFE,0xFB,0xFE,0xDF,0xFF,0x7F,0xFF,0xF7, -0xFE,0xFF,0xDF,0xFB,0xFB,0xFE,0xFF,0xFF, -0xFF,0xFF,0xFF,0xB7,0xFE,0xFA,0xFF,0xAB, -0xEF,0xFF,0xFD,0xB5,0x7B,0x7F,0xFB,0xF7, -0xFD,0xFF,0xFF,0xDD,0xFF,0xEF,0x8F,0xFF, -0x2F,0xFF,0xFB,0x7C,0xFF,0x3F,0xDF,0x73, -0xEB,0xFE,0x3F,0xFF,0xEF,0xFB,0xFE,0xFF, -0xEF,0xFD,0xFF,0xBF,0xFD,0x0F,0xFF,0xFF, -0xFF,0xF5,0xF9,0xFF,0x7F,0xD7,0xFD,0xFF, -0xDF,0xFF,0xF7,0xFB,0xFF,0x7F,0xBF,0xFF, -0xFF,0xF0,0x9F,0xFF,0xFE,0x7F,0x8B,0xE3, -0xF9,0xDE,0x27,0x9B,0xE6,0xBE,0x7F,0x9B, -0xC3,0xF8,0xDE,0x7F,0x9D,0xE7,0xFE,0x7F, -0xFF,0xFF,0x5F,0xD7,0xFF,0xFF,0xFF,0x4F, -0xFB,0xFF,0xFF,0x7F,0xFF,0xAF,0xFF,0x9F, -0x7F,0xFB,0xFF,0xE8,0xFF,0xFF,0xFE,0xBF, -0xAF,0xFF,0xFF,0xFE,0xBF,0xEF,0xF7,0xFF, -0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF, -0xFC,0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xFF, -0xFD,0x3F,0xCF,0xFF,0xFF,0xFF,0xFF,0xF7, -0xFF,0xFD,0x7F,0xFF,0xFF,0x93,0xFF,0xFF, -0x7A,0xDF,0xF7,0xFF,0xFF,0x7B,0x7F,0xB7, -0xEF,0xFF,0xFF,0xFD,0xBF,0xFD,0xFB,0xFF, -0xF7,0xFF,0xD7,0xFF,0xFF,0xFF,0xFC,0x9F, -0x6F,0xCB,0xFF,0xF4,0xBB,0xDF,0xD6,0xFD, -0xBF,0x2F,0xD3,0xF7,0xFF,0xDF,0xFF,0xCF, -0xFF,0xFA,0xBE,0xBD,0xAF,0x6A,0xDA,0xBE, -0xBB,0xAB,0x3A,0xBE,0x2D,0xAE,0xEB,0xDA, -0xF6,0x3F,0xAD,0xF5,0xDD,0xFF,0xCF,0xF1, -0xFF,0xF9,0x7F,0xFF,0x73,0xFE,0xFF,0xCF, -0xC3,0xF4,0xF7,0x2F,0xF3,0xFF,0xFC,0xFF, -0x7C,0x1F,0xFF,0x3F,0x4F,0xFF,0x7E,0xFF, -0xEF,0xBD,0xF6,0xFE,0xFF,0x2B,0xEF,0xDC, -0xFB,0xFD,0xFF,0xFB,0xFF,0xEA,0x7B,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFB,0xF7,0xDF,0xFF, -0xE3,0x7D,0xFF,0xB7,0xFF,0xBF,0xFF,0xFF, -0xDF,0xFF,0xF8,0xFF,0xBF,0xFF,0xBF,0xEB, -0xE7,0xFA,0xFE,0x3D,0xBF,0xE9,0xFC,0xBF, -0xFF,0xFA,0xFB,0xFE,0xFF,0xFF,0xFF,0xD9, -0xFF,0xFF,0xFF,0xF6,0x7F,0xFF,0xF6,0x7D, -0xFF,0xDF,0xCF,0xFD,0xBF,0xFB,0xEF,0x7E, -0xFF,0x7F,0xFF,0xFF,0xD3,0xFF,0xFD,0xFB, -0xFF,0xFB,0xFF,0xFF,0xFF,0xEF,0xFF,0xBF, -0xFE,0xFF,0xF7,0xEF,0xFF,0xFF,0xFF,0xFB, -0xFF,0x87,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF, -0x7B,0xFE,0xFF,0xFE,0x3B,0xF7,0xF7,0xFF, -0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF, -0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xF7, -0xFF,0xFF,0xAD,0xFF,0xFE,0xF7,0xFF,0xFF, -0x5F,0xFF,0xFF,0xDF,0xFF,0xFD,0xFF,0xF5, -0xFF,0xDF,0xFF,0xBD,0xFF,0xE9,0xFF,0xC7, -0xF3,0xFF,0xFF,0xF7,0xFF,0xF3,0xFF,0xF8, -0x3B,0xFF,0xFF,0x7B,0xDF,0xBF,0xFB,0xEF, -0xFB,0xFF,0xFB,0xF7,0xF7,0xBB,0xFF,0xFF, -0xFF,0xFF,0xFB,0xFF,0xFE,0x7F,0xF3,0x7F, -0x5E,0xB7,0xBF,0xFD,0x7F,0xFF,0xF9,0x7F, -0xFB,0xFF,0xEB,0xFD,0x7F,0x7F,0xFF,0xEF, -0xFB,0xE0,0x3F,0xFE,0xBF,0xBF,0xDF,0xFF, -0x7E,0xFF,0xF7,0xFF,0xFF,0xFE,0xBF,0xFF, -0xDB,0x78,0xFF,0xFF,0xFF,0xEE,0xA1,0xBF, -0xF5,0xDE,0xFB,0xF7,0xFF,0xFB,0xFF,0xFF, -0xFF,0xFF,0xFB,0xFF,0xFF,0xD7,0xFF,0xFF, -0xFF,0xFF,0xEF,0xF0,0xFF,0xFF,0xFF,0xF3, -0xF7,0xFF,0xEF,0xFF,0xE7,0xCF,0xFF,0xFB, -0xFF,0xEF,0xFF,0xFF,0x9F,0x9F,0xEF,0xFC, -0x16,0xBF,0xFE,0xF3,0xE4,0xFF,0xFF,0xC6, -0xFF,0xE7,0xFF,0xFF,0xFD,0xFF,0xBF,0xFF, -0xFF,0x3F,0xFF,0xBF,0xD6,0xAF,0x7F,0xFE, -0x6B,0x7E,0x7F,0xFF,0xAF,0xFF,0xFF,0xBF, -0xFF,0x5F,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF, -0xFF,0xBD,0xDB,0xFF,0xFE,0x5F,0xF2,0xFF, -0xFF,0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xEF,0x7F,0xFF,0xFF,0xFF,0xFF,0xDE,0xBF, -0xFF,0xFF,0xEF,0xFB,0x77,0xFE,0xBD,0x7F, -0x5F,0xFF,0xFF,0xFF,0xDF,0x6F,0xED,0xFF, -0xFD,0xFF,0x7F,0xFD,0x6F,0xFF,0xFF,0x77, -0xDA,0xCF,0xFD,0x5F,0xFF,0xBF,0xFF,0xFF, -0xDF,0x7F,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF, -0x66,0x7F,0xFF,0xFE,0xBF,0xE7,0xBF,0xFA, -0xFF,0xFE,0xFF,0xFF,0xFF,0xDF,0xFF,0x59, -0xEF,0xFF,0xEF,0xFB,0x7F,0x89,0xFF,0xFF, -0xE9,0xFF,0x6F,0xFF,0xF5,0xFF,0xFF,0xFF, -0xFF,0xFF,0x7F,0xF2,0xF7,0xFF,0xFF,0xEF, -0xF8,0x7F,0xFB,0xFF,0xFD,0xFF,0xFF,0xD9, -0xFF,0xEF,0xBB,0xFF,0xFF,0xFF,0xBF,0xEF, -0xDE,0xFF,0xFF,0x9F,0x7F,0xDF,0xFF,0xF7, -0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xAF, -0xFF,0xFF,0xF7,0x3F,0xEB,0x9F,0xFE,0x7F, -0x9E,0x7F,0x9F,0xFE,0x87,0xFF,0xED,0xDB, -0x56,0xFF,0xBF,0xAF,0x0B,0xD2,0xFF,0xEF, -0xDB,0x6E,0x7D,0xBD,0x6F,0xF8,0xFE,0x3F, -0xFA,0x5B,0xFF,0xFD,0xBF,0xEF,0xFF,0xBF, -0x6F,0xDB,0xE6,0xFF,0xFF,0x3F,0xFF,0xDF, -0xFE,0xFF,0xFF,0xFF,0xFF,0xDA,0x3F,0xFF, -0xFB,0xFE,0xFE,0xFF,0xFF,0xDF,0xF7,0xBD, -0xFF,0xFD,0xFF,0xFE,0xFF,0xFB,0xFF,0xFF, -0xFF,0xFF,0xF1,0x5F,0xFD,0x9F,0xDF,0xFD, -0xFF,0xFD,0x7F,0xFF,0xFF,0xFF,0xFF,0x76, -0xFA,0xFF,0xFF,0x7F,0xE3,0xF8,0xFF,0xAE, -0xFF,0xFB,0x7E,0x9D,0x73,0xFF,0xFA,0x7F, -0xDF,0xFF,0xFF,0x7F,0xFF,0xFB,0xCD,0xFF, -0x7F,0xEF,0xFB,0xFF,0xFD,0xFF,0xF7,0x7F, -0x7F,0xEF,0xFF,0xED,0xFF,0xFF,0xFF,0xB5, -0xFF,0xBF,0xFF,0xBF,0xFD,0xEF,0xDB,0xF7, -0xFF,0x93,0xFF,0xEF,0xE2,0xF9,0xBE,0x7F, -0x8B,0xE7,0xF9,0xFE,0x6B,0xE7,0xF9,0xFE, -0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x47,0xFF, -0xFF,0xFD,0xFF,0x9F,0xFF,0xD7,0xFF,0xFF, -0xFF,0xFF,0xF5,0xFF,0x9F,0xFF,0xF7,0xFE, -0xFF,0xBF,0xFE,0x6F,0xFF,0xFF,0xFB,0xFF, -0xFF,0xFF,0xAF,0xFF,0xFF,0xFF,0x7F,0xFB, -0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, -0xDF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xDF, -0xFF,0xFF,0xFF,0x5F,0xFF,0xFF,0xFF,0xFF, -0x5F,0xFB,0xFE,0xFF,0xF8,0x37,0xFF,0xFF, -0xEF,0xFF,0x7F,0xFE,0xBF,0xFF,0xFF,0xFE, -0xBF,0xFF,0xFF,0x7F,0xFF,0xBF,0xFD,0xFF, -0x7F,0xFA,0x7F,0xFF,0xFF,0x6F,0xFF,0xFF, -0x7D,0xFF,0xCF,0xFF,0xFF,0xFF,0x4F,0xFF, -0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0xBF, -0xFF,0xAE,0xEB,0xFA,0xFE,0xBB,0xAD,0xEB, -0xFA,0xF7,0xAF,0x6B,0xFA,0xF6,0xBF,0x25, -0xE9,0xF2,0x7F,0x45,0xFF,0xFF,0xFD,0xF7, -0xF7,0xBF,0xFF,0xDF,0xFF,0xFF,0xBF,0xFB, -0xFF,0xDF,0xF3,0xFF,0xF7,0x3F,0xCF,0xFF, -0xA1,0xFF,0xFF,0xBF,0xE7,0xFF,0xFF,0x7F, -0xFF,0x3D,0xFF,0xFF,0xFF,0xF7,0xFF,0x2F, -0xFF,0xFB,0xF5,0x7F,0xFE,0x57,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7, -0x3F,0xFF,0xFE,0xFF,0xFF,0xFF,0xFD,0xFE, -0xF7,0xEE,0xAF,0xFE,0xEE,0xE7,0xFA,0xFF, -0xFE,0x9D,0xF9,0x5E,0xFE,0xFF,0xEB,0xFF, -0xFF,0xDF,0xA7,0xFF,0xFF,0xFF,0xFC,0xDB, -0xFF,0xFF,0xFF,0x7E,0xFB,0xFF,0xFF,0xEF, -0xFB,0xFD,0xFF,0xDB,0xFF,0xFF,0xFF,0xEF, -0xFF,0xFF,0xFF,0xFD,0xBF,0xFE,0xBF,0xFF, -0x6F,0x7F,0xFF,0xF7,0xFF,0xFF,0xF9,0xFF, -0xF7,0xFF,0xBF,0xDE,0xF7,0xFF,0xFF,0xFF, -0xFA,0x7F,0xFD,0xBF,0x5F,0xFF,0xFF,0xBF, -0xFF,0xED,0xFF,0xF7,0xBF,0xFF,0xFF,0xEF, -0xFF,0xDF,0xFF,0xFF,0xFF,0xE6,0xFF,0xFB, -0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEB,0xFF, -0xFD,0xFF,0xF5,0xFF,0xF6,0x7F,0xDF,0xBD, -0xCF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF, -0xFF,0xF9,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3, -0xFF,0xEE,0xBF,0xFF,0x7D,0xEF,0xFE,0xFF, -0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFE, -0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xB5,0xAE, -0xFF,0xFF,0xB6,0xFE,0xBF,0xFF,0xFF,0xBF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0x27,0xFF,0xEF,0xFE,0x7F,0xDF,0xFF, -0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFD,0xFF,0xF7,0xF9,0x9F,0xFF, -0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F, -0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0x0F,0xFF,0xE7,0xBF,0xFE, -0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFC,0xBF, -0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xC4, -0x6B,0xFF,0x29,0x1F,0xFB,0xAF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xEF,0x1B,0xFE,0xFF,0xFC, -0x6F,0xFF,0xFF,0xFD,0x6A,0xF7,0xD7,0xF5, -0xBF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFE,0xBF,0xFF,0xFF,0xFA,0xFF,0xFF,0xF7, -0xFB,0xDD,0xBF,0xFF,0xE7,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x7F,0xFF, -0xFF,0xF5,0xFF,0xFF,0xF7,0xFD,0xB3,0xEF, -0xFD,0x7E,0x5D,0xFF,0xFD,0xFF,0xFF,0xFF, -0xFD,0x7F,0xD2,0xF5,0xFB,0x7E,0xCB,0xB7, -0xFF,0xFF,0xFF,0xC6,0xFF,0xFD,0xEE,0x63, -0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xFD,0x65, -0x5B,0xDF,0xFF,0xD5,0xFF,0xFF,0xFF,0xF6, -0xE7,0xBF,0xF7,0xA9,0xFF,0xFF,0xED,0xFF, -0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,0xFF,0xFF, -0xAF,0xFF,0xFF,0xFF,0xF8,0x1B,0xFF,0xE3, -0xD0,0xBF,0xFF,0xE1,0xFF,0xFF,0xFF,0xFF, -0xFF,0xD7,0xFF,0xFF,0xFF,0x5F,0xFF,0xFF, -0xFF,0xFF,0xAF,0xFF,0xDB,0x76,0xBF,0xFF, -0x7F,0xFF,0xBF,0xEF,0xFE,0xFF,0xBF,0xEF, -0xFB,0xFE,0xFF,0xFF,0xFF,0xBF,0xF2,0x7F, -0xFF,0x9F,0xFE,0xBD,0xFE,0x7F,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xF7,0x3F,0xEC,0x7F,0xF6,0x95,0xBB, -0xEF,0xF8,0xFE,0xFC,0xBF,0x2F,0xDA,0xFC, -0xBF,0x2F,0xCB,0xF2,0xFC,0xBF,0xEF,0xFF, -0xA9,0xBF,0xCF,0xFB,0xFF,0xFF,0xFF,0xFE, -0xDD,0xB7,0x6D,0xF6,0xD9,0xB6,0x6D,0x9B, -0x76,0xD9,0xBF,0xFB,0xFD,0xA3,0xFF,0xBF, -0xEF,0xFF,0xEF,0xFF,0xFF,0xFF,0x7F,0xDF, -0xFD,0xEF,0x7B,0xDE,0xF7,0xFD,0xEF,0x7F, -0xFF,0xFF,0x05,0xFF,0xFA,0xFE,0x7F,0xEF, -0xE3,0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xFF, -0xFF,0x5F,0xFF,0xFF,0xFD,0x7F,0xFB,0xAF, -0xFF,0x63,0xC8,0xFF,0xBF,0xEF,0xFF,0xFF, -0xFA,0x7F,0xFF,0xFF,0xFF,0xFE,0x9F,0xF7, -0xFF,0xFA,0xBF,0xFE,0x9F,0xFB,0x7F,0xFF, -0xFF,0xEF,0xD7,0xFF,0xFF,0xF5,0xFF,0xFF, -0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xBF,0xFF, -0xF9,0xBF,0xFF,0xBE,0x27,0x9F,0xE7,0xF9, -0xFE,0x7F,0x8B,0xE7,0xFE,0x7F,0x9F,0xE2, -0xF9,0xFE,0x7F,0x9F,0xE7,0xF1,0x7F,0xFF, -0xFF,0xFF,0xFB,0xFE,0xFF,0xFF,0xFF,0xD7, -0xFF,0xFF,0xFF,0xFF,0xF5,0xFF,0xFF,0xFF, -0xD7,0xFF,0xFA,0xFF,0xFE,0xFF,0xFF,0xFF, -0xFD,0xFF,0xFF,0xFF,0xAF,0xF7,0xFF,0xFF, -0xFF,0xEB,0xFF,0xFF,0xFF,0xAF,0xFF,0xC4, -0xFF,0xF7,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF, -0xFF,0x5F,0xFF,0xFF,0xFF,0xFF,0xD7,0xFF, -0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,0xFB,0x7A, -0xDF,0xF7,0xFD,0xFF,0xFF,0xFE,0xBF,0xFF, -0xFF,0x7F,0xFF,0xAF,0xFF,0xFF,0xFF,0xF7, -0xEF,0xE3,0xFF,0xDD,0xD2,0xFF,0xDF,0xFF, -0xFF,0xF2,0xFC,0xBF,0xCB,0xF6,0xFD,0xBF, -0x2F,0xCB,0xFF,0x7F,0xDF,0xDE,0xAF,0xFF, -0xDA,0xEE,0xBF,0xAF,0xE9,0xFA,0xF4,0xBD, -0xAF,0x5A,0xAE,0xBB,0xAB,0x6B,0xDA,0xDE, -0xBF,0xAD,0xD7,0x5E,0xFF,0xFF,0xBF,0xFC, -0xFF,0xDF,0xFD,0xFF,0xFF,0xFF,0xFF,0xDF, -0xF7,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFA, -0x1F,0xFF,0xFE,0xFB,0xEF,0xBF,0xFD,0xFF, -0xFD,0xBD,0x77,0xFF,0xFF,0xFF,0xFF,0x9D, -0xEF,0xFF,0xFF,0xFF,0xEF,0x7D,0xFF,0xFB, -0xFE,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEE, -0xBF,0xE4,0xFB,0xFF,0xFE,0x3F,0xFE,0xFF, -0xFF,0xFF,0xFF,0xAF,0xEA,0xFE,0xBF,0xAF, -0xEB,0xFA,0xFE,0xFF,0xFF,0xFF,0x55,0xF6, -0xFF,0xFE,0xF7,0xFF,0x7F,0xFF,0xEB,0xF7, -0x5F,0xC5,0xFD,0x7F,0x5F,0xD7,0xF5,0xFF, -0x6F,0xFB,0xFF,0x8A,0xFF,0xFF,0xFF,0xFF, -0xEB,0xFF,0xFF,0xFF,0xFF,0xFB,0xBF,0xBF, -0xEF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF, -0x77,0xDF,0xFB,0xFF,0xFD,0x7F,0xEF,0xFF, -0xFF,0xFF,0xBF,0x7F,0xFF,0xDF,0xBF,0xFF, -0xFB,0xFF,0xFF,0xFF,0xFE,0xEF,0xDF,0xFF, -0xFE,0xFF,0x9F,0xEF,0x7D,0xFF,0xF7,0xFF, -0x7F,0xFF,0xFF,0xDF,0xF7,0xFD,0xFF,0xEF, -0xDF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFB, -0xFD,0xFF,0xBF,0xDF,0xD1,0xFF,0xF8,0x3B, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0x7E,0xDB,0xFD,0xFF,0x77,0xDB,0xB7,0x7D, -0xBF,0xFB,0xFF,0xF8,0x7F,0xED,0x7B,0x5E, -0xFF,0xFE,0xFF,0xFF,0x4F,0xD7,0xFD,0x7F, -0xDF,0xD7,0xF5,0xFF,0x7F,0xFF,0xFF,0xFF, -0xF2,0x3F,0xFE,0xFF,0xBF,0xFF,0xFF,0xFF, -0xFF,0xBF,0xEF,0xFE,0xFF,0x3B,0xEE,0xFF, -0xFC,0xEF,0xFF,0xFF,0xFF,0x85,0xFF,0xFD, -0xFE,0xFF,0xF5,0xFF,0xFF,0xFE,0xFF,0xDF, -0xFB,0xFF,0x5F,0xBF,0xFF,0xFD,0xFF,0xFF, -0xFF,0xFF,0xA8,0xFF,0xFF,0x9F,0x9E,0xFF, -0xFF,0xFF,0x7F,0xF3,0xFF,0xFF,0xCF,0xFF, -0xF7,0xFD,0xFF,0x7F,0xFF,0xFF,0xFC,0x16, -0xBF,0xCF,0xA3,0xE5,0xEF,0x7F,0xFF,0xF3, -0xE4,0xFF,0xCF,0x93,0xFC,0xFF,0x3F,0xCF, -0xFF,0xFF,0xFF,0xD6,0x0F,0x7D,0xBF,0x6E, -0xFB,0xF4,0xFC,0xAF,0x6D,0xDB,0x77,0xB7, -0x6D,0xDB,0xF6,0xFD,0xBF,0xFF,0xFF,0xFF, -0xBF,0x9B,0xFA,0xDE,0xB7,0xB7,0xED,0xF9, -0x7E,0xB7,0xAC,0xEB,0xD6,0xB3,0xAD,0xEB, -0x7A,0xDF,0xFF,0xFF,0xFF,0xD8,0xBF,0xFF, -0xB7,0xED,0x9F,0x6F,0xDD,0xF7,0x68,0xDB, -0x37,0xB3,0x6C,0xDB,0x36,0xCD,0xB3,0x7F, -0xFF,0x7F,0xF5,0x6F,0xFD,0xEF,0x79,0x3D, -0xF7,0x93,0xE4,0x7A,0x9E,0xAD,0xEA,0x7A, -0x9E,0xF7,0xBD,0xEF,0xFF,0xFF,0xFF,0x76, -0x7F,0xFB,0xC6,0xFF,0xBB,0xEF,0xDA,0xFE, -0xFD,0xBF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, -0xFF,0xFF,0xFB,0xFF,0xA5,0xFF,0xFD,0xAB, -0x6F,0x78,0xDE,0x17,0x8F,0x79,0xDF,0xFD, -0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0xFF,0xFB, -0xFF,0xFB,0xFF,0xEF,0xFB,0xEF,0xFB,0xFE, -0xFF,0xBB,0xDA,0xF3,0xEF,0x3B,0xCE,0xF3, -0xBC,0xEF,0x3F,0xCF,0xDF,0xFF,0xB7,0xFF, -0xFF,0xFF,0xCF,0x73,0xFF,0xBF,0xEF,0xFF, -0xF3,0xFF,0x3F,0xCF,0xF3,0xFC,0xFF,0x3D, -0xCF,0x9F,0xFE,0x07,0xFF,0xAF,0xEB,0xFE, -0xFD,0xBF,0xEF,0xEB,0xFA,0xFF,0xAF,0xEB, -0xFA,0xFE,0xBF,0xAF,0xFB,0xFE,0x3F,0xFB, -0x9B,0xFF,0x7F,0xDF,0xFF,0xF3,0xFE,0xFF, -0xDE,0xF7,0xBF,0x7B,0xDE,0xF7,0xBD,0xEF, -0x7B,0xFE,0xFF,0xFF,0xDF,0x3F,0xFE,0xFF, -0xB7,0xFF,0xEF,0xF7,0xFF,0xBF,0xED,0xFE, -0xDF,0xB7,0xED,0xFB,0x7E,0xDF,0xFF,0xFF, -0xFF,0xFD,0x5F,0xEF,0xEB,0xFA,0xFE,0xF5, -0xBF,0x6F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFE,0xF8,0xFF,0xA8,0xFF, -0xFF,0xBF,0xEF,0xFB,0x6A,0xFB,0xB7,0xEF, -0xFB,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF, -0xEF,0xFB,0xFF,0xE0,0xFF,0xFF,0xFD,0x7F, -0x5C,0xD7,0x7D,0xDF,0xF3,0x5C,0xF5,0xCD, -0x73,0x5E,0xD7,0xB5,0xFD,0x7F,0xEF,0xFF, -0xDB,0xFF,0xFF,0xE2,0xF8,0xBE,0x2F,0x8F, -0xE7,0xF8,0xBE,0x6B,0xE2,0xF8,0xBE,0x2F, -0x8B,0xE2,0xF9,0xFE,0x7F,0xE7,0xFF,0xD7, -0xF5,0xFD,0x7F,0xFF,0xF7,0xF5,0xFD,0x7F, -0xD7,0xF5,0xFD,0x7F,0x5F,0xD7,0xF5,0xFF, -0xFF,0xFF,0x8F,0xFF,0xAF,0xEB,0xFA,0xFF, -0xFF,0xBF,0xEB,0xFA,0xFF,0x2F,0xEB,0xFA, -0xFE,0xBF,0xAF,0xEB,0xFF,0xFF,0xFE,0x5F, -0xFF,0x5F,0xFF,0xFF,0xFD,0xFF,0xFF,0xD7, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xBF,0xFE,0xB7,0xFD, -0xFF,0x7E,0xDF,0xF7,0xAD,0xFF,0x7F,0xF7, -0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F, -0xF6,0x7F,0xFF,0xFF,0xFF,0xDB,0xF6,0xFC, -0xAF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xEC,0xBF,0xFF, -0xAF,0xEB,0xFA,0xF6,0xAB,0x8F,0xEB,0xFA, -0xF7,0xA5,0xEB,0xFA,0xBE,0xBF,0xAF,0xEB, -0xFA,0xFF,0x6D,0xFF,0xFF,0x7F,0xDF,0x33, -0xDD,0xFF,0x7F,0xFE,0xF7,0xFC,0x7F,0xFB, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA9, -0xFF,0xFD,0xFF,0xFF,0xFE,0xFF,0xFF,0xDF, -0xFF,0xFF,0xEF,0xEF,0xFD,0xFF,0x7F,0xFF, -0xFF,0xFF,0xFF,0xFE,0xA7,0xFF,0xFF,0xFF, -0x77,0xDF,0xF7,0xFD,0x9F,0x7F,0xFE,0x77, -0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xAF,0xBF,0xAF,0xFF,0xF9,0xBE,0xBF, -0x8F,0xFB,0xFE,0xFE,0xEF,0xFB,0xFE,0xFF, -0xBF,0xEF,0xFB,0xFF,0xFF,0xFD,0xDF,0x6F, -0xEF,0xFF,0x7F,0xFF,0xBF,0xBF,0xDF,0xFF, -0xFC,0xFF,0xDF,0xF7,0xFD,0xEF,0x7F,0xDF, -0xFF,0xFF,0xFF,0x3F,0xF6,0xFF,0xCF,0xFF, -0xDB,0xFB,0xF7,0xFF,0xEB,0x7A,0xFF,0xFF, -0xFF,0xBF,0xEF,0xFB,0xFF,0xFF,0xFF,0xFE, -0x6D,0xFD,0xFF,0x5F,0xFB,0xFF,0xFF,0xF7, -0xFF,0x5F,0xF5,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xF8,0xFF,0xFB,0xFF, -0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xE7,0xF6, -0xBF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF, -0xFF,0xC9,0xFF,0xFF,0xFF,0xBD,0xFF,0xBF, -0xAF,0xEF,0xEF,0x3F,0xD1,0xFC,0x7F,0xFB, -0xC7,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3,0xFF, -0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0x77,0xFF, -0xDF,0xB7,0xFD,0xF7,0xFD,0xF7,0xFF,0xFF, -0xFF,0xFF,0xFF,0x57,0xFF,0xF7,0xA5,0xFD, -0x3F,0xDF,0xBF,0xBF,0xFE,0x7F,0xFF,0xFF, -0xFF,0xDF,0xFA,0xFD,0xFF,0xFF,0xFF,0xFE, -0x87,0xFF,0xE9,0xFF,0xFE,0xEF,0xBF,0xEF, -0xFE,0xFE,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFA,0x9F,0xFF,0x3F, -0xFF,0xFD,0xFD,0x57,0xDF,0xFD,0xF3,0xFF, -0xDF,0xFD,0xFF,0x5F,0xDF,0xF5,0xFD,0xFF, -0xFF,0xF9,0x8F,0xFF,0xFF,0xFF,0xEE,0x7F, -0xFF,0xFF,0xBF,0x5E,0xFE,0xEC,0xFB,0x3F, -0x7F,0x9F,0xEF,0xF9,0xFF,0xFF,0xCD,0x6B, -0xFF,0xFF,0xFF,0xC5,0xF3,0xFC,0xFA,0x38, -0xFF,0xAF,0x3F,0xEE,0x7F,0x9F,0xFF,0xD9, -0xFF,0xFF,0xFD,0x7A,0xF7,0xFF,0xF3,0xFF, -0xAF,0x6F,0xDB,0xF2,0xB9,0xE9,0xFB,0xFF, -0xFF,0xFF,0xFE,0xFF,0xFF,0xEF,0xFF,0xFB, -0xC5,0xBF,0xFF,0xEF,0xFF,0x5E,0xB7,0xAD, -0xCD,0x79,0x7C,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFD,0x93,0xFF,0xEF, -0xEA,0xFE,0xBF,0xEF,0x5B,0xD2,0xCD,0xF5, -0x6D,0x77,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF, -0xFF,0xFF,0x66,0xFF,0xD5,0x65,0x7D,0x5F, -0x75,0x9D,0x65,0x7F,0xD6,0xFB,0x4F,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xC7, -0xFF,0xBF,0xEF,0xFA,0xFE,0xFF,0xBF,0xEB, -0xFF,0xDF,0xFF,0x7E,0xFF,0xFF,0xEF,0xFD, -0x7E,0xD7,0xFF,0x78,0xDF,0xFF,0x5F,0xDF, -0xF5,0xBF,0x7F,0xDF,0xC5,0xFF,0x3F,0xF6, -0x7E,0xFF,0x0F,0xEF,0xF2,0x3E,0xBF,0xFF, -0xFB,0x3F,0xFF,0xFB,0x7F,0xFF,0xB3,0xFE, -0xFB,0xF6,0xFD,0xFF,0xDA,0xF7,0xFD,0xFF, -0x7F,0xDF,0xF7,0xBF,0xFF,0xFA,0x7F,0xFF, -0xFF,0xFF,0xFF,0x9F,0xFF,0xF3,0xDC,0xF9, -0xBF,0xCE,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7, -0xFF,0xFF,0xE2,0x7F,0xFE,0xFF,0xBF,0xEF, -0xEB,0xFA,0xFF,0x9F,0x67,0x1E,0xFF,0x8F, -0xE7,0xF8,0xFE,0x7F,0x8F,0xEF,0xFF,0xBD, -0xBF,0xFF,0xFB,0xFF,0xFF,0xDF,0xF7,0xFF, -0xFC,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFD,0xB3,0xFF,0xFF,0xEF, -0xFF,0xFF,0xBF,0xED,0xFF,0xFB,0xEE,0xFE, -0xFF,0xFF,0xEF,0xFF,0xFE,0xFF,0xFF,0xFF, -0xFF,0xB5,0xFF,0xB7,0xFD,0xFD,0x6E,0xFF, -0xFF,0xFE,0xFD,0x2F,0xD8,0xFE,0xBF,0x8F, -0xEB,0xF9,0xFE,0x3F,0xFF,0xFA,0xCF,0xFF, -0xE7,0xD9,0xFA,0xBF,0xDF,0x77,0xFC,0xFB, -0x3F,0xAB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFE, -0xFF,0xFF,0xEE,0x1F,0xFF,0xDF,0xF7,0xFF, -0xFF,0xFF,0x5F,0x97,0x35,0xBF,0x5E,0xFE, -0xBF,0xEF,0xFF,0xF7,0xFD,0xFF,0xFF,0xFA, -0xBF,0xFF,0xBE,0x6F,0x9F,0xE7,0xF8,0xBE, -0x2F,0x8B,0x66,0x94,0x7D,0x9D,0xE7,0xF9, -0xFE,0x7F,0x9F,0xE7,0xF1,0x7F,0xFF,0xFF, -0xFF,0xF7,0xF5,0xFD,0x7F,0x5F,0xFB,0xFD, -0x9E,0xFF,0xFB,0xFE,0xFF,0xFF,0xEF,0xFF, -0xFF,0xA0,0xFF,0xFF,0xFF,0xBF,0xEF,0xEB, -0xFA,0xFE,0xBF,0xB7,0xF7,0xF7,0xFF,0xFF, -0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF, -0xFD,0xFF,0xFF,0xFF,0xD7,0xFF,0xFF,0xFF, -0x7F,0xF5,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF, -0xBF,0xFF,0xFF,0xAB,0xFE,0xFB,0xFE,0xFF, -0xF7,0xAF,0xFF,0xFF,0xDE,0xF7,0xEB,0x5F, -0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF,0xFF, -0xB3,0xFF,0xC9,0xFE,0xFF,0xFF,0xFF,0xFF, -0xD6,0xFF,0xFF,0xCB,0xFF,0xFF,0xDF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFC,0x8F,0xFF,0xBA, -0xBE,0xBF,0xAF,0xEB,0x78,0xFE,0xB7,0xAD, -0x3A,0xFE,0xB7,0xAF,0xEB,0x7A,0xFE,0xBF, -0xAF,0xFF,0x9F,0xFF,0xFF,0xDF,0xFC,0xFF, -0xFF,0xFE,0xC3,0xFE,0xFF,0xFF,0x33,0xFC, -0xFF,0xBF,0xDF,0xF3,0xFF,0xFF,0xBB,0x9F, -0xFF,0xFF,0xFF,0xEB,0xDF,0xFF,0xFF,0xAF, -0xF7,0x6F,0xF9,0xBF,0xEF,0xFD,0xFF,0xFF, -0xFF,0xFF,0xFF,0xE3,0x7F,0xFF,0xFF,0xFF, -0xFB,0xFF,0xFF,0xBF,0xFD,0xFB,0xF7,0xFF, -0xDF,0xF7,0xFF,0xFE,0xEF,0x5F,0xBD,0xFF, -0xFA,0xFF,0xF8,0xFF,0xBF,0xAF,0xFB,0xFE, -0xFE,0x3F,0xEF,0xE8,0xFF,0xDF,0xF3,0xFD, -0xFF,0xFF,0xFF,0xFF,0xFF,0xED,0xFF,0xFB, -0xFD,0xFF,0xAF,0xFF,0xFF,0xFE,0xFE,0xBF, -0xDB,0xFF,0xFF,0xFF,0xBF,0xFF,0xDF,0xFF, -0xFD,0xFF,0xCB,0xFF,0xFF,0xFF,0xFF,0xFF, -0xBF,0x6F,0xFF,0x7F,0xB7,0xB3,0xFF,0xFF, -0xDF,0xFF,0xFB,0xEF,0xFF,0xFF,0xFF,0x07, -0xFF,0xFB,0xFF,0xFF,0xFF,0xED,0xFF,0xF5, -0x7C,0xFF,0x7F,0xFE,0xFF,0xFF,0xEF,0xCF, -0xFF,0xFB,0xFF,0xFF,0x2F,0xFF,0xFF,0xFF, -0xFF,0xF3,0xFF,0xFB,0xFF,0xFE,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF, -0xFD,0x1B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFE,0x7C,0xFF,0xFF,0xFF,0xFF, -0xEF,0xFF,0xFF,0xFF,0xFF,0xFB,0xBF,0x7F, -0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xDB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, -0xFF,0xFF,0xF0,0x7F,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xDF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,0xFE, -0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xEF,0xFE,0xFF,0xBF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xEF,0xFA,0xB5,0xFF,0xFF,0xFF, -0xF7,0xF7,0xFF,0xFF,0xFF,0xFF,0xDF,0xFB, -0xFC,0xFF,0xFF,0xFE,0xFF,0x7F,0xDF,0xBF, -0xFF,0xCB,0xBF,0xF9,0xFE,0x7F,0x9F,0xE7, -0xF9,0xFE,0x7F,0x97,0xE1,0xFE,0x79,0x9F, -0xE7,0xFD,0xFE,0x7F,0xDF,0xFE,0x37,0xFF, -0xFB,0xDE,0xDE,0xBD,0xEF,0xF3,0xFE,0xFB, -0xAF,0xEB,0xFE,0xFF,0xFF,0xCF,0xFF,0xFE, -0xFF,0xBF,0xFF,0x8F,0xFF,0xEF,0xFB,0xFE, -0xFF,0xBF,0xE7,0xF9,0x5E,0x7F,0xEF,0xFB, -0xDA,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFD, -0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF, -0xFF,0xFF,0x7F,0xFF,0xFF,0xF7,0xFB,0x7F, -0xFF,0xFF,0xFF,0xFF,0xFC,0x3F,0xFF,0xBF, -0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0x7B,0x7F, -0xBF,0xEF,0xFB,0xFE,0xFF,0xB5,0xEF,0xFB, -0xBF,0xFA,0x7F,0xFC,0xFF,0x3F,0xCF,0xF3, -0xFC,0xFF,0x3F,0xCF,0xBC,0xFF,0x3F,0xEF, -0xF3,0xFC,0xFE,0x3F,0xCF,0xFF,0xEE,0xEF, -0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0x6A,0xD7, -0xB7,0xFB,0xF8,0xFF,0xB7,0xEF,0xBA,0xFE, -0xFF,0xBF,0x7F,0xE9,0xFF,0xF9,0x7E,0x5F, -0x97,0xE5,0xF9,0xFE,0x7F,0xBF,0xF9,0x7E, -0x5F,0x9F,0xE5,0xFB,0xFE,0x5F,0xB7,0xFF, -0xA3,0xFF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7, -0xFD,0xFF,0x5E,0xF7,0x7D,0xFF,0x77,0xDF, -0xF7,0xFD,0xFF,0x7F,0xFF,0xD7,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFD,0xDF,0xFB,0x7F, -0xFF,0xFF,0xEF,0xFF,0xFE,0xFB,0xFF,0xFF, -0xBF,0xFE,0x8F,0xFF,0xDF,0xF7,0xFD,0xFD, -0x7F,0xDF,0xF7,0xFD,0x3E,0xDF,0xF5,0xBD, -0xFF,0x7F,0xDF,0xF7,0xFD,0xF7,0xFF,0x9F, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFD,0xFF,0xBE,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFD,0x3F,0xFF,0xDF,0xF7, -0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0xCF, -0x77,0xFC,0xFF,0x5F,0xDF,0xF7,0xFD,0xFF, -0xF4,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFD,0xFF,0xFF,0xFF,0xEE,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xED,0xFB,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xE9,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFB,0xFF,0xFF,0xFF,0xD3,0xFF,0xFF, -0xBF,0x3F,0xFB,0xFF,0xFF,0xFF,0xFB,0xF3, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xF7, -0xFF,0xFF,0xFF,0xFF,0x17,0xFF,0xFF,0xFF, -0xDF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF, -0xDF,0xDF,0xFF,0xFD,0xFF,0xFF,0xDF,0xF7, -0xFF,0x4F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFD, -0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0x9F,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF, -0xFF,0xFF,0x7A,0x3F,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF2, -0x7F,0xFF,0xFB,0xFE,0xFF,0xBF,0xEF,0xF8, -0xFE,0xFF,0xBF,0xFB,0xFE,0xFF,0x8F,0xEC, -0xFB,0xFE,0xFF,0xBF,0xF8,0xF7,0xFE,0xFF, -0xBF,0xEF,0xFB,0xFE,0xFD,0xBF,0xCF,0xEC, -0xFF,0x3F,0xEF,0xDB,0xF8,0xFF,0xBF,0xCF, -0xFF,0xF9,0xFF,0xFF,0xBF,0xFF,0xFB,0xFF, -0xFF,0xFF,0xEF,0xFB,0xDF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xBB,0xFF, -0xEF,0xFB,0xFE,0xEF,0xBF,0xEE,0xEB,0xFB, -0xFE,0xFF,0xEF,0xFE,0xEE,0xBF,0xFE,0xEB, -0xFF,0xEF,0xFF,0x17,0xFF,0x7E,0xEB,0xBB, -0xFE,0xBF,0xBE,0xFB,0xEF,0x5B,0xF7,0xBD, -0xFB,0xCF,0xBF,0xBF,0xBB,0xFB,0x7E,0xCC, -0xEF,0xFF -}; diff -ur --new-file old/linux/drivers/usb/dabfirmware.h new/linux/drivers/usb/dabfirmware.h --- old/linux/drivers/usb/dabfirmware.h Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/usb/dabfirmware.h Mon Jan 24 07:36:37 2000 @@ -0,0 +1,1408 @@ +/* + * dabdata.h - dab usb firmware and bitstream data + */ + +static INTEL_HEX_RECORD firmware[] = { + +{ 2, 0x0000, 0, {0x21,0x57} }, +{ 3, 0x0003, 0, {0x02,0x01,0x66} }, +{ 3, 0x000b, 0, {0x02,0x01,0x66} }, +{ 3, 0x0013, 0, {0x02,0x01,0x66} }, +{ 3, 0x001b, 0, {0x02,0x01,0x66} }, +{ 3, 0x0023, 0, {0x02,0x01,0x66} }, +{ 3, 0x002b, 0, {0x02,0x01,0x66} }, +{ 3, 0x0033, 0, {0x02,0x03,0x0f} }, +{ 3, 0x003b, 0, {0x02,0x01,0x66} }, +{ 3, 0x0043, 0, {0x02,0x01,0x00} }, +{ 3, 0x004b, 0, {0x02,0x01,0x66} }, +{ 3, 0x0053, 0, {0x02,0x01,0x66} }, +{ 3, 0x005b, 0, {0x02,0x04,0xbd} }, +{ 3, 0x0063, 0, {0x02,0x01,0x67} }, +{ 3, 0x0100, 0, {0x02,0x0c,0x5a} }, +{ 3, 0x0104, 0, {0x02,0x01,0xed} }, +{ 3, 0x0108, 0, {0x02,0x02,0x51} }, +{ 3, 0x010c, 0, {0x02,0x02,0x7c} }, +{ 3, 0x0110, 0, {0x02,0x02,0xe4} }, +{ 1, 0x0114, 0, {0x32} }, +{ 1, 0x0118, 0, {0x32} }, +{ 3, 0x011c, 0, {0x02,0x05,0xfd} }, +{ 3, 0x0120, 0, {0x02,0x00,0x00} }, +{ 3, 0x0124, 0, {0x02,0x00,0x00} }, +{ 3, 0x0128, 0, {0x02,0x04,0x3c} }, +{ 3, 0x012c, 0, {0x02,0x04,0x6a} }, +{ 3, 0x0130, 0, {0x02,0x00,0x00} }, +{ 3, 0x0134, 0, {0x02,0x00,0x00} }, +{ 3, 0x0138, 0, {0x02,0x00,0x00} }, +{ 3, 0x013c, 0, {0x02,0x00,0x00} }, +{ 3, 0x0140, 0, {0x02,0x00,0x00} }, +{ 3, 0x0144, 0, {0x02,0x00,0x00} }, +{ 3, 0x0148, 0, {0x02,0x00,0x00} }, +{ 3, 0x014c, 0, {0x02,0x00,0x00} }, +{ 3, 0x0150, 0, {0x02,0x00,0x00} }, +{ 3, 0x0154, 0, {0x02,0x00,0x00} }, +{ 10, 0x0157, 0, {0x75,0x81,0x7f,0xe5,0x82,0x60,0x03,0x02,0x01,0x61} }, +{ 5, 0x0161, 0, {0x12,0x07,0x6f,0x21,0x64} }, +{ 1, 0x0166, 0, {0x32} }, +{ 14, 0x0167, 0, {0xc0,0xd0,0xc0,0x86,0xc0,0x82,0xc0,0x83,0xc0,0xe0,0x90,0x7f,0x97,0xe0} }, +{ 14, 0x0175, 0, {0x44,0x80,0xf0,0x90,0x7f,0x69,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} }, +{ 14, 0x0183, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} }, +{ 14, 0x0191, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x90,0x7f,0x97,0xe0} }, +{ 3, 0x019f, 0, {0x55,0x7f,0xf0} }, +{ 14, 0x01a2, 0, {0x90,0x7f,0x9a,0xe0,0x30,0xe4,0x23,0x90,0x7f,0x68,0xf0,0xf0,0xf0,0xf0} }, +{ 14, 0x01b0, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} }, +{ 14, 0x01be, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} }, +{ 14, 0x01cc, 0, {0xe5,0xd8,0xc2,0xe3,0xf5,0xd8,0xd0,0xe0,0xd0,0x83,0xd0,0x82,0xd0,0x86} }, +{ 3, 0x01da, 0, {0xd0,0xd0,0x32} }, +{ 8, 0x01dd, 0, {0x75,0x86,0x00,0x90,0xff,0xc3,0x7c,0x05} }, +{ 7, 0x01e5, 0, {0xa3,0xe5,0x82,0x45,0x83,0x70,0xf9} }, +{ 1, 0x01ec, 0, {0x22} }, +{ 14, 0x01ed, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0xd0} }, +{ 14, 0x01fb, 0, {0x75,0xd0,0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91} }, +{ 13, 0x0209, 0, {0x90,0x88,0x00,0xe0,0xf5,0x41,0x90,0x7f,0xab,0x74,0x02,0xf0,0x90} }, +{ 9, 0x0216, 0, {0x7f,0xab,0x74,0x02,0xf0,0xe5,0x32,0x60,0x21} }, +{ 4, 0x021f, 0, {0x7a,0x00,0x7b,0x00} }, +{ 11, 0x0223, 0, {0xc3,0xea,0x94,0x18,0xeb,0x64,0x80,0x94,0x80,0x50,0x12} }, +{ 14, 0x022e, 0, {0x90,0x7f,0x69,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x0a,0xba,0x00} }, +{ 2, 0x023c, 0, {0x01,0x0b} }, +{ 2, 0x023e, 0, {0x80,0xe3} }, +{ 2, 0x0240, 0, {0xd0,0x86} }, +{ 14, 0x0242, 0, {0xd0,0xd0,0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0} }, +{ 1, 0x0250, 0, {0x32} }, +{ 14, 0x0251, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} }, +{ 14, 0x025f, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xab,0x74} }, +{ 4, 0x026d, 0, {0x04,0xf0,0xd0,0x86} }, +{ 11, 0x0271, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, +{ 14, 0x027c, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} }, +{ 14, 0x028a, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} }, +{ 13, 0x0298, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} }, +{ 12, 0x02a5, 0, {0x7f,0xab,0x74,0x08,0xf0,0x75,0x6e,0x00,0x75,0x6f,0x02,0x12} }, +{ 6, 0x02b1, 0, {0x11,0x44,0x75,0x70,0x39,0x75} }, +{ 6, 0x02b7, 0, {0x71,0x0c,0x75,0x72,0x02,0x12} }, +{ 12, 0x02bd, 0, {0x11,0x75,0x90,0x7f,0xd6,0xe4,0xf0,0x75,0xd8,0x20,0xd0,0x86} }, +{ 14, 0x02c9, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} }, +{ 13, 0x02d7, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, +{ 14, 0x02e4, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} }, +{ 14, 0x02f2, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xab,0x74} }, +{ 4, 0x0300, 0, {0x10,0xf0,0xd0,0x86} }, +{ 11, 0x0304, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, +{ 14, 0x030f, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} }, +{ 14, 0x031d, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} }, +{ 12, 0x032b, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0x75,0x6e,0x00,0x75,0x6f,0x02} }, +{ 7, 0x0337, 0, {0x12,0x11,0x44,0x75,0x70,0x40,0x75} }, +{ 6, 0x033e, 0, {0x71,0x0c,0x75,0x72,0x02,0x12} }, +{ 14, 0x0344, 0, {0x11,0x75,0x90,0x7f,0xd6,0x74,0x02,0xf0,0x90,0x7f,0xd6,0x74,0x06,0xf0} }, +{ 5, 0x0352, 0, {0x75,0xd8,0x10,0xd0,0x86} }, +{ 14, 0x0357, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} }, +{ 13, 0x0365, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, +{ 13, 0x0372, 0, {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x90,0x7f,0xa6,0x74,0x9a,0xf0,0x12} }, +{ 12, 0x037f, 0, {0x10,0x1b,0x90,0x7f,0xa6,0xe5,0x42,0xf0,0x12,0x10,0x1b,0x90} }, +{ 13, 0x038b, 0, {0x7f,0xa6,0xe5,0x43,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa5,0x74,0x40} }, +{ 1, 0x0398, 0, {0xf0} }, +{ 1, 0x0399, 0, {0x22} }, +{ 13, 0x039a, 0, {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x90,0x7f,0xa6,0x74,0x9a,0xf0,0x12} }, +{ 12, 0x03a7, 0, {0x10,0x1b,0x90,0x7f,0xa6,0xe5,0x44,0xf0,0x12,0x10,0x1b,0x90} }, +{ 12, 0x03b3, 0, {0x7f,0xa6,0xe5,0x45,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa6,0xe5} }, +{ 11, 0x03bf, 0, {0x46,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa5,0x74,0x40,0xf0} }, +{ 1, 0x03ca, 0, {0x22} }, +{ 10, 0x03cb, 0, {0x75,0x44,0x02,0x75,0x45,0x00,0x75,0x46,0x00,0x12} }, +{ 9, 0x03d5, 0, {0x03,0x9a,0x75,0x42,0x03,0x75,0x43,0x00,0x12} }, +{ 2, 0x03de, 0, {0x03,0x72} }, +{ 1, 0x03e0, 0, {0x22} }, +{ 12, 0x03e1, 0, {0x90,0x88,0x00,0xe5,0x36,0xf0,0x90,0x88,0x00,0x74,0x10,0x25} }, +{ 9, 0x03ed, 0, {0x36,0xf0,0x12,0x01,0xdd,0x75,0x42,0x01,0x75} }, +{ 9, 0x03f6, 0, {0x43,0x18,0x12,0x03,0x72,0x75,0x44,0x02,0x75} }, +{ 9, 0x03ff, 0,{0x45,0x00,0x75,0x46,0x00,0x12,0x03,0x9a,0x75} }, +{ 8, 0x0408, 0,{0x42,0x03,0x75,0x43,0x44,0x12,0x03,0x72} }, +{ 1, 0x0410, 0,{0x22} }, +{ 14, 0x0411, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} }, +{ 14, 0x041f, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xaa,0x74} }, +{ 4, 0x042d, 0, {0x02,0xf0,0xd0,0x86} }, +{ 11, 0x0431, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, +{ 14, 0x043c, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} }, +{ 14, 0x044a, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xa9,0x74} }, +{ 7, 0x0458, 0, {0x04,0xf0,0x75,0x30,0x01,0xd0,0x86} }, +{ 11, 0x045f, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, +{ 14, 0x046a, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} }, +{ 14, 0x0478, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xaa,0x74} }, +{ 7, 0x0486, 0, {0x04,0xf0,0x75,0x31,0x01,0xd0,0x86} }, +{ 11, 0x048d, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, +{ 14, 0x0498, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} }, +{ 12, 0x04a6, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe5,0xf5,0x91,0xd0,0x86} }, +{ 11, 0x04b2, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, +{ 14, 0x04bd, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} }, +{ 12, 0x04cb, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe7,0xf5,0x91,0xd0,0x86} }, +{ 11, 0x04d7, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, +{ 12, 0x04e2, 0, {0x90,0x7f,0xea,0xe0,0xfa,0x8a,0x20,0x90,0x7f,0x96,0xe4,0xf0} }, +{ 1, 0x04ee, 0, {0x22} }, +{ 7, 0x04ef, 0, {0x90,0x7f,0xea,0xe0,0xfa,0x8a,0x21} }, +{ 1, 0x04f6, 0, {0x22} }, +{ 14, 0x04f7, 0, {0x90,0x17,0x13,0xe0,0xfa,0x90,0x17,0x15,0xe0,0xfb,0x74,0x80,0x2a,0xfa} }, +{ 14, 0x0505, 0, {0x74,0x80,0x2b,0xfb,0xea,0x03,0x03,0x54,0x3f,0xfc,0xea,0xc4,0x23,0x54} }, +{ 14, 0x0513, 0, {0x1f,0xfa,0x2c,0xfa,0xeb,0x03,0x03,0x54,0x3f,0xfc,0xeb,0xc4,0x23,0x54} }, +{ 11, 0x0521, 0, {0x1f,0xfb,0x2c,0xfb,0x90,0x17,0x0a,0xe0,0xfc,0x60,0x02} }, +{ 2, 0x052c, 0, {0x7a,0x00} }, +{ 7, 0x052e, 0, {0x90,0x17,0x0c,0xe0,0xfc,0x60,0x02} }, +{ 2, 0x0535, 0, {0x7b,0x00} }, +{ 11, 0x0537, 0, {0xea,0x2b,0xfc,0xc3,0x13,0xf5,0x3a,0x75,0x44,0x02,0x8b} }, +{ 7, 0x0542, 0, {0x45,0x8a,0x46,0x12,0x03,0x9a,0x75} }, +{ 9, 0x0549, 0, {0x6e,0x08,0x75,0x6f,0x00,0x12,0x11,0x44,0x75} }, +{ 4, 0x0552, 0, {0x70,0x47,0x75,0x71} }, +{ 8, 0x0556, 0, {0x0c,0x75,0x72,0x02,0x12,0x11,0x75,0x85} }, +{ 5, 0x055e, 0, {0x3a,0x73,0x12,0x11,0xa0} }, +{ 1, 0x0563, 0, {0x22} }, +{ 14, 0x0564, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x65,0x02,0xf0,0x90} }, +{ 14, 0x0572, 0, {0x7f,0xeb,0xe0,0xfa,0x90,0x7f,0xea,0xe0,0xfb,0x90,0x7f,0xef,0xe0,0xfc} }, +{ 14, 0x0580, 0, {0x33,0x95,0xe0,0xfd,0x8c,0x05,0x7c,0x00,0x90,0x7f,0xee,0xe0,0xfe,0x33} }, +{ 14, 0x058e, 0, {0x95,0xe0,0xff,0xec,0x2e,0xfc,0xed,0x3f,0xfd,0x90,0x7f,0xe9,0xe0,0xfe} }, +{ 5, 0x059c, 0, {0xbe,0x01,0x02,0x80,0x03} }, +{ 3, 0x05a1, 0, {0x02,0x05,0xf9} }, +{ 6, 0x05a4, 0, {0xbc,0x01,0x21,0xbd,0x00,0x1e} }, +{ 14, 0x05aa, 0, {0xea,0xc4,0x03,0x54,0xf8,0xfc,0xeb,0x25,0xe0,0xfd,0x2c,0x24,0x00,0xfc} }, +{ 14, 0x05b8, 0, {0xe4,0x34,0x17,0xfd,0x90,0x7e,0xc0,0xe0,0xfe,0x8c,0x82,0x8d,0x83,0xf0} }, +{ 2, 0x05c6, 0, {0x80,0x31} }, +{ 14, 0x05c8, 0, {0xea,0xc4,0x03,0x54,0xf8,0xfa,0xeb,0x25,0xe0,0xfb,0x2a,0xfa,0x24,0x00} }, +{ 14, 0x05d6, 0, {0xfb,0xe4,0x34,0x17,0xfc,0x90,0x7e,0xc0,0xe0,0xfd,0x8b,0x82,0x8c,0x83} }, +{ 14, 0x05e4, 0, {0xf0,0x74,0x01,0x2a,0x24,0x00,0xfa,0xe4,0x34,0x17,0xfb,0x90,0x7e,0xc1} }, +{ 7, 0x05f2, 0, {0xe0,0xfc,0x8a,0x82,0x8b,0x83,0xf0} }, +{ 3, 0x05f9, 0, {0x75,0x38,0x01} }, +{ 1, 0x05fc, 0, {0x22} }, +{ 14, 0x05fd, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} }, +{ 14, 0x060b, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} }, +{ 13, 0x0619, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} }, +{ 13, 0x0626, 0, {0x7f,0xaa,0x74,0x01,0xf0,0x12,0x05,0x64,0x75,0x37,0x00,0xd0,0x86} }, +{ 14, 0x0633, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} }, +{ 13, 0x0641, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, +{ 14, 0x064e, 0, {0x90,0x7f,0xeb,0xe0,0xfa,0x90,0x7f,0xea,0xe0,0xfb,0x90,0x7f,0xee,0xe0} }, +{ 14, 0x065c, 0, {0xfc,0x33,0x95,0xe0,0xfd,0x90,0x7f,0x96,0xe0,0xfe,0x90,0x7f,0x96,0x74} }, +{ 14, 0x066a, 0, {0x80,0x65,0x06,0xf0,0x90,0x7f,0x00,0x74,0x01,0xf0,0xea,0xc4,0x03,0x54} }, +{ 14, 0x0678, 0, {0xf8,0xfe,0xeb,0x25,0xe0,0xfb,0x2e,0xfe,0x24,0x00,0xfb,0xe4,0x34,0x17} }, +{ 14, 0x0686, 0, {0xff,0x8b,0x82,0x8f,0x83,0xe0,0xfb,0x74,0x01,0x2e,0x24,0x00,0xfe,0xe4} }, +{ 14, 0x0694, 0, {0x34,0x17,0xff,0x8e,0x82,0x8f,0x83,0xe0,0xfe,0x90,0x7f,0xe9,0xe0,0xff} }, +{ 3, 0x06a2, 0, {0xbf,0x81,0x0a} }, +{ 10, 0x06a5, 0, {0x90,0x7f,0x00,0xeb,0xf0,0x90,0x7f,0x01,0xee,0xf0} }, +{ 8, 0x06af, 0, {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x82,0x1a} }, +{ 3, 0x06b7, 0, {0xba,0x01,0x0c} }, +{ 12, 0x06ba, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0b} }, +{ 11, 0x06c6, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0x74,0xb5,0xf0} }, +{ 8, 0x06d1, 0, {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x83,0x1b} }, +{ 3, 0x06d9, 0, {0xba,0x01,0x0d} }, +{ 13, 0x06dc, 0, {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0b} }, +{ 11, 0x06e9, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0x74,0x12,0xf0} }, +{ 8, 0x06f4, 0, {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x84,0x1c} }, +{ 3, 0x06fc, 0, {0xba,0x01,0x0d} }, +{ 13, 0x06ff, 0, {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0c} }, +{ 12, 0x070c, 0, {0x90,0x7f,0x00,0x74,0x80,0xf0,0x90,0x7f,0x01,0x74,0x01,0xf0} }, +{ 5, 0x0718, 0, {0x90,0x7f,0xb5,0xec,0xf0} }, +{ 1, 0x071d, 0, {0x22} }, +{ 12, 0x071e, 0, {0x75,0x36,0x0d,0x90,0x88,0x00,0x74,0x1d,0xf0,0x75,0x6b,0x80} }, +{ 10, 0x072a, 0, {0x75,0x6c,0x3c,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} }, +{ 9, 0x0734, 0, {0x6c,0x0f,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} }, +{ 9, 0x073d, 0, {0x6c,0x06,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} }, +{ 7, 0x0746, 0, {0x6c,0x01,0x12,0x10,0xe2,0x7a,0x00} }, +{ 3, 0x074d, 0, {0xba,0xff,0x00} }, +{ 2, 0x0750, 0, {0x50,0x0a} }, +{ 10, 0x0752, 0, {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xf1} }, +{ 10, 0x075c, 0, {0x75,0x6b,0x80,0x75,0x6c,0x3c,0x12,0x10,0xe2,0x75} }, +{ 8, 0x0766, 0, {0x6b,0x80,0x75,0x6c,0x0f,0x12,0x10,0xe2} }, +{ 1, 0x076e, 0, {0x22} }, +{ 14, 0x076f, 0, {0x90,0x7f,0xa1,0xe4,0xf0,0x90,0x7f,0xaf,0x74,0x01,0xf0,0x90,0x7f,0x92} }, +{ 14, 0x077d, 0, {0x74,0x02,0xf0,0x75,0x8e,0x31,0x75,0x89,0x21,0x75,0x88,0x00,0x75,0xc8} }, +{ 14, 0x078b, 0, {0x00,0x75,0x8d,0x40,0x75,0x98,0x40,0x75,0xc0,0x40,0x75,0x87,0x00,0x75} }, +{ 9, 0x0799, 0, {0x20,0x00,0x75,0x21,0x00,0x75,0x22,0x00,0x75} }, +{ 5, 0x07a2, 0, {0x23,0x00,0x75,0x47,0x00} }, +{ 7, 0x07a7, 0, {0xc3,0xe5,0x47,0x94,0x20,0x50,0x11} }, +{ 13, 0x07ae, 0, {0xe5,0x47,0x24,0x00,0xf5,0x82,0xe4,0x34,0x17,0xf5,0x83,0xe4,0xf0} }, +{ 4, 0x07bb, 0, {0x05,0x47,0x80,0xe8} }, +{ 9, 0x07bf, 0, {0xe4,0xf5,0x40,0xf5,0x3f,0xe4,0xf5,0x3c,0xf5} }, +{ 7, 0x07c8, 0, {0x3b,0xe4,0xf5,0x3e,0xf5,0x3d,0x75} }, +{ 11, 0x07cf, 0, {0x32,0x00,0x75,0x37,0x00,0x75,0x39,0x00,0x90,0x7f,0x93} }, +{ 14, 0x07da, 0, {0x74,0x3c,0xf0,0x90,0x7f,0x9c,0x74,0xff,0xf0,0x90,0x7f,0x96,0x74,0x80} }, +{ 14, 0x07e8, 0, {0xf0,0x90,0x7f,0x94,0x74,0x70,0xf0,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90} }, +{ 14, 0x07f6, 0, {0x7f,0x97,0xe4,0xf0,0x90,0x7f,0x95,0x74,0xc2,0xf0,0x90,0x7f,0x98,0x74} }, +{ 14, 0x0804, 0, {0x28,0xf0,0x90,0x7f,0x9e,0x74,0x28,0xf0,0x90,0x7f,0xf0,0xe4,0xf0,0x90} }, +{ 14, 0x0812, 0, {0x7f,0xf1,0xe4,0xf0,0x90,0x7f,0xf2,0xe4,0xf0,0x90,0x7f,0xf3,0xe4,0xf0} }, +{ 14, 0x0820, 0, {0x90,0x7f,0xf4,0xe4,0xf0,0x90,0x7f,0xf5,0xe4,0xf0,0x90,0x7f,0xf6,0xe4} }, +{ 14, 0x082e, 0, {0xf0,0x90,0x7f,0xf7,0xe4,0xf0,0x90,0x7f,0xf8,0xe4,0xf0,0x90,0x7f,0xf9} }, +{ 14, 0x083c, 0, {0x74,0x38,0xf0,0x90,0x7f,0xfa,0x74,0xa0,0xf0,0x90,0x7f,0xfb,0x74,0xa0} }, +{ 14, 0x084a, 0, {0xf0,0x90,0x7f,0xfc,0x74,0xa0,0xf0,0x90,0x7f,0xfd,0x74,0xa0,0xf0,0x90} }, +{ 14, 0x0858, 0, {0x7f,0xfe,0x74,0xa0,0xf0,0x90,0x7f,0xff,0x74,0xa0,0xf0,0x90,0x7f,0xe0} }, +{ 14, 0x0866, 0, {0x74,0x03,0xf0,0x90,0x7f,0xe1,0x74,0x01,0xf0,0x90,0x7f,0xdd,0x74,0x80} }, +{ 11, 0x0874, 0, {0xf0,0x12,0x12,0x43,0x12,0x07,0x1e,0x7a,0x00,0x7b,0x00} }, +{ 9, 0x087f, 0, {0xc3,0xea,0x94,0x1e,0xeb,0x94,0x00,0x50,0x17} }, +{ 12, 0x0888, 0, {0x90,0x88,0x00,0xe0,0xf5,0x47,0x90,0x88,0x0b,0xe0,0xf5,0x47} }, +{ 9, 0x0894, 0, {0x90,0x7f,0x68,0xf0,0x0a,0xba,0x00,0x01,0x0b} }, +{ 2, 0x089d, 0, {0x80,0xe0} }, +{ 12, 0x089f, 0, {0x12,0x03,0xe1,0x90,0x7f,0xd6,0xe4,0xf0,0x7a,0x00,0x7b,0x00} }, +{ 13, 0x08ab, 0, {0x8a,0x04,0x8b,0x05,0xc3,0xea,0x94,0xe0,0xeb,0x94,0x2e,0x50,0x1a} }, +{ 14, 0x08b8, 0, {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} }, +{ 10, 0x08c6, 0, {0x04,0xd0,0x03,0xd0,0x02,0x0a,0xba,0x00,0x01,0x0b} }, +{ 2, 0x08d0, 0, {0x80,0xd9} }, +{ 13, 0x08d2, 0, {0x90,0x7f,0xd6,0x74,0x02,0xf0,0x90,0x7f,0xd6,0x74,0x06,0xf0,0x90} }, +{ 14, 0x08df, 0, {0x7f,0xde,0x74,0x05,0xf0,0x90,0x7f,0xdf,0x74,0x05,0xf0,0x90,0x7f,0xac} }, +{ 14, 0x08ed, 0, {0xe4,0xf0,0x90,0x7f,0xad,0x74,0x05,0xf0,0x75,0xa8,0x80,0x75,0xf8,0x10} }, +{ 13, 0x08fb, 0, {0x90,0x7f,0xae,0x74,0x0b,0xf0,0x90,0x7f,0xe2,0x74,0x88,0xf0,0x90} }, +{ 12, 0x0908, 0, {0x7f,0xab,0x74,0x08,0xf0,0x75,0xe8,0x11,0x75,0x32,0x01,0x75} }, +{ 12, 0x0914, 0, {0x31,0x00,0x75,0x30,0x00,0xc0,0x04,0xc0,0x05,0x12,0x04,0xf7} }, +{ 10, 0x0920, 0, {0xd0,0x05,0xd0,0x04,0x75,0x34,0x00,0x75,0x35,0x01} }, +{ 13, 0x092a, 0, {0x90,0x7f,0xae,0x74,0x03,0xf0,0x8c,0x02,0xba,0x00,0x02,0x80,0x03} }, +{ 3, 0x0937, 0, {0x02,0x0a,0x3f} }, +{ 12, 0x093a, 0, {0x85,0x33,0x34,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90,0x7f,0x97} }, +{ 14, 0x0946, 0, {0x74,0x08,0xf0,0x90,0x7f,0x9d,0x74,0x88,0xf0,0x90,0x7f,0x9a,0xe0,0xfa} }, +{ 12, 0x0954, 0, {0x74,0x05,0x5a,0xf5,0x33,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90} }, +{ 13, 0x0960, 0, {0x7f,0x97,0x74,0x02,0xf0,0x90,0x7f,0x9d,0x74,0x82,0xf0,0xe5,0x33} }, +{ 13, 0x096d, 0, {0x25,0xe0,0xfa,0x90,0x7f,0x9a,0xe0,0x54,0x05,0xfb,0x4a,0xf5,0x33} }, +{ 2, 0x097a, 0, {0x60,0x0c} }, +{ 12, 0x097c, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x4a,0xf0} }, +{ 11, 0x0988, 0, {0x75,0x6e,0x00,0x75,0x6f,0x00,0xc0,0x04,0xc0,0x05,0x12} }, +{ 14, 0x0993, 0, {0x11,0x44,0xd0,0x05,0xd0,0x04,0x90,0x17,0x13,0xe0,0xfa,0x74,0x80,0x2a} }, +{ 6, 0x09a1, 0, {0xfa,0xe5,0x33,0xb4,0x04,0x29} }, +{ 3, 0x09a7, 0, {0xba,0xa0,0x00} }, +{ 2, 0x09aa, 0, {0x50,0x24} }, +{ 13, 0x09ac, 0, {0x90,0x17,0x13,0xe0,0x04,0xfb,0x0b,0x90,0x17,0x13,0xeb,0xf0,0x90} }, +{ 14, 0x09b9, 0, {0x17,0x13,0xe0,0xfb,0x90,0x17,0x15,0xf0,0xc0,0x02,0xc0,0x04,0xc0,0x05} }, +{ 9, 0x09c7, 0, {0x12,0x04,0xf7,0xd0,0x05,0xd0,0x04,0xd0,0x02} }, +{ 5, 0x09d0, 0, {0xe5,0x33,0xb4,0x02,0x26} }, +{ 6, 0x09d5, 0, {0xc3,0x74,0x04,0x9a,0x50,0x20} }, +{ 13, 0x09db, 0, {0x90,0x17,0x13,0xe0,0xfa,0x1a,0x1a,0x90,0x17,0x13,0xea,0xf0,0x90} }, +{ 13, 0x09e8, 0, {0x17,0x13,0xe0,0xfa,0x90,0x17,0x15,0xf0,0xc0,0x04,0xc0,0x05,0x12} }, +{ 6, 0x09f5, 0, {0x04,0xf7,0xd0,0x05,0xd0,0x04} }, +{ 5, 0x09fb, 0, {0xe5,0x33,0xb4,0x08,0x1d} }, +{ 4, 0x0a00, 0, {0xe5,0x34,0x70,0x19} }, +{ 10, 0x0a04, 0, {0x74,0x01,0x25,0x35,0x54,0x0f,0xf5,0x35,0x85,0x35} }, +{ 12, 0x0a0e, 0, {0x75,0x75,0x76,0x00,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0} }, +{ 3, 0x0a1a, 0, {0x05,0xd0,0x04} }, +{ 5, 0x0a1d, 0, {0xe5,0x33,0xb4,0x01,0x1d} }, +{ 4, 0x0a22, 0, {0xe5,0x34,0x70,0x19} }, +{ 10, 0x0a26, 0, {0xe5,0x35,0x24,0xff,0x54,0x0f,0xf5,0x35,0x85,0x35} }, +{ 12, 0x0a30, 0, {0x75,0x75,0x76,0x00,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0} }, +{ 3, 0x0a3c, 0, {0x05,0xd0,0x04} }, +{ 14, 0x0a3f, 0, {0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0,0x04,0x90,0x7f,0x96} }, +{ 14, 0x0a4d, 0, {0xe0,0xfa,0x90,0x7f,0x96,0x74,0x7f,0x5a,0xf0,0x90,0x7f,0x97,0x74,0x08} }, +{ 10, 0x0a5b, 0, {0xf0,0xc3,0xec,0x94,0x00,0xed,0x94,0x02,0x40,0x08} }, +{ 8, 0x0a65, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x20,0xe6,0x08} }, +{ 8, 0x0a6d, 0, {0xc3,0xe4,0x9c,0x74,0x08,0x9d,0x50,0x13} }, +{ 14, 0x0a75, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x40,0x65,0x02,0xf0,0x7c} }, +{ 5, 0x0a83, 0, {0x00,0x7d,0x00,0x80,0x05} }, +{ 5, 0x0a88, 0, {0x0c,0xbc,0x00,0x01,0x0d} }, +{ 5, 0x0a8d, 0, {0xe5,0x38,0xb4,0x01,0x0e} }, +{ 13, 0x0a92, 0, {0xc0,0x04,0xc0,0x05,0x12,0x04,0xf7,0xd0,0x05,0xd0,0x04,0x75,0x38} }, +{ 1, 0x0a9f, 0, {0x00} }, +{ 7, 0x0aa0, 0, {0xe5,0x31,0x70,0x03,0x02,0x09,0x2a} }, +{ 10, 0x0aa7, 0, {0x90,0x7f,0xc9,0xe0,0xfa,0x70,0x03,0x02,0x0c,0x2d} }, +{ 14, 0x0ab1, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x65,0x02,0xf0,0x90} }, +{ 9, 0x0abf, 0, {0x7d,0xc0,0xe0,0xfa,0xba,0x2c,0x02,0x80,0x03} }, +{ 3, 0x0ac8, 0, {0x02,0x0b,0x36} }, +{ 5, 0x0acb, 0, {0x75,0x32,0x00,0x7b,0x00} }, +{ 3, 0x0ad0, 0, {0xbb,0x64,0x00} }, +{ 2, 0x0ad3, 0, {0x50,0x1c} }, +{ 14, 0x0ad5, 0, {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} }, +{ 13, 0x0ae3, 0, {0x04,0xd0,0x03,0xd0,0x02,0x90,0x88,0x0f,0xe0,0xf5,0x47,0x0b,0x80} }, +{ 1, 0x0af0, 0, {0xdf} }, +{ 13, 0x0af1, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x07,0x1e,0x12,0x03,0xe1,0x12} }, +{ 12, 0x0afe, 0, {0x04,0xf7,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x75,0x6e,0x00,0x75} }, +{ 13, 0x0b0a, 0, {0x6f,0x01,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x11,0x44,0xd0,0x05} }, +{ 9, 0x0b17, 0, {0xd0,0x04,0xd0,0x02,0x75,0x70,0x4d,0x75,0x71} }, +{ 11, 0x0b20, 0, {0x0c,0x75,0x72,0x02,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12} }, +{ 11, 0x0b2b, 0, {0x11,0x75,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x02,0x0c,0x2d} }, +{ 3, 0x0b36, 0, {0xba,0x2a,0x3b} }, +{ 13, 0x0b39, 0, {0x90,0x7f,0x98,0x74,0x20,0xf0,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12} }, +{ 14, 0x0b46, 0, {0x01,0xdd,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x90,0x7f,0x98,0x74,0x28,0xf0} }, +{ 2, 0x0b54, 0, {0x7b,0x00} }, +{ 3, 0x0b56, 0, {0xbb,0x0a,0x00} }, +{ 5, 0x0b59, 0, {0x40,0x03,0x02,0x0c,0x2d} }, +{ 14, 0x0b5e, 0, {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} }, +{ 8, 0x0b6c, 0, {0x04,0xd0,0x03,0xd0,0x02,0x0b,0x80,0xe2} }, +{ 3, 0x0b74, 0, {0xba,0x2b,0x1a} }, +{ 8, 0x0b77, 0, {0x90,0x7f,0xc9,0xe0,0xfb,0xbb,0x40,0x12} }, +{ 14, 0x0b7f, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x12,0x05,0xd0,0x05,0xd0,0x04,0xd0} }, +{ 4, 0x0b8d, 0, {0x02,0x02,0x0c,0x2d} }, +{ 3, 0x0b91, 0, {0xba,0x10,0x1f} }, +{ 14, 0x0b94, 0, {0x90,0x7f,0x96,0xe0,0xfb,0x90,0x7f,0x96,0x74,0x80,0x65,0x03,0xf0,0xc0} }, +{ 14, 0x0ba2, 0, {0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x3d,0xd0,0x05,0xd0,0x04,0xd0,0x02} }, +{ 3, 0x0bb0, 0, {0x02,0x0c,0x2d} }, +{ 3, 0x0bb3, 0, {0xba,0x11,0x12} }, +{ 14, 0x0bb6, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x6a,0xd0,0x05,0xd0,0x04,0xd0} }, +{ 4, 0x0bc4, 0, {0x02,0x02,0x0c,0x2d} }, +{ 3, 0x0bc8, 0, {0xba,0x12,0x12} }, +{ 14, 0x0bcb, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x8f,0xd0,0x05,0xd0,0x04,0xd0} }, +{ 4, 0x0bd9, 0, {0x02,0x02,0x0c,0x2d} }, +{ 3, 0x0bdd, 0, {0xba,0x13,0x0b} }, +{ 11, 0x0be0, 0, {0x90,0x7d,0xc1,0xe0,0xfb,0x90,0x88,0x00,0xf0,0x80,0x42} }, +{ 3, 0x0beb, 0, {0xba,0x14,0x11} }, +{ 14, 0x0bee, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x11,0xdd,0xd0,0x05,0xd0,0x04,0xd0} }, +{ 3, 0x0bfc, 0, {0x02,0x80,0x2e} }, +{ 3, 0x0bff, 0, {0xba,0x15,0x1d} }, +{ 12, 0x0c02, 0, {0x90,0x7d,0xc1,0xe0,0xf5,0x75,0x90,0x7d,0xc2,0xe0,0xf5,0x76} }, +{ 14, 0x0c0e, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0,0x05,0xd0,0x04,0xd0} }, +{ 3, 0x0c1c, 0, {0x02,0x80,0x0e} }, +{ 3, 0x0c1f, 0, {0xba,0x16,0x0b} }, +{ 11, 0x0c22, 0, {0xc0,0x04,0xc0,0x05,0x12,0x13,0xa3,0xd0,0x05,0xd0,0x04} }, +{ 11, 0x0c2d, 0, {0x90,0x7f,0xc9,0xe4,0xf0,0x75,0x31,0x00,0x02,0x09,0x2a} }, +{ 1, 0x0c38, 0, {0x22} }, +{ 7, 0x0c39, 0, {0x53,0x55,0x50,0x45,0x4e,0x44,0x00} }, +{ 7, 0x0c40, 0, {0x52,0x45,0x53,0x55,0x4d,0x45,0x00} }, +{ 6, 0x0c47, 0, {0x20,0x56,0x6f,0x6c,0x20,0x00} }, +{ 13, 0x0c4d, 0, {0x44,0x41,0x42,0x55,0x53,0x42,0x20,0x76,0x31,0x2e,0x30,0x30,0x00} }, +{ 14, 0x0c5a, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} }, +{ 14, 0x0c68, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} }, +{ 13, 0x0c76, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} }, +{ 14, 0x0c83, 0, {0x7f,0xab,0x74,0x01,0xf0,0x90,0x7f,0xe8,0xe0,0xfa,0x90,0x7f,0xe9,0xe0} }, +{ 6, 0x0c91, 0, {0xfb,0xbb,0x00,0x02,0x80,0x03} }, +{ 3, 0x0c97, 0, {0x02,0x0d,0x38} }, +{ 3, 0x0c9a, 0, {0xba,0x80,0x14} }, +{ 14, 0x0c9d, 0, {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5} }, +{ 6, 0x0cab, 0, {0x74,0x02,0xf0,0x02,0x0e,0xcd} }, +{ 5, 0x0cb1, 0, {0xba,0x82,0x02,0x80,0x03} }, +{ 3, 0x0cb6, 0, {0x02,0x0d,0x1d} }, +{ 8, 0x0cb9, 0, {0x90,0x7f,0xec,0xe0,0xfc,0xbc,0x01,0x00} }, +{ 2, 0x0cc1, 0, {0x40,0x21} }, +{ 6, 0x0cc3, 0, {0xc3,0x74,0x07,0x9c,0x40,0x1b} }, +{ 14, 0x0cc9, 0, {0xec,0x24,0xff,0x25,0xe0,0xfd,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x7f,0xf5} }, +{ 13, 0x0cd7, 0, {0x83,0xe0,0xfd,0x53,0x05,0x01,0x90,0x7f,0x00,0xed,0xf0,0x80,0x2b} }, +{ 3, 0x0ce4, 0, {0xbc,0x81,0x00} }, +{ 2, 0x0ce7, 0, {0x40,0x21} }, +{ 6, 0x0ce9, 0, {0xc3,0x74,0x87,0x9c,0x40,0x1b} }, +{ 14, 0x0cef, 0, {0xec,0x24,0x7f,0x25,0xe0,0xfc,0x24,0xb6,0xf5,0x82,0xe4,0x34,0x7f,0xf5} }, +{ 13, 0x0cfd, 0, {0x83,0xe0,0xfc,0x53,0x04,0x01,0x90,0x7f,0x00,0xec,0xf0,0x80,0x05} }, +{ 5, 0x0d0a, 0, {0x90,0x7f,0x00,0xe4,0xf0} }, +{ 14, 0x0d0f, 0, {0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x02,0x0e,0xcd} }, +{ 5, 0x0d1d, 0, {0xba,0x81,0x02,0x80,0x03} }, +{ 3, 0x0d22, 0, {0x02,0x0e,0xc5} }, +{ 14, 0x0d25, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5,0x74} }, +{ 5, 0x0d33, 0, {0x02,0xf0,0x02,0x0e,0xcd} }, +{ 3, 0x0d38, 0, {0xbb,0x01,0x2d} }, +{ 6, 0x0d3b, 0, {0xba,0x00,0x03,0x02,0x0e,0xcd} }, +{ 3, 0x0d41, 0, {0xba,0x02,0x11} }, +{ 13, 0x0d44, 0, {0x75,0x59,0x00,0xc0,0x02,0xc0,0x03,0x12,0x0e,0xf0,0xd0,0x03,0xd0} }, +{ 4, 0x0d51, 0, {0x02,0x02,0x0e,0xcd} }, +{ 5, 0x0d55, 0, {0xba,0x21,0x02,0x80,0x03} }, +{ 3, 0x0d5a, 0, {0x02,0x0e,0xcd} }, +{ 11, 0x0d5d, 0, {0x75,0x37,0x01,0x90,0x7f,0xc5,0xe4,0xf0,0x02,0x0e,0xcd} }, +{ 3, 0x0d68, 0, {0xbb,0x03,0x1f} }, +{ 6, 0x0d6b, 0, {0xba,0x00,0x03,0x02,0x0e,0xcd} }, +{ 5, 0x0d71, 0, {0xba,0x02,0x02,0x80,0x03} }, +{ 3, 0x0d76, 0, {0x02,0x0e,0xcd} }, +{ 13, 0x0d79, 0, {0x75,0x59,0x01,0xc0,0x02,0xc0,0x03,0x12,0x0e,0xf0,0xd0,0x03,0xd0} }, +{ 4, 0x0d86, 0, {0x02,0x02,0x0e,0xcd} }, +{ 3, 0x0d8a, 0, {0xbb,0x06,0x54} }, +{ 5, 0x0d8d, 0, {0xba,0x80,0x02,0x80,0x03} }, +{ 3, 0x0d92, 0, {0x02,0x0e,0xc5} }, +{ 8, 0x0d95, 0, {0x90,0x7f,0xeb,0xe0,0xfc,0xbc,0x01,0x15} }, +{ 12, 0x0d9d, 0, {0x7c,0xfb,0x7d,0x0f,0x8d,0x06,0x7f,0x00,0x90,0x7f,0xd4,0xee} }, +{ 9, 0x0da9, 0, {0xf0,0x90,0x7f,0xd5,0xec,0xf0,0x02,0x0e,0xcd} }, +{ 10, 0x0db2, 0, {0x90,0x7f,0xeb,0xe0,0xfc,0xbc,0x02,0x02,0x80,0x03} }, +{ 3, 0x0dbc, 0, {0x02,0x0e,0xc5} }, +{ 10, 0x0dbf, 0, {0x90,0x7f,0xea,0xe0,0xfc,0xbc,0x00,0x02,0x80,0x03} }, +{ 3, 0x0dc9, 0, {0x02,0x0e,0xc5} }, +{ 12, 0x0dcc, 0, {0x7c,0x3b,0x7d,0x0f,0x8d,0x06,0x7f,0x00,0x90,0x7f,0xd4,0xee} }, +{ 9, 0x0dd8, 0, {0xf0,0x90,0x7f,0xd5,0xec,0xf0,0x02,0x0e,0xcd} }, +{ 6, 0x0de1, 0, {0xbb,0x07,0x03,0x02,0x0e,0xc5} }, +{ 3, 0x0de7, 0, {0xbb,0x08,0x10} }, +{ 13, 0x0dea, 0, {0xac,0x48,0x90,0x7f,0x00,0xec,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0} }, +{ 3, 0x0df7, 0, {0x02,0x0e,0xcd} }, +{ 3, 0x0dfa, 0, {0xbb,0x09,0x31} }, +{ 5, 0x0dfd, 0, {0xba,0x00,0x02,0x80,0x03} }, +{ 3, 0x0e02, 0, {0x02,0x0e,0xc5} }, +{ 14, 0x0e05, 0, {0x90,0x7f,0xea,0xe0,0xfc,0xc3,0x74,0x01,0x9c,0x50,0x03,0x02,0x0e,0xc5} }, +{ 8, 0x0e13, 0, {0x90,0x7f,0xea,0xe0,0xfc,0xbc,0x00,0x0a} }, +{ 10, 0x0e1b, 0, {0x90,0x17,0x21,0xe4,0xf0,0x90,0x17,0x22,0xe4,0xf0} }, +{ 9, 0x0e25, 0, {0x90,0x7f,0xea,0xe0,0xf5,0x48,0x02,0x0e,0xcd} }, +{ 3, 0x0e2e, 0, {0xbb,0x0a,0x27} }, +{ 5, 0x0e31, 0, {0xba,0x81,0x02,0x80,0x03} }, +{ 3, 0x0e36, 0, {0x02,0x0e,0xc5} }, +{ 14, 0x0e39, 0, {0x90,0x7f,0xec,0xe0,0xfa,0x24,0x20,0xfa,0xe4,0x34,0x17,0xfc,0x8a,0x82} }, +{ 14, 0x0e47, 0, {0x8c,0x83,0xe0,0xfa,0x90,0x7f,0x00,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0} }, +{ 3, 0x0e55, 0, {0x02,0x0e,0xcd} }, +{ 5, 0x0e58, 0, {0xbb,0x0b,0x02,0x80,0x03} }, +{ 3, 0x0e5d, 0, {0x02,0x0e,0xa9} }, +{ 13, 0x0e60, 0, {0x90,0x17,0x20,0xe4,0xf0,0x90,0x7f,0xec,0xe0,0xfa,0xba,0x01,0x1a} }, +{ 8, 0x0e6d, 0, {0x90,0x7f,0xed,0xe0,0xfa,0xba,0x00,0x12} }, +{ 14, 0x0e75, 0, {0x90,0x7f,0xea,0xe0,0xfa,0x90,0x17,0x21,0xf0,0xc0,0x03,0x12,0x04,0xe2} }, +{ 4, 0x0e83, 0, {0xd0,0x03,0x80,0x46} }, +{ 8, 0x0e87, 0, {0x90,0x7f,0xec,0xe0,0xfa,0xba,0x02,0x3e} }, +{ 8, 0x0e8f, 0, {0x90,0x7f,0xed,0xe0,0xfa,0xba,0x00,0x36} }, +{ 13, 0x0e97, 0, {0xc0,0x03,0x12,0x04,0xef,0xd0,0x03,0x90,0x7f,0xea,0xe0,0xfa,0x90} }, +{ 5, 0x0ea4, 0, {0x17,0x22,0xf0,0x80,0x24} }, +{ 5, 0x0ea9, 0, {0xbb,0x12,0x02,0x80,0x17} }, +{ 5, 0x0eae, 0, {0xbb,0x81,0x02,0x80,0x0d} }, +{ 5, 0x0eb3, 0, {0xbb,0x83,0x02,0x80,0x08} }, +{ 5, 0x0eb8, 0, {0xbb,0x82,0x02,0x80,0x03} }, +{ 3, 0x0ebd, 0, {0xbb,0x84,0x05} }, +{ 5, 0x0ec0, 0, {0x12,0x06,0x4e,0x80,0x08} }, +{ 8, 0x0ec5, 0, {0x90,0x7f,0xb4,0x74,0x03,0xf0,0x80,0x06} }, +{ 6, 0x0ecd, 0, {0x90,0x7f,0xb4,0x74,0x02,0xf0} }, +{ 2, 0x0ed3, 0, {0xd0,0x86} }, +{ 14, 0x0ed5, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} }, +{ 13, 0x0ee3, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, +{ 11, 0x0ef0, 0, {0x90,0x7f,0xec,0xe0,0xf5,0x5a,0xc3,0x94,0x01,0x40,0x1d} }, +{ 7, 0x0efb, 0, {0xc3,0x74,0x07,0x95,0x5a,0x40,0x16} }, +{ 13, 0x0f02, 0, {0xe5,0x5a,0x24,0xff,0x25,0xe0,0xfa,0x24,0xc6,0xf5,0x82,0xe4,0x34} }, +{ 9, 0x0f0f, 0, {0x7f,0xf5,0x83,0xaa,0x59,0xea,0xf0,0x80,0x22} }, +{ 7, 0x0f18, 0, {0xc3,0xe5,0x5a,0x94,0x81,0x40,0x1b} }, +{ 7, 0x0f1f, 0, {0xc3,0x74,0x87,0x95,0x5a,0x40,0x14} }, +{ 13, 0x0f26, 0, {0xe5,0x5a,0x24,0xff,0x25,0xe0,0xfa,0x24,0xb6,0xf5,0x82,0xe4,0x34} }, +{ 7, 0x0f33, 0, {0x7f,0xf5,0x83,0xaa,0x59,0xea,0xf0} }, +{ 1, 0x0f3a, 0, {0x22} }, +{ 14, 0x0f3b, 0, {0x09,0x02,0xba,0x00,0x03,0x01,0x00,0x40,0x00,0x09,0x04,0x00,0x00,0x00} }, +{ 14, 0x0f49, 0, {0x01,0x01,0x00,0x00,0x09,0x24,0x01,0x00,0x01,0x3d,0x00,0x01,0x01,0x0c} }, +{ 14, 0x0f57, 0, {0x24,0x02,0x01,0x10,0x07,0x00,0x02,0x03,0x00,0x00,0x00,0x0d,0x24,0x06} }, +{ 14, 0x0f65, 0, {0x03,0x01,0x02,0x15,0x00,0x03,0x00,0x03,0x00,0x00,0x09,0x24,0x03,0x02} }, +{ 14, 0x0f73, 0, {0x01,0x01,0x00,0x01,0x00,0x09,0x24,0x03,0x04,0x02,0x03,0x00,0x03,0x00} }, +{ 14, 0x0f81, 0, {0x09,0x24,0x03,0x05,0x03,0x06,0x00,0x01,0x00,0x09,0x04,0x01,0x00,0x00} }, +{ 14, 0x0f8f, 0, {0x01,0x02,0x00,0x00,0x09,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00,0x07} }, +{ 14, 0x0f9d, 0, {0x24,0x01,0x02,0x01,0x01,0x00,0x0b,0x24,0x02,0x01,0x02,0x02,0x10,0x01} }, +{ 14, 0x0fab, 0, {0x80,0xbb,0x00,0x09,0x05,0x88,0x05,0x00,0x01,0x01,0x00,0x00,0x07,0x25} }, +{ 14, 0x0fb9, 0, {0x01,0x00,0x00,0x00,0x00,0x09,0x04,0x02,0x00,0x02,0x00,0x00,0x00,0x00} }, +{ 14, 0x0fc7, 0, {0x07,0x05,0x82,0x02,0x40,0x00,0x00,0x07,0x05,0x02,0x02,0x40,0x00,0x00} }, +{ 14, 0x0fd5, 0, {0x09,0x04,0x02,0x01,0x03,0x00,0x00,0x00,0x00,0x07,0x05,0x82,0x02,0x40} }, +{ 14, 0x0fe3, 0, {0x00,0x00,0x07,0x05,0x02,0x02,0x40,0x00,0x00,0x09,0x05,0x89,0x05,0xa0} }, +{ 10, 0x0ff1, 0, {0x01,0x01,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00} }, +{ 14, 0x0ffb, 0, {0x12,0x01,0x00,0x01,0x00,0x00,0x00,0x40,0x47,0x05,0x99,0x99,0x00,0x01} }, +{ 14, 0x1009, 0, {0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x02,0xba} }, +{ 4, 0x1017, 0, {0x00,0x03,0x01,0x00} }, +{ 2, 0x101b, 0, {0x7a,0x00} }, +{ 3, 0x101d, 0, {0xba,0x05,0x00} }, +{ 2, 0x1020, 0, {0x50,0x17} }, +{ 8, 0x1022, 0, {0x90,0x7f,0xa5,0xe0,0xfb,0x30,0xe0,0x05} }, +{ 5, 0x102a, 0, {0x90,0x00,0x01,0x80,0x0d} }, +{ 10, 0x102f, 0, {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xe4} }, +{ 3, 0x1039, 0, {0x90,0x00,0x01} }, +{ 1, 0x103c, 0, {0x22} }, +{ 14, 0x103d, 0, {0x90,0x7d,0xc1,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x7c,0x00,0x7d} }, +{ 4, 0x104b, 0, {0x7e,0xeb,0x60,0x12} }, +{ 14, 0x104f, 0, {0x89,0x82,0x8a,0x83,0xe0,0xa3,0xa9,0x82,0xaa,0x83,0x8c,0x82,0x8d,0x83} }, +{ 4, 0x105d, 0, {0xf0,0x0c,0xdb,0xee} }, +{ 8, 0x1061, 0, {0x90,0x7d,0xc3,0xe0,0x90,0x7f,0xb9,0xf0} }, +{ 1, 0x1069, 0, {0x22} }, +{ 14, 0x106a, 0, {0x90,0x7d,0xc1,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x7c,0xc4,0x7d} }, +{ 4, 0x1078, 0, {0x7d,0xeb,0x60,0xe5} }, +{ 14, 0x107c, 0, {0x8c,0x82,0x8d,0x83,0xe0,0x0c,0x89,0x82,0x8a,0x83,0xf0,0xa3,0xa9,0x82} }, +{ 4, 0x108a, 0, {0xaa,0x83,0xdb,0xee} }, +{ 1, 0x108e, 0, {0x22} }, +{ 14, 0x108f, 0, {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x05,0x86,0x90,0x7d,0xc1,0xe0,0x05,0x86} }, +{ 14, 0x109d, 0, {0xa3,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa6,0x05,0x86,0xa3,0xa3,0xe0,0xf9} }, +{ 5, 0x10ab, 0, {0x60,0x16,0xa3,0x05,0x86} }, +{ 13, 0x10b0, 0, {0x90,0x7f,0xa6,0x05,0x86,0xe0,0xa3,0x05,0x86,0xf0,0xc0,0x01,0x12} }, +{ 6, 0x10bd, 0, {0x10,0x1b,0xd0,0x01,0xd9,0xed} }, +{ 6, 0x10c3, 0, {0x90,0x7f,0xa5,0x74,0x40,0xf0} }, +{ 1, 0x10c9, 0, {0x22} }, +{ 8, 0x10ca, 0, {0x90,0x88,0x02,0x74,0x01,0xf0,0x7a,0x00} }, +{ 3, 0x10d2, 0, {0xba,0xff,0x00} }, +{ 2, 0x10d5, 0, {0x50,0x0a} }, +{ 10, 0x10d7, 0, {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xf1} }, +{ 1, 0x10e1, 0, {0x22} }, +{ 5, 0x10e2, 0, {0xe5,0x6b,0xb4,0xc0,0x08} }, +{ 8, 0x10e7, 0, {0x90,0x88,0x03,0xe5,0x6c,0xf0,0x80,0x06} }, +{ 6, 0x10ef, 0, {0x90,0x88,0x02,0xe5,0x6c,0xf0} }, +{ 4, 0x10f5, 0, {0x7a,0x00,0x7b,0x00} }, +{ 11, 0x10f9, 0, {0xc3,0xea,0x94,0x32,0xeb,0x64,0x80,0x94,0x80,0x50,0x07} }, +{ 5, 0x1104, 0, {0x0a,0xba,0x00,0x01,0x0b} }, +{ 2, 0x1109, 0, {0x80,0xee} }, +{ 1, 0x110b, 0, {0x22} }, +{ 10, 0x110c, 0, {0x90,0x88,0x03,0xe5,0x6d,0xf0,0x05,0x39,0x7a,0x00} }, +{ 3, 0x1116, 0, {0xba,0x28,0x00} }, +{ 2, 0x1119, 0, {0x50,0x03} }, +{ 3, 0x111b, 0, {0x0a,0x80,0xf8} }, +{ 5, 0x111e, 0, {0xe5,0x39,0xb4,0x10,0x08} }, +{ 8, 0x1123, 0, {0x90,0x88,0x02,0x74,0xc0,0xf0,0x80,0x0e} }, +{ 5, 0x112b, 0, {0xe5,0x39,0xb4,0x20,0x09} }, +{ 9, 0x1130, 0, {0x90,0x88,0x02,0x74,0x80,0xf0,0x75,0x39,0x00} }, +{ 2, 0x1139, 0, {0x7a,0x00} }, +{ 3, 0x113b, 0, {0xba,0x28,0x00} }, +{ 2, 0x113e, 0, {0x50,0x03} }, +{ 3, 0x1140, 0, {0x0a,0x80,0xf8} }, +{ 1, 0x1143, 0, {0x22} }, +{ 4, 0x1144, 0, {0xe5,0x6f,0x60,0x02} }, +{ 2, 0x1148, 0, {0x80,0x07} }, +{ 7, 0x114a, 0, {0x7a,0x00,0x75,0x39,0x00,0x80,0x05} }, +{ 5, 0x1151, 0, {0x7a,0x40,0x75,0x39,0x10} }, +{ 9, 0x1156, 0, {0xe5,0x6e,0x2a,0xfa,0xe5,0x6e,0x25,0x39,0xf5} }, +{ 10, 0x115f, 0, {0x39,0x90,0x88,0x02,0x74,0x80,0x2a,0xf0,0x7a,0x00} }, +{ 8, 0x1169, 0, {0xc3,0xea,0x64,0x80,0x94,0xa8,0x50,0x03} }, +{ 3, 0x1171, 0, {0x0a,0x80,0xf5} }, +{ 1, 0x1174, 0, {0x22} }, +{ 6, 0x1175, 0, {0xaa,0x70,0xab,0x71,0xac,0x72} }, +{ 12, 0x117b, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x12,0x14,0xee,0xfd,0x60,0x18} }, +{ 13, 0x1187, 0, {0x8d,0x6d,0xc0,0x02,0xc0,0x03,0xc0,0x04,0x12,0x11,0x0c,0xd0,0x04} }, +{ 9, 0x1194, 0, {0xd0,0x03,0xd0,0x02,0x0a,0xba,0x00,0x01,0x0b} }, +{ 2, 0x119d, 0, {0x80,0xdc} }, +{ 1, 0x119f, 0, {0x22} }, +{ 13, 0x11a0, 0, {0xe5,0x73,0xc4,0x54,0x0f,0xfa,0x53,0x02,0x0f,0xc3,0x74,0x09,0x9a} }, +{ 2, 0x11ad, 0, {0x50,0x06} }, +{ 6, 0x11af, 0, {0x74,0x37,0x2a,0xfb,0x80,0x04} }, +{ 4, 0x11b5, 0, {0x74,0x30,0x2a,0xfb} }, +{ 12, 0x11b9, 0, {0x8b,0x6d,0xc0,0x03,0x12,0x11,0x0c,0xd0,0x03,0xaa,0x73,0x53} }, +{ 8, 0x11c5, 0, {0x02,0x0f,0xc3,0x74,0x09,0x9a,0x50,0x06} }, +{ 6, 0x11cd, 0, {0x74,0x37,0x2a,0xfb,0x80,0x04} }, +{ 4, 0x11d3, 0, {0x74,0x30,0x2a,0xfb} }, +{ 5, 0x11d7, 0, {0x8b,0x6d,0x12,0x11,0x0c} }, +{ 1, 0x11dc, 0, {0x22} }, +{ 7, 0x11dd, 0, {0x90,0x7d,0xc3,0xe0,0xfa,0x60,0x0f} }, +{ 12, 0x11e4, 0, {0x90,0x7d,0xc1,0xe0,0xf5,0x6e,0x90,0x7d,0xc2,0xe0,0xf5,0x6f} }, +{ 3, 0x11f0, 0, {0x12,0x11,0x44} }, +{ 12, 0x11f3, 0, {0x90,0x7d,0xff,0xe4,0xf0,0x75,0x70,0xc4,0x75,0x71,0x7d,0x75} }, +{ 5, 0x11ff, 0, {0x72,0x01,0x12,0x11,0x75} }, +{ 1, 0x1204, 0, {0x22} }, +{ 2, 0x1205, 0, {0x7a,0x04} }, +{ 3, 0x1207, 0, {0xba,0x40,0x00} }, +{ 2, 0x120a, 0, {0x50,0x36} }, +{ 14, 0x120c, 0, {0xea,0x24,0xc0,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe0,0xfb,0x7c,0x00} }, +{ 3, 0x121a, 0, {0xbc,0x08,0x00} }, +{ 2, 0x121d, 0, {0x50,0x20} }, +{ 6, 0x121f, 0, {0x8b,0x05,0xed,0x30,0xe7,0x0b} }, +{ 11, 0x1225, 0, {0x90,0x7f,0x96,0x74,0x42,0xf0,0x74,0xc3,0xf0,0x80,0x08} }, +{ 8, 0x1230, 0, {0x90,0x7f,0x96,0xe4,0xf0,0x74,0x81,0xf0} }, +{ 7, 0x1238, 0, {0xeb,0x25,0xe0,0xfb,0x0c,0x80,0xdb} }, +{ 3, 0x123f, 0, {0x0a,0x80,0xc5} }, +{ 1, 0x1242, 0, {0x22} }, +{ 4, 0x1243, 0, {0x7a,0x00,0x7b,0xef} }, +{ 3, 0x1247, 0, {0xba,0x10,0x00} }, +{ 2, 0x124a, 0, {0x50,0x20} }, +{ 14, 0x124c, 0, {0x74,0x11,0x2b,0xfb,0x24,0x00,0xfc,0xe4,0x34,0x18,0xfd,0x8c,0x82,0x8d} }, +{ 14, 0x125a, 0, {0x83,0xe4,0xf0,0xea,0x24,0x00,0xf5,0x82,0xe4,0x34,0x19,0xf5,0x83,0xe4} }, +{ 4, 0x1268, 0, {0xf0,0x0a,0x80,0xdb} }, +{ 1, 0x126c, 0, {0x22} }, +{ 14, 0x126d, 0, {0x74,0xf8,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} }, +{ 14, 0x127b, 0, {0x74,0xf9,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} }, +{ 14, 0x1289, 0, {0x74,0xfa,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} }, +{ 14, 0x1297, 0, {0x74,0xfb,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} }, +{ 14, 0x12a5, 0, {0x74,0xff,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} }, +{ 1, 0x12b3, 0, {0x22} }, +{ 14, 0x12b4, 0, {0x12,0x03,0xcb,0x12,0x12,0x6d,0x7a,0xc0,0x7b,0x87,0x7c,0x01,0x74,0x01} }, +{ 14, 0x12c2, 0, {0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x74} }, +{ 14, 0x12d0, 0, {0x01,0x12,0x14,0xbf,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e} }, +{ 14, 0x12de, 0, {0x83,0x8f,0xf0,0x74,0x06,0x12,0x14,0xbf,0x74,0x01,0x2a,0xfd,0xe4,0x3b} }, +{ 14, 0x12ec, 0, {0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83,0x8c,0xf0,0xe4,0x12,0x14,0xbf,0x74} }, +{ 14, 0x12fa, 0, {0x01,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0} }, +{ 14, 0x1308, 0, {0x74,0x0b,0x12,0x14,0xbf,0x74,0x01,0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07} }, +{ 14, 0x1316, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x74,0x08,0x12,0x14,0xbf,0x74,0x01,0x2d} }, +{ 14, 0x1324, 0, {0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0,0x74,0x01} }, +{ 14, 0x1332, 0, {0x12,0x14,0xbf,0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83} }, +{ 14, 0x1340, 0, {0x8c,0xf0,0xe4,0x12,0x14,0xbf,0x74,0x01,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f} }, +{ 14, 0x134e, 0, {0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0,0x74,0x03,0x12,0x14,0xbf,0x7d,0x00} }, +{ 3, 0x135c, 0, {0xbd,0x06,0x00} }, +{ 2, 0x135f, 0, {0x50,0x12} }, +{ 11, 0x1361, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x0a,0xba,0x00,0x01,0x0b} }, +{ 7, 0x136c, 0, {0xe4,0x12,0x14,0xbf,0x0d,0x80,0xe9} }, +{ 13, 0x1373, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0xe5,0x74,0x12,0x14,0xbf,0x74,0xf9} }, +{ 14, 0x1380, 0, {0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0x74,0x0f,0xf0,0x74} }, +{ 14, 0x138e, 0, {0xfe,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0x74,0x01,0xf0} }, +{ 6, 0x139c, 0, {0x12,0x03,0xe1,0x12,0x04,0xf7} }, +{ 1, 0x13a2, 0, {0x22} }, +{ 13, 0x13a3, 0, {0x90,0x7d,0xc1,0xe0,0xfa,0x24,0x00,0xfb,0xe4,0x34,0x19,0xfc,0x90} }, +{ 14, 0x13b0, 0, {0x7d,0xc2,0xe0,0xfd,0x8b,0x82,0x8c,0x83,0xf0,0x75,0xf0,0x11,0xea,0xa4} }, +{ 3, 0x13be, 0, {0xfa,0x7b,0x00} }, +{ 3, 0x13c1, 0, {0xbb,0x10,0x00} }, +{ 2, 0x13c4, 0, {0x50,0x24} }, +{ 14, 0x13c6, 0, {0xea,0x24,0x00,0xfc,0xe4,0x34,0x18,0xfd,0xeb,0x2c,0xfc,0xe4,0x3d,0xfd} }, +{ 14, 0x13d4, 0, {0x74,0x04,0x2b,0x24,0xc0,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe0,0xfe} }, +{ 8, 0x13e2, 0, {0x8c,0x82,0x8d,0x83,0xf0,0x0b,0x80,0xd7} }, +{ 14, 0x13ea, 0, {0xea,0x24,0x00,0xfa,0xe4,0x34,0x18,0xfb,0x74,0x10,0x2a,0xf5,0x82,0xe4} }, +{ 5, 0x13f8, 0, {0x3b,0xf5,0x83,0xe4,0xf0} }, +{ 1, 0x13fd, 0, {0x22} }, +{ 4, 0x13fe, 0, {0xe5,0x76,0x60,0x02} }, +{ 2, 0x1402, 0, {0x80,0x16} }, +{ 12, 0x1404, 0, {0x74,0x0f,0x55,0x75,0xfa,0x8a,0x75,0x24,0x00,0xf5,0x82,0xe4} }, +{ 10, 0x1410, 0, {0x34,0x19,0xf5,0x83,0xe0,0xf5,0x74,0x12,0x12,0xb4} }, +{ 10, 0x141a, 0, {0x12,0x10,0xca,0x75,0x6e,0x00,0x75,0x6f,0x00,0x12} }, +{ 6, 0x1424, 0, {0x11,0x44,0x75,0x70,0xb9,0x75} }, +{ 6, 0x142a, 0, {0x71,0x14,0x75,0x72,0x02,0x12} }, +{ 11, 0x1430, 0, {0x11,0x75,0xe5,0x76,0xb4,0x02,0x04,0x74,0x01,0x80,0x01} }, +{ 1, 0x143b, 0, {0xe4} }, +{ 3, 0x143c, 0, {0xfa,0x70,0x0f} }, +{ 12, 0x143f, 0, {0x74,0x01,0x25,0x75,0xf5,0x73,0xc0,0x02,0x12,0x11,0xa0,0xd0} }, +{ 3, 0x144b, 0, {0x02,0x80,0x0a} }, +{ 10, 0x144e, 0, {0x85,0x75,0x73,0xc0,0x02,0x12,0x11,0xa0,0xd0,0x02} }, +{ 12, 0x1458, 0, {0x75,0x6e,0x00,0x75,0x6f,0x01,0xc0,0x02,0x12,0x11,0x44,0xd0} }, +{ 4, 0x1464, 0, {0x02,0xea,0x70,0x1a} }, +{ 13, 0x1468, 0, {0x75,0xf0,0x11,0xe5,0x75,0xa4,0xfa,0x24,0x00,0xfa,0xe4,0x34,0x18} }, +{ 9, 0x1475, 0, {0xfb,0x8a,0x70,0x8b,0x71,0x75,0x72,0x01,0x12} }, +{ 4, 0x147e, 0, {0x11,0x75,0x80,0x36} }, +{ 2, 0x1482, 0, {0x7a,0x00} }, +{ 3, 0x1484, 0, {0xba,0x10,0x00} }, +{ 2, 0x1487, 0, {0x50,0x2f} }, +{ 13, 0x1489, 0, {0xea,0x24,0x00,0xf5,0x82,0xe4,0x34,0x19,0xf5,0x83,0xe0,0xfb,0xe5} }, +{ 4, 0x1496, 0, {0x75,0xb5,0x03,0x1b} }, +{ 14, 0x149a, 0, {0x75,0xf0,0x11,0xea,0xa4,0xfb,0x24,0x00,0xfb,0xe4,0x34,0x18,0xfc,0x8b} }, +{ 9, 0x14a8, 0, {0x70,0x8c,0x71,0x75,0x72,0x01,0xc0,0x02,0x12} }, +{ 4, 0x14b1, 0, {0x11,0x75,0xd0,0x02} }, +{ 3, 0x14b5, 0, {0x0a,0x80,0xcc} }, +{ 1, 0x14b8, 0, {0x22} }, +{ 6, 0x14b9, 0, {0x50,0x72,0x6f,0x67,0x20,0x00} }, +{ 14, 0x14bf, 0, {0xc8,0xc0,0xe0,0xc8,0xc0,0xe0,0xe5,0xf0,0x60,0x0b,0x14,0x60,0x0f,0x14} }, +{ 7, 0x14cd, 0, {0x60,0x11,0x14,0x60,0x12,0x80,0x15} }, +{ 7, 0x14d4, 0, {0xd0,0xe0,0xa8,0x82,0xf6,0x80,0x0e} }, +{ 5, 0x14db, 0, {0xd0,0xe0,0xf0,0x80,0x09} }, +{ 4, 0x14e0, 0, {0xd0,0xe0,0x80,0x05} }, +{ 5, 0x14e4, 0, {0xd0,0xe0,0xa8,0x82,0xf2} }, +{ 4, 0x14e9, 0, {0xc8,0xd0,0xe0,0xc8} }, +{ 1, 0x14ed, 0, {0x22} }, +{ 14, 0x14ee, 0, {0xc8,0xc0,0xe0,0xe5,0xf0,0x60,0x0d,0x14,0x60,0x0f,0x14,0x60,0x0f,0x14} }, +{ 6, 0x14fc, 0, {0x60,0x10,0x74,0xff,0x80,0x0f} }, +{ 5, 0x1502, 0, {0xa8,0x82,0xe6,0x80,0x0a} }, +{ 3, 0x1507, 0, {0xe0,0x80,0x07} }, +{ 4, 0x150a, 0, {0xe4,0x93,0x80,0x03} }, +{ 3, 0x150e, 0, {0xa8,0x82,0xe2} }, +{ 4, 0x1511, 0, {0xf8,0xd0,0xe0,0xc8} }, +{ 1, 0x1515, 0, {0x22} }, +{ 0, 0x0000, 1, {0} } + +}; + +static unsigned char bitstream[] = { + +0x00,0x09,0x0F,0xF0,0x0F,0xF0,0x0F,0xF0, 0x0F,0xF0,0x00,0x00,0x01,0x61,0x00,0x0D, +0x64,0x61,0x62,0x75,0x73,0x62,0x74,0x72, 0x2E,0x6E,0x63,0x64,0x00,0x62,0x00,0x0B, +0x73,0x31,0x30,0x78,0x6C,0x76,0x71,0x31, 0x30,0x30,0x00,0x63,0x00,0x0B,0x31,0x39, +0x39,0x39,0x2F,0x30,0x39,0x2F,0x32,0x34, 0x00,0x64,0x00,0x09,0x31,0x30,0x3A,0x34, +0x32,0x3A,0x34,0x36,0x00,0x65,0x00,0x00, 0x2E,0xC0,0xFF,0x20,0x17,0x5F,0x9F,0x5B, +0xFE,0xFB,0xBB,0xB7,0xBB,0xBB,0xFB,0xBF, 0xAF,0xEF,0xFB,0xDF,0xB7,0xFB,0xFB,0x7F, +0xBF,0xB7,0xEF,0xF2,0xFF,0xFB,0xFE,0xFF, 0xFF,0xEF,0xFF,0xFE,0xFF,0xBF,0xFF,0xFF, +0xFF,0xFF,0xAF,0xFF,0xFA,0xFF,0xFF,0xFF, 0xC9,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFB,0xFF,0xA3,0xFF,0xFB, +0xFE,0xFF,0xBF,0xEF,0xE3,0xFE,0xFF,0xBF, 0xE3,0xFE,0xFF,0xBF,0x6F,0xFB,0xF6,0xFF, +0xBF,0xFF,0x47,0xFF,0xFF,0x9F,0xEE,0xF9, 0xFE,0xCF,0x9F,0xEF,0xFB,0xCF,0x9B,0xEE, +0xF8,0xFE,0xEF,0x8F,0xEE,0xFB,0xFE,0x0B, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xBF,0xFF,0xFF,0xFB,0xFF,0xFF, 0xBF,0xFF,0xFF,0xFC,0x17,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xFB,0xFF,0xFF,0x7F,0xFF,0xFF, +0xFC,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x5F,0xFF, 0xFF,0xFD,0xFF,0xFF,0xDB,0xFF,0xFD,0xFF, +0x77,0xFF,0xFD,0xFF,0xFF,0xDF,0xFE,0xFD, 0xFF,0xFF,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFD,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1, +0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xE3,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF, +0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x67,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0x7F,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF, 0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0x2F,0xFF, +0xF3,0xFD,0xFF,0x7F,0xDE,0xF7,0xFD,0xFF, 0x7F,0xF7,0x7D,0xFF,0x7F,0xDF,0xF7,0xBD, +0xFF,0x7F,0xFF,0x1F,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xEF,0xFB, +0xFE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFF, 0x3F,0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F, +0x9F,0xE7,0xFA,0x7F,0x9F,0xE7,0xF9,0xFE, 0x7F,0x9F,0xE7,0xFF,0xFC,0x7F,0xBF,0xBF, +0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xB7, 0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, +0xFF,0xE0,0xFD,0xF9,0xFE,0x7F,0x9F,0xE7, 0xF9,0xFE,0x7F,0x9D,0xF9,0xFE,0x7D,0x9D, +0xE7,0xF9,0xFE,0x7F,0x9F,0xED,0xED,0xFF, 0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F, +0xDF,0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF, 0x7F,0xDF,0xFF,0x9B,0xFF,0xEF,0xFB,0xFE, +0xFB,0xBF,0xEF,0xBB,0xFE,0xFF,0xAF,0xBB, 0xBE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFF, +0xB7,0xBF,0xDB,0xF6,0xBD,0xBF,0x6B,0xDB, 0xF6,0xF9,0xBF,0x5B,0xD6,0xF9,0xBF,0x6F, +0xDB,0xF6,0xFD,0xBF,0xFF,0x0E,0xFF,0xFF, 0xFF,0xFF,0x5F,0xFF,0xF7,0xFF,0xFF,0x7F, +0xF7,0xBD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xDF,0x9F,0xFF,0xFF,0xFF,0xFE,0xFF, +0xFF,0xEF,0xFE,0xFE,0xFF,0xFF,0x77,0xFF, 0xFB,0xFB,0xFF,0xFF,0xFF,0xFF,0xF8,0x3F, +0xFF,0xFD,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xF4,0x7F,0xFF,0xFE,0xFD, 0xBE,0xFF,0xDF,0xFE,0xFF,0xFF,0xEF,0x7F, +0xFF,0xCF,0xFF,0xCF,0xFF,0xFF,0xFF,0xDF, 0xE6,0xFF,0xFF,0x7F,0xDF,0xF7,0xDD,0x7F, +0x7F,0xDF,0xF7,0xFF,0x7F,0xDF,0xD7,0xFD, 0xFF,0x7F,0xDF,0xF7,0xFF,0xCD,0xFF,0xF2, +0xFF,0xFF,0x4F,0x7F,0xF4,0xFF,0xFF,0xFF, 0xE7,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xBB,0xFF,0xEF,0xFF,0xFE,0xFF, 0xFF,0xFF,0xEF,0xFF,0xFF,0xEF,0xFF,0xFB, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x65, 0xEF,0xFF,0xFF,0x7F,0xFF,0xFD,0xEF,0xFF, +0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xCF,0xDF,0xFE,0xFF, +0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xF3,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFE,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBF,0xFF, 0xFF,0xFF,0xE3,0x7F,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xEF,0xEB,0xFF,0xFE,0xBF,0xFF, 0xEB,0xFF,0xFC,0x7F,0xFF,0xFF,0xFF,0xEE, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF, 0xD6,0xFF,0xFD,0xBF,0xFF,0xFB,0xFF,0xFE, +0xFD,0xFF,0xFF,0xFD,0xEF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xDE,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xBF,0xFF,0xFD,0xFF,0x7F,0xBF, 0xFF,0x5F,0xDF,0xFF,0xFF,0xBF,0x77,0xFF, +0xFF,0xFF,0x7F,0xD7,0xFF,0xFF,0xFF,0xFF, 0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xDF,0xEF, +0xFF,0xFF,0xFE,0xFB,0xFF,0xFF,0xDF,0xBF, 0xFF,0xFF,0xFF,0xFF,0xED,0xFF,0xB7,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xAF,0x7F,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xDF,0xBF,0xDF,0xF3,0xFD,0xFB,0xFF,0x5B, +0xFD,0xFF,0xBF,0xEF,0xF7,0xFF,0xFF,0x7D, 0xFF,0xFF,0xFF,0xFF,0xF8,0x3B,0xFF,0xBF, +0x6F,0xFF,0xFE,0xFF,0xBF,0xFF,0xEB,0x7D, 0xFF,0xEF,0xFB,0xFE,0xFF,0xFF,0xFF,0xFF, +0xFF,0xF2,0x7F,0xFC,0xFF,0x3F,0xDF,0xED, 0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0x5F,0xF7, +0xB5,0xFF,0xEF,0xFF,0xFF,0xFF,0xE0,0x3F, 0x9F,0x9E,0xFF,0xFF,0xEF,0xFF,0xDF,0xFF, +0xBF,0x5F,0xBF,0xCF,0xF3,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0x69,0xAF,0x33,0xFD,0xFF, +0xFB,0xFF,0xFF,0xFF,0xFF,0xFC,0xFF,0x7F, 0xD9,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xF5, +0xA3,0xDF,0x6E,0xDE,0xFF,0xFF,0xBD,0xFF, 0xFF,0xFE,0xFF,0xFF,0xFF,0xFE,0xE7,0xFD, +0xFF,0xFF,0xFF,0xF9,0xEF,0xC6,0xFE,0xB7, 0xAD,0xE5,0xF9,0xFF,0xFF,0xFF,0xCF,0xFF, +0xFF,0xFF,0xCD,0xFB,0x7F,0xFF,0xFF,0xFF, 0xF9,0xF6,0x0F,0xDF,0xEC,0xCF,0x7F,0xFF, +0xFB,0x7F,0xFF,0xFF,0xFF,0xFD,0xFF,0xFE, 0xF9,0xFD,0x7F,0xFF,0x7F,0xFF,0xF9,0x5B, +0xFF,0x73,0xDC,0xFD,0x7B,0xDF,0xFF,0xFF, 0xFF,0x7B,0xFF,0xFF,0xF7,0x53,0xD6,0xFF, +0xFF,0xFF,0xFF,0xD8,0x9F,0xFE,0xFF,0xEF, 0x7F,0xEE,0xFF,0xFF,0xFF,0xFB,0xED,0xED, +0xFD,0xFF,0xFE,0xFF,0xFF,0xFB,0x7F,0xFF, 0xE2,0x7F,0xFF,0x6F,0xD8,0x57,0xF7,0xFF, +0xFF,0xFF,0xDF,0xFF,0xE8,0xFF,0xFF,0xFD, 0xFF,0xFF,0xFC,0x7F,0xFF,0xE4,0xFF,0xFB, +0xEF,0xFB,0xFE,0xDF,0xB7,0xED,0xFF,0xFE, 0xDF,0x7F,0xFF,0xFE,0x7F,0xB7,0xFF,0xFF, +0xFF,0xFF,0x89,0xFF,0xFF,0xCF,0xF3,0xFE, 0x7F,0xFF,0xEF,0xFF,0xFE,0x7E,0x7F,0xFB, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF1, 0xFF,0xEB,0x7A,0xD5,0xBF,0x6F,0xDB,0xBE, +0xFD,0xB7,0xD8,0xF6,0xE5,0xBF,0x6F,0xFB, 0xFE,0xF5,0xBD,0x7E,0x06,0xFF,0xDF,0xF7, +0xFB,0xF6,0xFF,0x3F,0xFF,0xDB,0xFF,0xFF, 0x6F,0xFB,0xF7,0xFF,0xFF,0xFF,0xFB,0xFE, +0xF7,0xAF,0xFF,0xB7,0xED,0xEF,0xF7,0xFE, 0xFF,0xFF,0xDF,0xFF,0xFE,0xFF,0xEF,0xFF, +0xFF,0xFF,0xFF,0xBF,0xF7,0xFC,0x1F,0xEE, 0xFB,0xFE,0xBD,0xFF,0x7F,0x5F,0xD7,0xFD, +0xFB,0x43,0xFF,0xFF,0xFD,0xFF,0x5F,0xFF, 0xF7,0xFF,0xF9,0x3F,0xFF,0xCF,0xF3,0xFD, +0xF7,0x7E,0xEF,0xA7,0xF9,0xFE,0x8F,0xA7, 0xE9,0xF3,0x7E,0x9F,0xFB,0xF8,0xFF,0xFF, +0x3F,0xFD,0x7F,0x5F,0xDF,0xFD,0xFF,0xFF, 0x5F,0xFF,0xFD,0x5F,0xFF,0xFF,0x7F,0xFD, +0x7F,0xFD,0x9F,0xFF,0xE0,0xFF,0xFA,0xF8, 0xBE,0x6F,0x9F,0xE6,0xF8,0xBE,0x3F,0x9A, +0xF9,0xBE,0x6F,0x9F,0xE2,0xF9,0xFE,0x6F, 0x9F,0xF9,0xFF,0xF5,0xFD,0x7F,0xCF,0xDF, +0xFD,0xFD,0x7F,0xFF,0xF5,0xFF,0xFF,0xFF, 0xF7,0xF5,0xFD,0x0F,0xDB,0xFF,0xD3,0xFF, +0xEB,0xFA,0xFF,0xFF,0xBF,0xFF,0xFA,0xFF, 0xFF,0xCB,0xFB,0xFE,0xFF,0xFF,0xEB,0xFA, +0xFE,0xFF,0xFF,0xB7,0xFF,0xFF,0xFF,0xFF, 0xBF,0xFF,0xDF,0xF5,0xFF,0xFF,0xD7,0xFF, +0xFF,0xFF,0xDF,0xD7,0xF5,0xFF,0x7F,0xFE, 0x4F,0xFF,0xFD,0xFF,0x7F,0x7F,0xFF,0xAD, +0xEB,0xFB,0xFF,0xAD,0xFF,0xFF,0xFF,0xFF, 0xAF,0xEB,0xFB,0xFF,0xFC,0x0D,0xFF,0xFF, +0xDF,0xD2,0xFD,0xFF,0xFF,0xFD,0xF6,0xFF, 0xFF,0x7F,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF, +0xFF,0xFB,0x3F,0x7D,0xEB,0x32,0xFE,0xBF, 0x2F,0xEB,0xFA,0xAE,0xBD,0xE0,0xFA,0x7E, +0xBF,0xAD,0xEB,0xFA,0xFE,0xBF,0xF5,0x7F, 0xFF,0xDE,0xFE,0xE3,0xFB,0xFF,0xFF,0xFF, +0xDF,0xEF,0x4F,0xDF,0xFF,0x7F,0xDF,0xFF, 0xF7,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0xEF, +0xFB,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xDF, 0xED,0xFB,0xDF,0xFF,0xBF,0xFF,0xFF,0xFF, +0x81,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF, 0xFF,0xFF,0xFE,0xDD,0xFE,0xEF,0xFD,0xFF, +0xFF,0xFB,0xFE,0xF7,0xFF,0x93,0xFD,0xFB, 0x7E,0xFF,0xFE,0x87,0xE9,0xFF,0x7F,0xB3, +0x9F,0xFE,0xFE,0xFF,0xAF,0xFD,0xFE,0x7E, 0x3F,0xFE,0x67,0xFF,0xFF,0xF7,0xFF,0xFF, +0xFC,0xF7,0xDF,0xFD,0xFF,0x7F,0xFF,0xFF, 0x7F,0x6D,0xFF,0xFF,0xFE,0xFF,0xFF,0x2F, +0xFF,0xBF,0xFF,0xFF,0xEE,0xFF,0xBE,0xFF, 0xFF,0xFE,0xFF,0xEF,0xFF,0xFF,0xFE,0xFF, +0xEF,0xFF,0xFF,0xFA,0x5F,0xFF,0xFF,0xFB, 0xFF,0xFF,0xEF,0xFF,0xFB,0xFE,0xFD,0xFF, +0xFE,0xFF,0xFB,0xFF,0xFF,0xFF,0x7F,0xFF, 0xFE,0xBF,0xDF,0xFF,0xFB,0xFF,0xFF,0xF7, +0xFC,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF2,0x7F,0xFF, +0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF, 0xF3,0xFF,0xFF,0xFF,0xEF,0xFB,0xFF,0xFF, +0xFF,0xDF,0xE2,0xFF,0xFF,0xFB,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFB,0xE7,0xFF,0xFD, +0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xED, 0xEF,0xFD,0xFF,0xFF,0xDF,0xD7,0xF5,0xFD, +0x7F,0x5D,0xFD,0xFF,0x7F,0xDF,0x97,0xF4, 0xFD,0x7B,0x5F,0xFF,0xC9,0xFF,0xFB,0xFE, +0xFF,0xBF,0xFF,0x5F,0xFF,0xFF,0xF7,0xFF, 0xEF,0xFD,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xF7,0xFF,0xD7,0xFD,0x7D,0x7F,0xFF, 0xFF,0xFF,0xFF,0xEF,0xDF,0xF7,0xFD,0xFF, +0xBB,0xFF,0xFF,0x7F,0xFF,0xFE,0xE3,0xFF, 0xF9,0xFE,0x7F,0xBF,0xEF,0xFB,0xFE,0xFF, +0xBF,0xF9,0xFE,0xFF,0x9F,0xEF,0xF9,0xFE, 0xFF,0xBF,0xF3,0xDA,0xFF,0x37,0xCD,0xF3, +0x7C,0xDF,0x37,0xCD,0xF3,0x7F,0x37,0xCD, 0xF3,0x7C,0xDF,0x37,0xCC,0xF3,0x7F,0x5A, +0xBD,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,0xFD, 0xBF,0x6F,0xDE,0xFD,0xBF,0x6F,0xDB,0xF6, +0xFD,0xBF,0x6F,0xFE,0xF1,0x6F,0xEB,0x7A, 0xDE,0xB7,0xAD,0xEB,0x7A,0xDE,0xB7,0xAF, +0x7A,0xDE,0xB7,0xAD,0xEB,0x7A,0xDE,0xB7, 0xFF,0x7E,0xFF,0xFE,0xCD,0xB3,0x6C,0xDB, +0x36,0xCD,0xB3,0x6C,0xDE,0xCD,0xB3,0x6C, 0xDB,0x36,0xCD,0xB3,0x6C,0xDF,0xC9,0xBF, +0xF7,0xBD,0xEF,0x7A,0x9E,0xA7,0xA9,0xEA, 0x7A,0xB7,0xBD,0xEA,0x7B,0xDE,0xA7,0xBD, +0xCA,0x72,0x8D,0x91,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xEF,0xFB,0xFE,0xF7,0xEF,0xFB, +0xFE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFE, 0x87,0xFF,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6, +0xFD,0xBF,0x6F,0xF6,0xFD,0xBF,0x6F,0xDB, 0xF6,0xFD,0xBF,0x6F,0xFE,0x4F,0xFF,0xBF, +0xEF,0xBB,0xEE,0xFB,0xBE,0xEF,0xBB,0xEF, 0xBE,0xEF,0xBB,0xEE,0xFB,0xBE,0xEF,0xBB, +0xEF,0xFC,0x5F,0xFF,0xFF,0xFF,0x3F,0xCF, 0xF3,0xFC,0xFF,0x3F,0xCF,0xFC,0xFF,0x3F, +0xCF,0xF3,0xFC,0xFF,0x3F,0xCF,0xFD,0x9F, 0xFE,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF, +0xEB,0xFE,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF, 0xAF,0xEB,0xFF,0xE1,0x6F,0xFD,0xFF,0x7F, +0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFD,0xFF, 0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF, +0x7A,0xBF,0xFB,0xFE,0xDF,0xB7,0xED,0xFB, 0x7E,0xDF,0xB7,0xFB,0x7E,0xDF,0xB7,0xED, +0xFB,0x7E,0xDF,0xB7,0xFF,0xC9,0xFF,0xFF, 0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, +0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEE, 0xFB,0xFE,0xBB,0xFF,0xFE,0xFF,0xBF,0xEF, +0xFB,0xFE,0xFF,0xBF,0xEF,0xFE,0xFF,0xBF, 0xEF,0xFB,0xFE,0xFF,0x3F,0xCF,0xFF,0xE7, +0xFE,0xFF,0xF5,0xFD,0x77,0x5D,0xD7,0x35, 0xDD,0x77,0xD7,0xF5,0xCD,0x7B,0x5D,0xD7, +0xF5,0xDD,0x77,0xFE,0x27,0xFF,0xFF,0x8B, 0xE2,0xF8,0xBE,0x2F,0x8B,0xE2,0xF9,0xAF, +0x8B,0xE2,0xF8,0xBE,0x2F,0x8B,0xE2,0xF9, 0xFE,0x1F,0xFF,0x5F,0xD7,0xF5,0xFD,0x7F, +0x5F,0xD7,0xF5,0xFF,0x5F,0xD7,0xF5,0xFD, 0x7F,0x5F,0xD7,0xF5,0xFF,0xFA,0x3F,0xFE, +0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,0xEB, 0xEC,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF, +0xEB,0xFF,0xFE,0x7F,0xFD,0x7F,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6, 0xFF,0xFA,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF, +0xF7,0xFC,0xFF,0xDF,0xF7,0xFD,0xFF,0x7F, 0xDF,0xF7,0xFD,0xFF,0xF5,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0x02,0xFF,0xFE,0xBF,0xAB,0xEB,0xFA, 0xBE,0xBF,0x23,0xEB,0xDE,0x1F,0xAF,0xEA, +0xFA,0xFE,0xAF,0xAF,0xEB,0xFD,0x97,0xFF, 0xF3,0xFC,0x7B,0x1F,0xCF,0xF1,0xFC,0x7F, +0x1F,0xF1,0xFC,0x77,0x1F,0xCD,0xF1,0xFC, 0xFF,0x1F,0xFE,0x87,0xFF,0xAF,0xEF,0xFA, +0xFE,0xFF,0xAF,0xEF,0xFA,0xFD,0xBF,0x2B, 0xFB,0x7E,0xBF,0xBF,0xEB,0xFB,0xFB,0xFB, +0xDF,0xFF,0xFB,0xF7,0xFF,0xFF,0x7F,0xF7, 0xF7,0xFF,0xFD,0xDF,0xFE,0xFC,0xDF,0xFF, +0xDF,0xFF,0xFD,0xFF,0xDA,0xBF,0xFF,0xBB, 0xEF,0xFB,0xF9,0xFF,0xBE,0xEF,0xFB,0xFB, +0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFF,0xF7,0x7F,0xFD,0xD7,0xFF,0xFF,0x7F, +0xFF,0xFF,0xFF,0xFE,0xF7,0xFF,0xFE,0xFF, 0xF7,0xFF,0xFF,0x7F,0xFF,0xFF,0xEC,0xFF, +0xFF,0xFE,0xDF,0xBF,0xFF,0xFB,0xFE,0xFF, 0xBB,0x68,0xAE,0x1F,0xAE,0xFB,0xFB,0xFF, +0xFF,0xBF,0xFF,0xD5,0xFF,0x7F,0xFF,0xFF, 0xF7,0xFE,0xFE,0xFF,0xBF,0xEF,0x9F,0xFD, +0x7F,0xFF,0xCB,0xFF,0xFF,0xDF,0xFF,0xFF, 0xBB,0xF7,0xBF,0xFF,0xFF,0xFF,0xFF,0xDF, +0xFF,0xBF,0xFB,0xFF,0xFF,0xFF,0xDE,0x3F, 0xFF,0xFF,0xFF,0xFF,0xFF,0xA7,0xFF,0xFF, +0xFF,0xFF,0xEF,0xFF,0x7F,0xFB,0xFD,0xFB, 0x7F,0xFF,0xFF,0xFF,0xFF,0xCF,0xF3,0x7C, +0xFF,0x7F,0x8D,0x7F,0xFF,0xFF,0xFF,0xFF, 0xFB,0xFF,0xF7,0xFB,0xFE,0xFD,0xFF,0xFF, +0xFF,0xFF,0xF7,0xFD,0xFF,0x7F,0xFD,0x1F, 0xFD,0xFF,0xFF,0xFF,0xFF,0xBF,0xDF,0xFF, +0xFF,0xFE,0x5C,0xFF,0x6D,0xFF,0x7F,0xAB, 0xE7,0xF1,0xFF,0xFD,0x9F,0xFF,0xFF,0xAD, +0xEB,0x7A,0x3F,0x1F,0xFF,0xFF,0xFE,0xBF, 0xAF,0xF3,0xDE,0xF5,0xFF,0x8F,0xFB,0xDF, +0xE6,0x7F,0xFF,0xDF,0xF3,0xFD,0xFF,0x7E, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xF7,0xF3, +0x7F,0xDF,0xF7,0xEF,0xFF,0xF6,0x3F,0x9F, 0xDF,0xFF,0xFF,0xEE,0xFF,0xFF,0xEF,0xFB, +0xFF,0xFF,0xF9,0xFB,0xFE,0x4F,0xBF,0xEF, 0xBB,0xFF,0x69,0xAF,0xAF,0xFC,0xFF,0x3F, +0xDD,0xFF,0xFC,0xBF,0x8F,0xFF,0xFD,0xF3, 0xBF,0xED,0x9E,0xFC,0xBF,0x6F,0xF5,0xD3, +0xDF,0xFF,0xDB,0xD6,0xF5,0xEF,0xFD,0xFE, 0xFF,0xB9,0xFF,0x1F,0xD2,0xA9,0xAF,0xFF, +0xDB,0xF7,0xBF,0xEF,0x46,0xFF,0xFF,0xAD, 0xEB,0x7A,0xDF,0xEF,0xF7,0xFF,0x7F,0xF7, +0x9F,0xED,0xFF,0x7F,0xFF,0xAD,0xEB,0x7F, 0xF5,0x6F,0xFF,0xFD,0xFB,0xD6,0xF4,0xF7, +0xFB,0xF9,0x7E,0x7F,0xFF,0x5F,0xC2,0xFE, 0xBF,0xFD,0xFB,0x33,0xDF,0xF9,0x5B,0xFF, +0xFF,0xDD,0x67,0x7D,0xCF,0xEF,0xDB,0xEC, 0xFF,0x77,0xDD,0xF7,0xFD,0xFF,0xFF,0xDE, +0xA7,0xBF,0xD4,0x9F,0xFF,0xFF,0xBF,0xEF, 0xFE,0xFF,0xDF,0xEF,0xBB,0xFF,0xFF,0xEF, +0xEB,0xFA,0xFF,0xEF,0xBD,0xFB,0xFF,0xE2, 0x7F,0xFF,0xDF,0xDF,0xF7,0xFD,0xBF,0xBB, +0x73,0xF7,0xFD,0x7F,0xDF,0xDE,0xF7,0xBF, 0xEA,0xDB,0xF6,0xFF,0xD6,0xFF,0xFF,0x66, +0xFF,0xBE,0xFF,0xBF,0x6B,0xD9,0xF6,0xDF, 0xFF,0xFB,0x7E,0x7F,0xB7,0x7E,0xFF,0xFE, +0xFF,0xCD,0xFF,0xFE,0x7F,0xFF,0xFC,0xFD, 0x3F,0xFB,0xFB,0xF7,0xFF,0xFF,0xFB,0xF6, +0x7D,0xFE,0x7F,0xFF,0xFC,0xFF,0xB9,0xFF, 0xF9,0xFA,0xFE,0xBF,0xAF,0x5B,0xD6,0xED, +0xAD,0x7B,0xF6,0xF9,0xBF,0xEF,0xF8,0xFA, 0xFE,0xBF,0xFE,0xE6,0xFF,0xFF,0xF7,0xFD, +0xFF,0x7F,0xBF,0xEF,0xF3,0xFF,0xFF,0x6F, 0xF7,0xFE,0xFF,0xFF,0xF7,0xFD,0xFE,0xF7, +0xEF,0xFF,0xFB,0xEF,0xFB,0x7E,0xDE,0xFE, 0xFF,0xBF,0xFF,0xFE,0xFF,0xFF,0xFB,0xFF, +0xFF,0xEF,0xFB,0x6F,0xFC,0x1F,0xFE,0xE7, 0xFF,0xFF,0xFF,0xEF,0xFF,0xD3,0xB4,0xBB, +0xFF,0xFF,0xFD,0xBF,0x6F,0xE3,0xFE,0xFF, 0xBF,0xFC,0xBF,0xF7,0xCF,0xF7,0xFD,0xFF, +0x2F,0xDF,0xAB,0xEA,0xFF,0xDF,0xE7,0xEA, 0x9A,0xAF,0xEF,0xFB,0xFE,0xFF,0xF5,0x3F, +0xFD,0x7E,0xFF,0xD7,0xF5,0xFB,0xFF,0xFD, 0xF7,0xFF,0x7F,0xFE,0xF7,0xFD,0xFF,0xD7, +0xFF,0xD7,0x7F,0xEE,0x7F,0xFA,0x79,0xFE, 0x2F,0x8B,0xE6,0xF9,0xFE,0x3F,0x9E,0xF9, +0xBE,0x2F,0x0B,0xE7,0xF9,0xFE,0x2F,0x9F, 0xFD,0xFF,0xFE,0x7D,0x7F,0x5F,0xD7,0xFF, +0xFF,0x7F,0xFF,0xFD,0xFF,0x7F,0x5F,0x97, 0xFF,0xFD,0x7F,0x5F,0xFF,0xE3,0xFF,0xFF, +0xFA,0xFE,0xBF,0xAF,0xFB,0xFB,0xFF,0xFF, 0xCF,0xEB,0xFE,0xBF,0xAF,0xFF,0xFA,0xFE, +0xBF,0xFF,0x87,0xFF,0xFF,0xF5,0xFF,0xFF, 0xFF,0xFF,0xFD,0xFF,0x7F,0xFF,0xFF,0xFF, +0xFB,0xFF,0xFF,0xF5,0xFF,0xFF,0xFE,0x0F, 0xFF,0xFD,0xEB,0xFF,0xFF,0xF7,0xFF,0xEF, +0x7B,0xDF,0xFE,0xFF,0xFF,0xDF,0xF7,0xFD, 0xEB,0x7F,0xDF,0xFF,0x5F,0xFF,0xFF,0xFF, +0xFF,0xFD,0xBF,0xFF,0x7E,0xFA,0xBF,0xC7, 0xDB,0xF7,0xBD,0x3F,0xFB,0xFF,0xF6,0xFF, +0xFA,0xAF,0xFF,0xEB,0xFA,0xFE,0x3F,0x2F, 0xEA,0xFA,0x3E,0xAD,0xC9,0xBA,0xF6,0xAD, +0xAF,0xEB,0xFA,0xF6,0xBF,0xFE,0x7F,0xFF, 0xFF,0xFD,0xFF,0xF1,0x7F,0x3F,0xCF,0xF1, +0xEF,0xFF,0x7F,0xFF,0xBC,0xDF,0xDF,0xF7, 0xDD,0xFF,0xE0,0x7F,0xFF,0xFF,0xFE,0xFF, +0xFA,0xEC,0xBB,0x7F,0x5F,0xFF,0xFB,0xEC, 0xFF,0xEF,0xB7,0xFF,0xF7,0xFF,0xFF,0xB5, +0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xEE,0xDF, 0x5F,0xDF,0xDE,0xFF,0xAE,0xE7,0x77,0xFF, +0xFF,0xDF,0xF7,0xFF,0xE3,0xFF,0xFA,0xBB, 0xFE,0xFF,0xAF,0xFD,0xFB,0xFE,0xBF,0xAB, +0xF9,0xFE,0xFF,0xBF,0x7F,0xBF,0xFE,0xBD, 0xFE,0xD7,0xFF,0x9F,0xFD,0xFF,0xBE,0xEF, +0xFF,0xEE,0xFD,0xBB,0x5B,0xEF,0xFF,0x7F, 0xEF,0xFF,0xEF,0xFF,0x7F,0xFF,0x4F,0xFF, +0xEF,0xFB,0xBC,0xFC,0xFF,0xFF,0xFF,0xFE, 0xFE,0xFD,0xFA,0xFE,0xFB,0xFF,0xFD,0xF3, +0xFB,0xFF,0xF8,0x5F,0xFF,0xFF,0xD7,0xF5, 0xFD,0xDF,0xEF,0xFF,0xF3,0xDC,0x5F,0xCE, +0xF5,0xBD,0xFF,0xFF,0xD7,0xFF,0xFF,0xF9, 0x3F,0xFF,0xDF,0xF7,0xFF,0xFE,0xFF,0xFD, +0xFF,0xFB,0xFF,0xF7,0xB9,0x7D,0xFE,0xDF, 0xFF,0xFF,0xFF,0xFF,0xF9,0x7F,0xFF,0xFE, +0xFF,0xFF,0x7F,0xFF,0xFE,0xFF,0xFF,0xF7, 0xF6,0xFF,0xBF,0xF1,0xF8,0xFF,0xFF,0xFF, +0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF, 0xFF,0xFF,0xFF,0xFF,0xEF,0xEF,0xFF,0xFF, +0x9B,0xFB,0x7F,0xFF,0xFF,0xFF,0xC1,0xFF, 0xDF,0xFF,0x3F,0x5F,0xD7,0xBF,0xEF,0xBB, +0xDE,0xEE,0xFF,0x7F,0xDF,0xFF,0xFE,0xF5, 0x7F,0xDF,0xFF,0x99,0xFF,0xFF,0xFA,0xFF, +0xBF,0xFD,0xEB,0x7A,0xFF,0xB7,0xFE,0xFE, 0xFF,0xFF,0xEF,0xFF,0xFF,0xFD,0xBF,0xFF, +0x97,0xFF,0xFD,0xF7,0xFF,0x7F,0xF7,0xFF, 0xFF,0xFD,0x5F,0xFE,0xF3,0xF9,0xDF,0xDF, +0xFF,0xFF,0xFC,0xFF,0xFF,0x83,0xFF,0xFF, 0xFE,0xFF,0x9E,0xEC,0xFB,0xEE,0xFF,0x9F, +0xBF,0xEF,0xFF,0xFE,0xED,0x7B,0xFF,0xFF, 0xFF,0xF1,0x5A,0xFF,0xFF,0xFD,0xFF,0x7C, +0x69,0x3B,0xDF,0xFF,0x7F,0x1F,0xDF,0xFF, 0xFD,0xBA,0xFF,0xFF,0xFB,0xFF,0x5B,0xBD, +0xFF,0xFF,0xFF,0xFF,0xD7,0xB6,0xED,0xE9, 0xFF,0xD6,0xBD,0x6F,0x5F,0xFB,0xFF,0xEF, +0xFF,0x5F,0xFE,0xF6,0x6F,0xFF,0xFF,0xFF, 0xFF,0xF7,0xEB,0x7A,0xDF,0xFF,0x9F,0x7F, +0x7F,0xFF,0xB7,0xFF,0xFF,0xFE,0xDF,0xFF, 0x6C,0xFF,0xFB,0xFF,0xBB,0x6F,0xEB,0xFE, +0xCC,0xF7,0xA5,0xFA,0x5C,0xF5,0x75,0xBB, 0xB7,0xDF,0xFE,0x6F,0x5F,0xC5,0xBF,0xFD, +0x7B,0xFE,0xFF,0x95,0xE7,0x29,0xCF,0x4F, 0xF5,0x91,0xEE,0x6B,0xDF,0xEF,0xFD,0x54, +0xF5,0xBD,0xB1,0xFF,0xEF,0xEE,0xFB,0xBE, 0xBF,0xAF,0xFE,0xDE,0xBD,0x6F,0xDA,0xF2, +0xFF,0xAF,0xBE,0xFF,0xFF,0xFD,0x7E,0xA7, 0xFF,0xF7,0xFF,0xBF,0xEF,0x7B,0xF6,0xFD, +0xBD,0x4A,0xF2,0x85,0x85,0xBF,0x5B,0xFE, 0xB5,0xFD,0xFA,0xFF,0x4F,0xFF,0xFE,0xDF, +0xFF,0xED,0xFF,0xBF,0xFF,0xBF,0x7F,0xFE, 0xFF,0xB7,0x6D,0xFF,0xF7,0xBF,0xBF,0xEF, +0xFD,0x1F,0xFF,0xFE,0x7D,0xFF,0x67,0xFF, 0xFF,0xFF,0x3F,0x7F,0xFE,0xBF,0xFF,0xE7, +0xDF,0xE7,0xFF,0xEF,0x6B,0xFC,0x1F,0xFF, 0xBF,0xEF,0xFB,0xFE,0xDE,0xBF,0xAF,0xFA, +0xFF,0xB6,0xEF,0xF9,0xFE,0xFF,0x8F,0xEF, 0xDB,0xEF,0xAB,0x6F,0xFB,0xFE,0xFF,0xFF, +0xEF,0xFD,0xFF,0x7F,0xFF,0xFF,0xDE,0xFF, 0xFF,0xEF,0xFF,0xFF,0xFF,0x3F,0xFF,0x6C, +0xFF,0xBF,0xFB,0xFF,0xFE,0xFF,0xFB,0xFE, 0xDF,0xFF,0xFF,0xEF,0xFF,0xFF,0xBF,0xFF, +0xFF,0xFE,0xFB,0xFF,0xD5,0x7F,0xFF,0xFF, 0xEF,0xFB,0xFF,0xFF,0xBF,0xEF,0x43,0xB5, +0xFD,0x6F,0xCF,0xD6,0xBE,0x3F,0x7F,0xDB, 0xFE,0xC3,0xFF,0xFD,0xFF,0xAF,0xEB,0xFB, +0xFC,0xFF,0x3E,0xEF,0xE8,0xFA,0xBD,0xCD, 0xAA,0xFE,0xFE,0x7D,0xCF,0xFF,0xB7,0xFF, +0xF7,0xFF,0xFF,0xFF,0xFD,0xFF,0x75,0xCD, 0x52,0xD7,0xFD,0xFB,0xF7,0xDD,0xFB,0xEF, +0xEB,0xFF,0xFF,0x4F,0xFF,0xBF,0x9F,0xE7, 0xF9,0xFC,0x7F,0x8B,0xC3,0xF9,0xAF,0x8F, +0xE7,0xE9,0xBE,0x7F,0x9F,0xE6,0xF9,0xFC, 0x5F,0xFF,0xFF,0xF7,0xFD,0xFF,0x7A,0x5F, +0xD7,0xED,0xFF,0xFF,0xD7,0xFF,0xDD,0x7F, 0xE7,0xFF,0xFC,0xFF,0xFC,0x3F,0xFF,0xFF, +0xFF,0xFB,0xFF,0xFE,0xBF,0xAF,0xFF,0xFD, 0xFF,0xEF,0xFF,0xEB,0xFF,0xFF,0xFF,0xFF, +0xFF,0xF7,0x7F,0xFF,0x7F,0xDF,0xFF,0xFD, 0xFD,0x7F,0xFE,0xF7,0xFD,0x7F,0xDF,0xFF, +0xFD,0xFF,0xFF,0xDF,0xFB,0xFF,0xEE,0xFF, 0xFB,0xFF,0xF7,0xFD,0xFF,0x7A,0xDF,0xF5, +0xFD,0xFA,0xDF,0xF7,0xFC,0xFF,0x7F,0xDF, 0xBF,0xED,0xFF,0xC9,0xFF,0xDF,0xFF,0xBF, +0x2F,0xFB,0xFF,0xBC,0xAD,0xFF,0xF7,0xFF, 0xFF,0xEF,0xD3,0xFF,0x7D,0xBF,0x6F,0xFF, +0xFA,0xFF,0xFE,0xBF,0xAE,0xEA,0xFA,0xBE, 0xAD,0xA5,0xEB,0xCE,0xBF,0xA7,0xEB,0x5A, +0xDE,0xBD,0xAF,0x6B,0xFD,0x57,0xFF,0xFF, 0xF4,0x7F,0x1F,0x7F,0xFD,0xFF,0x7F,0x36, +0xF0,0xDF,0x79,0xFF,0xFF,0xFF,0xF7,0xFD, 0xBF,0xFF,0x87,0xFF,0xFB,0xF3,0xFC,0xFF, +0xFF,0xFF,0xFF,0x7E,0xFF,0xBF,0xDF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,0xF8,0x9F, +0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFD, 0xF7,0xFC,0xBD,0xFF,0xFE,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFB,0xF9,0xBF,0xFF,0xFF,0xEB, 0xE2,0xFE,0xFF,0xBF,0xEF,0xA9,0xBA,0x2F, +0xEB,0xF9,0xFE,0x77,0xDF,0xF7,0xFF,0xFF, 0xF9,0x7F,0xFF,0xFF,0x7F,0xEF,0xD7,0xFF, +0xFD,0xFF,0xFB,0xF5,0xFF,0xBF,0x6F,0xDF, 0xFF,0xFF,0xFD,0xFF,0xFF,0xF0,0xFF,0xFF, +0xFF,0x3F,0xCF,0xFF,0xBA,0xEE,0x9B,0xBF, 0xEE,0xD7,0xFE,0xCD,0xEF,0xFF,0xDF,0xBF, +0xFF,0xFF,0xC5,0xFF,0xFF,0xFD,0x7F,0x4F, 0xFD,0xF6,0xD9,0xFF,0x4F,0xD6,0xFD,0xBF, +0x6E,0xFF,0xFF,0xF4,0x7F,0xFF,0x7F,0x8B, 0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xF9,0xFE, +0x37,0xFF,0xD9,0xFB,0xF5,0xAF,0xFD,0xFF, 0xFF,0xFB,0xFF,0xFF,0x07,0xFF,0xFF,0xFF, +0xFB,0xF7,0xFF,0xFD,0xFF,0x7C,0xFA,0x7E, 0x4F,0xFC,0xDF,0x1D,0xC7,0xFF,0xFF,0xFF, +0xFF,0xAE,0xFF,0xFF,0xFF,0xFF,0xFD,0xFB, 0xFF,0xFF,0xFE,0xFE,0xFC,0xFF,0x7F,0x7F, +0xBF,0xEF,0xFE,0xFF,0xFF,0xFF,0x5F,0xFD, 0xFF,0xFF,0xFF,0xFD,0x6F,0x5A,0xD7,0x7B, +0xBE,0x5F,0xFE,0x39,0xFF,0xF7,0xFF,0xF7, 0xFD,0xFE,0xAA,0x1F,0xFF,0xFF,0xFF,0xFF, +0xFE,0xFE,0xAB,0xAF,0xFD,0xFE,0xBF,0xFF, 0xF7,0xFF,0x7F,0xFE,0x8F,0xE3,0xFB,0xEE, +0x7F,0xFF,0xFF,0xFF,0xFF,0xEB,0xFB,0xFF, 0xFD,0xBF,0xEF,0xDF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFB,0xE4,0x3F,0xFF,0xDF, 0xFF,0xFF,0xFF,0xFF,0xF3,0xEF,0xBB,0xFB, +0xBF,0xEF,0xBB,0xFF,0xD7,0xBF,0xFF,0xFF, 0xFF,0x29,0xAF,0xF7,0xFF,0xFF,0xFB,0xFF, +0xFB,0xE6,0xFF,0x0F,0xFB,0x3F,0xDF,0x0F, 0xFF,0xAF,0xFF,0xFF,0xFF,0xF5,0xC3,0xDF, +0x5F,0xFF,0xFF,0xFF,0xFE,0x6B,0xCA,0xBE, 0xBC,0xFF,0x9F,0xF2,0xBF,0xFF,0xFE,0xFA, +0xFF,0xFF,0xEF,0x16,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFC,0xDF,0x97,0xFD,0x79,0xFF,0x37, +0xE7,0x7F,0xFF,0xFF,0xB5,0xFF,0xFF,0xF6, 0x2F,0xFF,0xFD,0xFB,0xFE,0xFF,0xFF,0xFD, +0x5F,0x57,0x5F,0xFF,0xDB,0x52,0xDF,0xFF, 0xFD,0xBF,0xFF,0xFF,0xFC,0xDB,0xFF,0x7B, +0xB5,0xFD,0x7F,0xFF,0x71,0x9C,0x6E,0xFF, 0xF6,0x35,0xA5,0x9B,0xFF,0xFF,0xFD,0xFF, +0xFF,0xDB,0x9E,0x7F,0xFE,0xEF,0xFB,0xFF, 0xFF,0xBD,0xEF,0xFF,0xDE,0xB7,0xF9,0x4B, +0xFF,0xF5,0xEF,0xFF,0xFF,0xFF,0xE8,0x7E, 0xFF,0xEA,0xDF,0xF7,0xFF,0xFD,0x69,0x5B, +0xFC,0x9F,0xEF,0x78,0xD6,0xFF,0xEB,0xEF, 0xFF,0xFF,0xFF,0xE8,0xFF,0xFF,0xED,0xFF, +0xFF,0xFF,0xFF,0xE3,0xF9,0xF6,0xBF,0xFF, 0xFF,0xFE,0xDF,0xFF,0x7F,0xFF,0xFF,0xFF, +0xD1,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF, 0xE7,0xF9,0xFF,0xBF,0x7F,0xD9,0xFF,0xFD, +0xFE,0x7F,0xFF,0xFE,0xFF,0xF9,0xFF,0xFB, 0xD6,0xDF,0xBF,0xEF,0x5B,0xD6,0xFF,0xBF, +0xFB,0xF6,0xFF,0xBF,0xEF,0xF8,0xF6,0xDD, 0xBE,0xFE,0x16,0xFF,0xBF,0xEF,0xFF,0xFE, +0xFF,0xBF,0xEF,0xFF,0xFF,0xFF,0x6F,0xFB, 0xFF,0xFF,0xFF,0x6F,0xF3,0xFF,0xF7,0xEF, +0xFB,0xFF,0xBF,0xFF,0xEF,0xFE,0xFF,0xBF, 0xFF,0xFF,0xFF,0xBE,0xBF,0xFF,0xEF,0xFF, +0x7F,0xEF,0xFF,0xFD,0x17,0xFB,0x7B,0xFF, 0xFF,0xFD,0x7F,0xDB,0xF6,0xF4,0x7F,0xFA, +0xFE,0xF5,0xBF,0xEB,0xE3,0xF7,0xFF,0xFF, 0xE9,0xBF,0xFF,0xAF,0xF7,0xFD,0xF3,0x7E, +0x8F,0xA3,0xEA,0xFF,0xCB,0xF3,0xEE,0xFF, 0xBF,0xEF,0xF7,0xF9,0xFF,0xFE,0x7F,0xFF, +0xFF,0xFF,0xFF,0xF5,0xFB,0xF6,0xFF,0xF5, 0x2F,0xFE,0xFB,0xD7,0xBF,0xFF,0xBE,0xDF, +0x9F,0xFF,0xF0,0xFF,0xFF,0xF9,0xFE,0x7F, 0x8F,0xA3,0xF8,0xFE,0x6F,0x9F,0xF9,0xF6, +0x2F,0x9F,0xE7,0xF9,0xFE,0x2F,0x9F,0xE1, 0xFF,0xFF,0xFF,0x7F,0xDF,0xF7,0xF5,0xFD, +0x7F,0x7F,0xF5,0xFF,0x9F,0x5F,0xFB,0xFE, 0xFF,0x7F,0xFF,0xFF,0xCB,0xFF,0xFF,0xFB, +0xFE,0xFF,0xBF,0xAF,0xFB,0xFE,0xFF,0xDF, 0xFE,0xFE,0xBF,0xF7,0xFF,0xFF,0xFF,0xFF, +0xFF,0xC7,0xFF,0xFF,0xFD,0xFF,0x7F,0xDD, 0xF7,0xFD,0xFF,0xFF,0xD7,0xFF,0xFD,0x7F, +0xFF,0xFB,0xFD,0xFF,0xFF,0xFE,0xEF,0x7F, 0xFD,0xEF,0xFB,0xFE,0xFB,0xFD,0xFF,0x7F, +0xDF,0xFD,0xFF,0x7A,0xDF,0xF7,0xFD,0xFF, 0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xD3,0xF7, +0xFF,0xFF,0x6F,0xDB,0xFF,0xFF,0xEF,0xCB, 0xF4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, +0x29,0xFF,0xE8,0xDA,0x76,0x9F,0xAF,0x6A, 0xDA,0xFE,0x35,0xEB,0xDA,0xD6,0xBF,0xAB, +0xEB,0x7A,0xDE,0xBF,0xD7,0x7F,0xFF,0xFE, 0xFF,0xBF,0xEF,0xFD,0xDF,0x77,0xBF,0xFD, +0x37,0xEF,0xFF,0xEF,0xFF,0x3F,0xFF,0xFF, 0xFF,0xFE,0x7F,0xFF,0xFF,0xFF,0xF7,0x7E, +0xDF,0xFF,0xFF,0xFF,0xFA,0xB7,0x7F,0xFF, 0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x89,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x9F,0xFB,0xFF,0xFF,0xFF,0xE7,0xFF, +0xFF,0xFF,0xFF,0xAA,0xFF,0xAB,0xFB,0xFA, 0xEF,0xBF,0xFF,0xDF,0xFA,0x7B,0xB9,0xFE, +0xFE,0xFF,0xFD,0xFF,0xF7,0xFE,0x3F,0xFF, 0xB7,0xFF,0xF7,0xEE,0xFF,0x7F,0xEF,0xFF, +0xFF,0x7F,0xFF,0x1F,0xFB,0xFF,0xBF,0xFB, 0xFE,0xFF,0xBD,0xFF,0xFF,0x2F,0xFF,0xBF, +0xFF,0x7F,0xDF,0xFA,0xFF,0xFF,0xFC,0xEE, 0xF5,0xF3,0xBE,0xFB,0x0F,0xEF,0xF3,0xBE, +0xEF,0xFC,0x5F,0xFF,0x5A,0xFF,0xF7,0xDF, 0xFF,0xFF,0xFE,0xD5,0xFC,0x5F,0xFB,0xF2, +0xFF,0xFF,0x2F,0xBB,0xF3,0xFF,0xFF,0xBF, 0xFF,0xEF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF, +0xBF,0xFF,0xFF,0xFD,0x7B,0xFF,0xDF,0xB9, 0xFF,0xFB,0xFF,0xD8,0x7F,0xFF,0xFF,0xFF, +0xFB,0xFF,0xFC,0x7F,0x1F,0xBF,0xE0,0xDF, 0xF7,0xEF,0xFF,0xFD,0x7F,0xFE,0xDF,0xFF, +0xE0,0xFF,0xFF,0xFD,0xEF,0xFB,0xFF,0xFE, 0xF7,0xDF,0xFF,0xEB,0x5F,0xFF,0xF7,0xFF, +0xFF,0xFF,0xFF,0xBF,0xFF,0xFD,0xFF,0xFD, 0xFF,0xFF,0xFF,0xF7,0xFD,0xFF,0x3B,0xDC, +0xFD,0x6D,0x7B,0x5F,0x57,0xF5,0xFD,0x7F, 0x5F,0xFF,0xB1,0xFF,0xEB,0xFF,0xFF,0xFF, +0xFB,0xFB,0xFE,0xFF,0xBF,0xFB,0xBE,0xFF, 0xBF,0xEF,0xFB,0xFE,0xFF,0xAF,0xFE,0xF7, +0xDF,0xDF,0xFF,0xFF,0xFF,0x7F,0xCF,0xF3, 0xF8,0xFF,0xD7,0xFB,0xFF,0x5F,0xBF,0xF7, +0xFB,0xFF,0x7F,0xFE,0x23,0xFF,0xFF,0xFE, 0x7F,0xF3,0xFF,0xFB,0xFE,0xFF,0xFF,0xF3, +0xFF,0xFF,0xF5,0xF9,0xFF,0x3F,0xFF,0xFF, 0xF0,0x9A,0xFF,0xBE,0x7F,0xFF,0xFC,0xF9, +0xFF,0xFD,0xAF,0xEB,0xFE,0xBF,0xFF,0xCF, 0xF3,0xFE,0x7F,0xFF,0xFF,0x5B,0xBD,0xFF, +0xBC,0xEB,0xFF,0xD7,0xD4,0xAF,0xAF,0xFD, 0xFF,0xCF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7, +0xFD,0xFE,0xFF,0x6F,0xFF,0xFB,0xFF,0xFF, 0xFF,0xFD,0x7F,0x5E,0xFD,0xBF,0xDB,0xF6, +0xFD,0xBF,0x6F,0xFB,0xEE,0xFD,0xFF,0x7A, 0xFF,0xFA,0xFB,0xFF,0x3F,0xFB,0xB7,0x5F, +0xD6,0xF7,0x1F,0x71,0xDC,0x77,0x1D,0xC7, 0x31,0xDC,0x77,0xDF,0xF9,0xBF,0xF5,0x5B, +0xF4,0xD7,0x9D,0xAE,0xFF,0xBF,0xFD,0xBF, 0xDB,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,0xFE, +0x3D,0x81,0xFF,0xEB,0xFE,0xFE,0xFE,0xFF, 0xEB,0x7A,0xDF,0x7D,0x77,0x7D,0xF5,0x79, +0xDF,0x57,0xDD,0xF5,0x7D,0x7E,0xE6,0xFF, 0xD6,0x3F,0xBF,0x7F,0xFF,0xD4,0xF5,0x3F, +0xBF,0xFB,0xBE,0xEF,0xB3,0xEE,0xFB,0x9E, 0xEF,0xBB,0xFE,0x8B,0xFF,0xFE,0xDF,0xB7, +0xED,0xFF,0xF7,0xFD,0xFE,0xFF,0xEF,0xBB, 0xEE,0xFF,0xBE,0xEF,0xBB,0xEE,0xEB,0xFC, +0x1F,0xFF,0xFF,0xFD,0xFF,0xE7,0xFF,0xF7, 0xFD,0xFF,0xEF,0xFE,0xFF,0xBF,0xEF,0xFB, +0xFE,0xFF,0xBF,0xEB,0xFA,0x1F,0xFF,0xB7, 0xEF,0x5B,0xFE,0xFF,0xAF,0xEB,0xDD,0xE7, +0xDE,0x77,0x9D,0xE7,0x79,0xDE,0x77,0x9D, 0xBF,0xE6,0x6F,0xFF,0xFE,0xFF,0xBF,0xEF, +0xFB,0xFE,0xFD,0xBF,0x6F,0xF6,0xFD,0xBF, 0x6F,0xDB,0xF6,0xFD,0xBF,0xFF,0x7E,0xFF, +0xFF,0xFB,0xFE,0xFE,0xFF,0xEF,0xFB,0xFD, 0xEF,0x7E,0xF7,0xBD,0xEF,0x7B,0xDE,0xF7, +0xBD,0xEF,0xFF,0xD5,0xFF,0xBF,0xFF,0xEF, 0xFE,0xFF,0xFC,0x3F,0x0F,0xE7,0xFE,0x7F, +0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7,0xFE, 0xF3,0xFF,0xFE,0xDF,0xAD,0xDF,0x67,0xEE, +0xFB,0xBF,0xEF,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFE,0xFF,0xBF,0xEF,0xFF,0x23,0xFF,0xFF, +0xFF,0xFF,0x7F,0xFF,0xF3,0xBC,0xDB,0xFE, 0xFB,0xFF,0xFB,0xBE,0xF7,0xFB,0xFF,0x7F, +0xDF,0xFF,0xCF,0xFB,0xFF,0x9F,0xE3,0xF9, 0xBE,0x3F,0x8F,0xE7,0x79,0xFF,0x9D,0xE7, +0xF9,0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x5F, 0xFF,0xCF,0xF7,0xFF,0xFF,0xFF,0xDF,0xF7, +0xFE,0x7F,0xE7,0xF9,0xFE,0x7F,0xFF,0xFF, 0xFB,0xFE,0xFF,0xFF,0xBF,0xFF,0xBF,0xBF, +0xFF,0xFE,0xFF,0xBF,0xEF,0xFF,0xFD,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFD,0xFF, +0xFF,0x3F,0xFF,0xBF,0xFF,0xF7,0xFF,0xFF, 0x7F,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xE8,0xEF,0xFF, 0x5F,0xF7,0xBF,0xF9,0xFE,0xDF,0xB7,0xFD, +0xFF,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7, 0xFD,0xFF,0xDD,0xFF,0xF2,0xFF,0xBF,0xFF, +0xFF,0xBF,0xFF,0xFF,0x2F,0xF2,0xFF,0xBF, 0x2F,0x7B,0xD2,0xF7,0xBF,0x2F,0xFF,0xBB, +0xFF,0xEE,0x8F,0xAF,0xEB,0xFA,0xFE,0x3F, 0xA7,0x69,0xCE,0x8F,0xA4,0xEA,0xFA,0xEE, +0xB7,0xAE,0xEB,0xFD,0xC7,0xFF,0xF7,0xF7, 0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3E,0xF3, +0x74,0xFF,0x3F,0x4F,0xFF,0xE7,0xFF,0x3F, 0xFE,0xA7,0xFF,0xFF,0xDF,0xF7,0xB7,0xFF, +0xF7,0xFF,0xBA,0xEF,0x37,0xEB,0xFB,0xFE, 0xBF,0xFB,0xFE,0xF3,0xFF,0xF9,0xDF,0xFF, +0xBF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF, 0xFD,0xDF,0xFF,0xFD,0xFF,0xFF,0xFB,0xFE, +0xFD,0xFF,0xFB,0xBF,0xFE,0x3F,0xED,0xFF, 0xDF,0xBE,0x3D,0xA7,0xFB,0xFA,0x3F,0xE6, +0xE1,0xFE,0xFE,0x3F,0xEF,0xE3,0xDF,0xF5, 0x7F,0xFE,0xFF,0x7E,0xFF,0xFF,0xFF,0xFF, +0xEF,0x6F,0xF6,0xFF,0x7D,0xEF,0xD7,0xDE, 0xFF,0x7D,0xEF,0xFF,0xF2,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0x7B,0xDE,0xFB,0xE6,0xEE, 0xEF,0x37,0x6E,0xF3,0x7E,0xEB,0x37,0xEF, +0xFF,0xC1,0xFF,0xFE,0xFF,0xF7,0xEF,0xFF, 0xFF,0xFF,0xBF,0x3F,0xD2,0xDF,0xBF,0x2F, +0x7B,0xE2,0xFF,0xFE,0x3B,0xBD,0xDB,0xFF, 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFE, +0xFF,0xFB,0xFF,0xFF,0xBF,0xFF,0xFB,0xDF, 0xFF,0xBF,0xFF,0xB7,0xFF,0xFF,0xBF,0xEF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF, 0x7F,0xFF,0x1F,0xEF,0xF1,0xFD,0xFF,0xF6, +0xAF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF, 0xFF,0xFF,0xFE,0x9F,0xFF,0xFF,0xFF,0x77, +0xEF,0xF7,0xFB,0xFF,0xFE,0x5F,0xFF,0xFF, 0xBF,0xCF,0xFB,0xF7,0xDD,0xF7,0xF5,0xFF, +0x5F,0xD5,0xF5,0xFD,0x7F,0x5F,0xD7,0xF5, 0xFF,0xFB,0x0F,0xFF,0xFF,0xA9,0xEA,0x7A, +0xFF,0xAF,0x8F,0xFE,0xDF,0xAF,0xEF,0xFB, 0xFE,0xFF,0xBF,0xEF,0xFB,0xDF,0xE5,0x5F, +0xFF,0xFF,0xFF,0xFF,0xFF,0xBD,0x57,0xFF, 0xFF,0x6F,0x77,0xBF,0xF7,0xFB,0xFF,0x7F, +0xBF,0xF7,0xFF,0xFC,0xBF,0xFF,0x9F,0xFF, 0xFF,0xEF,0xFF,0xFE,0xFF,0xFF,0xFF,0x1F, +0xCF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFF,0xFB, 0x65,0xAF,0xF3,0x7C,0xFF,0x3F,0xDF,0xFF, +0xFD,0xE9,0xFE,0x7F,0xE7,0xFF,0xFE,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFD,0xE3,0xDF,0xFB, +0xDB,0xF6,0xFD,0xEF,0x5B,0xFB,0xFF,0xDF, 0xFC,0xFF,0x3F,0xDF,0xF3,0xFD,0xFF,0x7F, +0xDF,0xEF,0x66,0xFF,0xDF,0xAD,0xEB,0x7A, 0xDE,0xF7,0xF7,0xE7,0xD9,0xFD,0x9F,0x67, +0xD9,0xF6,0x7D,0x9F,0xE7,0xDF,0xF5,0x47, 0xFD,0x65,0x5B,0xD6,0xF4,0xFE,0xFF,0xEF, +0xFF,0x6D,0xF6,0xDD,0xB7,0x6D,0xDB,0x76, 0xDC,0xB7,0x7D,0xFA,0x9B,0xF6,0x6D,0x9D, +0x67,0x59,0xDF,0xF7,0xDD,0xFF,0xEB,0xFE, 0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,0xE3, +0xD1,0x9F,0xFF,0xBD,0xBF,0xEF,0xFE,0xF7, 0xBF,0xBF,0xF7,0xD7,0x7F,0xDD,0xF7,0x9D, +0xDF,0x7F,0xDF,0xF7,0xFF,0xE0,0x7F,0xFD, 0xC1,0xDF,0xF7,0xFD,0xC7,0x7F,0x7F,0xFB, +0xFF,0xBB,0xEC,0xFB,0x3E,0xFF,0xBF,0xEC, 0xFB,0xFF,0xD8,0x7F,0xBF,0x6C,0xFF,0xBE, +0xFF,0xBF,0xED,0xFF,0xEF,0xFE,0xFB,0xBF, 0xEF,0xFB,0xFE,0xFF,0xBF,0xEE,0xFF,0xC5, +0xFF,0xAF,0x6F,0xFF,0xFC,0xFD,0x3F,0xE7, 0xFF,0xFE,0xFF,0xEF,0xFB,0xFE,0xFF,0xBF, +0xEF,0xFB,0xFE,0xBF,0x89,0xFE,0xFA,0xBA, 0xFE,0xBF,0xAF,0xFB,0xF6,0xF5,0xD9,0x7D, +0x97,0x65,0xD9,0x74,0x5D,0x97,0x65,0xD3, 0xFE,0xD6,0xFF,0xBF,0xF7,0xFD,0xFF,0x7F, +0xBF,0xCF,0xFB,0xFE,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xEF,0xFB,0xFF,0xF6,0x8F,0xFB, +0xFF,0xEF,0xFB,0x7E,0xDB,0xFE,0xFF,0xBE, 0xEF,0xEE,0xFB,0xBE,0xEF,0xBB,0xEE,0xFB, +0xBE,0xFF,0xFF,0xDF,0xFF,0x43,0xFF,0xFF, 0xFB,0xEF,0x5F,0xB7,0xFE,0x7F,0xE7,0xF9, +0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0xF9, 0xBF,0xFE,0xAF,0x77,0xFD,0xFF,0x2F,0xAF, +0xA7,0xFE,0xFF,0xEF,0xFB,0xFE,0xFF,0xBF, 0xEF,0xFB,0xFE,0xFF,0xF1,0x7F,0xEF,0xDF, +0xFF,0x97,0xF5,0xEF,0xFF,0xDF,0xFF,0xFF, 0xBF,0xFF,0xBF,0xFF,0xFF,0xFE,0xFF,0xFF, +0xFF,0xE0,0xFF,0xFF,0xF9,0xFE,0x2F,0x8B, 0xE3,0xF8,0xBE,0x77,0x9F,0xF9,0xDA,0x77, +0x9D,0xE7,0x79,0xDE,0x77,0x9F,0xDD,0xFF, 0xFD,0xFD,0x7F,0x5F,0xD7,0xFD,0xFF,0x7F, +0xE7,0xFE,0x7F,0x97,0xE7,0xFB,0xFE,0xFF, 0xBF,0xEF,0xFF,0xAB,0xFF,0xEF,0xFA,0xFE, +0xBF,0xAF,0xFF,0xFA,0xFF,0xFF,0xDF,0xFF, 0xFB,0xFF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF, +0x67,0xFF,0xF7,0xF5,0xFF,0xFF,0xFF,0xDF, 0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xBD, 0xEB,0xFF,0xFF,0xF7,0xAD,0xEB,0xFF,0xDF, +0xFD,0xFF,0x3F,0xDF,0xF7,0xFD,0xFF,0x7F, 0xDF,0xFF,0x5F,0xFF,0xF7,0xFF,0xFF,0xFD, +0xBF,0xFF,0xCB,0xF4,0xFF,0x7F,0xD3,0xF7, 0xFD,0x3F,0x7F,0xD3,0xF7,0xFF,0xFC,0x3F, +0xFF,0xEA,0xFA,0xBE,0xAF,0xAB,0xEB,0xBA, 0xF4,0x95,0x6B,0x52,0xD4,0xAD,0x2F,0x4A, +0xD2,0xF6,0xBF,0xD2,0x7F,0xF7,0x3F,0xFF, 0xFF,0xF3,0x7F,0xFF,0xFF,0xF7,0xFF,0xBA, +0xDF,0xFB,0xFD,0xFF,0xBF,0xFF,0xFB,0xFF, 0xF8,0x7F,0xEA,0xFF,0xFE,0xFE,0xDF,0xFF, +0xF7,0xFF,0x7F,0xBB,0xFF,0xFF,0xBF,0xDF, 0xFB,0xFF,0xFF,0xBF,0xFF,0xB1,0x7F,0xFF, +0xFB,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF, 0xCF,0xFE,0xFF,0xFF,0xEF,0xFF,0xF7,0xFF, +0xFF,0xFF,0xF1,0xFF,0x69,0xBE,0xFA,0xBF, 0xAF,0xE2,0xFF,0xFE,0xFD,0xAF,0xF3,0xFE, +0xFF,0xBF,0xEF,0xFB,0xFC,0xFF,0xFF,0x07, 0xFD,0x95,0xDB,0xDF,0x7F,0xDF,0xAF,0xFF, +0xF7,0xAF,0x36,0xFE,0xBF,0x65,0xEB,0xF6, 0xFE,0x9F,0x6F,0xFE,0x07,0xFF,0xCF,0xFF, +0xF8,0xFE,0xFF,0xCF,0xFF,0xF6,0xFA,0xE7, 0xFB,0xFE,0xFF,0xBB,0xED,0xF9,0xFF,0xFF, +0xFF,0x5F,0xFF,0xFF,0xFF,0x75,0xFF,0xEF, 0x7E,0xFD,0xE0,0xE8,0x5E,0xD3,0xE5,0xF9, +0x3E,0x5F,0xD7,0xF7,0xFF,0xFA,0x2F,0xFB, 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0x7F, +0x7F,0xD7,0xF5,0x7D,0x5F,0x57,0xD5,0xF5, 0xEF,0xFF,0xF3,0x7F,0xFC,0x7F,0xFF,0xC7, +0xF1,0xFF,0xFF,0x1F,0xCF,0xB0,0xFF,0x3F, 0xCF,0xF3,0xFC,0xFF,0x3F,0xCE,0xFF,0xE4, +0xFF,0xDF,0x7F,0xFE,0xF7,0xBB,0xFF,0xFF, 0xDF,0xEF,0xEE,0xFF,0xBF,0xEF,0xFB,0xFE, +0xBF,0xBF,0xEF,0xFF,0xD1,0xFF,0xFF,0xFF, 0xFD,0xFB,0xFF,0xFD,0xFF,0xFB,0x9F,0xE9, +0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0xBF, 0xFF,0xB3,0xFF,0xFF,0xF7,0xFF,0xFF,0xAF, +0xF7,0xFF,0xB6,0x3F,0xEB,0xFA,0xFE,0xBF, 0xAF,0xEB,0xFA,0xFE,0xBF,0xFE,0xA7,0xFF, +0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF, 0xFE,0x9F,0xF7,0xF9,0xFF,0x7F,0x9F,0xE7, +0xFF,0xFF,0xFE,0xAF,0x6F,0xFF,0xFF,0xFF, 0x9F,0xFF,0xDF,0xFF,0x7D,0x5F,0xDD,0xFF, +0xFB,0xBF,0xE7,0xBB,0xFF,0xFB,0xDF,0x6D, 0x5F,0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xEB,0xF7,0xFF,0xE7,0xEF,0xF7,0xFF,0xFF, 0x7F,0xFF,0xF7,0xFF,0xFC,0x8F,0xFF,0xEF, +0xFD,0xFE,0xFF,0xBE,0xF4,0xF2,0x7D,0xD7, 0xCF,0xFF,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xCF,0x6B,0xFF,0xBF,0x3F,0xFB,0xF2, 0xFC,0x7F,0xEB,0xFF,0x9F,0xFA,0xFF,0xFF, +0x3F,0xFF,0xF3,0xFF,0xFF,0xFD,0x70,0xF7, 0xFF,0xFF,0xBF,0xFF,0xFB,0xD7,0xFE,0xF5, +0x77,0xFF,0x15,0xDD,0x77,0xFD,0xFF,0x7F, 0xDF,0xF7,0xFB,0xCD,0xBF,0xFF,0xFD,0xFF, +0xFF,0xDF,0x37,0xCD,0xF9,0xEC,0xFE,0xEF, 0xBB,0xF4,0xFB,0x3F,0x4F,0xB3,0xFF,0xFD, +0xCB,0xFF,0xE9,0x7E,0x54,0x9F,0xE5,0x4B, 0xB7,0xFF,0xDD,0x7D,0xC7,0x71,0xDD,0x77, +0x5D,0xD7,0x75,0xCD,0x7F,0xD6,0xFF,0xD3, 0xF6,0xF9,0x3F,0x6D,0x95,0xAF,0x7F,0xFE, +0xFF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFE,0xF6,0xC7,0xFF,0xAD,0x7B,0xCA,0xFF, +0xBF,0xBF,0xEF,0xFD,0xE3,0xDF,0xB7,0xED, 0xFB,0x7E,0xDF,0x37,0xED,0xE3,0xFB,0xDF, +0xFF,0x52,0x5C,0x15,0xFD,0xCF,0x7F,0xDF, 0xFE,0xEF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEC, +0x7B,0xFE,0xFF,0xFE,0x3E,0x7F,0xDA,0xF7, 0xFD,0xFF,0x7F,0xFF,0xFF,0xFB,0xEF,0xBB, +0x6F,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFF, 0xF7,0x7D,0xFF,0xD8,0xFF,0xFD,0xBF,0x7F, +0xFB,0xFF,0xFF,0x9F,0xFB,0xFE,0x7F,0x9F, 0xE7,0xF9,0xFE,0x7F,0x9F,0xEA,0x7F,0xF6, +0xBF,0xBD,0x6A,0x5A,0xF6,0xE5,0xBF,0x77, 0x5F,0x6D,0xDD,0x77,0x5D,0xD7,0x75,0xDD, +0x77,0xFF,0xA5,0xBF,0xCF,0xFB,0xFF,0xFF, 0xBF,0xCF,0xFB,0xFD,0xFF,0xBF,0xF3,0xFE, +0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFD,0xAB, 0xFF,0xBF,0xBF,0xFF,0xFB,0xFF,0x7F,0xEF, +0xFF,0xBE,0xFB,0xEE,0xFB,0xBE,0xEF,0xBB, 0xEE,0xFB,0xBF,0xFF,0xB5,0xFF,0xD0,0xBC, +0xFD,0x2F,0x4B,0xF7,0xFF,0xFF,0x9F,0xF9, 0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x9F, +0xFA,0x8F,0xFD,0xAB,0xFA,0xDA,0xBF,0xAF, 0xB3,0xFD,0xFF,0xBF,0xFB,0xFE,0xFF,0xBF, +0xEF,0xFB,0xFE,0xF7,0xBF,0xFF,0x9F,0xFF, 0x77,0xF7,0xBD,0xFD,0x77,0xDF,0xFF,0x7E, +0xDF,0xED,0xBB,0xFE,0xFF,0xBE,0xEF,0xFB, 0xFE,0xFF,0xFA,0x3F,0xFF,0xBE,0x6F,0x8F, +0xE6,0xF9,0xFE,0x7F,0x9F,0xC7,0xFE,0x7F, 0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7,0xFB, +0x7F,0xFF,0x7F,0xCF,0xFF,0xFD,0xFF,0xFF, 0xDF,0xFB,0xAF,0xBF,0xEF,0xFF,0xFE,0xFF, +0x9F,0xEF,0xFB,0xFF,0xFC,0xFF,0xFB,0xFE, 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xF7, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xF5,0xFF,0xFF,0xFF,0x3F,0xDF,0xF7, +0xFF,0xFF,0x7F,0xEF,0xFE,0xFF,0xBF,0xFF, 0xFB,0xFF,0xFF,0xBF,0xEF,0xFF,0xB3,0x7F, +0xFF,0x7B,0x5E,0xF7,0xFD,0xFF,0x7B,0x7F, 0xF7,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F, +0xDF,0xF7,0xFF,0x17,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xDD,0xF6,0xFC,0xBF,0xCB,0xF2, +0xBC,0xBF,0x2F,0xCB,0xF2,0xFC,0xBF,0xFE, 0x8F,0xFF,0xFA,0x7E,0xBF,0xA7,0xEB,0xDA, +0xFC,0xBF,0xAF,0x7A,0xFE,0xBF,0xAF,0xEA, 0xFA,0xFE,0xBF,0xAF,0xF4,0xDF,0xFE,0xFF, +0xF3,0x3C,0x7F,0x3E,0xFF,0xCF,0xF8,0xBF, 0x8F,0xE3,0xF8,0xFE,0x3F,0x8F,0xE7,0xE8, +0xFF,0xFC,0x9F,0xFF,0xFF,0xCF,0xEB,0xB3, 0xE7,0xFB,0x7B,0xF3,0xFE,0xFF,0xCF,0xDB, +0xFB,0xFB,0xBF,0x6F,0x6F,0xDF,0xEC,0x7F, 0xFF,0xFF,0xF7,0xFD,0xFD,0xFF,0xFF,0xFF, +0xFF,0xB2,0xBF,0xFF,0xDE,0xFD,0xBD,0xEF, 0xFB,0xF6,0xDF,0xEA,0xE7,0xDB,0xFE,0xBB, +0xFF,0xEB,0xFB,0xBF,0x9F,0x8F,0xE8,0xFE, 0x3F,0x8F,0xA3,0xF8,0xFE,0x3F,0x8F,0xFF, +0xF8,0x7E,0xFD,0xFD,0x7F,0xFF,0xFB,0xCD, 0xFF,0xFD,0xFF,0x5F,0xEF,0xFD,0xFF,0xFF, +0xDF,0xF7,0xFD,0xFF,0xBE,0x90,0xFF,0xFF, 0xEE,0xFF,0x3F,0xBF,0xF3,0xBB,0xFE,0xB7, +0xAB,0xFA,0xFE,0xAF,0xAD,0xEA,0xFA,0xDE, 0xAB,0xFF,0x63,0xFF,0xFE,0xF2,0xFF,0xB3, +0xFF,0xDF,0xEE,0x7D,0xFF,0x03,0xF1,0xF4, 0x3F,0x1F,0xC3,0xF1,0xEC,0x7F,0xFE,0x6F, +0xFF,0xFB,0xFB,0xFF,0x9F,0xFF,0xBF,0xFF, 0x7B,0x5F,0xFD,0xFF,0xDF,0xF7,0xFD,0xFD, +0x7F,0x7F,0xDF,0xFE,0xCF,0xFB,0xFF,0xFF, 0xAF,0xFB,0xFF,0x1F,0xEF,0xA5,0xFD,0xBF, +0xDF,0xFB,0x7D,0xFF,0xBF,0xDF,0xFB,0xFF, 0xFD,0x3B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, +0xAF,0xF3,0xFF,0xFB,0x7F,0xBF,0xD7,0xFB, 0xBF,0x7F,0xBB,0xF7,0xFF,0xF8,0x7F,0xFF, +0xFA,0x5F,0xD7,0xFF,0xDF,0x7F,0xEF,0xFF, 0xFF,0x7F,0xDB,0xF7,0xFD,0xFF,0x7F,0xDF, +0xB7,0xFB,0xEC,0xFF,0xFF,0xF7,0xBF,0xEF, 0xFD,0xFC,0xFB,0xFF,0xEF,0xF0,0xFE,0x3F, +0x8F,0xE3,0xF8,0xFE,0x3F,0x8F,0xEF,0x8D, 0xFF,0xFF,0xEF,0x7F,0xBF,0xFF,0xFB,0xFF, +0xDB,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xEF,0xD8,0xFF,0x2E,0x7F, +0xBE,0xEF,0xFE,0x6E,0xFF,0xBF,0xF9,0xFF, 0xFF,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFC,0x66,0xBE,0x47,0xF3,0x7F,0xDF,0xFE, 0x87,0x9F,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xD6,0x6F,0x7C, 0xFB,0x4F,0xD2,0xFF,0xFD,0x2B,0xFE,0xFF, +0xFF,0xFD,0x5F,0xD7,0xD5,0xF5,0x7D,0xFF, 0xFF,0xFF,0xBF,0x9B,0xFF,0xFF,0xDF,0xB7, +0xFF,0xFF,0xDF,0xFF,0x3F,0xCF,0xFE,0x7F, 0xBF,0xEF,0xFB,0xFC,0xFF,0x3F,0xFF,0xD9, +0xBF,0xFE,0x97,0xEC,0x8F,0xB7,0xFE,0x9B, 0x7D,0xFD,0xB7,0xDD,0x77,0x1D,0xC7,0x71, +0xDD,0x77,0x5D,0xD7,0xF3,0x6F,0xFD,0x3F, 0x73,0xDD,0xAF,0xFD,0x7A,0xFF,0xFF,0xAF, +0xFE,0xFD,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF, 0xEF,0x66,0x7F,0xFF,0xFF,0xBF,0xBF,0xFF, +0xFB,0xFF,0xF7,0xDF,0xFD,0xFB,0x7D,0xDF, 0xB7,0xCD,0xF3,0x7C,0x5F,0x3F,0x91,0x3F, +0xFF,0x3D,0xEF,0x7B,0xFF,0xFC,0xFF,0xCA, 0xEF,0xFE,0xFF,0xBD,0xEF,0xFB,0x1E,0xE7, +0xBB,0xEC,0x7F,0xB3,0xFF,0xFD,0x9F,0xFF, 0xFF,0xFE,0xFF,0xFF,0x7F,0xBF,0xFB,0xFE, +0xFF,0xBF,0xEF,0xFB,0xEE,0xFB,0xBF,0xDF, 0x67,0xFF,0xFF,0xBF,0xEF,0xDB,0xFF,0xBC, +0xFE,0x7F,0xFB,0xFF,0x9F,0xEF,0xF9,0xFE, 0x7F,0x9F,0xE7,0xF9,0xFE,0x87,0xFF,0xEE, +0xFB,0xBE,0xE5,0xBF,0xEF,0xF9,0xD7,0x65, 0xF7,0xDD,0xE7,0x7D,0xDF,0x77,0x5D,0xD7, +0x7F,0xF8,0x9B,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFF,0xFF,0xBF,0xEF,0xFB,0xFF,0x7F,0xCF, +0xF3,0xFC,0xFF,0xBF,0xEF,0xFF,0xDB,0x3F, 0xEF,0xFB,0xFE,0xFF,0xDF,0xFF,0xFE,0xFB, +0xBB,0xEF,0xBF,0xEF,0xBB,0xEE,0xFB,0xBE, 0xEF,0xBB,0xFF,0xFC,0x7F,0xFD,0x3B,0x5B, +0xD6,0xE5,0xFD,0x4F,0xC3,0xFB,0xFF,0xBF, 0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFF, +0xB4,0xFF,0xFA,0xBC,0x8F,0xB2,0xE9,0xD2, 0x2E,0xCF,0xFB,0xFF,0xBF,0xEF,0xFB,0xFE, +0xFF,0xBF,0xEF,0xFB,0xFF,0xEC,0xFF,0xFD, 0xFD,0x7F,0xDF,0xF7,0xE4,0xDF,0x5F,0xFF, +0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xC3,0xFF,0xEF,0xE6,0xF8,0xFE, +0x3F,0x8B,0x83,0xF9,0xFE,0x7F,0xE7,0xF9, 0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x17, +0xFD,0xFF,0xFF,0xFF,0x7F,0x5F,0xF7,0x2C, 0xFF,0xFF,0xFF,0xFE,0x7F,0xFF,0xE7,0xF9, +0xFE,0x7F,0x9F,0xFE,0x2F,0xFF,0xFF,0xEF, 0xFF,0xFE,0xBF,0xEF,0xAD,0xFF,0xFF,0x7F, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFE,0xDF,0xFF,0xDF,0xFF,0xFD,0xFD,0x7F, +0xDF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0x3F,0xFE, +0xF7,0xFD,0xEF,0x7A,0xFF,0xB1,0xBD,0xFF, 0x7F,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7,0xFD, +0xFF,0x7F,0xF3,0x27,0xFF,0xDF,0xFF,0xDD, 0xFF,0xFC,0x9B,0xFF,0xCB,0xFC,0xBF,0x2F, +0xCB,0xF2,0xFC,0xBF,0x2F,0xC9,0xFF,0xDE, 0xFF,0xDF,0xAF,0xEB,0xDA,0xFE,0xBB,0xAF, +0xEB,0xF8,0xF7,0xAF,0xE8,0xFA,0xFE,0xBF, 0xAF,0xEB,0xF2,0xFF,0xFD,0xFF,0xFF,0xEF, +0xBD,0xD7,0xBF,0xFF,0xFF,0xDE,0x8F,0xB8, 0xDE,0x37,0x8D,0xA3,0x78,0xDA,0x3F,0x8F, +0xFF,0xA1,0xFF,0xFF,0xFB,0xFB,0xFF,0xFF, 0xFF,0xFF,0xA7,0xBD,0xFB,0x76,0xFD,0xBF, +0xEF,0xDB,0xFE,0xBB,0xBF,0xFE,0x27,0x7F, 0xFF,0xFE,0xFE,0xFD,0xF5,0xFF,0xEF,0xF5, +0xDF,0x1F,0xE7,0xFD,0xFF,0x7F,0xDF,0xF7, 0xFD,0xFF,0xFF,0xCD,0xFD,0xAE,0xFF,0xFA, +0x3E,0x3F,0xAB,0xFD,0xF8,0x7E,0x8F,0xE3, 0xF8,0xFE,0x3E,0x8F,0xE3,0xF8,0xFF,0xFE, +0x1F,0xEF,0xDF,0xBF,0xFE,0xDE,0xDF,0xD9, 0xFF,0xDF,0xBC,0xFF,0xFF,0x7F,0xFF,0xEF, +0xFD,0x7F,0xDF,0xF7,0xF9,0x3F,0xFE,0xFF, 0xFF,0x6F,0xFE,0xDE,0xBF,0xF7,0xED,0xEA, +0xFD,0x8F,0x83,0xF8,0xEA,0x3F,0x8F,0xEF, 0xFF,0xF4,0x7F,0xFF,0xEF,0xEF,0x7B,0xF3, +0xF1,0x5F,0xFF,0xFF,0xF1,0x3B,0x7F,0xDF, 0xF7,0xFD,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF, +0xFF,0xFF,0xF7,0xFF,0x6F,0xFF,0x7F,0xFF, 0xFF,0xF7,0xDE,0xF7,0xBF,0xEF,0xFB,0xF7, +0xFD,0xFF,0xFF,0xF5,0xFA,0xFF,0xFF,0xFB, 0xE7,0xFF,0xF3,0xF8,0x7F,0xF3,0xDF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0xEF, 0xBB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, +0xFF,0x7F,0xFF,0x9F,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xCF,0xFF,0x37,0xFF,0xFF, +0x7F,0xDF,0x77,0x5D,0xE7,0xFC,0xFF,0xBF, 0xF7,0xF5,0xFB,0xFF,0xFF,0xD7,0xF5,0xFB, +0xFF,0xFF,0x45,0xFD,0x7F,0xEA,0xFD,0xBE, 0xBF,0xDF,0xF7,0xFF,0xFF,0xDB,0xFB,0xFE, +0xFF,0xBF,0xEF,0xFF,0xFF,0xFF,0xFB,0x5F, 0x7F,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFE,0xFF,0xEF,0xFD,0xFF,0x7F,0xDF, 0xFF,0xEF,0xFB,0xF8,0x0F,0xF3,0xFF,0xF9, +0x2E,0xFB,0xFE,0xFC,0xF3,0xEF,0xFF,0xFF, 0xBF,0xFF,0xFB,0xE7,0xFF,0xFE,0x7E,0xFF, +0xC0,0x6B,0xCF,0xFF,0x34,0xDF,0xF1,0xFD, 0xFF,0xEF,0xFF,0xFF,0xFF,0xDF,0xF7,0xFD, +0xCF,0x7F,0x9C,0xFD,0xFD,0x6C,0xF7,0xFF, 0xF6,0xFD,0xEB,0x2B,0x9F,0xFF,0xFC,0xFE, +0x7E,0xFF,0xFF,0xFF,0xFF,0xD7,0xF3,0xF7, 0xFF,0xFB,0xE1,0xBF,0xFF,0xEB,0x7A,0xDE, +0xD7,0xFB,0xFF,0xF9,0xFE,0xFF,0xFF,0xF3, 0xDE,0x7F,0xFD,0xE7,0x7F,0xFF,0xFD,0xBB, +0xFF,0xFF,0x7E,0xCC,0xF6,0xAF,0x5F,0x7F, 0xFE,0xF4,0x7D,0xF7,0xFD,0xBB,0x6E,0xDB, +0xB7,0xFF,0xF7,0xDF,0x66,0xFF,0xFF,0xF7, 0x3D,0xCF,0xDE,0xBD,0xFF,0xFF,0xDE,0xDB, +0x8D,0xF7,0x7E,0xDF,0xB7,0xEF,0x7F,0xFF, 0xF6,0x87,0xFF,0xFF,0xEF,0xFE,0xDE,0xBF, +0xFF,0xFF,0xFF,0xBB,0xEF,0xFD,0xFF,0x7B, 0xDE,0xF7,0x3F,0xFF,0xBF,0xFB,0xDB,0xFF, +0xF2,0xB6,0xFD,0xBD,0x7F,0xE7,0xFF,0xFF, 0xFF,0x6F,0xF7,0xFF,0xFF,0xFF,0xFE,0x77, +0xFF,0xBF,0xF8,0xAF,0xFF,0xDF,0xBF,0xFF, 0xBF,0x7F,0xFB,0xFF,0xFF,0xFF,0xDB,0xFE, +0xFF,0xBF,0xFF,0xFA,0xFF,0xFD,0xFF,0xF6, 0x7F,0xFF,0x9F,0xFF,0xFF,0x3F,0xEF,0xF8, +0xEE,0x7E,0x9F,0xBA,0xFE,0xBF,0x8F,0xEF, 0xFE,0xFE,0xF9,0xFF,0xFA,0x7F,0xFE,0x7E, +0xBF,0xAF,0xFB,0x96,0xFD,0x9F,0xEF,0x5E, 0x65,0xBE,0xEF,0x5B,0xB6,0xFF,0xBE,0xE3, +0xFF,0xB5,0xBF,0xFF,0xFD,0xFF,0x7F,0xFF, 0xEF,0xDF,0xFE,0xFF,0xBF,0xFB,0xFE,0xFF, +0xBF,0xCF,0xFF,0xFF,0xFF,0xFD,0x9B,0xFF, 0xFE,0xFB,0xFE,0xDF,0xFF,0x7F,0xFF,0xF7, +0xFE,0xFF,0xDF,0xFB,0xFB,0xFE,0xFF,0xFF, 0xFF,0xFF,0xFF,0xB7,0xFE,0xFA,0xFF,0xAB, +0xEF,0xFF,0xFD,0xB5,0x7B,0x7F,0xFB,0xF7, 0xFD,0xFF,0xFF,0xDD,0xFF,0xEF,0x8F,0xFF, +0x2F,0xFF,0xFB,0x7C,0xFF,0x3F,0xDF,0x73, 0xEB,0xFE,0x3F,0xFF,0xEF,0xFB,0xFE,0xFF, +0xEF,0xFD,0xFF,0xBF,0xFD,0x0F,0xFF,0xFF, 0xFF,0xF5,0xF9,0xFF,0x7F,0xD7,0xFD,0xFF, +0xDF,0xFF,0xF7,0xFB,0xFF,0x7F,0xBF,0xFF, 0xFF,0xF0,0x9F,0xFF,0xFE,0x7F,0x8B,0xE3, +0xF9,0xDE,0x27,0x9B,0xE6,0xBE,0x7F,0x9B, 0xC3,0xF8,0xDE,0x7F,0x9D,0xE7,0xFE,0x7F, +0xFF,0xFF,0x5F,0xD7,0xFF,0xFF,0xFF,0x4F, 0xFB,0xFF,0xFF,0x7F,0xFF,0xAF,0xFF,0x9F, +0x7F,0xFB,0xFF,0xE8,0xFF,0xFF,0xFE,0xBF, 0xAF,0xFF,0xFF,0xFE,0xBF,0xEF,0xF7,0xFF, +0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF, 0xFC,0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xFF, +0xFD,0x3F,0xCF,0xFF,0xFF,0xFF,0xFF,0xF7, 0xFF,0xFD,0x7F,0xFF,0xFF,0x93,0xFF,0xFF, +0x7A,0xDF,0xF7,0xFF,0xFF,0x7B,0x7F,0xB7, 0xEF,0xFF,0xFF,0xFD,0xBF,0xFD,0xFB,0xFF, +0xF7,0xFF,0xD7,0xFF,0xFF,0xFF,0xFC,0x9F, 0x6F,0xCB,0xFF,0xF4,0xBB,0xDF,0xD6,0xFD, +0xBF,0x2F,0xD3,0xF7,0xFF,0xDF,0xFF,0xCF, 0xFF,0xFA,0xBE,0xBD,0xAF,0x6A,0xDA,0xBE, +0xBB,0xAB,0x3A,0xBE,0x2D,0xAE,0xEB,0xDA, 0xF6,0x3F,0xAD,0xF5,0xDD,0xFF,0xCF,0xF1, +0xFF,0xF9,0x7F,0xFF,0x73,0xFE,0xFF,0xCF, 0xC3,0xF4,0xF7,0x2F,0xF3,0xFF,0xFC,0xFF, +0x7C,0x1F,0xFF,0x3F,0x4F,0xFF,0x7E,0xFF, 0xEF,0xBD,0xF6,0xFE,0xFF,0x2B,0xEF,0xDC, +0xFB,0xFD,0xFF,0xFB,0xFF,0xEA,0x7B,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFB,0xF7,0xDF,0xFF, +0xE3,0x7D,0xFF,0xB7,0xFF,0xBF,0xFF,0xFF, 0xDF,0xFF,0xF8,0xFF,0xBF,0xFF,0xBF,0xEB, +0xE7,0xFA,0xFE,0x3D,0xBF,0xE9,0xFC,0xBF, 0xFF,0xFA,0xFB,0xFE,0xFF,0xFF,0xFF,0xD9, +0xFF,0xFF,0xFF,0xF6,0x7F,0xFF,0xF6,0x7D, 0xFF,0xDF,0xCF,0xFD,0xBF,0xFB,0xEF,0x7E, +0xFF,0x7F,0xFF,0xFF,0xD3,0xFF,0xFD,0xFB, 0xFF,0xFB,0xFF,0xFF,0xFF,0xEF,0xFF,0xBF, +0xFE,0xFF,0xF7,0xEF,0xFF,0xFF,0xFF,0xFB, 0xFF,0x87,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF, +0x7B,0xFE,0xFF,0xFE,0x3B,0xF7,0xF7,0xFF, 0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF, +0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xF7, 0xFF,0xFF,0xAD,0xFF,0xFE,0xF7,0xFF,0xFF, +0x5F,0xFF,0xFF,0xDF,0xFF,0xFD,0xFF,0xF5, 0xFF,0xDF,0xFF,0xBD,0xFF,0xE9,0xFF,0xC7, +0xF3,0xFF,0xFF,0xF7,0xFF,0xF3,0xFF,0xF8, 0x3B,0xFF,0xFF,0x7B,0xDF,0xBF,0xFB,0xEF, +0xFB,0xFF,0xFB,0xF7,0xF7,0xBB,0xFF,0xFF, 0xFF,0xFF,0xFB,0xFF,0xFE,0x7F,0xF3,0x7F, +0x5E,0xB7,0xBF,0xFD,0x7F,0xFF,0xF9,0x7F, 0xFB,0xFF,0xEB,0xFD,0x7F,0x7F,0xFF,0xEF, +0xFB,0xE0,0x3F,0xFE,0xBF,0xBF,0xDF,0xFF, 0x7E,0xFF,0xF7,0xFF,0xFF,0xFE,0xBF,0xFF, +0xDB,0x78,0xFF,0xFF,0xFF,0xEE,0xA1,0xBF, 0xF5,0xDE,0xFB,0xF7,0xFF,0xFB,0xFF,0xFF, +0xFF,0xFF,0xFB,0xFF,0xFF,0xD7,0xFF,0xFF, 0xFF,0xFF,0xEF,0xF0,0xFF,0xFF,0xFF,0xF3, +0xF7,0xFF,0xEF,0xFF,0xE7,0xCF,0xFF,0xFB, 0xFF,0xEF,0xFF,0xFF,0x9F,0x9F,0xEF,0xFC, +0x16,0xBF,0xFE,0xF3,0xE4,0xFF,0xFF,0xC6, 0xFF,0xE7,0xFF,0xFF,0xFD,0xFF,0xBF,0xFF, +0xFF,0x3F,0xFF,0xBF,0xD6,0xAF,0x7F,0xFE, 0x6B,0x7E,0x7F,0xFF,0xAF,0xFF,0xFF,0xBF, +0xFF,0x5F,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF, 0xFF,0xBD,0xDB,0xFF,0xFE,0x5F,0xF2,0xFF, +0xFF,0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xEF,0x7F,0xFF,0xFF,0xFF,0xFF,0xDE,0xBF, +0xFF,0xFF,0xEF,0xFB,0x77,0xFE,0xBD,0x7F, 0x5F,0xFF,0xFF,0xFF,0xDF,0x6F,0xED,0xFF, +0xFD,0xFF,0x7F,0xFD,0x6F,0xFF,0xFF,0x77, 0xDA,0xCF,0xFD,0x5F,0xFF,0xBF,0xFF,0xFF, +0xDF,0x7F,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF, 0x66,0x7F,0xFF,0xFE,0xBF,0xE7,0xBF,0xFA, +0xFF,0xFE,0xFF,0xFF,0xFF,0xDF,0xFF,0x59, 0xEF,0xFF,0xEF,0xFB,0x7F,0x89,0xFF,0xFF, +0xE9,0xFF,0x6F,0xFF,0xF5,0xFF,0xFF,0xFF, 0xFF,0xFF,0x7F,0xF2,0xF7,0xFF,0xFF,0xEF, +0xF8,0x7F,0xFB,0xFF,0xFD,0xFF,0xFF,0xD9, 0xFF,0xEF,0xBB,0xFF,0xFF,0xFF,0xBF,0xEF, +0xDE,0xFF,0xFF,0x9F,0x7F,0xDF,0xFF,0xF7, 0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xAF, +0xFF,0xFF,0xF7,0x3F,0xEB,0x9F,0xFE,0x7F, 0x9E,0x7F,0x9F,0xFE,0x87,0xFF,0xED,0xDB, +0x56,0xFF,0xBF,0xAF,0x0B,0xD2,0xFF,0xEF, 0xDB,0x6E,0x7D,0xBD,0x6F,0xF8,0xFE,0x3F, +0xFA,0x5B,0xFF,0xFD,0xBF,0xEF,0xFF,0xBF, 0x6F,0xDB,0xE6,0xFF,0xFF,0x3F,0xFF,0xDF, +0xFE,0xFF,0xFF,0xFF,0xFF,0xDA,0x3F,0xFF, 0xFB,0xFE,0xFE,0xFF,0xFF,0xDF,0xF7,0xBD, +0xFF,0xFD,0xFF,0xFE,0xFF,0xFB,0xFF,0xFF, 0xFF,0xFF,0xF1,0x5F,0xFD,0x9F,0xDF,0xFD, +0xFF,0xFD,0x7F,0xFF,0xFF,0xFF,0xFF,0x76, 0xFA,0xFF,0xFF,0x7F,0xE3,0xF8,0xFF,0xAE, +0xFF,0xFB,0x7E,0x9D,0x73,0xFF,0xFA,0x7F, 0xDF,0xFF,0xFF,0x7F,0xFF,0xFB,0xCD,0xFF, +0x7F,0xEF,0xFB,0xFF,0xFD,0xFF,0xF7,0x7F, 0x7F,0xEF,0xFF,0xED,0xFF,0xFF,0xFF,0xB5, +0xFF,0xBF,0xFF,0xBF,0xFD,0xEF,0xDB,0xF7, 0xFF,0x93,0xFF,0xEF,0xE2,0xF9,0xBE,0x7F, +0x8B,0xE7,0xF9,0xFE,0x6B,0xE7,0xF9,0xFE, 0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x47,0xFF, +0xFF,0xFD,0xFF,0x9F,0xFF,0xD7,0xFF,0xFF, 0xFF,0xFF,0xF5,0xFF,0x9F,0xFF,0xF7,0xFE, +0xFF,0xBF,0xFE,0x6F,0xFF,0xFF,0xFB,0xFF, 0xFF,0xFF,0xAF,0xFF,0xFF,0xFF,0x7F,0xFB, +0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, 0xDF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xDF, +0xFF,0xFF,0xFF,0x5F,0xFF,0xFF,0xFF,0xFF, 0x5F,0xFB,0xFE,0xFF,0xF8,0x37,0xFF,0xFF, +0xEF,0xFF,0x7F,0xFE,0xBF,0xFF,0xFF,0xFE, 0xBF,0xFF,0xFF,0x7F,0xFF,0xBF,0xFD,0xFF, +0x7F,0xFA,0x7F,0xFF,0xFF,0x6F,0xFF,0xFF, 0x7D,0xFF,0xCF,0xFF,0xFF,0xFF,0x4F,0xFF, +0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0xBF, 0xFF,0xAE,0xEB,0xFA,0xFE,0xBB,0xAD,0xEB, +0xFA,0xF7,0xAF,0x6B,0xFA,0xF6,0xBF,0x25, 0xE9,0xF2,0x7F,0x45,0xFF,0xFF,0xFD,0xF7, +0xF7,0xBF,0xFF,0xDF,0xFF,0xFF,0xBF,0xFB, 0xFF,0xDF,0xF3,0xFF,0xF7,0x3F,0xCF,0xFF, +0xA1,0xFF,0xFF,0xBF,0xE7,0xFF,0xFF,0x7F, 0xFF,0x3D,0xFF,0xFF,0xFF,0xF7,0xFF,0x2F, +0xFF,0xFB,0xF5,0x7F,0xFE,0x57,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7, +0x3F,0xFF,0xFE,0xFF,0xFF,0xFF,0xFD,0xFE, 0xF7,0xEE,0xAF,0xFE,0xEE,0xE7,0xFA,0xFF, +0xFE,0x9D,0xF9,0x5E,0xFE,0xFF,0xEB,0xFF, 0xFF,0xDF,0xA7,0xFF,0xFF,0xFF,0xFC,0xDB, +0xFF,0xFF,0xFF,0x7E,0xFB,0xFF,0xFF,0xEF, 0xFB,0xFD,0xFF,0xDB,0xFF,0xFF,0xFF,0xEF, +0xFF,0xFF,0xFF,0xFD,0xBF,0xFE,0xBF,0xFF, 0x6F,0x7F,0xFF,0xF7,0xFF,0xFF,0xF9,0xFF, +0xF7,0xFF,0xBF,0xDE,0xF7,0xFF,0xFF,0xFF, 0xFA,0x7F,0xFD,0xBF,0x5F,0xFF,0xFF,0xBF, +0xFF,0xED,0xFF,0xF7,0xBF,0xFF,0xFF,0xEF, 0xFF,0xDF,0xFF,0xFF,0xFF,0xE6,0xFF,0xFB, +0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEB,0xFF, +0xFD,0xFF,0xF5,0xFF,0xF6,0x7F,0xDF,0xBD, 0xCF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF, +0xFF,0xF9,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3, 0xFF,0xEE,0xBF,0xFF,0x7D,0xEF,0xFE,0xFF, +0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFE, 0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xB5,0xAE, +0xFF,0xFF,0xB6,0xFE,0xBF,0xFF,0xFF,0xBF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0x27,0xFF,0xEF,0xFE,0x7F,0xDF,0xFF, 0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFD,0xFF,0xF7,0xF9,0x9F,0xFF, 0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F, +0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0x0F,0xFF,0xE7,0xBF,0xFE, +0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFC,0xBF, 0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xC4, +0x6B,0xFF,0x29,0x1F,0xFB,0xAF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xEF,0x1B,0xFE,0xFF,0xFC, +0x6F,0xFF,0xFF,0xFD,0x6A,0xF7,0xD7,0xF5, 0xBF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFE,0xBF,0xFF,0xFF,0xFA,0xFF,0xFF,0xF7, 0xFB,0xDD,0xBF,0xFF,0xE7,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x7F,0xFF, 0xFF,0xF5,0xFF,0xFF,0xF7,0xFD,0xB3,0xEF, +0xFD,0x7E,0x5D,0xFF,0xFD,0xFF,0xFF,0xFF, 0xFD,0x7F,0xD2,0xF5,0xFB,0x7E,0xCB,0xB7, +0xFF,0xFF,0xFF,0xC6,0xFF,0xFD,0xEE,0x63, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xFD,0x65, +0x5B,0xDF,0xFF,0xD5,0xFF,0xFF,0xFF,0xF6, 0xE7,0xBF,0xF7,0xA9,0xFF,0xFF,0xED,0xFF, +0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,0xFF,0xFF, 0xAF,0xFF,0xFF,0xFF,0xF8,0x1B,0xFF,0xE3, +0xD0,0xBF,0xFF,0xE1,0xFF,0xFF,0xFF,0xFF, 0xFF,0xD7,0xFF,0xFF,0xFF,0x5F,0xFF,0xFF, +0xFF,0xFF,0xAF,0xFF,0xDB,0x76,0xBF,0xFF, 0x7F,0xFF,0xBF,0xEF,0xFE,0xFF,0xBF,0xEF, +0xFB,0xFE,0xFF,0xFF,0xFF,0xBF,0xF2,0x7F, 0xFF,0x9F,0xFE,0xBD,0xFE,0x7F,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xF7,0x3F,0xEC,0x7F,0xF6,0x95,0xBB, +0xEF,0xF8,0xFE,0xFC,0xBF,0x2F,0xDA,0xFC, 0xBF,0x2F,0xCB,0xF2,0xFC,0xBF,0xEF,0xFF, +0xA9,0xBF,0xCF,0xFB,0xFF,0xFF,0xFF,0xFE, 0xDD,0xB7,0x6D,0xF6,0xD9,0xB6,0x6D,0x9B, +0x76,0xD9,0xBF,0xFB,0xFD,0xA3,0xFF,0xBF, 0xEF,0xFF,0xEF,0xFF,0xFF,0xFF,0x7F,0xDF, +0xFD,0xEF,0x7B,0xDE,0xF7,0xFD,0xEF,0x7F, 0xFF,0xFF,0x05,0xFF,0xFA,0xFE,0x7F,0xEF, +0xE3,0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xFF, 0xFF,0x5F,0xFF,0xFF,0xFD,0x7F,0xFB,0xAF, +0xFF,0x63,0xC8,0xFF,0xBF,0xEF,0xFF,0xFF, 0xFA,0x7F,0xFF,0xFF,0xFF,0xFE,0x9F,0xF7, +0xFF,0xFA,0xBF,0xFE,0x9F,0xFB,0x7F,0xFF, 0xFF,0xEF,0xD7,0xFF,0xFF,0xF5,0xFF,0xFF, +0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xBF,0xFF, 0xF9,0xBF,0xFF,0xBE,0x27,0x9F,0xE7,0xF9, +0xFE,0x7F,0x8B,0xE7,0xFE,0x7F,0x9F,0xE2, 0xF9,0xFE,0x7F,0x9F,0xE7,0xF1,0x7F,0xFF, +0xFF,0xFF,0xFB,0xFE,0xFF,0xFF,0xFF,0xD7, 0xFF,0xFF,0xFF,0xFF,0xF5,0xFF,0xFF,0xFF, +0xD7,0xFF,0xFA,0xFF,0xFE,0xFF,0xFF,0xFF, 0xFD,0xFF,0xFF,0xFF,0xAF,0xF7,0xFF,0xFF, +0xFF,0xEB,0xFF,0xFF,0xFF,0xAF,0xFF,0xC4, 0xFF,0xF7,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF, +0xFF,0x5F,0xFF,0xFF,0xFF,0xFF,0xD7,0xFF, 0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,0xFB,0x7A, +0xDF,0xF7,0xFD,0xFF,0xFF,0xFE,0xBF,0xFF, 0xFF,0x7F,0xFF,0xAF,0xFF,0xFF,0xFF,0xF7, +0xEF,0xE3,0xFF,0xDD,0xD2,0xFF,0xDF,0xFF, 0xFF,0xF2,0xFC,0xBF,0xCB,0xF6,0xFD,0xBF, +0x2F,0xCB,0xFF,0x7F,0xDF,0xDE,0xAF,0xFF, 0xDA,0xEE,0xBF,0xAF,0xE9,0xFA,0xF4,0xBD, +0xAF,0x5A,0xAE,0xBB,0xAB,0x6B,0xDA,0xDE, 0xBF,0xAD,0xD7,0x5E,0xFF,0xFF,0xBF,0xFC, +0xFF,0xDF,0xFD,0xFF,0xFF,0xFF,0xFF,0xDF, 0xF7,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFA, +0x1F,0xFF,0xFE,0xFB,0xEF,0xBF,0xFD,0xFF, 0xFD,0xBD,0x77,0xFF,0xFF,0xFF,0xFF,0x9D, +0xEF,0xFF,0xFF,0xFF,0xEF,0x7D,0xFF,0xFB, 0xFE,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEE, 0xBF,0xE4,0xFB,0xFF,0xFE,0x3F,0xFE,0xFF, +0xFF,0xFF,0xFF,0xAF,0xEA,0xFE,0xBF,0xAF, 0xEB,0xFA,0xFE,0xFF,0xFF,0xFF,0x55,0xF6, +0xFF,0xFE,0xF7,0xFF,0x7F,0xFF,0xEB,0xF7, 0x5F,0xC5,0xFD,0x7F,0x5F,0xD7,0xF5,0xFF, +0x6F,0xFB,0xFF,0x8A,0xFF,0xFF,0xFF,0xFF, 0xEB,0xFF,0xFF,0xFF,0xFF,0xFB,0xBF,0xBF, +0xEF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF, 0x77,0xDF,0xFB,0xFF,0xFD,0x7F,0xEF,0xFF, +0xFF,0xFF,0xBF,0x7F,0xFF,0xDF,0xBF,0xFF, 0xFB,0xFF,0xFF,0xFF,0xFE,0xEF,0xDF,0xFF, +0xFE,0xFF,0x9F,0xEF,0x7D,0xFF,0xF7,0xFF, 0x7F,0xFF,0xFF,0xDF,0xF7,0xFD,0xFF,0xEF, +0xDF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFB, +0xFD,0xFF,0xBF,0xDF,0xD1,0xFF,0xF8,0x3B, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0x7E,0xDB,0xFD,0xFF,0x77,0xDB,0xB7,0x7D, 0xBF,0xFB,0xFF,0xF8,0x7F,0xED,0x7B,0x5E, +0xFF,0xFE,0xFF,0xFF,0x4F,0xD7,0xFD,0x7F, 0xDF,0xD7,0xF5,0xFF,0x7F,0xFF,0xFF,0xFF, +0xF2,0x3F,0xFE,0xFF,0xBF,0xFF,0xFF,0xFF, 0xFF,0xBF,0xEF,0xFE,0xFF,0x3B,0xEE,0xFF, +0xFC,0xEF,0xFF,0xFF,0xFF,0x85,0xFF,0xFD, 0xFE,0xFF,0xF5,0xFF,0xFF,0xFE,0xFF,0xDF, +0xFB,0xFF,0x5F,0xBF,0xFF,0xFD,0xFF,0xFF, 0xFF,0xFF,0xA8,0xFF,0xFF,0x9F,0x9E,0xFF, +0xFF,0xFF,0x7F,0xF3,0xFF,0xFF,0xCF,0xFF, 0xF7,0xFD,0xFF,0x7F,0xFF,0xFF,0xFC,0x16, +0xBF,0xCF,0xA3,0xE5,0xEF,0x7F,0xFF,0xF3, 0xE4,0xFF,0xCF,0x93,0xFC,0xFF,0x3F,0xCF, +0xFF,0xFF,0xFF,0xD6,0x0F,0x7D,0xBF,0x6E, 0xFB,0xF4,0xFC,0xAF,0x6D,0xDB,0x77,0xB7, +0x6D,0xDB,0xF6,0xFD,0xBF,0xFF,0xFF,0xFF, 0xBF,0x9B,0xFA,0xDE,0xB7,0xB7,0xED,0xF9, +0x7E,0xB7,0xAC,0xEB,0xD6,0xB3,0xAD,0xEB, 0x7A,0xDF,0xFF,0xFF,0xFF,0xD8,0xBF,0xFF, +0xB7,0xED,0x9F,0x6F,0xDD,0xF7,0x68,0xDB, 0x37,0xB3,0x6C,0xDB,0x36,0xCD,0xB3,0x7F, +0xFF,0x7F,0xF5,0x6F,0xFD,0xEF,0x79,0x3D, 0xF7,0x93,0xE4,0x7A,0x9E,0xAD,0xEA,0x7A, +0x9E,0xF7,0xBD,0xEF,0xFF,0xFF,0xFF,0x76, 0x7F,0xFB,0xC6,0xFF,0xBB,0xEF,0xDA,0xFE, +0xFD,0xBF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFF,0xFF,0xFB,0xFF,0xA5,0xFF,0xFD,0xAB, +0x6F,0x78,0xDE,0x17,0x8F,0x79,0xDF,0xFD, 0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0xFF,0xFB, +0xFF,0xFB,0xFF,0xEF,0xFB,0xEF,0xFB,0xFE, 0xFF,0xBB,0xDA,0xF3,0xEF,0x3B,0xCE,0xF3, +0xBC,0xEF,0x3F,0xCF,0xDF,0xFF,0xB7,0xFF, 0xFF,0xFF,0xCF,0x73,0xFF,0xBF,0xEF,0xFF, +0xF3,0xFF,0x3F,0xCF,0xF3,0xFC,0xFF,0x3D, 0xCF,0x9F,0xFE,0x07,0xFF,0xAF,0xEB,0xFE, +0xFD,0xBF,0xEF,0xEB,0xFA,0xFF,0xAF,0xEB, 0xFA,0xFE,0xBF,0xAF,0xFB,0xFE,0x3F,0xFB, +0x9B,0xFF,0x7F,0xDF,0xFF,0xF3,0xFE,0xFF, 0xDE,0xF7,0xBF,0x7B,0xDE,0xF7,0xBD,0xEF, +0x7B,0xFE,0xFF,0xFF,0xDF,0x3F,0xFE,0xFF, 0xB7,0xFF,0xEF,0xF7,0xFF,0xBF,0xED,0xFE, +0xDF,0xB7,0xED,0xFB,0x7E,0xDF,0xFF,0xFF, 0xFF,0xFD,0x5F,0xEF,0xEB,0xFA,0xFE,0xF5, +0xBF,0x6F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xF8,0xFF,0xA8,0xFF, +0xFF,0xBF,0xEF,0xFB,0x6A,0xFB,0xB7,0xEF, 0xFB,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF, +0xEF,0xFB,0xFF,0xE0,0xFF,0xFF,0xFD,0x7F, 0x5C,0xD7,0x7D,0xDF,0xF3,0x5C,0xF5,0xCD, +0x73,0x5E,0xD7,0xB5,0xFD,0x7F,0xEF,0xFF, 0xDB,0xFF,0xFF,0xE2,0xF8,0xBE,0x2F,0x8F, +0xE7,0xF8,0xBE,0x6B,0xE2,0xF8,0xBE,0x2F, 0x8B,0xE2,0xF9,0xFE,0x7F,0xE7,0xFF,0xD7, +0xF5,0xFD,0x7F,0xFF,0xF7,0xF5,0xFD,0x7F, 0xD7,0xF5,0xFD,0x7F,0x5F,0xD7,0xF5,0xFF, +0xFF,0xFF,0x8F,0xFF,0xAF,0xEB,0xFA,0xFF, 0xFF,0xBF,0xEB,0xFA,0xFF,0x2F,0xEB,0xFA, +0xFE,0xBF,0xAF,0xEB,0xFF,0xFF,0xFE,0x5F, 0xFF,0x5F,0xFF,0xFF,0xFD,0xFF,0xFF,0xD7, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xBF,0xFE,0xB7,0xFD, +0xFF,0x7E,0xDF,0xF7,0xAD,0xFF,0x7F,0xF7, 0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F, +0xF6,0x7F,0xFF,0xFF,0xFF,0xDB,0xF6,0xFC, 0xAF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xEC,0xBF,0xFF, 0xAF,0xEB,0xFA,0xF6,0xAB,0x8F,0xEB,0xFA, +0xF7,0xA5,0xEB,0xFA,0xBE,0xBF,0xAF,0xEB, 0xFA,0xFF,0x6D,0xFF,0xFF,0x7F,0xDF,0x33, +0xDD,0xFF,0x7F,0xFE,0xF7,0xFC,0x7F,0xFB, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA9, +0xFF,0xFD,0xFF,0xFF,0xFE,0xFF,0xFF,0xDF, 0xFF,0xFF,0xEF,0xEF,0xFD,0xFF,0x7F,0xFF, +0xFF,0xFF,0xFF,0xFE,0xA7,0xFF,0xFF,0xFF, 0x77,0xDF,0xF7,0xFD,0x9F,0x7F,0xFE,0x77, +0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xAF,0xBF,0xAF,0xFF,0xF9,0xBE,0xBF, +0x8F,0xFB,0xFE,0xFE,0xEF,0xFB,0xFE,0xFF, 0xBF,0xEF,0xFB,0xFF,0xFF,0xFD,0xDF,0x6F, +0xEF,0xFF,0x7F,0xFF,0xBF,0xBF,0xDF,0xFF, 0xFC,0xFF,0xDF,0xF7,0xFD,0xEF,0x7F,0xDF, +0xFF,0xFF,0xFF,0x3F,0xF6,0xFF,0xCF,0xFF, 0xDB,0xFB,0xF7,0xFF,0xEB,0x7A,0xFF,0xFF, +0xFF,0xBF,0xEF,0xFB,0xFF,0xFF,0xFF,0xFE, 0x6D,0xFD,0xFF,0x5F,0xFB,0xFF,0xFF,0xF7, +0xFF,0x5F,0xF5,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xF8,0xFF,0xFB,0xFF, +0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xE7,0xF6, 0xBF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF, +0xFF,0xC9,0xFF,0xFF,0xFF,0xBD,0xFF,0xBF, 0xAF,0xEF,0xEF,0x3F,0xD1,0xFC,0x7F,0xFB, +0xC7,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3,0xFF, 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0x77,0xFF, +0xDF,0xB7,0xFD,0xF7,0xFD,0xF7,0xFF,0xFF, 0xFF,0xFF,0xFF,0x57,0xFF,0xF7,0xA5,0xFD, +0x3F,0xDF,0xBF,0xBF,0xFE,0x7F,0xFF,0xFF, 0xFF,0xDF,0xFA,0xFD,0xFF,0xFF,0xFF,0xFE, +0x87,0xFF,0xE9,0xFF,0xFE,0xEF,0xBF,0xEF, 0xFE,0xFE,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFA,0x9F,0xFF,0x3F, 0xFF,0xFD,0xFD,0x57,0xDF,0xFD,0xF3,0xFF, +0xDF,0xFD,0xFF,0x5F,0xDF,0xF5,0xFD,0xFF, 0xFF,0xF9,0x8F,0xFF,0xFF,0xFF,0xEE,0x7F, +0xFF,0xFF,0xBF,0x5E,0xFE,0xEC,0xFB,0x3F, 0x7F,0x9F,0xEF,0xF9,0xFF,0xFF,0xCD,0x6B, +0xFF,0xFF,0xFF,0xC5,0xF3,0xFC,0xFA,0x38, 0xFF,0xAF,0x3F,0xEE,0x7F,0x9F,0xFF,0xD9, +0xFF,0xFF,0xFD,0x7A,0xF7,0xFF,0xF3,0xFF, 0xAF,0x6F,0xDB,0xF2,0xB9,0xE9,0xFB,0xFF, +0xFF,0xFF,0xFE,0xFF,0xFF,0xEF,0xFF,0xFB, 0xC5,0xBF,0xFF,0xEF,0xFF,0x5E,0xB7,0xAD, +0xCD,0x79,0x7C,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0x93,0xFF,0xEF, +0xEA,0xFE,0xBF,0xEF,0x5B,0xD2,0xCD,0xF5, 0x6D,0x77,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF, +0xFF,0xFF,0x66,0xFF,0xD5,0x65,0x7D,0x5F, 0x75,0x9D,0x65,0x7F,0xD6,0xFB,0x4F,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xC7, 0xFF,0xBF,0xEF,0xFA,0xFE,0xFF,0xBF,0xEB, +0xFF,0xDF,0xFF,0x7E,0xFF,0xFF,0xEF,0xFD, 0x7E,0xD7,0xFF,0x78,0xDF,0xFF,0x5F,0xDF, +0xF5,0xBF,0x7F,0xDF,0xC5,0xFF,0x3F,0xF6, 0x7E,0xFF,0x0F,0xEF,0xF2,0x3E,0xBF,0xFF, +0xFB,0x3F,0xFF,0xFB,0x7F,0xFF,0xB3,0xFE, 0xFB,0xF6,0xFD,0xFF,0xDA,0xF7,0xFD,0xFF, +0x7F,0xDF,0xF7,0xBF,0xFF,0xFA,0x7F,0xFF, 0xFF,0xFF,0xFF,0x9F,0xFF,0xF3,0xDC,0xF9, +0xBF,0xCE,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7, 0xFF,0xFF,0xE2,0x7F,0xFE,0xFF,0xBF,0xEF, +0xEB,0xFA,0xFF,0x9F,0x67,0x1E,0xFF,0x8F, 0xE7,0xF8,0xFE,0x7F,0x8F,0xEF,0xFF,0xBD, +0xBF,0xFF,0xFB,0xFF,0xFF,0xDF,0xF7,0xFF, 0xFC,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFD,0xB3,0xFF,0xFF,0xEF, 0xFF,0xFF,0xBF,0xED,0xFF,0xFB,0xEE,0xFE, +0xFF,0xFF,0xEF,0xFF,0xFE,0xFF,0xFF,0xFF, 0xFF,0xB5,0xFF,0xB7,0xFD,0xFD,0x6E,0xFF, +0xFF,0xFE,0xFD,0x2F,0xD8,0xFE,0xBF,0x8F, 0xEB,0xF9,0xFE,0x3F,0xFF,0xFA,0xCF,0xFF, +0xE7,0xD9,0xFA,0xBF,0xDF,0x77,0xFC,0xFB, 0x3F,0xAB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFE, +0xFF,0xFF,0xEE,0x1F,0xFF,0xDF,0xF7,0xFF, 0xFF,0xFF,0x5F,0x97,0x35,0xBF,0x5E,0xFE, +0xBF,0xEF,0xFF,0xF7,0xFD,0xFF,0xFF,0xFA, 0xBF,0xFF,0xBE,0x6F,0x9F,0xE7,0xF8,0xBE, +0x2F,0x8B,0x66,0x94,0x7D,0x9D,0xE7,0xF9, 0xFE,0x7F,0x9F,0xE7,0xF1,0x7F,0xFF,0xFF, +0xFF,0xF7,0xF5,0xFD,0x7F,0x5F,0xFB,0xFD, 0x9E,0xFF,0xFB,0xFE,0xFF,0xFF,0xEF,0xFF, +0xFF,0xA0,0xFF,0xFF,0xFF,0xBF,0xEF,0xEB, 0xFA,0xFE,0xBF,0xB7,0xF7,0xF7,0xFF,0xFF, +0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF, 0xFD,0xFF,0xFF,0xFF,0xD7,0xFF,0xFF,0xFF, +0x7F,0xF5,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF, 0xBF,0xFF,0xFF,0xAB,0xFE,0xFB,0xFE,0xFF, +0xF7,0xAF,0xFF,0xFF,0xDE,0xF7,0xEB,0x5F, 0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF,0xFF, +0xB3,0xFF,0xC9,0xFE,0xFF,0xFF,0xFF,0xFF, 0xD6,0xFF,0xFF,0xCB,0xFF,0xFF,0xDF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFC,0x8F,0xFF,0xBA, 0xBE,0xBF,0xAF,0xEB,0x78,0xFE,0xB7,0xAD, +0x3A,0xFE,0xB7,0xAF,0xEB,0x7A,0xFE,0xBF, 0xAF,0xFF,0x9F,0xFF,0xFF,0xDF,0xFC,0xFF, +0xFF,0xFE,0xC3,0xFE,0xFF,0xFF,0x33,0xFC, 0xFF,0xBF,0xDF,0xF3,0xFF,0xFF,0xBB,0x9F, +0xFF,0xFF,0xFF,0xEB,0xDF,0xFF,0xFF,0xAF, 0xF7,0x6F,0xF9,0xBF,0xEF,0xFD,0xFF,0xFF, +0xFF,0xFF,0xFF,0xE3,0x7F,0xFF,0xFF,0xFF, 0xFB,0xFF,0xFF,0xBF,0xFD,0xFB,0xF7,0xFF, +0xDF,0xF7,0xFF,0xFE,0xEF,0x5F,0xBD,0xFF, 0xFA,0xFF,0xF8,0xFF,0xBF,0xAF,0xFB,0xFE, +0xFE,0x3F,0xEF,0xE8,0xFF,0xDF,0xF3,0xFD, 0xFF,0xFF,0xFF,0xFF,0xFF,0xED,0xFF,0xFB, +0xFD,0xFF,0xAF,0xFF,0xFF,0xFE,0xFE,0xBF, 0xDB,0xFF,0xFF,0xFF,0xBF,0xFF,0xDF,0xFF, +0xFD,0xFF,0xCB,0xFF,0xFF,0xFF,0xFF,0xFF, 0xBF,0x6F,0xFF,0x7F,0xB7,0xB3,0xFF,0xFF, +0xDF,0xFF,0xFB,0xEF,0xFF,0xFF,0xFF,0x07, 0xFF,0xFB,0xFF,0xFF,0xFF,0xED,0xFF,0xF5, +0x7C,0xFF,0x7F,0xFE,0xFF,0xFF,0xEF,0xCF, 0xFF,0xFB,0xFF,0xFF,0x2F,0xFF,0xFF,0xFF, +0xFF,0xF3,0xFF,0xFB,0xFF,0xFE,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF, +0xFD,0x1B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFE,0x7C,0xFF,0xFF,0xFF,0xFF, +0xEF,0xFF,0xFF,0xFF,0xFF,0xFB,0xBF,0x7F, 0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xDB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, 0xFF,0xFF,0xF0,0x7F,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xDF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,0xFE, +0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xEF,0xFE,0xFF,0xBF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xEF,0xFA,0xB5,0xFF,0xFF,0xFF, 0xF7,0xF7,0xFF,0xFF,0xFF,0xFF,0xDF,0xFB, +0xFC,0xFF,0xFF,0xFE,0xFF,0x7F,0xDF,0xBF, 0xFF,0xCB,0xBF,0xF9,0xFE,0x7F,0x9F,0xE7, +0xF9,0xFE,0x7F,0x97,0xE1,0xFE,0x79,0x9F, 0xE7,0xFD,0xFE,0x7F,0xDF,0xFE,0x37,0xFF, +0xFB,0xDE,0xDE,0xBD,0xEF,0xF3,0xFE,0xFB, 0xAF,0xEB,0xFE,0xFF,0xFF,0xCF,0xFF,0xFE, +0xFF,0xBF,0xFF,0x8F,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xE7,0xF9,0x5E,0x7F,0xEF,0xFB, +0xDA,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFD, 0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF, +0xFF,0xFF,0x7F,0xFF,0xFF,0xF7,0xFB,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFC,0x3F,0xFF,0xBF, +0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0x7B,0x7F, 0xBF,0xEF,0xFB,0xFE,0xFF,0xB5,0xEF,0xFB, +0xBF,0xFA,0x7F,0xFC,0xFF,0x3F,0xCF,0xF3, 0xFC,0xFF,0x3F,0xCF,0xBC,0xFF,0x3F,0xEF, +0xF3,0xFC,0xFE,0x3F,0xCF,0xFF,0xEE,0xEF, 0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0x6A,0xD7, +0xB7,0xFB,0xF8,0xFF,0xB7,0xEF,0xBA,0xFE, 0xFF,0xBF,0x7F,0xE9,0xFF,0xF9,0x7E,0x5F, +0x97,0xE5,0xF9,0xFE,0x7F,0xBF,0xF9,0x7E, 0x5F,0x9F,0xE5,0xFB,0xFE,0x5F,0xB7,0xFF, +0xA3,0xFF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7, 0xFD,0xFF,0x5E,0xF7,0x7D,0xFF,0x77,0xDF, +0xF7,0xFD,0xFF,0x7F,0xFF,0xD7,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xDF,0xFB,0x7F, +0xFF,0xFF,0xEF,0xFF,0xFE,0xFB,0xFF,0xFF, 0xBF,0xFE,0x8F,0xFF,0xDF,0xF7,0xFD,0xFD, +0x7F,0xDF,0xF7,0xFD,0x3E,0xDF,0xF5,0xBD, 0xFF,0x7F,0xDF,0xF7,0xFD,0xF7,0xFF,0x9F, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFD,0xFF,0xBE,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFD,0x3F,0xFF,0xDF,0xF7, 0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0xCF, +0x77,0xFC,0xFF,0x5F,0xDF,0xF7,0xFD,0xFF, 0xF4,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFD,0xFF,0xFF,0xFF,0xEE,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xED,0xFB,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xE9,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFB,0xFF,0xFF,0xFF,0xD3,0xFF,0xFF, +0xBF,0x3F,0xFB,0xFF,0xFF,0xFF,0xFB,0xF3, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xF7, 0xFF,0xFF,0xFF,0xFF,0x17,0xFF,0xFF,0xFF, +0xDF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF, 0xDF,0xDF,0xFF,0xFD,0xFF,0xFF,0xDF,0xF7, +0xFF,0x4F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFD, +0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0x9F,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF, 0xFF,0xFF,0x7A,0x3F,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF2, +0x7F,0xFF,0xFB,0xFE,0xFF,0xBF,0xEF,0xF8, 0xFE,0xFF,0xBF,0xFB,0xFE,0xFF,0x8F,0xEC, +0xFB,0xFE,0xFF,0xBF,0xF8,0xF7,0xFE,0xFF, 0xBF,0xEF,0xFB,0xFE,0xFD,0xBF,0xCF,0xEC, +0xFF,0x3F,0xEF,0xDB,0xF8,0xFF,0xBF,0xCF, 0xFF,0xF9,0xFF,0xFF,0xBF,0xFF,0xFB,0xFF, +0xFF,0xFF,0xEF,0xFB,0xDF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xBB,0xFF, +0xEF,0xFB,0xFE,0xEF,0xBF,0xEE,0xEB,0xFB, 0xFE,0xFF,0xEF,0xFE,0xEE,0xBF,0xFE,0xEB, +0xFF,0xEF,0xFF,0x17,0xFF,0x7E,0xEB,0xBB, 0xFE,0xBF,0xBE,0xFB,0xEF,0x5B,0xF7,0xBD, +0xFB,0xCF,0xBF,0xBF,0xBB,0xFB,0x7E,0xCC, 0xEF,0xFF + +}; diff -ur --new-file old/linux/drivers/usb/dabusb.c new/linux/drivers/usb/dabusb.c --- old/linux/drivers/usb/dabusb.c Fri Jan 7 20:43:09 2000 +++ new/linux/drivers/usb/dabusb.c Sat Jan 22 01:49:11 2000 @@ -44,8 +44,7 @@ #include "usb.h" #include "dabusb.h" -#include "bitstream.h" -#include "firmware.h" +#include "dabfirmware.h" /* --------------------------------------------------------------------- */ #define NRDABUSB 4 diff -ur --new-file old/linux/drivers/usb/dc2xx.c new/linux/drivers/usb/dc2xx.c --- old/linux/drivers/usb/dc2xx.c Thu Jan 20 18:47:10 2000 +++ new/linux/drivers/usb/dc2xx.c Tue Jan 25 20:37:21 2000 @@ -148,7 +148,7 @@ * they matter in the application protocol. */ for (retries = 0; retries < MAX_READ_RETRY; retries++) { - unsigned long count; + int count; int result; if (signal_pending (current)) { @@ -216,7 +216,7 @@ } while (thistime) { int result; - unsigned long count; + int count; if (signal_pending (current)) { if (!bytes_written) diff -ur --new-file old/linux/drivers/usb/devices.c new/linux/drivers/usb/devices.c --- old/linux/drivers/usb/devices.c Fri Jan 21 00:00:16 2000 +++ new/linux/drivers/usb/devices.c Tue Jan 25 20:37:21 2000 @@ -309,7 +309,7 @@ return start; } -static char *usb_dump_desc(char *start, char *end, const struct usb_device *dev) +static char *usb_dump_desc(char *start, char *end, struct usb_device *dev) { int i; @@ -365,7 +365,7 @@ /*****************************************************************/ -static char *usb_device_dump(char *start, char *end, const struct usb_device *usbdev, +static char *usb_device_dump(char *start, char *end, struct usb_device *usbdev, int bus, int level, int index, int count) { int chix; diff -ur --new-file old/linux/drivers/usb/firmware.h new/linux/drivers/usb/firmware.h --- old/linux/drivers/usb/firmware.h Sat Dec 18 01:49:45 1999 +++ new/linux/drivers/usb/firmware.h Thu Jan 1 01:00:00 1970 @@ -1,3213 +0,0 @@ -//$Id: firmware.h,v 1.1 1999/12/17 08:55:05 fliegl Exp $ -static INTEL_HEX_RECORD firmware[] = { -{ 2, - 0x0, - 0, - {0x21,0x57} -}, -{ 3, - 0x3, - 0, - {0x02,0x01,0x66} -}, -{ 3, - 0xb, - 0, - {0x02,0x01,0x66} -}, -{ 3, - 0x13, - 0, - {0x02,0x01,0x66} -}, -{ 3, - 0x1b, - 0, - {0x02,0x01,0x66} -}, -{ 3, - 0x23, - 0, - {0x02,0x01,0x66} -}, -{ 3, - 0x2b, - 0, - {0x02,0x01,0x66} -}, -{ 3, - 0x33, - 0, - {0x02,0x03,0x0f} -}, -{ 3, - 0x3b, - 0, - {0x02,0x01,0x66} -}, -{ 3, - 0x43, - 0, - {0x02,0x01,0x00} -}, -{ 3, - 0x4b, - 0, - {0x02,0x01,0x66} -}, -{ 3, - 0x53, - 0, - {0x02,0x01,0x66} -}, -{ 3, - 0x5b, - 0, - {0x02,0x04,0xbd} -}, -{ 3, - 0x63, - 0, - {0x02,0x01,0x67} -}, -{ 3, - 0x100, - 0, - {0x02,0x0c,0x5a} -}, -{ 3, - 0x104, - 0, - {0x02,0x01,0xed} -}, -{ 3, - 0x108, - 0, - {0x02,0x02,0x51} -}, -{ 3, - 0x10c, - 0, - {0x02,0x02,0x7c} -}, -{ 3, - 0x110, - 0, - {0x02,0x02,0xe4} -}, -{ 1, - 0x114, - 0, - {0x32} -}, -{ 1, - 0x118, - 0, - {0x32} -}, -{ 3, - 0x11c, - 0, - {0x02,0x05,0xfd} -}, -{ 3, - 0x120, - 0, - {0x02,0x00,0x00} -}, -{ 3, - 0x124, - 0, - {0x02,0x00,0x00} -}, -{ 3, - 0x128, - 0, - {0x02,0x04,0x3c} -}, -{ 3, - 0x12c, - 0, - {0x02,0x04,0x6a} -}, -{ 3, - 0x130, - 0, - {0x02,0x00,0x00} -}, -{ 3, - 0x134, - 0, - {0x02,0x00,0x00} -}, -{ 3, - 0x138, - 0, - {0x02,0x00,0x00} -}, -{ 3, - 0x13c, - 0, - {0x02,0x00,0x00} -}, -{ 3, - 0x140, - 0, - {0x02,0x00,0x00} -}, -{ 3, - 0x144, - 0, - {0x02,0x00,0x00} -}, -{ 3, - 0x148, - 0, - {0x02,0x00,0x00} -}, -{ 3, - 0x14c, - 0, - {0x02,0x00,0x00} -}, -{ 3, - 0x150, - 0, - {0x02,0x00,0x00} -}, -{ 3, - 0x154, - 0, - {0x02,0x00,0x00} -}, -{ 10, - 0x157, - 0, - {0x75,0x81,0x7f,0xe5,0x82,0x60,0x03,0x02,0x01,0x61} -}, -{ 5, - 0x161, - 0, - {0x12,0x07,0x6f,0x21,0x64} -}, -{ 1, - 0x166, - 0, - {0x32} -}, -{ 14, - 0x167, - 0, - {0xc0,0xd0,0xc0,0x86,0xc0,0x82,0xc0,0x83,0xc0,0xe0,0x90,0x7f,0x97,0xe0} -}, -{ 14, - 0x175, - 0, - {0x44,0x80,0xf0,0x90,0x7f,0x69,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} -}, -{ 14, - 0x183, - 0, - {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} -}, -{ 14, - 0x191, - 0, - {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x90,0x7f,0x97,0xe0} -}, -{ 3, - 0x19f, - 0, - {0x55,0x7f,0xf0} -}, -{ 14, - 0x1a2, - 0, - {0x90,0x7f,0x9a,0xe0,0x30,0xe4,0x23,0x90,0x7f,0x68,0xf0,0xf0,0xf0,0xf0} -}, -{ 14, - 0x1b0, - 0, - {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} -}, -{ 14, - 0x1be, - 0, - {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} -}, -{ 14, - 0x1cc, - 0, - {0xe5,0xd8,0xc2,0xe3,0xf5,0xd8,0xd0,0xe0,0xd0,0x83,0xd0,0x82,0xd0,0x86} -}, -{ 3, - 0x1da, - 0, - {0xd0,0xd0,0x32} -}, -{ 8, - 0x1dd, - 0, - {0x75,0x86,0x00,0x90,0xff,0xc3,0x7c,0x05} -}, -{ 7, - 0x1e5, - 0, - {0xa3,0xe5,0x82,0x45,0x83,0x70,0xf9} -}, -{ 1, - 0x1ec, - 0, - {0x22} -}, -{ 14, - 0x1ed, - 0, - {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0xd0} -}, -{ 14, - 0x1fb, - 0, - {0x75,0xd0,0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91} -}, -{ 13, - 0x209, - 0, - {0x90,0x88,0x00,0xe0,0xf5,0x41,0x90,0x7f,0xab,0x74,0x02,0xf0,0x90} -}, -{ 9, - 0x216, - 0, - {0x7f,0xab,0x74,0x02,0xf0,0xe5,0x32,0x60,0x21} -}, -{ 4, - 0x21f, - 0, - {0x7a,0x00,0x7b,0x00} -}, -{ 11, - 0x223, - 0, - {0xc3,0xea,0x94,0x18,0xeb,0x64,0x80,0x94,0x80,0x50,0x12} -}, -{ 14, - 0x22e, - 0, - {0x90,0x7f,0x69,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x0a,0xba,0x00} -}, -{ 2, - 0x23c, - 0, - {0x01,0x0b} -}, -{ 2, - 0x23e, - 0, - {0x80,0xe3} -}, -{ 2, - 0x240, - 0, - {0xd0,0x86} -}, -{ 14, - 0x242, - 0, - {0xd0,0xd0,0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0} -}, -{ 1, - 0x250, - 0, - {0x32} -}, -{ 14, - 0x251, - 0, - {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} -}, -{ 14, - 0x25f, - 0, - {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xab,0x74} -}, -{ 4, - 0x26d, - 0, - {0x04,0xf0,0xd0,0x86} -}, -{ 11, - 0x271, - 0, - {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} -}, -{ 14, - 0x27c, - 0, - {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} -}, -{ 14, - 0x28a, - 0, - {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} -}, -{ 13, - 0x298, - 0, - {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} -}, -{ 12, - 0x2a5, - 0, - {0x7f,0xab,0x74,0x08,0xf0,0x75,0x6e,0x00,0x75,0x6f,0x02,0x12} -}, -{ 6, - 0x2b1, - 0, - {0x11,0x44,0x75,0x70,0x39,0x75} -}, -{ 6, - 0x2b7, - 0, - {0x71,0x0c,0x75,0x72,0x02,0x12} -}, -{ 12, - 0x2bd, - 0, - {0x11,0x75,0x90,0x7f,0xd6,0xe4,0xf0,0x75,0xd8,0x20,0xd0,0x86} -}, -{ 14, - 0x2c9, - 0, - {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} -}, -{ 13, - 0x2d7, - 0, - {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} -}, -{ 14, - 0x2e4, - 0, - {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} -}, -{ 14, - 0x2f2, - 0, - {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xab,0x74} -}, -{ 4, - 0x300, - 0, - {0x10,0xf0,0xd0,0x86} -}, -{ 11, - 0x304, - 0, - {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} -}, -{ 14, - 0x30f, - 0, - {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} -}, -{ 14, - 0x31d, - 0, - {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} -}, -{ 12, - 0x32b, - 0, - {0x00,0xc0,0x86,0x75,0x86,0x00,0x75,0x6e,0x00,0x75,0x6f,0x02} -}, -{ 7, - 0x337, - 0, - {0x12,0x11,0x44,0x75,0x70,0x40,0x75} -}, -{ 6, - 0x33e, - 0, - {0x71,0x0c,0x75,0x72,0x02,0x12} -}, -{ 14, - 0x344, - 0, - {0x11,0x75,0x90,0x7f,0xd6,0x74,0x02,0xf0,0x90,0x7f,0xd6,0x74,0x06,0xf0} -}, -{ 5, - 0x352, - 0, - {0x75,0xd8,0x10,0xd0,0x86} -}, -{ 14, - 0x357, - 0, - {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} -}, -{ 13, - 0x365, - 0, - {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} -}, -{ 13, - 0x372, - 0, - {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x90,0x7f,0xa6,0x74,0x9a,0xf0,0x12} -}, -{ 12, - 0x37f, - 0, - {0x10,0x1b,0x90,0x7f,0xa6,0xe5,0x42,0xf0,0x12,0x10,0x1b,0x90} -}, -{ 13, - 0x38b, - 0, - {0x7f,0xa6,0xe5,0x43,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa5,0x74,0x40} -}, -{ 1, - 0x398, - 0, - {0xf0} -}, -{ 1, - 0x399, - 0, - {0x22} -}, -{ 13, - 0x39a, - 0, - {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x90,0x7f,0xa6,0x74,0x9a,0xf0,0x12} -}, -{ 12, - 0x3a7, - 0, - {0x10,0x1b,0x90,0x7f,0xa6,0xe5,0x44,0xf0,0x12,0x10,0x1b,0x90} -}, -{ 12, - 0x3b3, - 0, - {0x7f,0xa6,0xe5,0x45,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa6,0xe5} -}, -{ 11, - 0x3bf, - 0, - {0x46,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa5,0x74,0x40,0xf0} -}, -{ 1, - 0x3ca, - 0, - {0x22} -}, -{ 10, - 0x3cb, - 0, - {0x75,0x44,0x02,0x75,0x45,0x00,0x75,0x46,0x00,0x12} -}, -{ 9, - 0x3d5, - 0, - {0x03,0x9a,0x75,0x42,0x03,0x75,0x43,0x00,0x12} -}, -{ 2, - 0x3de, - 0, - {0x03,0x72} -}, -{ 1, - 0x3e0, - 0, - {0x22} -}, -{ 12, - 0x3e1, - 0, - {0x90,0x88,0x00,0xe5,0x36,0xf0,0x90,0x88,0x00,0x74,0x10,0x25} -}, -{ 9, - 0x3ed, - 0, - {0x36,0xf0,0x12,0x01,0xdd,0x75,0x42,0x01,0x75} -}, -{ 9, - 0x3f6, - 0, - {0x43,0x18,0x12,0x03,0x72,0x75,0x44,0x02,0x75} -}, -{ 9, - 0x3ff, - 0, - {0x45,0x00,0x75,0x46,0x00,0x12,0x03,0x9a,0x75} -}, -{ 8, - 0x408, - 0, - {0x42,0x03,0x75,0x43,0x44,0x12,0x03,0x72} -}, -{ 1, - 0x410, - 0, - {0x22} -}, -{ 14, - 0x411, - 0, - {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} -}, -{ 14, - 0x41f, - 0, - {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xaa,0x74} -}, -{ 4, - 0x42d, - 0, - {0x02,0xf0,0xd0,0x86} -}, -{ 11, - 0x431, - 0, - {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} -}, -{ 14, - 0x43c, - 0, - {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} -}, -{ 14, - 0x44a, - 0, - {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xa9,0x74} -}, -{ 7, - 0x458, - 0, - {0x04,0xf0,0x75,0x30,0x01,0xd0,0x86} -}, -{ 11, - 0x45f, - 0, - {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} -}, -{ 14, - 0x46a, - 0, - {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} -}, -{ 14, - 0x478, - 0, - {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xaa,0x74} -}, -{ 7, - 0x486, - 0, - {0x04,0xf0,0x75,0x31,0x01,0xd0,0x86} -}, -{ 11, - 0x48d, - 0, - {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} -}, -{ 14, - 0x498, - 0, - {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} -}, -{ 12, - 0x4a6, - 0, - {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe5,0xf5,0x91,0xd0,0x86} -}, -{ 11, - 0x4b2, - 0, - {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} -}, -{ 14, - 0x4bd, - 0, - {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} -}, -{ 12, - 0x4cb, - 0, - {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe7,0xf5,0x91,0xd0,0x86} -}, -{ 11, - 0x4d7, - 0, - {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} -}, -{ 12, - 0x4e2, - 0, - {0x90,0x7f,0xea,0xe0,0xfa,0x8a,0x20,0x90,0x7f,0x96,0xe4,0xf0} -}, -{ 1, - 0x4ee, - 0, - {0x22} -}, -{ 7, - 0x4ef, - 0, - {0x90,0x7f,0xea,0xe0,0xfa,0x8a,0x21} -}, -{ 1, - 0x4f6, - 0, - {0x22} -}, -{ 14, - 0x4f7, - 0, - {0x90,0x17,0x13,0xe0,0xfa,0x90,0x17,0x15,0xe0,0xfb,0x74,0x80,0x2a,0xfa} -}, -{ 14, - 0x505, - 0, - {0x74,0x80,0x2b,0xfb,0xea,0x03,0x03,0x54,0x3f,0xfc,0xea,0xc4,0x23,0x54} -}, -{ 14, - 0x513, - 0, - {0x1f,0xfa,0x2c,0xfa,0xeb,0x03,0x03,0x54,0x3f,0xfc,0xeb,0xc4,0x23,0x54} -}, -{ 11, - 0x521, - 0, - {0x1f,0xfb,0x2c,0xfb,0x90,0x17,0x0a,0xe0,0xfc,0x60,0x02} -}, -{ 2, - 0x52c, - 0, - {0x7a,0x00} -}, -{ 7, - 0x52e, - 0, - {0x90,0x17,0x0c,0xe0,0xfc,0x60,0x02} -}, -{ 2, - 0x535, - 0, - {0x7b,0x00} -}, -{ 11, - 0x537, - 0, - {0xea,0x2b,0xfc,0xc3,0x13,0xf5,0x3a,0x75,0x44,0x02,0x8b} -}, -{ 7, - 0x542, - 0, - {0x45,0x8a,0x46,0x12,0x03,0x9a,0x75} -}, -{ 9, - 0x549, - 0, - {0x6e,0x08,0x75,0x6f,0x00,0x12,0x11,0x44,0x75} -}, -{ 4, - 0x552, - 0, - {0x70,0x47,0x75,0x71} -}, -{ 8, - 0x556, - 0, - {0x0c,0x75,0x72,0x02,0x12,0x11,0x75,0x85} -}, -{ 5, - 0x55e, - 0, - {0x3a,0x73,0x12,0x11,0xa0} -}, -{ 1, - 0x563, - 0, - {0x22} -}, -{ 14, - 0x564, - 0, - {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x65,0x02,0xf0,0x90} -}, -{ 14, - 0x572, - 0, - {0x7f,0xeb,0xe0,0xfa,0x90,0x7f,0xea,0xe0,0xfb,0x90,0x7f,0xef,0xe0,0xfc} -}, -{ 14, - 0x580, - 0, - {0x33,0x95,0xe0,0xfd,0x8c,0x05,0x7c,0x00,0x90,0x7f,0xee,0xe0,0xfe,0x33} -}, -{ 14, - 0x58e, - 0, - {0x95,0xe0,0xff,0xec,0x2e,0xfc,0xed,0x3f,0xfd,0x90,0x7f,0xe9,0xe0,0xfe} -}, -{ 5, - 0x59c, - 0, - {0xbe,0x01,0x02,0x80,0x03} -}, -{ 3, - 0x5a1, - 0, - {0x02,0x05,0xf9} -}, -{ 6, - 0x5a4, - 0, - {0xbc,0x01,0x21,0xbd,0x00,0x1e} -}, -{ 14, - 0x5aa, - 0, - {0xea,0xc4,0x03,0x54,0xf8,0xfc,0xeb,0x25,0xe0,0xfd,0x2c,0x24,0x00,0xfc} -}, -{ 14, - 0x5b8, - 0, - {0xe4,0x34,0x17,0xfd,0x90,0x7e,0xc0,0xe0,0xfe,0x8c,0x82,0x8d,0x83,0xf0} -}, -{ 2, - 0x5c6, - 0, - {0x80,0x31} -}, -{ 14, - 0x5c8, - 0, - {0xea,0xc4,0x03,0x54,0xf8,0xfa,0xeb,0x25,0xe0,0xfb,0x2a,0xfa,0x24,0x00} -}, -{ 14, - 0x5d6, - 0, - {0xfb,0xe4,0x34,0x17,0xfc,0x90,0x7e,0xc0,0xe0,0xfd,0x8b,0x82,0x8c,0x83} -}, -{ 14, - 0x5e4, - 0, - {0xf0,0x74,0x01,0x2a,0x24,0x00,0xfa,0xe4,0x34,0x17,0xfb,0x90,0x7e,0xc1} -}, -{ 7, - 0x5f2, - 0, - {0xe0,0xfc,0x8a,0x82,0x8b,0x83,0xf0} -}, -{ 3, - 0x5f9, - 0, - {0x75,0x38,0x01} -}, -{ 1, - 0x5fc, - 0, - {0x22} -}, -{ 14, - 0x5fd, - 0, - {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} -}, -{ 14, - 0x60b, - 0, - {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} -}, -{ 13, - 0x619, - 0, - {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} -}, -{ 13, - 0x626, - 0, - {0x7f,0xaa,0x74,0x01,0xf0,0x12,0x05,0x64,0x75,0x37,0x00,0xd0,0x86} -}, -{ 14, - 0x633, - 0, - {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} -}, -{ 13, - 0x641, - 0, - {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} -}, -{ 14, - 0x64e, - 0, - {0x90,0x7f,0xeb,0xe0,0xfa,0x90,0x7f,0xea,0xe0,0xfb,0x90,0x7f,0xee,0xe0} -}, -{ 14, - 0x65c, - 0, - {0xfc,0x33,0x95,0xe0,0xfd,0x90,0x7f,0x96,0xe0,0xfe,0x90,0x7f,0x96,0x74} -}, -{ 14, - 0x66a, - 0, - {0x80,0x65,0x06,0xf0,0x90,0x7f,0x00,0x74,0x01,0xf0,0xea,0xc4,0x03,0x54} -}, -{ 14, - 0x678, - 0, - {0xf8,0xfe,0xeb,0x25,0xe0,0xfb,0x2e,0xfe,0x24,0x00,0xfb,0xe4,0x34,0x17} -}, -{ 14, - 0x686, - 0, - {0xff,0x8b,0x82,0x8f,0x83,0xe0,0xfb,0x74,0x01,0x2e,0x24,0x00,0xfe,0xe4} -}, -{ 14, - 0x694, - 0, - {0x34,0x17,0xff,0x8e,0x82,0x8f,0x83,0xe0,0xfe,0x90,0x7f,0xe9,0xe0,0xff} -}, -{ 3, - 0x6a2, - 0, - {0xbf,0x81,0x0a} -}, -{ 10, - 0x6a5, - 0, - {0x90,0x7f,0x00,0xeb,0xf0,0x90,0x7f,0x01,0xee,0xf0} -}, -{ 8, - 0x6af, - 0, - {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x82,0x1a} -}, -{ 3, - 0x6b7, - 0, - {0xba,0x01,0x0c} -}, -{ 12, - 0x6ba, - 0, - {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0b} -}, -{ 11, - 0x6c6, - 0, - {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0x74,0xb5,0xf0} -}, -{ 8, - 0x6d1, - 0, - {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x83,0x1b} -}, -{ 3, - 0x6d9, - 0, - {0xba,0x01,0x0d} -}, -{ 13, - 0x6dc, - 0, - {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0b} -}, -{ 11, - 0x6e9, - 0, - {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0x74,0x12,0xf0} -}, -{ 8, - 0x6f4, - 0, - {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x84,0x1c} -}, -{ 3, - 0x6fc, - 0, - {0xba,0x01,0x0d} -}, -{ 13, - 0x6ff, - 0, - {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0c} -}, -{ 12, - 0x70c, - 0, - {0x90,0x7f,0x00,0x74,0x80,0xf0,0x90,0x7f,0x01,0x74,0x01,0xf0} -}, -{ 5, - 0x718, - 0, - {0x90,0x7f,0xb5,0xec,0xf0} -}, -{ 1, - 0x71d, - 0, - {0x22} -}, -{ 12, - 0x71e, - 0, - {0x75,0x36,0x0d,0x90,0x88,0x00,0x74,0x1d,0xf0,0x75,0x6b,0x80} -}, -{ 10, - 0x72a, - 0, - {0x75,0x6c,0x3c,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} -}, -{ 9, - 0x734, - 0, - {0x6c,0x0f,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} -}, -{ 9, - 0x73d, - 0, - {0x6c,0x06,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} -}, -{ 7, - 0x746, - 0, - {0x6c,0x01,0x12,0x10,0xe2,0x7a,0x00} -}, -{ 3, - 0x74d, - 0, - {0xba,0xff,0x00} -}, -{ 2, - 0x750, - 0, - {0x50,0x0a} -}, -{ 10, - 0x752, - 0, - {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xf1} -}, -{ 10, - 0x75c, - 0, - {0x75,0x6b,0x80,0x75,0x6c,0x3c,0x12,0x10,0xe2,0x75} -}, -{ 8, - 0x766, - 0, - {0x6b,0x80,0x75,0x6c,0x0f,0x12,0x10,0xe2} -}, -{ 1, - 0x76e, - 0, - {0x22} -}, -{ 14, - 0x76f, - 0, - {0x90,0x7f,0xa1,0xe4,0xf0,0x90,0x7f,0xaf,0x74,0x01,0xf0,0x90,0x7f,0x92} -}, -{ 14, - 0x77d, - 0, - {0x74,0x02,0xf0,0x75,0x8e,0x31,0x75,0x89,0x21,0x75,0x88,0x00,0x75,0xc8} -}, -{ 14, - 0x78b, - 0, - {0x00,0x75,0x8d,0x40,0x75,0x98,0x40,0x75,0xc0,0x40,0x75,0x87,0x00,0x75} -}, -{ 9, - 0x799, - 0, - {0x20,0x00,0x75,0x21,0x00,0x75,0x22,0x00,0x75} -}, -{ 5, - 0x7a2, - 0, - {0x23,0x00,0x75,0x47,0x00} -}, -{ 7, - 0x7a7, - 0, - {0xc3,0xe5,0x47,0x94,0x20,0x50,0x11} -}, -{ 13, - 0x7ae, - 0, - {0xe5,0x47,0x24,0x00,0xf5,0x82,0xe4,0x34,0x17,0xf5,0x83,0xe4,0xf0} -}, -{ 4, - 0x7bb, - 0, - {0x05,0x47,0x80,0xe8} -}, -{ 9, - 0x7bf, - 0, - {0xe4,0xf5,0x40,0xf5,0x3f,0xe4,0xf5,0x3c,0xf5} -}, -{ 7, - 0x7c8, - 0, - {0x3b,0xe4,0xf5,0x3e,0xf5,0x3d,0x75} -}, -{ 11, - 0x7cf, - 0, - {0x32,0x00,0x75,0x37,0x00,0x75,0x39,0x00,0x90,0x7f,0x93} -}, -{ 14, - 0x7da, - 0, - {0x74,0x3c,0xf0,0x90,0x7f,0x9c,0x74,0xff,0xf0,0x90,0x7f,0x96,0x74,0x80} -}, -{ 14, - 0x7e8, - 0, - {0xf0,0x90,0x7f,0x94,0x74,0x70,0xf0,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90} -}, -{ 14, - 0x7f6, - 0, - {0x7f,0x97,0xe4,0xf0,0x90,0x7f,0x95,0x74,0xc2,0xf0,0x90,0x7f,0x98,0x74} -}, -{ 14, - 0x804, - 0, - {0x28,0xf0,0x90,0x7f,0x9e,0x74,0x28,0xf0,0x90,0x7f,0xf0,0xe4,0xf0,0x90} -}, -{ 14, - 0x812, - 0, - {0x7f,0xf1,0xe4,0xf0,0x90,0x7f,0xf2,0xe4,0xf0,0x90,0x7f,0xf3,0xe4,0xf0} -}, -{ 14, - 0x820, - 0, - {0x90,0x7f,0xf4,0xe4,0xf0,0x90,0x7f,0xf5,0xe4,0xf0,0x90,0x7f,0xf6,0xe4} -}, -{ 14, - 0x82e, - 0, - {0xf0,0x90,0x7f,0xf7,0xe4,0xf0,0x90,0x7f,0xf8,0xe4,0xf0,0x90,0x7f,0xf9} -}, -{ 14, - 0x83c, - 0, - {0x74,0x38,0xf0,0x90,0x7f,0xfa,0x74,0xa0,0xf0,0x90,0x7f,0xfb,0x74,0xa0} -}, -{ 14, - 0x84a, - 0, - {0xf0,0x90,0x7f,0xfc,0x74,0xa0,0xf0,0x90,0x7f,0xfd,0x74,0xa0,0xf0,0x90} -}, -{ 14, - 0x858, - 0, - {0x7f,0xfe,0x74,0xa0,0xf0,0x90,0x7f,0xff,0x74,0xa0,0xf0,0x90,0x7f,0xe0} -}, -{ 14, - 0x866, - 0, - {0x74,0x03,0xf0,0x90,0x7f,0xe1,0x74,0x01,0xf0,0x90,0x7f,0xdd,0x74,0x80} -}, -{ 11, - 0x874, - 0, - {0xf0,0x12,0x12,0x43,0x12,0x07,0x1e,0x7a,0x00,0x7b,0x00} -}, -{ 9, - 0x87f, - 0, - {0xc3,0xea,0x94,0x1e,0xeb,0x94,0x00,0x50,0x17} -}, -{ 12, - 0x888, - 0, - {0x90,0x88,0x00,0xe0,0xf5,0x47,0x90,0x88,0x0b,0xe0,0xf5,0x47} -}, -{ 9, - 0x894, - 0, - {0x90,0x7f,0x68,0xf0,0x0a,0xba,0x00,0x01,0x0b} -}, -{ 2, - 0x89d, - 0, - {0x80,0xe0} -}, -{ 12, - 0x89f, - 0, - {0x12,0x03,0xe1,0x90,0x7f,0xd6,0xe4,0xf0,0x7a,0x00,0x7b,0x00} -}, -{ 13, - 0x8ab, - 0, - {0x8a,0x04,0x8b,0x05,0xc3,0xea,0x94,0xe0,0xeb,0x94,0x2e,0x50,0x1a} -}, -{ 14, - 0x8b8, - 0, - {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} -}, -{ 10, - 0x8c6, - 0, - {0x04,0xd0,0x03,0xd0,0x02,0x0a,0xba,0x00,0x01,0x0b} -}, -{ 2, - 0x8d0, - 0, - {0x80,0xd9} -}, -{ 13, - 0x8d2, - 0, - {0x90,0x7f,0xd6,0x74,0x02,0xf0,0x90,0x7f,0xd6,0x74,0x06,0xf0,0x90} -}, -{ 14, - 0x8df, - 0, - {0x7f,0xde,0x74,0x05,0xf0,0x90,0x7f,0xdf,0x74,0x05,0xf0,0x90,0x7f,0xac} -}, -{ 14, - 0x8ed, - 0, - {0xe4,0xf0,0x90,0x7f,0xad,0x74,0x05,0xf0,0x75,0xa8,0x80,0x75,0xf8,0x10} -}, -{ 13, - 0x8fb, - 0, - {0x90,0x7f,0xae,0x74,0x0b,0xf0,0x90,0x7f,0xe2,0x74,0x88,0xf0,0x90} -}, -{ 12, - 0x908, - 0, - {0x7f,0xab,0x74,0x08,0xf0,0x75,0xe8,0x11,0x75,0x32,0x01,0x75} -}, -{ 12, - 0x914, - 0, - {0x31,0x00,0x75,0x30,0x00,0xc0,0x04,0xc0,0x05,0x12,0x04,0xf7} -}, -{ 10, - 0x920, - 0, - {0xd0,0x05,0xd0,0x04,0x75,0x34,0x00,0x75,0x35,0x01} -}, -{ 13, - 0x92a, - 0, - {0x90,0x7f,0xae,0x74,0x03,0xf0,0x8c,0x02,0xba,0x00,0x02,0x80,0x03} -}, -{ 3, - 0x937, - 0, - {0x02,0x0a,0x3f} -}, -{ 12, - 0x93a, - 0, - {0x85,0x33,0x34,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90,0x7f,0x97} -}, -{ 14, - 0x946, - 0, - {0x74,0x08,0xf0,0x90,0x7f,0x9d,0x74,0x88,0xf0,0x90,0x7f,0x9a,0xe0,0xfa} -}, -{ 12, - 0x954, - 0, - {0x74,0x05,0x5a,0xf5,0x33,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90} -}, -{ 13, - 0x960, - 0, - {0x7f,0x97,0x74,0x02,0xf0,0x90,0x7f,0x9d,0x74,0x82,0xf0,0xe5,0x33} -}, -{ 13, - 0x96d, - 0, - {0x25,0xe0,0xfa,0x90,0x7f,0x9a,0xe0,0x54,0x05,0xfb,0x4a,0xf5,0x33} -}, -{ 2, - 0x97a, - 0, - {0x60,0x0c} -}, -{ 12, - 0x97c, - 0, - {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x4a,0xf0} -}, -{ 11, - 0x988, - 0, - {0x75,0x6e,0x00,0x75,0x6f,0x00,0xc0,0x04,0xc0,0x05,0x12} -}, -{ 14, - 0x993, - 0, - {0x11,0x44,0xd0,0x05,0xd0,0x04,0x90,0x17,0x13,0xe0,0xfa,0x74,0x80,0x2a} -}, -{ 6, - 0x9a1, - 0, - {0xfa,0xe5,0x33,0xb4,0x04,0x29} -}, -{ 3, - 0x9a7, - 0, - {0xba,0xa0,0x00} -}, -{ 2, - 0x9aa, - 0, - {0x50,0x24} -}, -{ 13, - 0x9ac, - 0, - {0x90,0x17,0x13,0xe0,0x04,0xfb,0x0b,0x90,0x17,0x13,0xeb,0xf0,0x90} -}, -{ 14, - 0x9b9, - 0, - {0x17,0x13,0xe0,0xfb,0x90,0x17,0x15,0xf0,0xc0,0x02,0xc0,0x04,0xc0,0x05} -}, -{ 9, - 0x9c7, - 0, - {0x12,0x04,0xf7,0xd0,0x05,0xd0,0x04,0xd0,0x02} -}, -{ 5, - 0x9d0, - 0, - {0xe5,0x33,0xb4,0x02,0x26} -}, -{ 6, - 0x9d5, - 0, - {0xc3,0x74,0x04,0x9a,0x50,0x20} -}, -{ 13, - 0x9db, - 0, - {0x90,0x17,0x13,0xe0,0xfa,0x1a,0x1a,0x90,0x17,0x13,0xea,0xf0,0x90} -}, -{ 13, - 0x9e8, - 0, - {0x17,0x13,0xe0,0xfa,0x90,0x17,0x15,0xf0,0xc0,0x04,0xc0,0x05,0x12} -}, -{ 6, - 0x9f5, - 0, - {0x04,0xf7,0xd0,0x05,0xd0,0x04} -}, -{ 5, - 0x9fb, - 0, - {0xe5,0x33,0xb4,0x08,0x1d} -}, -{ 4, - 0xa00, - 0, - {0xe5,0x34,0x70,0x19} -}, -{ 10, - 0xa04, - 0, - {0x74,0x01,0x25,0x35,0x54,0x0f,0xf5,0x35,0x85,0x35} -}, -{ 12, - 0xa0e, - 0, - {0x75,0x75,0x76,0x00,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0} -}, -{ 3, - 0xa1a, - 0, - {0x05,0xd0,0x04} -}, -{ 5, - 0xa1d, - 0, - {0xe5,0x33,0xb4,0x01,0x1d} -}, -{ 4, - 0xa22, - 0, - {0xe5,0x34,0x70,0x19} -}, -{ 10, - 0xa26, - 0, - {0xe5,0x35,0x24,0xff,0x54,0x0f,0xf5,0x35,0x85,0x35} -}, -{ 12, - 0xa30, - 0, - {0x75,0x75,0x76,0x00,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0} -}, -{ 3, - 0xa3c, - 0, - {0x05,0xd0,0x04} -}, -{ 14, - 0xa3f, - 0, - {0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0,0x04,0x90,0x7f,0x96} -}, -{ 14, - 0xa4d, - 0, - {0xe0,0xfa,0x90,0x7f,0x96,0x74,0x7f,0x5a,0xf0,0x90,0x7f,0x97,0x74,0x08} -}, -{ 10, - 0xa5b, - 0, - {0xf0,0xc3,0xec,0x94,0x00,0xed,0x94,0x02,0x40,0x08} -}, -{ 8, - 0xa65, - 0, - {0x90,0x7f,0x96,0xe0,0xfa,0x20,0xe6,0x08} -}, -{ 8, - 0xa6d, - 0, - {0xc3,0xe4,0x9c,0x74,0x08,0x9d,0x50,0x13} -}, -{ 14, - 0xa75, - 0, - {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x40,0x65,0x02,0xf0,0x7c} -}, -{ 5, - 0xa83, - 0, - {0x00,0x7d,0x00,0x80,0x05} -}, -{ 5, - 0xa88, - 0, - {0x0c,0xbc,0x00,0x01,0x0d} -}, -{ 5, - 0xa8d, - 0, - {0xe5,0x38,0xb4,0x01,0x0e} -}, -{ 13, - 0xa92, - 0, - {0xc0,0x04,0xc0,0x05,0x12,0x04,0xf7,0xd0,0x05,0xd0,0x04,0x75,0x38} -}, -{ 1, - 0xa9f, - 0, - {0x00} -}, -{ 7, - 0xaa0, - 0, - {0xe5,0x31,0x70,0x03,0x02,0x09,0x2a} -}, -{ 10, - 0xaa7, - 0, - {0x90,0x7f,0xc9,0xe0,0xfa,0x70,0x03,0x02,0x0c,0x2d} -}, -{ 14, - 0xab1, - 0, - {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x65,0x02,0xf0,0x90} -}, -{ 9, - 0xabf, - 0, - {0x7d,0xc0,0xe0,0xfa,0xba,0x2c,0x02,0x80,0x03} -}, -{ 3, - 0xac8, - 0, - {0x02,0x0b,0x36} -}, -{ 5, - 0xacb, - 0, - {0x75,0x32,0x00,0x7b,0x00} -}, -{ 3, - 0xad0, - 0, - {0xbb,0x64,0x00} -}, -{ 2, - 0xad3, - 0, - {0x50,0x1c} -}, -{ 14, - 0xad5, - 0, - {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} -}, -{ 13, - 0xae3, - 0, - {0x04,0xd0,0x03,0xd0,0x02,0x90,0x88,0x0f,0xe0,0xf5,0x47,0x0b,0x80} -}, -{ 1, - 0xaf0, - 0, - {0xdf} -}, -{ 13, - 0xaf1, - 0, - {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x07,0x1e,0x12,0x03,0xe1,0x12} -}, -{ 12, - 0xafe, - 0, - {0x04,0xf7,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x75,0x6e,0x00,0x75} -}, -{ 13, - 0xb0a, - 0, - {0x6f,0x01,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x11,0x44,0xd0,0x05} -}, -{ 9, - 0xb17, - 0, - {0xd0,0x04,0xd0,0x02,0x75,0x70,0x4d,0x75,0x71} -}, -{ 11, - 0xb20, - 0, - {0x0c,0x75,0x72,0x02,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12} -}, -{ 11, - 0xb2b, - 0, - {0x11,0x75,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x02,0x0c,0x2d} -}, -{ 3, - 0xb36, - 0, - {0xba,0x2a,0x3b} -}, -{ 13, - 0xb39, - 0, - {0x90,0x7f,0x98,0x74,0x20,0xf0,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12} -}, -{ 14, - 0xb46, - 0, - {0x01,0xdd,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x90,0x7f,0x98,0x74,0x28,0xf0} -}, -{ 2, - 0xb54, - 0, - {0x7b,0x00} -}, -{ 3, - 0xb56, - 0, - {0xbb,0x0a,0x00} -}, -{ 5, - 0xb59, - 0, - {0x40,0x03,0x02,0x0c,0x2d} -}, -{ 14, - 0xb5e, - 0, - {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} -}, -{ 8, - 0xb6c, - 0, - {0x04,0xd0,0x03,0xd0,0x02,0x0b,0x80,0xe2} -}, -{ 3, - 0xb74, - 0, - {0xba,0x2b,0x1a} -}, -{ 8, - 0xb77, - 0, - {0x90,0x7f,0xc9,0xe0,0xfb,0xbb,0x40,0x12} -}, -{ 14, - 0xb7f, - 0, - {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x12,0x05,0xd0,0x05,0xd0,0x04,0xd0} -}, -{ 4, - 0xb8d, - 0, - {0x02,0x02,0x0c,0x2d} -}, -{ 3, - 0xb91, - 0, - {0xba,0x10,0x1f} -}, -{ 14, - 0xb94, - 0, - {0x90,0x7f,0x96,0xe0,0xfb,0x90,0x7f,0x96,0x74,0x80,0x65,0x03,0xf0,0xc0} -}, -{ 14, - 0xba2, - 0, - {0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x3d,0xd0,0x05,0xd0,0x04,0xd0,0x02} -}, -{ 3, - 0xbb0, - 0, - {0x02,0x0c,0x2d} -}, -{ 3, - 0xbb3, - 0, - {0xba,0x11,0x12} -}, -{ 14, - 0xbb6, - 0, - {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x6a,0xd0,0x05,0xd0,0x04,0xd0} -}, -{ 4, - 0xbc4, - 0, - {0x02,0x02,0x0c,0x2d} -}, -{ 3, - 0xbc8, - 0, - {0xba,0x12,0x12} -}, -{ 14, - 0xbcb, - 0, - {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x8f,0xd0,0x05,0xd0,0x04,0xd0} -}, -{ 4, - 0xbd9, - 0, - {0x02,0x02,0x0c,0x2d} -}, -{ 3, - 0xbdd, - 0, - {0xba,0x13,0x0b} -}, -{ 11, - 0xbe0, - 0, - {0x90,0x7d,0xc1,0xe0,0xfb,0x90,0x88,0x00,0xf0,0x80,0x42} -}, -{ 3, - 0xbeb, - 0, - {0xba,0x14,0x11} -}, -{ 14, - 0xbee, - 0, - {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x11,0xdd,0xd0,0x05,0xd0,0x04,0xd0} -}, -{ 3, - 0xbfc, - 0, - {0x02,0x80,0x2e} -}, -{ 3, - 0xbff, - 0, - {0xba,0x15,0x1d} -}, -{ 12, - 0xc02, - 0, - {0x90,0x7d,0xc1,0xe0,0xf5,0x75,0x90,0x7d,0xc2,0xe0,0xf5,0x76} -}, -{ 14, - 0xc0e, - 0, - {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0,0x05,0xd0,0x04,0xd0} -}, -{ 3, - 0xc1c, - 0, - {0x02,0x80,0x0e} -}, -{ 3, - 0xc1f, - 0, - {0xba,0x16,0x0b} -}, -{ 11, - 0xc22, - 0, - {0xc0,0x04,0xc0,0x05,0x12,0x13,0xa3,0xd0,0x05,0xd0,0x04} -}, -{ 11, - 0xc2d, - 0, - {0x90,0x7f,0xc9,0xe4,0xf0,0x75,0x31,0x00,0x02,0x09,0x2a} -}, -{ 1, - 0xc38, - 0, - {0x22} -}, -{ 7, - 0xc39, - 0, - {0x53,0x55,0x50,0x45,0x4e,0x44,0x00} -}, -{ 7, - 0xc40, - 0, - {0x52,0x45,0x53,0x55,0x4d,0x45,0x00} -}, -{ 6, - 0xc47, - 0, - {0x20,0x56,0x6f,0x6c,0x20,0x00} -}, -{ 13, - 0xc4d, - 0, - {0x44,0x41,0x42,0x55,0x53,0x42,0x20,0x76,0x31,0x2e,0x30,0x30,0x00} -}, -{ 14, - 0xc5a, - 0, - {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} -}, -{ 14, - 0xc68, - 0, - {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} -}, -{ 13, - 0xc76, - 0, - {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} -}, -{ 14, - 0xc83, - 0, - {0x7f,0xab,0x74,0x01,0xf0,0x90,0x7f,0xe8,0xe0,0xfa,0x90,0x7f,0xe9,0xe0} -}, -{ 6, - 0xc91, - 0, - {0xfb,0xbb,0x00,0x02,0x80,0x03} -}, -{ 3, - 0xc97, - 0, - {0x02,0x0d,0x38} -}, -{ 3, - 0xc9a, - 0, - {0xba,0x80,0x14} -}, -{ 14, - 0xc9d, - 0, - {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5} -}, -{ 6, - 0xcab, - 0, - {0x74,0x02,0xf0,0x02,0x0e,0xcd} -}, -{ 5, - 0xcb1, - 0, - {0xba,0x82,0x02,0x80,0x03} -}, -{ 3, - 0xcb6, - 0, - {0x02,0x0d,0x1d} -}, -{ 8, - 0xcb9, - 0, - {0x90,0x7f,0xec,0xe0,0xfc,0xbc,0x01,0x00} -}, -{ 2, - 0xcc1, - 0, - {0x40,0x21} -}, -{ 6, - 0xcc3, - 0, - {0xc3,0x74,0x07,0x9c,0x40,0x1b} -}, -{ 14, - 0xcc9, - 0, - {0xec,0x24,0xff,0x25,0xe0,0xfd,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x7f,0xf5} -}, -{ 13, - 0xcd7, - 0, - {0x83,0xe0,0xfd,0x53,0x05,0x01,0x90,0x7f,0x00,0xed,0xf0,0x80,0x2b} -}, -{ 3, - 0xce4, - 0, - {0xbc,0x81,0x00} -}, -{ 2, - 0xce7, - 0, - {0x40,0x21} -}, -{ 6, - 0xce9, - 0, - {0xc3,0x74,0x87,0x9c,0x40,0x1b} -}, -{ 14, - 0xcef, - 0, - {0xec,0x24,0x7f,0x25,0xe0,0xfc,0x24,0xb6,0xf5,0x82,0xe4,0x34,0x7f,0xf5} -}, -{ 13, - 0xcfd, - 0, - {0x83,0xe0,0xfc,0x53,0x04,0x01,0x90,0x7f,0x00,0xec,0xf0,0x80,0x05} -}, -{ 5, - 0xd0a, - 0, - {0x90,0x7f,0x00,0xe4,0xf0} -}, -{ 14, - 0xd0f, - 0, - {0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x02,0x0e,0xcd} -}, -{ 5, - 0xd1d, - 0, - {0xba,0x81,0x02,0x80,0x03} -}, -{ 3, - 0xd22, - 0, - {0x02,0x0e,0xc5} -}, -{ 14, - 0xd25, - 0, - {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5,0x74} -}, -{ 5, - 0xd33, - 0, - {0x02,0xf0,0x02,0x0e,0xcd} -}, -{ 3, - 0xd38, - 0, - {0xbb,0x01,0x2d} -}, -{ 6, - 0xd3b, - 0, - {0xba,0x00,0x03,0x02,0x0e,0xcd} -}, -{ 3, - 0xd41, - 0, - {0xba,0x02,0x11} -}, -{ 13, - 0xd44, - 0, - {0x75,0x59,0x00,0xc0,0x02,0xc0,0x03,0x12,0x0e,0xf0,0xd0,0x03,0xd0} -}, -{ 4, - 0xd51, - 0, - {0x02,0x02,0x0e,0xcd} -}, -{ 5, - 0xd55, - 0, - {0xba,0x21,0x02,0x80,0x03} -}, -{ 3, - 0xd5a, - 0, - {0x02,0x0e,0xcd} -}, -{ 11, - 0xd5d, - 0, - {0x75,0x37,0x01,0x90,0x7f,0xc5,0xe4,0xf0,0x02,0x0e,0xcd} -}, -{ 3, - 0xd68, - 0, - {0xbb,0x03,0x1f} -}, -{ 6, - 0xd6b, - 0, - {0xba,0x00,0x03,0x02,0x0e,0xcd} -}, -{ 5, - 0xd71, - 0, - {0xba,0x02,0x02,0x80,0x03} -}, -{ 3, - 0xd76, - 0, - {0x02,0x0e,0xcd} -}, -{ 13, - 0xd79, - 0, - {0x75,0x59,0x01,0xc0,0x02,0xc0,0x03,0x12,0x0e,0xf0,0xd0,0x03,0xd0} -}, -{ 4, - 0xd86, - 0, - {0x02,0x02,0x0e,0xcd} -}, -{ 3, - 0xd8a, - 0, - {0xbb,0x06,0x54} -}, -{ 5, - 0xd8d, - 0, - {0xba,0x80,0x02,0x80,0x03} -}, -{ 3, - 0xd92, - 0, - {0x02,0x0e,0xc5} -}, -{ 8, - 0xd95, - 0, - {0x90,0x7f,0xeb,0xe0,0xfc,0xbc,0x01,0x15} -}, -{ 12, - 0xd9d, - 0, - {0x7c,0xfb,0x7d,0x0f,0x8d,0x06,0x7f,0x00,0x90,0x7f,0xd4,0xee} -}, -{ 9, - 0xda9, - 0, - {0xf0,0x90,0x7f,0xd5,0xec,0xf0,0x02,0x0e,0xcd} -}, -{ 10, - 0xdb2, - 0, - {0x90,0x7f,0xeb,0xe0,0xfc,0xbc,0x02,0x02,0x80,0x03} -}, -{ 3, - 0xdbc, - 0, - {0x02,0x0e,0xc5} -}, -{ 10, - 0xdbf, - 0, - {0x90,0x7f,0xea,0xe0,0xfc,0xbc,0x00,0x02,0x80,0x03} -}, -{ 3, - 0xdc9, - 0, - {0x02,0x0e,0xc5} -}, -{ 12, - 0xdcc, - 0, - {0x7c,0x3b,0x7d,0x0f,0x8d,0x06,0x7f,0x00,0x90,0x7f,0xd4,0xee} -}, -{ 9, - 0xdd8, - 0, - {0xf0,0x90,0x7f,0xd5,0xec,0xf0,0x02,0x0e,0xcd} -}, -{ 6, - 0xde1, - 0, - {0xbb,0x07,0x03,0x02,0x0e,0xc5} -}, -{ 3, - 0xde7, - 0, - {0xbb,0x08,0x10} -}, -{ 13, - 0xdea, - 0, - {0xac,0x48,0x90,0x7f,0x00,0xec,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0} -}, -{ 3, - 0xdf7, - 0, - {0x02,0x0e,0xcd} -}, -{ 3, - 0xdfa, - 0, - {0xbb,0x09,0x31} -}, -{ 5, - 0xdfd, - 0, - {0xba,0x00,0x02,0x80,0x03} -}, -{ 3, - 0xe02, - 0, - {0x02,0x0e,0xc5} -}, -{ 14, - 0xe05, - 0, - {0x90,0x7f,0xea,0xe0,0xfc,0xc3,0x74,0x01,0x9c,0x50,0x03,0x02,0x0e,0xc5} -}, -{ 8, - 0xe13, - 0, - {0x90,0x7f,0xea,0xe0,0xfc,0xbc,0x00,0x0a} -}, -{ 10, - 0xe1b, - 0, - {0x90,0x17,0x21,0xe4,0xf0,0x90,0x17,0x22,0xe4,0xf0} -}, -{ 9, - 0xe25, - 0, - {0x90,0x7f,0xea,0xe0,0xf5,0x48,0x02,0x0e,0xcd} -}, -{ 3, - 0xe2e, - 0, - {0xbb,0x0a,0x27} -}, -{ 5, - 0xe31, - 0, - {0xba,0x81,0x02,0x80,0x03} -}, -{ 3, - 0xe36, - 0, - {0x02,0x0e,0xc5} -}, -{ 14, - 0xe39, - 0, - {0x90,0x7f,0xec,0xe0,0xfa,0x24,0x20,0xfa,0xe4,0x34,0x17,0xfc,0x8a,0x82} -}, -{ 14, - 0xe47, - 0, - {0x8c,0x83,0xe0,0xfa,0x90,0x7f,0x00,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0} -}, -{ 3, - 0xe55, - 0, - {0x02,0x0e,0xcd} -}, -{ 5, - 0xe58, - 0, - {0xbb,0x0b,0x02,0x80,0x03} -}, -{ 3, - 0xe5d, - 0, - {0x02,0x0e,0xa9} -}, -{ 13, - 0xe60, - 0, - {0x90,0x17,0x20,0xe4,0xf0,0x90,0x7f,0xec,0xe0,0xfa,0xba,0x01,0x1a} -}, -{ 8, - 0xe6d, - 0, - {0x90,0x7f,0xed,0xe0,0xfa,0xba,0x00,0x12} -}, -{ 14, - 0xe75, - 0, - {0x90,0x7f,0xea,0xe0,0xfa,0x90,0x17,0x21,0xf0,0xc0,0x03,0x12,0x04,0xe2} -}, -{ 4, - 0xe83, - 0, - {0xd0,0x03,0x80,0x46} -}, -{ 8, - 0xe87, - 0, - {0x90,0x7f,0xec,0xe0,0xfa,0xba,0x02,0x3e} -}, -{ 8, - 0xe8f, - 0, - {0x90,0x7f,0xed,0xe0,0xfa,0xba,0x00,0x36} -}, -{ 13, - 0xe97, - 0, - {0xc0,0x03,0x12,0x04,0xef,0xd0,0x03,0x90,0x7f,0xea,0xe0,0xfa,0x90} -}, -{ 5, - 0xea4, - 0, - {0x17,0x22,0xf0,0x80,0x24} -}, -{ 5, - 0xea9, - 0, - {0xbb,0x12,0x02,0x80,0x17} -}, -{ 5, - 0xeae, - 0, - {0xbb,0x81,0x02,0x80,0x0d} -}, -{ 5, - 0xeb3, - 0, - {0xbb,0x83,0x02,0x80,0x08} -}, -{ 5, - 0xeb8, - 0, - {0xbb,0x82,0x02,0x80,0x03} -}, -{ 3, - 0xebd, - 0, - {0xbb,0x84,0x05} -}, -{ 5, - 0xec0, - 0, - {0x12,0x06,0x4e,0x80,0x08} -}, -{ 8, - 0xec5, - 0, - {0x90,0x7f,0xb4,0x74,0x03,0xf0,0x80,0x06} -}, -{ 6, - 0xecd, - 0, - {0x90,0x7f,0xb4,0x74,0x02,0xf0} -}, -{ 2, - 0xed3, - 0, - {0xd0,0x86} -}, -{ 14, - 0xed5, - 0, - {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} -}, -{ 13, - 0xee3, - 0, - {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} -}, -{ 11, - 0xef0, - 0, - {0x90,0x7f,0xec,0xe0,0xf5,0x5a,0xc3,0x94,0x01,0x40,0x1d} -}, -{ 7, - 0xefb, - 0, - {0xc3,0x74,0x07,0x95,0x5a,0x40,0x16} -}, -{ 13, - 0xf02, - 0, - {0xe5,0x5a,0x24,0xff,0x25,0xe0,0xfa,0x24,0xc6,0xf5,0x82,0xe4,0x34} -}, -{ 9, - 0xf0f, - 0, - {0x7f,0xf5,0x83,0xaa,0x59,0xea,0xf0,0x80,0x22} -}, -{ 7, - 0xf18, - 0, - {0xc3,0xe5,0x5a,0x94,0x81,0x40,0x1b} -}, -{ 7, - 0xf1f, - 0, - {0xc3,0x74,0x87,0x95,0x5a,0x40,0x14} -}, -{ 13, - 0xf26, - 0, - {0xe5,0x5a,0x24,0xff,0x25,0xe0,0xfa,0x24,0xb6,0xf5,0x82,0xe4,0x34} -}, -{ 7, - 0xf33, - 0, - {0x7f,0xf5,0x83,0xaa,0x59,0xea,0xf0} -}, -{ 1, - 0xf3a, - 0, - {0x22} -}, -{ 14, - 0xf3b, - 0, - {0x09,0x02,0xba,0x00,0x03,0x01,0x00,0x40,0x00,0x09,0x04,0x00,0x00,0x00} -}, -{ 14, - 0xf49, - 0, - {0x01,0x01,0x00,0x00,0x09,0x24,0x01,0x00,0x01,0x3d,0x00,0x01,0x01,0x0c} -}, -{ 14, - 0xf57, - 0, - {0x24,0x02,0x01,0x10,0x07,0x00,0x02,0x03,0x00,0x00,0x00,0x0d,0x24,0x06} -}, -{ 14, - 0xf65, - 0, - {0x03,0x01,0x02,0x15,0x00,0x03,0x00,0x03,0x00,0x00,0x09,0x24,0x03,0x02} -}, -{ 14, - 0xf73, - 0, - {0x01,0x01,0x00,0x01,0x00,0x09,0x24,0x03,0x04,0x02,0x03,0x00,0x03,0x00} -}, -{ 14, - 0xf81, - 0, - {0x09,0x24,0x03,0x05,0x03,0x06,0x00,0x01,0x00,0x09,0x04,0x01,0x00,0x00} -}, -{ 14, - 0xf8f, - 0, - {0x01,0x02,0x00,0x00,0x09,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00,0x07} -}, -{ 14, - 0xf9d, - 0, - {0x24,0x01,0x02,0x01,0x01,0x00,0x0b,0x24,0x02,0x01,0x02,0x02,0x10,0x01} -}, -{ 14, - 0xfab, - 0, - {0x80,0xbb,0x00,0x09,0x05,0x88,0x05,0x00,0x01,0x01,0x00,0x00,0x07,0x25} -}, -{ 14, - 0xfb9, - 0, - {0x01,0x00,0x00,0x00,0x00,0x09,0x04,0x02,0x00,0x02,0x00,0x00,0x00,0x00} -}, -{ 14, - 0xfc7, - 0, - {0x07,0x05,0x82,0x02,0x40,0x00,0x00,0x07,0x05,0x02,0x02,0x40,0x00,0x00} -}, -{ 14, - 0xfd5, - 0, - {0x09,0x04,0x02,0x01,0x03,0x00,0x00,0x00,0x00,0x07,0x05,0x82,0x02,0x40} -}, -{ 14, - 0xfe3, - 0, - {0x00,0x00,0x07,0x05,0x02,0x02,0x40,0x00,0x00,0x09,0x05,0x89,0x05,0xa0} -}, -{ 10, - 0xff1, - 0, - {0x01,0x01,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00} -}, -{ 14, - 0xffb, - 0, - {0x12,0x01,0x00,0x01,0x00,0x00,0x00,0x40,0x47,0x05,0x99,0x99,0x00,0x01} -}, -{ 14, - 0x1009, - 0, - {0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x02,0xba} -}, -{ 4, - 0x1017, - 0, - {0x00,0x03,0x01,0x00} -}, -{ 2, - 0x101b, - 0, - {0x7a,0x00} -}, -{ 3, - 0x101d, - 0, - {0xba,0x05,0x00} -}, -{ 2, - 0x1020, - 0, - {0x50,0x17} -}, -{ 8, - 0x1022, - 0, - {0x90,0x7f,0xa5,0xe0,0xfb,0x30,0xe0,0x05} -}, -{ 5, - 0x102a, - 0, - {0x90,0x00,0x01,0x80,0x0d} -}, -{ 10, - 0x102f, - 0, - {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xe4} -}, -{ 3, - 0x1039, - 0, - {0x90,0x00,0x01} -}, -{ 1, - 0x103c, - 0, - {0x22} -}, -{ 14, - 0x103d, - 0, - {0x90,0x7d,0xc1,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x7c,0x00,0x7d} -}, -{ 4, - 0x104b, - 0, - {0x7e,0xeb,0x60,0x12} -}, -{ 14, - 0x104f, - 0, - {0x89,0x82,0x8a,0x83,0xe0,0xa3,0xa9,0x82,0xaa,0x83,0x8c,0x82,0x8d,0x83} -}, -{ 4, - 0x105d, - 0, - {0xf0,0x0c,0xdb,0xee} -}, -{ 8, - 0x1061, - 0, - {0x90,0x7d,0xc3,0xe0,0x90,0x7f,0xb9,0xf0} -}, -{ 1, - 0x1069, - 0, - {0x22} -}, -{ 14, - 0x106a, - 0, - {0x90,0x7d,0xc1,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x7c,0xc4,0x7d} -}, -{ 4, - 0x1078, - 0, - {0x7d,0xeb,0x60,0xe5} -}, -{ 14, - 0x107c, - 0, - {0x8c,0x82,0x8d,0x83,0xe0,0x0c,0x89,0x82,0x8a,0x83,0xf0,0xa3,0xa9,0x82} -}, -{ 4, - 0x108a, - 0, - {0xaa,0x83,0xdb,0xee} -}, -{ 1, - 0x108e, - 0, - {0x22} -}, -{ 14, - 0x108f, - 0, - {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x05,0x86,0x90,0x7d,0xc1,0xe0,0x05,0x86} -}, -{ 14, - 0x109d, - 0, - {0xa3,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa6,0x05,0x86,0xa3,0xa3,0xe0,0xf9} -}, -{ 5, - 0x10ab, - 0, - {0x60,0x16,0xa3,0x05,0x86} -}, -{ 13, - 0x10b0, - 0, - {0x90,0x7f,0xa6,0x05,0x86,0xe0,0xa3,0x05,0x86,0xf0,0xc0,0x01,0x12} -}, -{ 6, - 0x10bd, - 0, - {0x10,0x1b,0xd0,0x01,0xd9,0xed} -}, -{ 6, - 0x10c3, - 0, - {0x90,0x7f,0xa5,0x74,0x40,0xf0} -}, -{ 1, - 0x10c9, - 0, - {0x22} -}, -{ 8, - 0x10ca, - 0, - {0x90,0x88,0x02,0x74,0x01,0xf0,0x7a,0x00} -}, -{ 3, - 0x10d2, - 0, - {0xba,0xff,0x00} -}, -{ 2, - 0x10d5, - 0, - {0x50,0x0a} -}, -{ 10, - 0x10d7, - 0, - {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xf1} -}, -{ 1, - 0x10e1, - 0, - {0x22} -}, -{ 5, - 0x10e2, - 0, - {0xe5,0x6b,0xb4,0xc0,0x08} -}, -{ 8, - 0x10e7, - 0, - {0x90,0x88,0x03,0xe5,0x6c,0xf0,0x80,0x06} -}, -{ 6, - 0x10ef, - 0, - {0x90,0x88,0x02,0xe5,0x6c,0xf0} -}, -{ 4, - 0x10f5, - 0, - {0x7a,0x00,0x7b,0x00} -}, -{ 11, - 0x10f9, - 0, - {0xc3,0xea,0x94,0x32,0xeb,0x64,0x80,0x94,0x80,0x50,0x07} -}, -{ 5, - 0x1104, - 0, - {0x0a,0xba,0x00,0x01,0x0b} -}, -{ 2, - 0x1109, - 0, - {0x80,0xee} -}, -{ 1, - 0x110b, - 0, - {0x22} -}, -{ 10, - 0x110c, - 0, - {0x90,0x88,0x03,0xe5,0x6d,0xf0,0x05,0x39,0x7a,0x00} -}, -{ 3, - 0x1116, - 0, - {0xba,0x28,0x00} -}, -{ 2, - 0x1119, - 0, - {0x50,0x03} -}, -{ 3, - 0x111b, - 0, - {0x0a,0x80,0xf8} -}, -{ 5, - 0x111e, - 0, - {0xe5,0x39,0xb4,0x10,0x08} -}, -{ 8, - 0x1123, - 0, - {0x90,0x88,0x02,0x74,0xc0,0xf0,0x80,0x0e} -}, -{ 5, - 0x112b, - 0, - {0xe5,0x39,0xb4,0x20,0x09} -}, -{ 9, - 0x1130, - 0, - {0x90,0x88,0x02,0x74,0x80,0xf0,0x75,0x39,0x00} -}, -{ 2, - 0x1139, - 0, - {0x7a,0x00} -}, -{ 3, - 0x113b, - 0, - {0xba,0x28,0x00} -}, -{ 2, - 0x113e, - 0, - {0x50,0x03} -}, -{ 3, - 0x1140, - 0, - {0x0a,0x80,0xf8} -}, -{ 1, - 0x1143, - 0, - {0x22} -}, -{ 4, - 0x1144, - 0, - {0xe5,0x6f,0x60,0x02} -}, -{ 2, - 0x1148, - 0, - {0x80,0x07} -}, -{ 7, - 0x114a, - 0, - {0x7a,0x00,0x75,0x39,0x00,0x80,0x05} -}, -{ 5, - 0x1151, - 0, - {0x7a,0x40,0x75,0x39,0x10} -}, -{ 9, - 0x1156, - 0, - {0xe5,0x6e,0x2a,0xfa,0xe5,0x6e,0x25,0x39,0xf5} -}, -{ 10, - 0x115f, - 0, - {0x39,0x90,0x88,0x02,0x74,0x80,0x2a,0xf0,0x7a,0x00} -}, -{ 8, - 0x1169, - 0, - {0xc3,0xea,0x64,0x80,0x94,0xa8,0x50,0x03} -}, -{ 3, - 0x1171, - 0, - {0x0a,0x80,0xf5} -}, -{ 1, - 0x1174, - 0, - {0x22} -}, -{ 6, - 0x1175, - 0, - {0xaa,0x70,0xab,0x71,0xac,0x72} -}, -{ 12, - 0x117b, - 0, - {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x12,0x14,0xee,0xfd,0x60,0x18} -}, -{ 13, - 0x1187, - 0, - {0x8d,0x6d,0xc0,0x02,0xc0,0x03,0xc0,0x04,0x12,0x11,0x0c,0xd0,0x04} -}, -{ 9, - 0x1194, - 0, - {0xd0,0x03,0xd0,0x02,0x0a,0xba,0x00,0x01,0x0b} -}, -{ 2, - 0x119d, - 0, - {0x80,0xdc} -}, -{ 1, - 0x119f, - 0, - {0x22} -}, -{ 13, - 0x11a0, - 0, - {0xe5,0x73,0xc4,0x54,0x0f,0xfa,0x53,0x02,0x0f,0xc3,0x74,0x09,0x9a} -}, -{ 2, - 0x11ad, - 0, - {0x50,0x06} -}, -{ 6, - 0x11af, - 0, - {0x74,0x37,0x2a,0xfb,0x80,0x04} -}, -{ 4, - 0x11b5, - 0, - {0x74,0x30,0x2a,0xfb} -}, -{ 12, - 0x11b9, - 0, - {0x8b,0x6d,0xc0,0x03,0x12,0x11,0x0c,0xd0,0x03,0xaa,0x73,0x53} -}, -{ 8, - 0x11c5, - 0, - {0x02,0x0f,0xc3,0x74,0x09,0x9a,0x50,0x06} -}, -{ 6, - 0x11cd, - 0, - {0x74,0x37,0x2a,0xfb,0x80,0x04} -}, -{ 4, - 0x11d3, - 0, - {0x74,0x30,0x2a,0xfb} -}, -{ 5, - 0x11d7, - 0, - {0x8b,0x6d,0x12,0x11,0x0c} -}, -{ 1, - 0x11dc, - 0, - {0x22} -}, -{ 7, - 0x11dd, - 0, - {0x90,0x7d,0xc3,0xe0,0xfa,0x60,0x0f} -}, -{ 12, - 0x11e4, - 0, - {0x90,0x7d,0xc1,0xe0,0xf5,0x6e,0x90,0x7d,0xc2,0xe0,0xf5,0x6f} -}, -{ 3, - 0x11f0, - 0, - {0x12,0x11,0x44} -}, -{ 12, - 0x11f3, - 0, - {0x90,0x7d,0xff,0xe4,0xf0,0x75,0x70,0xc4,0x75,0x71,0x7d,0x75} -}, -{ 5, - 0x11ff, - 0, - {0x72,0x01,0x12,0x11,0x75} -}, -{ 1, - 0x1204, - 0, - {0x22} -}, -{ 2, - 0x1205, - 0, - {0x7a,0x04} -}, -{ 3, - 0x1207, - 0, - {0xba,0x40,0x00} -}, -{ 2, - 0x120a, - 0, - {0x50,0x36} -}, -{ 14, - 0x120c, - 0, - {0xea,0x24,0xc0,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe0,0xfb,0x7c,0x00} -}, -{ 3, - 0x121a, - 0, - {0xbc,0x08,0x00} -}, -{ 2, - 0x121d, - 0, - {0x50,0x20} -}, -{ 6, - 0x121f, - 0, - {0x8b,0x05,0xed,0x30,0xe7,0x0b} -}, -{ 11, - 0x1225, - 0, - {0x90,0x7f,0x96,0x74,0x42,0xf0,0x74,0xc3,0xf0,0x80,0x08} -}, -{ 8, - 0x1230, - 0, - {0x90,0x7f,0x96,0xe4,0xf0,0x74,0x81,0xf0} -}, -{ 7, - 0x1238, - 0, - {0xeb,0x25,0xe0,0xfb,0x0c,0x80,0xdb} -}, -{ 3, - 0x123f, - 0, - {0x0a,0x80,0xc5} -}, -{ 1, - 0x1242, - 0, - {0x22} -}, -{ 4, - 0x1243, - 0, - {0x7a,0x00,0x7b,0xef} -}, -{ 3, - 0x1247, - 0, - {0xba,0x10,0x00} -}, -{ 2, - 0x124a, - 0, - {0x50,0x20} -}, -{ 14, - 0x124c, - 0, - {0x74,0x11,0x2b,0xfb,0x24,0x00,0xfc,0xe4,0x34,0x18,0xfd,0x8c,0x82,0x8d} -}, -{ 14, - 0x125a, - 0, - {0x83,0xe4,0xf0,0xea,0x24,0x00,0xf5,0x82,0xe4,0x34,0x19,0xf5,0x83,0xe4} -}, -{ 4, - 0x1268, - 0, - {0xf0,0x0a,0x80,0xdb} -}, -{ 1, - 0x126c, - 0, - {0x22} -}, -{ 14, - 0x126d, - 0, - {0x74,0xf8,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} -}, -{ 14, - 0x127b, - 0, - {0x74,0xf9,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} -}, -{ 14, - 0x1289, - 0, - {0x74,0xfa,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} -}, -{ 14, - 0x1297, - 0, - {0x74,0xfb,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} -}, -{ 14, - 0x12a5, - 0, - {0x74,0xff,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} -}, -{ 1, - 0x12b3, - 0, - {0x22} -}, -{ 14, - 0x12b4, - 0, - {0x12,0x03,0xcb,0x12,0x12,0x6d,0x7a,0xc0,0x7b,0x87,0x7c,0x01,0x74,0x01} -}, -{ 14, - 0x12c2, - 0, - {0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x74} -}, -{ 14, - 0x12d0, - 0, - {0x01,0x12,0x14,0xbf,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e} -}, -{ 14, - 0x12de, - 0, - {0x83,0x8f,0xf0,0x74,0x06,0x12,0x14,0xbf,0x74,0x01,0x2a,0xfd,0xe4,0x3b} -}, -{ 14, - 0x12ec, - 0, - {0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83,0x8c,0xf0,0xe4,0x12,0x14,0xbf,0x74} -}, -{ 14, - 0x12fa, - 0, - {0x01,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0} -}, -{ 14, - 0x1308, - 0, - {0x74,0x0b,0x12,0x14,0xbf,0x74,0x01,0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07} -}, -{ 14, - 0x1316, - 0, - {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x74,0x08,0x12,0x14,0xbf,0x74,0x01,0x2d} -}, -{ 14, - 0x1324, - 0, - {0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0,0x74,0x01} -}, -{ 14, - 0x1332, - 0, - {0x12,0x14,0xbf,0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83} -}, -{ 14, - 0x1340, - 0, - {0x8c,0xf0,0xe4,0x12,0x14,0xbf,0x74,0x01,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f} -}, -{ 14, - 0x134e, - 0, - {0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0,0x74,0x03,0x12,0x14,0xbf,0x7d,0x00} -}, -{ 3, - 0x135c, - 0, - {0xbd,0x06,0x00} -}, -{ 2, - 0x135f, - 0, - {0x50,0x12} -}, -{ 11, - 0x1361, - 0, - {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x0a,0xba,0x00,0x01,0x0b} -}, -{ 7, - 0x136c, - 0, - {0xe4,0x12,0x14,0xbf,0x0d,0x80,0xe9} -}, -{ 13, - 0x1373, - 0, - {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0xe5,0x74,0x12,0x14,0xbf,0x74,0xf9} -}, -{ 14, - 0x1380, - 0, - {0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0x74,0x0f,0xf0,0x74} -}, -{ 14, - 0x138e, - 0, - {0xfe,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0x74,0x01,0xf0} -}, -{ 6, - 0x139c, - 0, - {0x12,0x03,0xe1,0x12,0x04,0xf7} -}, -{ 1, - 0x13a2, - 0, - {0x22} -}, -{ 13, - 0x13a3, - 0, - {0x90,0x7d,0xc1,0xe0,0xfa,0x24,0x00,0xfb,0xe4,0x34,0x19,0xfc,0x90} -}, -{ 14, - 0x13b0, - 0, - {0x7d,0xc2,0xe0,0xfd,0x8b,0x82,0x8c,0x83,0xf0,0x75,0xf0,0x11,0xea,0xa4} -}, -{ 3, - 0x13be, - 0, - {0xfa,0x7b,0x00} -}, -{ 3, - 0x13c1, - 0, - {0xbb,0x10,0x00} -}, -{ 2, - 0x13c4, - 0, - {0x50,0x24} -}, -{ 14, - 0x13c6, - 0, - {0xea,0x24,0x00,0xfc,0xe4,0x34,0x18,0xfd,0xeb,0x2c,0xfc,0xe4,0x3d,0xfd} -}, -{ 14, - 0x13d4, - 0, - {0x74,0x04,0x2b,0x24,0xc0,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe0,0xfe} -}, -{ 8, - 0x13e2, - 0, - {0x8c,0x82,0x8d,0x83,0xf0,0x0b,0x80,0xd7} -}, -{ 14, - 0x13ea, - 0, - {0xea,0x24,0x00,0xfa,0xe4,0x34,0x18,0xfb,0x74,0x10,0x2a,0xf5,0x82,0xe4} -}, -{ 5, - 0x13f8, - 0, - {0x3b,0xf5,0x83,0xe4,0xf0} -}, -{ 1, - 0x13fd, - 0, - {0x22} -}, -{ 4, - 0x13fe, - 0, - {0xe5,0x76,0x60,0x02} -}, -{ 2, - 0x1402, - 0, - {0x80,0x16} -}, -{ 12, - 0x1404, - 0, - {0x74,0x0f,0x55,0x75,0xfa,0x8a,0x75,0x24,0x00,0xf5,0x82,0xe4} -}, -{ 10, - 0x1410, - 0, - {0x34,0x19,0xf5,0x83,0xe0,0xf5,0x74,0x12,0x12,0xb4} -}, -{ 10, - 0x141a, - 0, - {0x12,0x10,0xca,0x75,0x6e,0x00,0x75,0x6f,0x00,0x12} -}, -{ 6, - 0x1424, - 0, - {0x11,0x44,0x75,0x70,0xb9,0x75} -}, -{ 6, - 0x142a, - 0, - {0x71,0x14,0x75,0x72,0x02,0x12} -}, -{ 11, - 0x1430, - 0, - {0x11,0x75,0xe5,0x76,0xb4,0x02,0x04,0x74,0x01,0x80,0x01} -}, -{ 1, - 0x143b, - 0, - {0xe4} -}, -{ 3, - 0x143c, - 0, - {0xfa,0x70,0x0f} -}, -{ 12, - 0x143f, - 0, - {0x74,0x01,0x25,0x75,0xf5,0x73,0xc0,0x02,0x12,0x11,0xa0,0xd0} -}, -{ 3, - 0x144b, - 0, - {0x02,0x80,0x0a} -}, -{ 10, - 0x144e, - 0, - {0x85,0x75,0x73,0xc0,0x02,0x12,0x11,0xa0,0xd0,0x02} -}, -{ 12, - 0x1458, - 0, - {0x75,0x6e,0x00,0x75,0x6f,0x01,0xc0,0x02,0x12,0x11,0x44,0xd0} -}, -{ 4, - 0x1464, - 0, - {0x02,0xea,0x70,0x1a} -}, -{ 13, - 0x1468, - 0, - {0x75,0xf0,0x11,0xe5,0x75,0xa4,0xfa,0x24,0x00,0xfa,0xe4,0x34,0x18} -}, -{ 9, - 0x1475, - 0, - {0xfb,0x8a,0x70,0x8b,0x71,0x75,0x72,0x01,0x12} -}, -{ 4, - 0x147e, - 0, - {0x11,0x75,0x80,0x36} -}, -{ 2, - 0x1482, - 0, - {0x7a,0x00} -}, -{ 3, - 0x1484, - 0, - {0xba,0x10,0x00} -}, -{ 2, - 0x1487, - 0, - {0x50,0x2f} -}, -{ 13, - 0x1489, - 0, - {0xea,0x24,0x00,0xf5,0x82,0xe4,0x34,0x19,0xf5,0x83,0xe0,0xfb,0xe5} -}, -{ 4, - 0x1496, - 0, - {0x75,0xb5,0x03,0x1b} -}, -{ 14, - 0x149a, - 0, - {0x75,0xf0,0x11,0xea,0xa4,0xfb,0x24,0x00,0xfb,0xe4,0x34,0x18,0xfc,0x8b} -}, -{ 9, - 0x14a8, - 0, - {0x70,0x8c,0x71,0x75,0x72,0x01,0xc0,0x02,0x12} -}, -{ 4, - 0x14b1, - 0, - {0x11,0x75,0xd0,0x02} -}, -{ 3, - 0x14b5, - 0, - {0x0a,0x80,0xcc} -}, -{ 1, - 0x14b8, - 0, - {0x22} -}, -{ 6, - 0x14b9, - 0, - {0x50,0x72,0x6f,0x67,0x20,0x00} -}, -{ 14, - 0x14bf, - 0, - {0xc8,0xc0,0xe0,0xc8,0xc0,0xe0,0xe5,0xf0,0x60,0x0b,0x14,0x60,0x0f,0x14} -}, -{ 7, - 0x14cd, - 0, - {0x60,0x11,0x14,0x60,0x12,0x80,0x15} -}, -{ 7, - 0x14d4, - 0, - {0xd0,0xe0,0xa8,0x82,0xf6,0x80,0x0e} -}, -{ 5, - 0x14db, - 0, - {0xd0,0xe0,0xf0,0x80,0x09} -}, -{ 4, - 0x14e0, - 0, - {0xd0,0xe0,0x80,0x05} -}, -{ 5, - 0x14e4, - 0, - {0xd0,0xe0,0xa8,0x82,0xf2} -}, -{ 4, - 0x14e9, - 0, - {0xc8,0xd0,0xe0,0xc8} -}, -{ 1, - 0x14ed, - 0, - {0x22} -}, -{ 14, - 0x14ee, - 0, - {0xc8,0xc0,0xe0,0xe5,0xf0,0x60,0x0d,0x14,0x60,0x0f,0x14,0x60,0x0f,0x14} -}, -{ 6, - 0x14fc, - 0, - {0x60,0x10,0x74,0xff,0x80,0x0f} -}, -{ 5, - 0x1502, - 0, - {0xa8,0x82,0xe6,0x80,0x0a} -}, -{ 3, - 0x1507, - 0, - {0xe0,0x80,0x07} -}, -{ 4, - 0x150a, - 0, - {0xe4,0x93,0x80,0x03} -}, -{ 3, - 0x150e, - 0, - {0xa8,0x82,0xe2} -}, -{ 4, - 0x1511, - 0, - {0xf8,0xd0,0xe0,0xc8} -}, -{ 1, - 0x1515, - 0, - {0x22} -}, -{ 0, - 0x0, - 1, - {0} -} -}; diff -ur --new-file old/linux/drivers/usb/graphire.c new/linux/drivers/usb/graphire.c --- old/linux/drivers/usb/graphire.c Thu Jan 20 18:48:48 2000 +++ new/linux/drivers/usb/graphire.c Tue Jan 25 00:21:55 2000 @@ -1,11 +1,16 @@ /* - * graphire.c Version 0.1 + * graphire.c Version 0.2 * - * Copyright (c) 1999 Vojtech Pavlik + * Copyright (c) 2000 Vojtech Pavlik + * Copyright (c) 2000 Andreas Bach Aaen * * USB Wacom Graphire tablet support * * Sponsored by SuSE + * + * ChangeLog: + * v0.1 (vp) - Initial release + * v0.2 (aba) - Support for all buttons / combinations */ /* @@ -57,14 +62,19 @@ * byte 7: pen presure high bits / mouse distance * * There are also two single-byte feature reports (2 and 3). + * + * Resolution: + * X: 0 - 10206 + * Y: 0 - 7422 + * + * (0,0) is upper left corner */ -#define USB_VENDOR_ID_WACOM 0xffff /* FIXME */ -#define USB_DEVICE_ID_WACOM_GRAPHIRE 0xffff /* FIXME */ +#define USB_VENDOR_ID_WACOM 0x056a +#define USB_DEVICE_ID_WACOM_GRAPHIRE 0x0010 struct graphire { signed char data[8]; - int oldx, oldy; struct input_dev dev; struct urb irq; }; @@ -80,44 +90,38 @@ if (data[0] != 2) dbg("received unknown report #%d", data[0]); - input_report_abs(dev, ABS_X, data[2] | ((__u32)data[3] << 8)); - input_report_abs(dev, ABS_Y, data[4] | ((__u32)data[5] << 8)); - - input_report_key(dev, BTN_NEAR, !!(data[1] & 0x80)); + if ( data[1] & 0x80 ) { + input_report_abs(dev, ABS_X, data[2] | ((__u32)data[3] << 8)); + input_report_abs(dev, ABS_Y, 7422 - (data[4] | ((__u32)data[5] << 8))); + } switch ((data[1] >> 5) & 3) { case 0: /* Pen */ - input_report_key(dev, BTN_PEN, !!(data[1] & 0x01)); - input_report_key(dev, BTN_PEN_SIDE, !!(data[1] & 0x02)); - input_report_key(dev, BTN_PEN_SIDE2, !!(data[1] & 0x04)); + input_report_key(dev, BTN_TOOL_PEN, !!(data[1] & 0x80)); + input_report_key(dev, BTN_TOUCH, !!(data[1] & 0x01)); + input_report_key(dev, BTN_STYLUS, !!(data[1] & 0x02)); + input_report_key(dev, BTN_STYLUS2, !!(data[1] & 0x04)); input_report_abs(dev, ABS_PRESSURE, data[6] | ((__u32)data[7] << 8)); break; case 1: /* Rubber */ - input_report_key(dev, BTN_RUBBER, !!(data[1] & 0x01)); - input_report_key(dev, BTN_PEN_SIDE, !!(data[1] & 0x02)); - input_report_key(dev, BTN_PEN_SIDE2, !!(data[1] & 0x04)); + input_report_key(dev, BTN_TOOL_RUBBER, !!(data[1] & 0x80)); + input_report_key(dev, BTN_TOUCH, !!(data[1] & 0x01)); + input_report_key(dev, BTN_STYLUS, !!(data[1] & 0x02)); + input_report_key(dev, BTN_STYLUS2, !!(data[1] & 0x04)); input_report_abs(dev, ABS_PRESSURE, data[6] | ((__u32)data[7] << 8)); break; case 2: /* Mouse */ - input_report_key(dev, BTN_LEFT, !!(data[0] & 0x01)); - input_report_key(dev, BTN_RIGHT, !!(data[0] & 0x02)); - input_report_key(dev, BTN_MIDDLE, !!(data[0] & 0x04)); + input_report_key(dev, BTN_TOOL_MOUSE, data[7] > 24); + input_report_key(dev, BTN_LEFT, !!(data[1] & 0x01)); + input_report_key(dev, BTN_RIGHT, !!(data[1] & 0x02)); + input_report_key(dev, BTN_MIDDLE, !!(data[1] & 0x04)); input_report_abs(dev, ABS_DISTANCE, data[7]); - - if (data[1] & 0x80) { - input_report_rel(dev, REL_X, dev->abs[ABS_X] - graphire->oldx); - input_report_rel(dev, REL_Y, dev->abs[ABS_Y] - graphire->oldy); - } - input_report_rel(dev, REL_WHEEL, (signed char) data[6]); break; } - - graphire->oldx = dev->abs[ABS_X]; - graphire->oldy = dev->abs[ABS_Y]; } static void *graphire_probe(struct usb_device *dev, unsigned int ifnum) @@ -136,11 +140,16 @@ graphire->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); graphire->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); - graphire->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_PEN) | BIT(BTN_RUBBER); - graphire->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_PEN_SIDE) | BIT(BTN_PEN_SIDE2) | BIT(BTN_NEAR); - graphire->dev.relbit[0] |= BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL); + graphire->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE); + graphire->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2); + graphire->dev.relbit[0] |= BIT(REL_WHEEL); graphire->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_DISTANCE); + graphire->dev.absmax[ABS_X] = 10206; + graphire->dev.absmax[ABS_Y] = 7422; + graphire->dev.absmax[ABS_PRESSURE] = 511; + graphire->dev.absmax[ABS_DISTANCE] = 32; + FILL_INT_URB(&graphire->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), graphire->data, 8, graphire_irq, graphire, endpoint->bInterval); @@ -151,7 +160,7 @@ input_register_device(&graphire->dev); - printk(KERN_INFO "input%d: Wacom Graphire USB\n", graphire->dev.number); + printk(KERN_INFO "input%d: Wacom Graphire\n", graphire->dev.number); return graphire; } diff -ur --new-file old/linux/drivers/usb/hid.c new/linux/drivers/usb/hid.c --- old/linux/drivers/usb/hid.c Thu Jan 20 18:48:48 2000 +++ new/linux/drivers/usb/hid.c Mon Jan 24 07:39:14 2000 @@ -742,7 +742,11 @@ switch (device->application) { case HID_GD_GAMEPAD: usage->code += 0x10; case HID_GD_JOYSTICK: usage->code += 0x10; - case HID_GD_MOUSE: usage->code += 0x10; + case HID_GD_MOUSE: usage->code += 0x10; break; + default: + if (field->physical == HID_GD_POINTER) + usage->code += 0x10; + break; } break; @@ -769,7 +773,49 @@ usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; break; + case HID_UP_DIGITIZER: + + switch (usage->hid & 0xff) { + + case 0x30: /* TipPressure */ + + usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; + usage->code = ABS_PRESSURE; + clear_bit(usage->code, bit); + break; + + case 0x32: /* InRange */ + + usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; + switch (field->physical & 0xff) { + case 0x21: usage->code = BTN_TOOL_MOUSE; break; + case 0x22: usage->code = BTN_TOOL_FINGER; break; + default: usage->code = BTN_TOOL_PEN; break; + } + break; + + case 0x33: /* Touch */ + case 0x42: /* TipSwitch */ + case 0x43: /* TipSwitch2 */ + + usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; + usage->code = BTN_TOUCH; + clear_bit(usage->code, bit); + break; + + case 0x44: /* BarrelSwitch */ + + usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; + usage->code = BTN_STYLUS; + clear_bit(usage->code, bit); + break; + + default: goto unknown; + } + break; + default: + unknown: if (field->flags & HID_MAIN_ITEM_RELATIVE) { usage->code = REL_MISC; @@ -777,7 +823,7 @@ break; } - if (field->logical_minimum == 0 && field->logical_maximum == 1) { + if (field->report_size == 1) { usage->code = BTN_MISC; usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; break; @@ -959,7 +1005,7 @@ static void hid_read_report(struct hid_device *hid, struct hid_report *report) { #if 0 - int rlen = ((report->size - 1) >> 3) + 1 + hid->report_enum[HID_INPUT_REPORT].numbered; + int rlen = ((report->size - 1) >> 3) + 1; char rdata[rlen]; struct urb urb; int read, j; @@ -973,7 +1019,7 @@ dbg("getting report type %d id %d len %d", report->type + 1, report->id, rlen); - if ((read = usb_get_report(hid->dev, report->type + 1, report->id, hid->ifnum, rdata, rlen)) != rlen) { + if ((read = usb_get_report(hid->dev, hid->ifnum, report->type + 1, report->id, rdata, rlen)) != rlen) { dbg("reading report failed rlen %d read %d", rlen, read); #ifdef DEBUG printk(KERN_DEBUG __FILE__ ": report = "); @@ -1013,13 +1059,6 @@ void hid_output_report(struct hid_report *report, __u8 *data) { unsigned n; - -#if 0 - /* skip the ID if we have a single report */ - if (report->device->report_enum[report->type].numbered) - *data++ = report->id; -#endif - for (n = 0; n < report->maxfield; n++) hid_output_field(report->field[n], data); }; @@ -1142,7 +1181,7 @@ hid_configure_usage(hid, report->field[i], report->field[i]->usage + j); if (k == HID_INPUT_REPORT) { - usb_set_idle(hid->dev, 0, report->id); + usb_set_idle(hid->dev, hid->ifnum, report->id, 0); hid_read_report(hid, report); } } @@ -1151,7 +1190,7 @@ static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum) { - struct usb_interface_descriptor *interface = &dev->actconfig->interface[ifnum].altsetting[0]; + struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0; struct hid_descriptor *hdesc; struct hid_device *hid; unsigned rsize = 0; @@ -1178,7 +1217,7 @@ { __u8 rdesc[rsize]; - if ((n = usb_get_class_descriptor(dev, USB_DT_REPORT, 0, ifnum, rdesc, rsize)) < 0) { + if ((n = usb_get_class_descriptor(dev, interface->bInterfaceNumber, USB_DT_REPORT, 0, rdesc, rsize)) < 0) { dbg("reading report descriptor failed"); return NULL; } @@ -1226,19 +1265,22 @@ return NULL; } + hid->version = hdesc->bcdHID; + hid->country = hdesc->bCountryCode; + hid->dev = dev; + hid->ifnum = interface->bInterfaceNumber; + hid->dr.requesttype = USB_TYPE_CLASS | USB_RECIP_INTERFACE; hid->dr.request = USB_REQ_SET_REPORT; hid->dr.value = 0x200; - hid->dr.index = interface->bInterfaceNumber; + hid->dr.index = hid->ifnum; hid->dr.length = 1; FILL_CONTROL_URB(&hid->urbout, dev, usb_sndctrlpipe(dev, 0), (void*) &hid->dr, hid->bufout, 1, hid_ctrl, hid); - hid->version = hdesc->bcdHID; - hid->country = hdesc->bCountryCode; - hid->dev = dev; - hid->ifnum = ifnum; + if (interface->bInterfaceSubClass == 1) + usb_set_protocol(dev, hid->ifnum, 1); return hid; } diff -ur --new-file old/linux/drivers/usb/hid.h new/linux/drivers/usb/hid.h --- old/linux/drivers/usb/hid.h Thu Jan 20 18:48:48 2000 +++ new/linux/drivers/usb/hid.h Tue Jan 25 20:41:20 2000 @@ -30,7 +30,6 @@ * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic */ -#include #include #include #include @@ -164,6 +163,7 @@ #define HID_USAGE 0x0000ffff +#define HID_GD_POINTER 0x00010001 #define HID_GD_MOUSE 0x00010002 #define HID_GD_JOYSTICK 0x00010004 #define HID_GD_GAMEPAD 0x00010005 diff -ur --new-file old/linux/drivers/usb/hub.c new/linux/drivers/usb/hub.c --- old/linux/drivers/usb/hub.c Thu Jan 13 22:45:34 2000 +++ new/linux/drivers/usb/hub.c Fri Jan 21 22:03:02 2000 @@ -5,7 +5,7 @@ * (C) Copyright 1999 Johannes Erdfelt * (C) Copyright 1999 Gregory P. Smith * - * $Id: hub.c,v 1.15 1999/12/27 15:17:45 acher Exp $ + * $Id: hub.c,v 1.21 2000/01/16 21:19:44 acher Exp $ */ #include @@ -22,15 +22,6 @@ #include "usb.h" #include "hub.h" -#ifdef __alpha -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) -extern long __kernel_thread(unsigned long, int (*)(void *), void *); -static inline long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -{ - return __kernel_thread(flags | CLONE_VM, fn, arg); -} -#endif -#endif /* Wakes up khubd */ static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED; @@ -112,6 +103,16 @@ return 1; } +static void usb_hub_power_on(struct usb_hub *hub) +{ + int i; + + /* Enable power to the ports */ + dbg("enabling power on all ports"); + for (i = 0; i < hub->nports; i++) + usb_set_port_feature(hub->dev, i + 1, USB_PORT_FEAT_POWER); +} + static int usb_hub_configure(struct usb_hub *hub) { struct usb_device *dev = hub->dev; @@ -191,10 +192,8 @@ dbg("%sover-current condition exists", (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? "" : "no "); - /* Enable power to the ports */ - dbg("enabling power on all ports"); - for (i = 0; i < hub->nports; i++) - usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER); + usb_hub_power_on(hub); + return 0; } @@ -322,13 +321,17 @@ portchange = le16_to_cpu(portsts.wPortChange); dbg("portstatus %x, change %x, %s", portstatus, portchange, portstatus&(1<children[port])) { usb_disconnect(&hub->children[port]); - /* We're done now, we already disconnected the device */ - return; + /* Return now if nothing is connected */ + if (!(portstatus & USB_PORT_STAT_CONNECTION)) + return; } wait_ms(400); @@ -350,7 +353,11 @@ dbg("portstatus %x, change %x, %s", portstatus ,portchange, portstatus&(1<bus); @@ -432,8 +442,6 @@ if (portchange & USB_PORT_STAT_C_CONNECTION) { dbg("port %d connection change", i + 1); - usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_CONNECTION); - usb_hub_port_connect_change(dev, i); } @@ -442,12 +450,15 @@ usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_ENABLE); } - if (portchange & USB_PORT_STAT_C_SUSPEND) + if (portstatus & USB_PORT_STAT_SUSPEND) { dbg("port %d suspend change", i + 1); - + usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_SUSPEND); + } + if (portchange & USB_PORT_STAT_C_OVERCURRENT) { - dbg("port %d over-current change", i + 1); + err("port %d over-current change", i + 1); usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_OVER_CURRENT); + usb_hub_power_on(hub); } if (portchange & USB_PORT_STAT_C_RESET) { @@ -468,7 +479,9 @@ } if (hubchange & HUB_CHANGE_OVERCURRENT) { dbg("hub overcurrent change"); + wait_ms(500); //Cool down usb_clear_hub_feature(dev, C_HUB_OVER_CURRENT); + usb_hub_power_on(hub); } } } /* end while (1) */ @@ -491,6 +504,7 @@ * This thread doesn't need any user-level access, * so get rid of all our resources */ + exit_files(current); /* daemonize doesn't do exit_files */ daemonize(); /* Setup a nice name */ diff -ur --new-file old/linux/drivers/usb/ibmcam.c new/linux/drivers/usb/ibmcam.c --- old/linux/drivers/usb/ibmcam.c Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/usb/ibmcam.c Mon Jan 24 07:39:14 2000 @@ -0,0 +1,2346 @@ +/* + * USB IBM C-It Video Camera driver + * + * Supports IBM C-It Video Camera. + * + * This driver is based on earlier work of: + * + * (C) Copyright 1999 Johannes Erdfelt + * (C) Copyright 1999 Randy Dunlap + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "usb.h" +#include "ibmcam.h" + +#define ENABLE_HEXDUMP 0 /* Enable if you need it */ +static int debug = 0; + +/* Completion states of the data parser */ +typedef enum { + scan_Continue, /* Just parse next item */ + scan_NextFrame, /* Frame done, send it to V4L */ + scan_Out, /* Not enough data for frame */ + scan_EndParse /* End parsing */ +} scan_state_t; + +/* Bit flags (options) */ +#define FLAGS_RETRY_VIDIOCSYNC (1 << 0) +#define FLAGS_MONOCHROME (1 << 1) +#define FLAGS_DISPLAY_HINTS (1 << 2) +#define FLAGS_OVERLAY_STATS (1 << 3) +#define FLAGS_FORCE_TESTPATTERN (1 << 4) + +static int flags = 0; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */ + +/* This is the size of V4L frame that we provide */ +static const int imgwidth = V4L_FRAME_WIDTH_USED; +static const int imgheight = V4L_FRAME_HEIGHT; +static const int min_imgwidth = 8; +static const int min_imgheight = 4; + +#define LIGHTING_MIN 0 /* 0=Bright 1=Med 2=Low */ +#define LIGHTING_MAX 2 +static int lighting = (LIGHTING_MIN + LIGHTING_MAX) / 2; /* Medium */ + +#define SHARPNESS_MIN 0 +#define SHARPNESS_MAX 6 +static int sharpness = 4; /* Low noise, good details */ + +#define FRAMERATE_MIN 0 +#define FRAMERATE_MAX 6 +static int framerate = 2; /* Lower, reliable frame rate (8-12 fps) */ + +enum { + VIDEOSIZE_128x96 = 0, + VIDEOSIZE_176x144, + VIDEOSIZE_352x288 +}; + +static int videosize = VIDEOSIZE_352x288; + +/* + * The value of 'scratchbufsize' affects quality of the picture + * in many ways. Shorter buffers may cause loss of data when client + * is too slow. Larger buffers are memory-consuming and take longer + * to work with. This setting can be adjusted, but the default value + * should be OK for most desktop users. + */ +#define DEFAULT_SCRATCH_BUF_SIZE (0x10000) /* 64 KB */ +static const int scratchbufsize = DEFAULT_SCRATCH_BUF_SIZE; + +/* + * Here we define several initialization variables. They may + * be used to automatically set color, hue, brightness and + * contrast to desired values. This is particularly useful in + * case of webcams (which have no controls and no on-screen + * output) and also when a client V4L software is used that + * does not have some of those controls. In any case it's + * good to have startup values as options. + * + * These values are all in [0..255] range. This simplifies + * operation. Note that actual values of V4L variables may + * be scaled up (as much as << 8). User can see that only + * on overlay output, however, or through a V4L client. + */ +static int init_brightness = 128; +static int init_contrast = 192; +static int init_color = 128; +static int init_hue = 128; + +MODULE_PARM(debug, "i"); +MODULE_PARM(flags, "i"); +MODULE_PARM(framerate, "i"); +MODULE_PARM(lighting, "i"); +MODULE_PARM(sharpness, "i"); +MODULE_PARM(videosize, "i"); +MODULE_PARM(init_brightness, "i"); +MODULE_PARM(init_contrast, "i"); +MODULE_PARM(init_color, "i"); +MODULE_PARM(init_hue, "i"); + +MODULE_AUTHOR ("module author"); +MODULE_DESCRIPTION ("IBM/Xirlink C-it USB Camera Driver for Linux (c) 2000"); + +/* Still mysterious i2c commands */ +static const unsigned short unknown_88 = 0x0088; +static const unsigned short unknown_89 = 0x0089; +static const unsigned short bright_3x[3] = { 0x0031, 0x0032, 0x0033 }; +static const unsigned short contrast_14 = 0x0014; +static const unsigned short light_27 = 0x0027; +static const unsigned short sharp_13 = 0x0013; + +/*******************************/ +/* Memory management functions */ +/*******************************/ + +#define MDEBUG(x) do { } while(0) /* Debug memory management */ + +static struct usb_driver ibmcam_driver; + +/* Given PGD from the address space's page table, return the kernel + * virtual mapping of the physical memory mapped at ADR. + */ +static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr) +{ + unsigned long ret = 0UL; + pmd_t *pmd; + pte_t *ptep, pte; + + if (!pgd_none(*pgd)) { + pmd = pmd_offset(pgd, adr); + if (!pmd_none(*pmd)) { + ptep = pte_offset(pmd, adr); + pte = *ptep; + if (pte_present(pte)) + ret = page_address(pte_page(pte)) | (adr & (PAGE_SIZE-1)); + } + } + MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret)); + return ret; +} + +static inline unsigned long uvirt_to_bus(unsigned long adr) +{ + unsigned long kva, ret; + + kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr); + ret = virt_to_bus((void *)kva); + MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret)); + return ret; +} + +static inline unsigned long kvirt_to_bus(unsigned long adr) +{ + unsigned long va, kva, ret; + + va = VMALLOC_VMADDR(adr); + kva = uvirt_to_kva(pgd_offset_k(va), va); + ret = virt_to_bus((void *)kva); + MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret)); + return ret; +} + +/* Here we want the physical address of the memory. + * This is used when initializing the contents of the + * area and marking the pages as reserved. + */ +static inline unsigned long kvirt_to_pa(unsigned long adr) +{ + unsigned long va, kva, ret; + + va = VMALLOC_VMADDR(adr); + kva = uvirt_to_kva(pgd_offset_k(va), va); + ret = __pa(kva); + MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret)); + return ret; +} + +static void *rvmalloc(unsigned long size) +{ + void *mem; + unsigned long adr, page; + + /* Round it off to PAGE_SIZE */ + size += (PAGE_SIZE - 1); + size &= ~(PAGE_SIZE - 1); + + mem = vmalloc(size); + if (!mem) + return NULL; + + memset(mem, 0, size); /* Clear the ram out, no junk to the user */ + adr = (unsigned long) mem; + while (size > 0) { + page = kvirt_to_pa(adr); + mem_map_reserve(MAP_NR(__va(page))); + adr += PAGE_SIZE; + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; + } + + return mem; +} + +static void rvfree(void *mem, unsigned long size) +{ + unsigned long adr, page; + + if (!mem) + return; + + size += (PAGE_SIZE - 1); + size &= ~(PAGE_SIZE - 1); + + adr=(unsigned long) mem; + while (size > 0) { + page = kvirt_to_pa(adr); + mem_map_unreserve(MAP_NR(__va(page))); + adr += PAGE_SIZE; + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; + } + vfree(mem); +} + +/* + * usb_ibmcam_overlaychar() + * + * History: + * 1/2/00 Created. + */ +void usb_ibmcam_overlaychar( + struct usb_ibmcam *ibmcam, + struct ibmcam_frame *frame, + int x, int y, int ch) +{ + static const unsigned short digits[16] = { + 0xF6DE, /* 0 */ + 0x2492, /* 1 */ + 0xE7CE, /* 2 */ + 0xE79E, /* 3 */ + 0xB792, /* 4 */ + 0xF39E, /* 5 */ + 0xF3DE, /* 6 */ + 0xF492, /* 7 */ + 0xF7DE, /* 8 */ + 0xF79E, /* 9 */ + 0x77DA, /* a */ + 0xD75C, /* b */ + 0xF24E, /* c */ + 0xD6DC, /* d */ + 0xF34E, /* e */ + 0xF348 /* f */ + }; + unsigned short digit; + int ix, iy; + + if ((ibmcam == NULL) || (frame == NULL)) + return; + + if (ch >= '0' && ch <= '9') + ch -= '0'; + else if (ch >= 'A' && ch <= 'F') + ch = 10 + (ch - 'A'); + else if (ch >= 'a' && ch <= 'f') + ch = 10 + (ch - 'a'); + else + return; + digit = digits[ch]; + + for (iy=0; iy < 5; iy++) { + for (ix=0; ix < 3; ix++) { + if (digit & 0x8000) { + IBMCAM_PUTPIXEL(frame, x+ix, y+iy, 0xFF, 0xFF, 0xFF); + } + digit = digit << 1; + } + } +} + +/* + * usb_ibmcam_overlaystring() + * + * History: + * 1/2/00 Created. + */ +void usb_ibmcam_overlaystring( + struct usb_ibmcam *ibmcam, + struct ibmcam_frame *frame, + int x, int y, const char *str) +{ + while (*str) { + usb_ibmcam_overlaychar(ibmcam, frame, x, y, *str); + str++; + x += 4; /* 3 pixels character + 1 space */ + } +} + +/* + * usb_ibmcam_overlaystats() + * + * Overlays important debugging information. + * + * History: + * 1/2/00 Created. + */ +void usb_ibmcam_overlaystats(struct usb_ibmcam *ibmcam, struct ibmcam_frame *frame) +{ + const int y_diff = 8; + char tmp[16]; + int x = 10; + int y = 10; + + sprintf(tmp, "%8x", ibmcam->frame_num); + usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp); + y += y_diff; + + sprintf(tmp, "%8lx", ibmcam->urb_count); + usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp); + y += y_diff; + + sprintf(tmp, "%8lx", ibmcam->urb_length); + usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp); + y += y_diff; + + sprintf(tmp, "%8lx", ibmcam->data_count); + usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp); + y += y_diff; + + sprintf(tmp, "%8lx", ibmcam->header_count); + usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp); + y += y_diff; + + sprintf(tmp, "%8lx", ibmcam->scratch_ovf_count); + usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp); + y += y_diff; + + sprintf(tmp, "%8lx", ibmcam->iso_skip_count); + usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp); + y += y_diff; + + sprintf(tmp, "%8lx", ibmcam->iso_err_count); + usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp); + y += y_diff; + + sprintf(tmp, "%8x", ibmcam->vpic.colour); + usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp); + y += y_diff; + + sprintf(tmp, "%8x", ibmcam->vpic.hue); + usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp); + y += y_diff; + + sprintf(tmp, "%8x", ibmcam->vpic.brightness >> 8); + usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp); + y += y_diff; + + sprintf(tmp, "%8x", ibmcam->vpic.contrast >> 12); + usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp); + y += y_diff; + + sprintf(tmp, "%8d", ibmcam->vpic.whiteness >> 8); + usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp); + y += y_diff; +} + +/* + * usb_ibmcam_testpattern() + * + * Procedure forms a test pattern (yellow grid on blue background). + * + * Parameters: + * fullframe: if TRUE then entire frame is filled, otherwise the procedure + * continues from the current scanline. + * pmode 0: fill the frame with solid blue color (like on VCR or TV) + * 1: Draw a colored grid + * + * History: + * 1/2/00 Created. + */ +void usb_ibmcam_testpattern(struct usb_ibmcam *ibmcam, int fullframe, int pmode) +{ + static const char proc[] = "usb_ibmcam_testpattern"; + struct ibmcam_frame *frame; + unsigned char *f; + int num_cell = 0; + int scan_length = 0; + static int num_pass = 0; + + if (ibmcam == NULL) { + printk(KERN_ERR "%s: ibmcam == NULL\n", proc); + return; + } + if ((ibmcam->curframe < 0) || (ibmcam->curframe >= IBMCAM_NUMFRAMES)) { + printk(KERN_ERR "%s: ibmcam->curframe=%d.\n", proc, ibmcam->curframe); + return; + } + + /* Grab the current frame */ + frame = &ibmcam->frame[ibmcam->curframe]; + + /* Optionally start at the beginning */ + if (fullframe) { + frame->curline = 0; + frame->scanlength = 0; + } + + /* Form every scan line */ + for (; frame->curline < imgheight; frame->curline++) { + int i; + + f = frame->data + (imgwidth * 3 * frame->curline); + for (i=0; i < imgwidth; i++) { + unsigned char cb=0x80; + unsigned char cg = 0; + unsigned char cr = 0; + + if (pmode == 1) { + if (frame->curline % 32 == 0) + cb = 0, cg = cr = 0xFF; + else if (i % 32 == 0) { + if (frame->curline % 32 == 1) + num_cell++; + cb = 0, cg = cr = 0xFF; + } else { + cb = ((num_cell*7) + num_pass) & 0xFF; + cg = ((num_cell*5) + num_pass*2) & 0xFF; + cr = ((num_cell*3) + num_pass*3) & 0xFF; + } + } else { + /* Just the blue screen */ + } + + *f++ = cb; + *f++ = cg; + *f++ = cr; + scan_length += 3; + } + } + + frame->grabstate = FRAME_DONE; + frame->scanlength += scan_length; + ++num_pass; + + /* We do this unconditionally, regardless of FLAGS_OVERLAY_STATS */ + usb_ibmcam_overlaystats(ibmcam, frame); +} + +static unsigned char *ibmcam_find_header(const unsigned char hdr_sig, unsigned char *data, int len) +{ + while (len >= 4) + { + if ((data[0] == 0x00) && (data[1] == 0xFF) && (data[2] == 0x00)) + { +#if 0 + /* This code helps to detect new frame markers */ + printk(KERN_DEBUG "Header sig: 00 FF 00 %02X\n", data[3]); +#endif + if (data[3] == hdr_sig) { + if (debug > 2) + printk(KERN_DEBUG "Header found.\n"); + return data; + } + } + ++data; + --len; + } + return NULL; +} + +/* How much data is left in the scratch buf? */ +#define scratch_left(x) (ibmcam->scratchlen - (int)((char *)x - (char *)ibmcam->scratch)) + +/* Grab the remaining */ +static void usb_ibmcam_align_scratch(struct usb_ibmcam *ibmcam, unsigned char *data) +{ + unsigned long left; + + left = scratch_left(data); + memmove(ibmcam->scratch, data, left); + ibmcam->scratchlen = left; +} + +/* + * usb_ibmcam_find_header() + * + * Locate one of supported header markers in the scratch buffer. + * Once found, remove all preceding bytes AND the marker (4 bytes) + * from the scratch buffer. Whatever follows must be video lines. + * + * History: + * 1/21/00 Created. + */ +static scan_state_t usb_ibmcam_find_header(struct usb_ibmcam *ibmcam) +{ + struct ibmcam_frame *frame; + unsigned char *data, *tmp; + + data = ibmcam->scratch; + frame = &ibmcam->frame[ibmcam->curframe]; + tmp = ibmcam_find_header(frame->hdr_sig, data, scratch_left(data)); + + if (tmp == NULL) { + /* No header - entire scratch buffer is useless! */ + if (debug > 2) + printk(KERN_DEBUG "Skipping frame, no header\n"); + ibmcam->scratchlen = 0; + return scan_EndParse; + } + /* Header found */ + data = tmp+4; + + ibmcam->has_hdr = 1; + ibmcam->header_count++; + frame->scanstate = STATE_LINES; + frame->curline = 0; + + if (flags & FLAGS_FORCE_TESTPATTERN) { + usb_ibmcam_testpattern(ibmcam, 1, 1); + return scan_NextFrame; + } + usb_ibmcam_align_scratch(ibmcam, data); + return scan_Continue; +} + +/* + * usb_ibmcam_parse_lines() + * + * Parse one line (TODO: more than one!) from the scratch buffer, put + * decoded RGB value into the current frame buffer and add the written + * number of bytes (RGB) to the *pcopylen. + * + * History: + * 1/21/00 Created. + */ +static scan_state_t usb_ibmcam_parse_lines(struct usb_ibmcam *ibmcam, long *pcopylen) +{ + struct ibmcam_frame *frame; + unsigned char *data, *f, *chromaLine; + unsigned int len; + const int v4l_linesize = imgwidth * V4L_BYTES_PER_PIXEL; /* V4L line offset */ + int y, u, v, i, frame_done=0, mono_plane, hue_corr, color_corr; + + hue_corr = (ibmcam->vpic.hue - 0x8000) >> 10; /* -32..+31 */ + color_corr = (ibmcam->vpic.colour - 0x8000) >> 10; /* -32..+31 */ + + data = ibmcam->scratch; + frame = &ibmcam->frame[ibmcam->curframe]; + + len = frame->frmwidth * 3; /* 1 line of mono + 1 line of color */ + /*printk(KERN_DEBUG "len=%d. left=%d.\n",len,scratch_left(data));*/ + + mono_plane = ((frame->curline & 1) == 0); + + /* + * Lines are organized this way (or are they?) + * + * I420: + * ~~~~ + * ___________________________________ + * |-----Y-----|---UVUVUV...UVUV-----| \ + * |-----------+---------------------| \ + * |<-- 176 -->|<------ 176*2 ------>| Total 72. pairs of lines + * |... ... ...| / + * |___________|_____________________| / + * - odd line- ------- even line --- + * + * another format: + * ~~~~~~~~~~~~~~ + * ___________________________________ + * |-----Y-----|---UVUVUV...UVUV-----| \ + * |-----------+---------------------| \ + * |<-- 352 -->|<------ 352*2 ------>| Total 144. pairs of lines + * |... ... ...| / + * |___________|_____________________| / + * - odd line- ------- even line --- + */ + + /* Make sure there's enough data for the entire line */ + if (scratch_left(data) < (len+1024)) { + /*printk(KERN_DEBUG "out of data, need %u.\n", len);*/ + return scan_Out; + } + + /* + * Make sure that our writing into output buffer + * will not exceed the buffer. Mind that we may write + * not into current output scanline but in several after + * it as well (if we enlarge image vertically.) + */ + if ((frame->curline + 1) >= V4L_FRAME_HEIGHT) + return scan_NextFrame; + + /* + * Now we are sure that entire line (representing all 'frame->frmwidth' + * pixels from the camera) is available in the scratch buffer. We + * start copying the line left-aligned to the V4L buffer (which + * might be larger - not smaller, hopefully). If the camera + * line is shorter then we should pad the V4L buffer with something + * (black in this case) to complete the line. + */ + f = frame->data + (v4l_linesize * frame->curline); + + /* + * chromaLine points to 1st pixel of the line with chrominance. + * If current line is monochrome then chromaLine points to next + * line after monochrome one. If current line has chrominance + * then chromaLine points to this very line. Such method allows + * to access chrominance data uniformly. + * + * To obtain chrominance data from the 'chromaLine' use this: + * v = chromaLine[0]; // 0-1:[0], 2-3:[4], 4-5:[8]... + * u = chromaLine[2]; // 0-1:[2], 2-3:[6], 4-5:[10]... + * + * Indices must be calculated this way: + * v_index = (i >> 1) << 2; + * u_index = (i >> 1) << 2 + 2; + * + * where 'i' is the column number [0..frame->frmwidth-1] + */ + chromaLine = data; + if (mono_plane) + chromaLine += frame->frmwidth; + + for (i = 0; i < frame->frmwidth; i++, data += (mono_plane ? 1 : 2)) + { + unsigned char rv, gv, bv; /* RGB components */ + + /* + * Search for potential Start-Of-Frame marker. It should + * not be here, of course, but if your formats don't match + * you might exceed the frame. We must match the marker to + * each byte of multi-byte data element if it is multi-byte. + */ +#if 1 + if (scratch_left(data) >= (4+2)) { + unsigned char *dp; + int j; + + for (j=0, dp=data; j < 2; j++, dp++) { + if ((dp[0] == 0x00) && (dp[1] == 0xFF) && + (dp[2] == 0x00) && (dp[3] == frame->hdr_sig)) { + ibmcam->has_hdr = 2; + frame_done++; + break; + } + } + } +#endif + + /* Check for various visual debugging hints (colorized pixels) */ + if ((flags & FLAGS_DISPLAY_HINTS) && (ibmcam->has_hdr)) { + /* + * This is bad and should not happen. This means that + * we somehow overshoot the line and encountered new + * frame! Obviously our camera/V4L frame size is out + * of whack. This cyan dot will help you to figure + * out where exactly the new frame arrived. + */ + if (ibmcam->has_hdr == 1) { + bv = 0; /* Yellow marker */ + gv = 0xFF; + rv = 0xFF; + } else { + bv = 0xFF; /* Cyan marker */ + gv = 0xFF; + rv = 0; + } + ibmcam->has_hdr = 0; + goto make_pixel; + } + + y = mono_plane ? data[0] : data[1]; + + if (flags & FLAGS_MONOCHROME) /* Use monochrome for debugging */ + rv = gv = bv = y; + else { + if (frame->order_uv) { + u = chromaLine[(i >> 1) << 2] + hue_corr; + v = chromaLine[((i >> 1) << 2) + 2] + color_corr; + } else { + v = chromaLine[(i >> 1) << 2] + color_corr; + u = chromaLine[((i >> 1) << 2) + 2] + hue_corr; + } + YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv); + } + + make_pixel: + /* + * The purpose of creating the pixel here, in one, + * dedicated place is that we may need to make the + * pixel wider and taller than it actually is. This + * may be used if camera generates small frames for + * sake of frame rate (or any other reason.) + * + * The output data consists of B, G, R bytes + * (in this order). + */ +#if USES_IBMCAM_PUTPIXEL + IBMCAM_PUTPIXEL(frame, i, frame->curline, rv, gv, bv); +#else + *f++ = bv; + *f++ = gv; + *f++ = rv; +#endif + /* + * Typically we do not decide within a legitimate frame + * that we want to end the frame. However debugging code + * may detect marker of new frame within the data. Then + * this condition activates. The 'data' pointer is already + * pointing at the new marker, so we'd better leave it as is. + */ + if (frame_done) + break; /* End scanning of lines */ + } + /* + * Account for number of bytes that we wrote into output V4L frame. + * We do it here, after we are done with the scanline, because we + * may fill more than one output scanline if we do vertical + * enlargement. + */ + frame->curline++; + *pcopylen += v4l_linesize; + usb_ibmcam_align_scratch(ibmcam, data); + + if (frame_done || (frame->curline >= frame->frmheight)) + return scan_NextFrame; + else + return scan_Continue; +} + +/* + * ibmcam_parse_data() + * + * Generic routine to parse the scratch buffer. It employs either + * usb_ibmcam_find_header() or usb_ibmcam_parse_lines() to do most + * of work. + * + * History: + * 1/21/00 Created. + */ +static void ibmcam_parse_data(struct usb_ibmcam *ibmcam) +{ + struct ibmcam_frame *frame; + unsigned char *data = ibmcam->scratch; + scan_state_t newstate; + long copylen = 0; + + /* Grab the current frame and the previous frame */ + frame = &ibmcam->frame[ibmcam->curframe]; + + /* printk(KERN_DEBUG "parsing %u.\n", ibmcam->scratchlen); */ + + while (1) { + + newstate = scan_Out; + if (scratch_left(data)) { + if (frame->scanstate == STATE_SCANNING) + newstate = usb_ibmcam_find_header(ibmcam); + else if (frame->scanstate == STATE_LINES) + newstate = usb_ibmcam_parse_lines(ibmcam, ©len); + } + if (newstate == scan_Continue) + continue; + else if ((newstate == scan_NextFrame) || (newstate == scan_Out)) + break; + else + return; /* scan_EndParse */ + } + + if (newstate == scan_NextFrame) { + frame->grabstate = FRAME_DONE; + ibmcam->curframe = -1; + ibmcam->frame_num++; + + /* Optionally display statistics on the screen */ + if (flags & FLAGS_OVERLAY_STATS) + usb_ibmcam_overlaystats(ibmcam, frame); + + /* This will cause the process to request another frame. */ + if (waitqueue_active(&frame->wq)) + wake_up_interruptible(&frame->wq); + } + + /* Update the frame's uncompressed length. */ + frame->scanlength += copylen; +} + +#if ENABLE_HEXDUMP +static void ibmcam_hexdump(const unsigned char *data, int len) +{ + char tmp[80]; + int i, k; + + for (i=k=0; len > 0; i++, len--) { + if (i > 0 && (i%16 == 0)) { + printk("%s\n", tmp); + k=0; + } + k += sprintf(&tmp[k], "%02x ", data[i]); + } + if (k > 0) + printk("%s\n", tmp); +} +#endif + +/* + * Make all of the blocks of data contiguous + */ +static int ibmcam_compress_isochronous(struct usb_ibmcam *ibmcam, urb_t *urb) +{ + unsigned char *cdata, *data, *data0; + int i, totlen = 0; + + data = data0 = ibmcam->scratch + ibmcam->scratchlen; + for (i = 0; i < urb->number_of_packets; i++) { + int n = urb->iso_frame_desc[i].actual_length; + int st = urb->iso_frame_desc[i].status; + + cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset; + + /* Detect and ignore errored packets */ + if (st < 0) { + if (debug >= 1) { + printk(KERN_ERR "ibmcam data error: [%d] len=%d, status=%X\n", + i, n, st); + } + ibmcam->iso_err_count++; + continue; + } + + /* Detect and ignore empty packets */ + if (n <= 0) { + ibmcam->iso_skip_count++; + continue; + } + + /* + * If camera continues to feed us with data but there is no + * consumption (if, for example, V4L client fell asleep) we + * may overflow the buffer. We have to move old data over to + * free room for new data. This is bad for old data. If we + * just drop new data then it's bad for new data... choose + * your favorite evil here. + */ + if ((ibmcam->scratchlen + n) > scratchbufsize) { +#if 0 + ibmcam->scratch_ovf_count++; + if (debug >= 3) + printk(KERN_ERR "ibmcam: scratch buf overflow! " + "scr_len: %d, n: %d\n", ibmcam->scratchlen, n ); + return totlen; +#else + int mv; + + ibmcam->scratch_ovf_count++; + if (debug >= 3) { + printk(KERN_ERR "ibmcam: scratch buf overflow! " + "scr_len: %d, n: %d\n", ibmcam->scratchlen, n ); + } + mv = (ibmcam->scratchlen + n) - scratchbufsize; + if (ibmcam->scratchlen >= mv) { + int newslen = ibmcam->scratchlen - mv; + memmove(ibmcam->scratch, ibmcam->scratch + mv, newslen); + ibmcam->scratchlen = newslen; + data = data0 = ibmcam->scratch + ibmcam->scratchlen; + } else { + printk(KERN_ERR "ibmcam: scratch buf too small\n"); + return totlen; + } +#endif + } + + /* Now we know that there is enough room in scratch buffer */ + memmove(data, cdata, n); + data += n; + totlen += n; + ibmcam->scratchlen += n; + } +#if 0 + if (totlen > 0) { + static int foo=0; + if (foo < 1) { + printk(KERN_DEBUG "+%d.\n", totlen); + ibmcam_hexdump(data0, (totlen > 64) ? 64:totlen); + ++foo; + } + } +#endif + return totlen; +} + +static void ibmcam_isoc_irq(struct urb *urb) +{ + int len; + struct usb_ibmcam *ibmcam = urb->context; + struct ibmcam_sbuf *sbuf; + int i; + + /* We don't want to do anything if we are about to be removed! */ + if (ibmcam->remove_pending) + return; + +#if 0 + if (urb->actual_length > 0) { + printk(KERN_DEBUG "ibmcam_isoc_irq: %p status %d, " + " errcount = %d, length = %d\n", urb, urb->status, + urb->error_count, urb->actual_length); + } else { + static int c = 0; + if (c++ % 100 == 0) + printk(KERN_DEBUG "ibmcam_isoc_irq: no data\n"); + } +#endif + + if (!ibmcam->streaming) { + if (debug >= 1) + printk(KERN_DEBUG "ibmcam: oops, not streaming, but interrupt\n"); + return; + } + + sbuf = &ibmcam->sbuf[ibmcam->cursbuf]; + + /* Copy the data received into our scratch buffer */ + len = ibmcam_compress_isochronous(ibmcam, urb); + + ibmcam->urb_count++; + ibmcam->urb_length = len; + ibmcam->data_count += len; + +#if 0 /* This code prints few initial bytes of ISO data: used to decode markers */ + if (ibmcam->urb_count % 64 == 1) { + if (ibmcam->urb_count == 1) { + ibmcam_hexdump(ibmcam->scratch, + (ibmcam->scratchlen > 32) ? 32 : ibmcam->scratchlen); + } + } +#endif + + /* If we collected enough data let's parse! */ + if (ibmcam->scratchlen) { + /* If we don't have a frame we're current working on, complain */ + if (ibmcam->curframe >= 0) + ibmcam_parse_data(ibmcam); + else { + if (debug >= 1) + printk(KERN_DEBUG "ibmcam: received data, but no frame available\n"); + } + } + + for (i = 0; i < FRAMES_PER_DESC; i++) { + sbuf->urb->iso_frame_desc[i].status = 0; + sbuf->urb->iso_frame_desc[i].actual_length = 0; + } + + /* Move to the next sbuf */ + ibmcam->cursbuf = (ibmcam->cursbuf + 1) % IBMCAM_NUMSBUF; + + return; +} + +static int usb_ibmcam_veio( + struct usb_device *dev, + unsigned char req, + unsigned short value, + unsigned short index) +{ + static const char proc[] = "usb_ibmcam_veio"; + unsigned char cp[8] = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef }; + const unsigned short len = sizeof(cp); + int i; + + if (req == 1) { + i = usb_control_msg( + dev, + usb_rcvctrlpipe(dev, 0), + req, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, + value, + index, + cp, + len, + HZ); +#if 0 + printk(KERN_DEBUG "USB => %02x%02x%02x%02x%02x%02x%02x%02x " + "(req=$%02x val=$%04x ind=$%04x len=%d.)\n", + cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7], + req, value, index, len); +#endif + } else { + i = usb_control_msg( + dev, + usb_sndctrlpipe(dev, 0), + req, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, + value, + index, + NULL, + 0, + HZ); + } + if (i < 0) + printk(KERN_ERR "%s: ERROR=%d.\n", proc, i); + return i; +} + +/* + * usb_ibmcam_calculate_fps() + * + * This procedure roughly calculates the real frame rate based + * on FPS code (framerate=NNN option). Actual FPS differs + * slightly depending on lighting conditions, so that actual frame + * rate is determined by the camera. Since I don't know how to ask + * the camera what FPS is now I have to use the FPS code instead. + * + * The FPS code is in range [0..6], 0 is slowest, 6 is fastest. + * Corresponding real FPS should be in range [3..30] frames per second. + * The conversion formula is obvious: + * + * real_fps = 3 + (fps_code * 4.5) + * + * History: + * 1/18/00 Created. + */ +static int usb_ibmcam_calculate_fps(void) +{ + return 3 + framerate*4 + framerate/2; +} + +/* + * usb_ibmcam_send_FF_04_02() + * + * This procedure sends magic 3-command prefix to the camera. + * The purpose of this prefix is not known. + * + * History: + * 1/2/00 Created. + */ +static void usb_ibmcam_send_FF_04_02(struct usb_device *dev) +{ + usb_ibmcam_veio(dev, 0, 0x00FF, 0x0127); + usb_ibmcam_veio(dev, 0, 0x0004, 0x0124); + usb_ibmcam_veio(dev, 0, 0x0002, 0x0124); +} + +static void usb_ibmcam_send_00_04_06(struct usb_device *dev) +{ + usb_ibmcam_veio(dev, 0, 0x0000, 0x0127); + usb_ibmcam_veio(dev, 0, 0x0004, 0x0124); + usb_ibmcam_veio(dev, 0, 0x0006, 0x0124); +} + +static void usb_ibmcam_send_x_00(struct usb_device *dev, unsigned short x) +{ + usb_ibmcam_veio(dev, 0, x, 0x0127); + usb_ibmcam_veio(dev, 0, 0x0000, 0x0124); +} + +static void usb_ibmcam_send_x_00_05(struct usb_device *dev, unsigned short x) +{ + usb_ibmcam_send_x_00(dev, x); + usb_ibmcam_veio(dev, 0, 0x0005, 0x0124); +} + +static void usb_ibmcam_send_x_00_05_02(struct usb_device *dev, unsigned short x) +{ + usb_ibmcam_veio(dev, 0, x, 0x0127); + usb_ibmcam_veio(dev, 0, 0x0000, 0x0124); + usb_ibmcam_veio(dev, 0, 0x0005, 0x0124); + usb_ibmcam_veio(dev, 0, 0x0002, 0x0124); +} + +static void usb_ibmcam_send_x_01_00_05(struct usb_device *dev, unsigned short x) +{ + usb_ibmcam_veio(dev, 0, x, 0x0127); + usb_ibmcam_veio(dev, 0, 0x0001, 0x0124); + usb_ibmcam_veio(dev, 0, 0x0000, 0x0124); + usb_ibmcam_veio(dev, 0, 0x0005, 0x0124); +} + +static void usb_ibmcam_send_x_00_05_02_01(struct usb_device *dev, unsigned short x) +{ + usb_ibmcam_veio(dev, 0, x, 0x0127); + usb_ibmcam_veio(dev, 0, 0x0000, 0x0124); + usb_ibmcam_veio(dev, 0, 0x0005, 0x0124); + usb_ibmcam_veio(dev, 0, 0x0002, 0x0124); + usb_ibmcam_veio(dev, 0, 0x0001, 0x0124); +} + +static void usb_ibmcam_send_x_00_05_02_08_01(struct usb_device *dev, unsigned short x) +{ + usb_ibmcam_veio(dev, 0, x, 0x0127); + usb_ibmcam_veio(dev, 0, 0x0000, 0x0124); + usb_ibmcam_veio(dev, 0, 0x0005, 0x0124); + usb_ibmcam_veio(dev, 0, 0x0002, 0x0124); + usb_ibmcam_veio(dev, 0, 0x0008, 0x0124); + usb_ibmcam_veio(dev, 0, 0x0001, 0x0124); +} + +static void usb_ibmcam_Packet_Format1(struct usb_device *dev, unsigned char fkey, unsigned char val) +{ + usb_ibmcam_send_x_01_00_05 (dev, unknown_88); + usb_ibmcam_send_x_00_05 (dev, fkey); + usb_ibmcam_send_x_00_05_02_08_01(dev, val); + usb_ibmcam_send_x_00_05 (dev, unknown_88); + usb_ibmcam_send_x_00_05_02_01 (dev, fkey); + usb_ibmcam_send_x_00_05 (dev, unknown_89); + usb_ibmcam_send_x_00 (dev, fkey); + usb_ibmcam_send_00_04_06 (dev); + usb_ibmcam_veio (dev, 1, 0x0000, 0x0126); + usb_ibmcam_send_FF_04_02 (dev); +} + +static void usb_ibmcam_PacketFormat2(struct usb_device *dev, unsigned char fkey, unsigned char val) +{ + usb_ibmcam_send_x_01_00_05 (dev, unknown_88); + usb_ibmcam_send_x_00_05 (dev, fkey); + usb_ibmcam_send_x_00_05_02 (dev, val); +} + +/* + * usb_ibmcam_adjust_contrast() + * + * The contrast value changes from 0 (high contrast) to 15 (low contrast). + * This is in reverse to usual order of things (such as TV controls), so + * we reverse it again here. + * + * TODO: we probably don't need to send the setup 5 times... + * + * History: + * 1/2/00 Created. + */ +static void usb_ibmcam_adjust_contrast(struct usb_ibmcam *ibmcam) +{ + struct usb_device *dev = ibmcam->dev; + unsigned char new_contrast = ibmcam->vpic.contrast >> 12; + const int ntries = 5; + + if (new_contrast >= 16) + new_contrast = 15; + new_contrast = 15 - new_contrast; + if (new_contrast != ibmcam->vpic_old.contrast) { + int i; + ibmcam->vpic_old.contrast = new_contrast; + for (i=0; i < ntries; i++) { + usb_ibmcam_Packet_Format1(dev, contrast_14, new_contrast); + usb_ibmcam_send_FF_04_02(dev); + } + /*usb_ibmcam_veio(dev, 0, 0x00FF, 0x0127);*/ + } +} + +/* + * usb_ibmcam_change_lighting_conditions() + * + * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low. + * Low lighting forces slower FPS. Lighting is set as a module parameter. + * + * History: + * 1/5/00 Created. + */ +static void usb_ibmcam_change_lighting_conditions(struct usb_ibmcam *ibmcam) +{ + static const char proc[] = "usb_ibmcam_change_lighting_conditions"; + struct usb_device *dev = ibmcam->dev; + const int ntries = 5; + int i; + + RESTRICT_TO_RANGE(lighting, LIGHTING_MIN, LIGHTING_MAX); + if (debug > 0) + printk(KERN_INFO "%s: Set lighting to %hu.\n", proc, lighting); + + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, light_27, (unsigned short) lighting); +} + +static void usb_ibmcam_set_sharpness(struct usb_ibmcam *ibmcam) +{ + static const char proc[] = "usb_ibmcam_set_sharpness"; + struct usb_device *dev = ibmcam->dev; + static const unsigned short sa[] = { 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a }; + unsigned short i, sv; + + RESTRICT_TO_RANGE(sharpness, SHARPNESS_MIN, SHARPNESS_MAX); + if (debug > 0) + printk(KERN_INFO "%s: Set sharpness to %hu.\n", proc, sharpness); + + sv = sa[sharpness - SHARPNESS_MIN]; + for (i=0; i < 2; i++) { + usb_ibmcam_send_x_01_00_05 (dev, unknown_88); + usb_ibmcam_send_x_00_05 (dev, sharp_13); + usb_ibmcam_send_x_00_05_02 (dev, sv); + } +} + +static void usb_ibmcam_set_brightness(struct usb_ibmcam *ibmcam) +{ + static const char proc[] = "usb_ibmcam_set_brightness"; + struct usb_device *dev = ibmcam->dev; + static const unsigned short n = 1; + unsigned short i, j, bv[3]; + + bv[0] = bv[1] = bv[2] = ibmcam->vpic.brightness >> 10; + if (bv[0] == (ibmcam->vpic_old.brightness >> 10)) + return; + ibmcam->vpic_old.brightness = ibmcam->vpic.brightness; + + if (debug > 0) + printk(KERN_INFO "%s: Set brightness to (%hu,%hu,%hu)\n", + proc, bv[0], bv[1], bv[2]); + + for (j=0; j < 3; j++) + for (i=0; i < n; i++) + usb_ibmcam_Packet_Format1(dev, bright_3x[j], bv[j]); +} + +static void usb_ibmcam_adjust_picture(struct usb_ibmcam *ibmcam) +{ + usb_ibmcam_adjust_contrast(ibmcam); + usb_ibmcam_set_brightness(ibmcam); +} + +static int usb_ibmcam_setup(struct usb_ibmcam *ibmcam) +{ + struct usb_device *dev = ibmcam->dev; + const int ntries = 5; + int i; + + usb_ibmcam_veio(dev, 1, 0, 0x128); + usb_ibmcam_veio(dev, 1, 0x00, 0x0100); + usb_ibmcam_veio(dev, 0, 0x01, 0x0100); /* LED On */ + usb_ibmcam_veio(dev, 1, 0x00, 0x0100); + usb_ibmcam_veio(dev, 0, 0x81, 0x0100); /* LED Off */ + usb_ibmcam_veio(dev, 1, 0x00, 0x0100); + usb_ibmcam_veio(dev, 0, 0x01, 0x0100); /* LED On */ + usb_ibmcam_veio(dev, 0, 0x01, 0x0108); + + usb_ibmcam_veio(dev, 0, 0x03, 0x0112); + usb_ibmcam_veio(dev, 1, 0x00, 0x0115); + usb_ibmcam_veio(dev, 0, 0x06, 0x0115); + usb_ibmcam_veio(dev, 1, 0x00, 0x0116); + usb_ibmcam_veio(dev, 0, 0x44, 0x0116); + usb_ibmcam_veio(dev, 1, 0x00, 0x0116); + usb_ibmcam_veio(dev, 0, 0x40, 0x0116); + usb_ibmcam_veio(dev, 1, 0x00, 0x0115); + usb_ibmcam_veio(dev, 0, 0x0e, 0x0115); + usb_ibmcam_veio(dev, 0, 0x19, 0x012c); + + usb_ibmcam_Packet_Format1(dev, 0x00, 0x1e); + usb_ibmcam_Packet_Format1(dev, 0x39, 0x0d); + usb_ibmcam_Packet_Format1(dev, 0x39, 0x09); + usb_ibmcam_Packet_Format1(dev, 0x3b, 0x00); + usb_ibmcam_Packet_Format1(dev, 0x28, 0x22); + usb_ibmcam_Packet_Format1(dev, light_27, 0); + usb_ibmcam_Packet_Format1(dev, 0x2b, 0x1f); + usb_ibmcam_Packet_Format1(dev, 0x39, 0x08); + + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, 0x2c, 0x00); + + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, 0x30, 0x14); + + usb_ibmcam_PacketFormat2(dev, 0x39, 0x02); + usb_ibmcam_PacketFormat2(dev, 0x01, 0xe1); + usb_ibmcam_PacketFormat2(dev, 0x02, 0xcd); + usb_ibmcam_PacketFormat2(dev, 0x03, 0xcd); + usb_ibmcam_PacketFormat2(dev, 0x04, 0xfa); + usb_ibmcam_PacketFormat2(dev, 0x3f, 0xff); + usb_ibmcam_PacketFormat2(dev, 0x39, 0x00); + + usb_ibmcam_PacketFormat2(dev, 0x39, 0x02); + usb_ibmcam_PacketFormat2(dev, 0x0a, 0x37); + usb_ibmcam_PacketFormat2(dev, 0x0b, 0xb8); + usb_ibmcam_PacketFormat2(dev, 0x0c, 0xf3); + usb_ibmcam_PacketFormat2(dev, 0x0d, 0xe3); + usb_ibmcam_PacketFormat2(dev, 0x0e, 0x0d); + usb_ibmcam_PacketFormat2(dev, 0x0f, 0xf2); + usb_ibmcam_PacketFormat2(dev, 0x10, 0xd5); + usb_ibmcam_PacketFormat2(dev, 0x11, 0xba); + usb_ibmcam_PacketFormat2(dev, 0x12, 0x53); + usb_ibmcam_PacketFormat2(dev, 0x3f, 0xff); + usb_ibmcam_PacketFormat2(dev, 0x39, 0x00); + + usb_ibmcam_PacketFormat2(dev, 0x39, 0x02); + usb_ibmcam_PacketFormat2(dev, 0x16, 0x00); + usb_ibmcam_PacketFormat2(dev, 0x17, 0x28); + usb_ibmcam_PacketFormat2(dev, 0x18, 0x7d); + usb_ibmcam_PacketFormat2(dev, 0x19, 0xbe); + usb_ibmcam_PacketFormat2(dev, 0x3f, 0xff); + usb_ibmcam_PacketFormat2(dev, 0x39, 0x00); + + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, 0x00, 0x18); + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, 0x13, 0x18); + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, 0x14, 0x06); + + /* This is default brightness */ + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, 0x31, 0x37); + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, 0x32, 0x46); + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, 0x33, 0x55); + + usb_ibmcam_Packet_Format1(dev, 0x2e, 0x04); + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, 0x2d, 0x04); + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, 0x29, 0x80); + usb_ibmcam_Packet_Format1(dev, 0x2c, 0x01); + usb_ibmcam_Packet_Format1(dev, 0x30, 0x17); + usb_ibmcam_Packet_Format1(dev, 0x39, 0x08); + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, 0x34, 0x00); + + usb_ibmcam_veio(dev, 0, 0x00, 0x0101); + usb_ibmcam_veio(dev, 0, 0x00, 0x010a); + + switch (videosize) { + case VIDEOSIZE_128x96: + usb_ibmcam_veio(dev, 0, 0x80, 0x0103); + usb_ibmcam_veio(dev, 0, 0x60, 0x0105); + usb_ibmcam_veio(dev, 0, 0x0c, 0x010b); + usb_ibmcam_veio(dev, 0, 0x04, 0x011b); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x0b, 0x011d); + usb_ibmcam_veio(dev, 0, 0x00, 0x011e); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x00, 0x0129); + break; + case VIDEOSIZE_176x144: + usb_ibmcam_veio(dev, 0, 0xb0, 0x0103); + usb_ibmcam_veio(dev, 0, 0x8f, 0x0105); + usb_ibmcam_veio(dev, 0, 0x06, 0x010b); + usb_ibmcam_veio(dev, 0, 0x04, 0x011b); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x0d, 0x011d); + usb_ibmcam_veio(dev, 0, 0x00, 0x011e); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x03, 0x0129); + break; + case VIDEOSIZE_352x288: + usb_ibmcam_veio(dev, 0, 0xb0, 0x0103); + usb_ibmcam_veio(dev, 0, 0x90, 0x0105); + usb_ibmcam_veio(dev, 0, 0x02, 0x010b); + usb_ibmcam_veio(dev, 0, 0x04, 0x011b); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x05, 0x011d); + usb_ibmcam_veio(dev, 0, 0x00, 0x011e); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x00, 0x0129); + break; + } + + usb_ibmcam_veio(dev, 0, 0xff, 0x012b); + + /* This is another brightness - don't know why */ + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, 0x31, 0xc3); + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, 0x32, 0xd2); + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, 0x33, 0xe1); + + /* Default contrast */ + for (i=0; i < ntries; i++) + usb_ibmcam_Packet_Format1(dev, contrast_14, 0x0a); + + /* Default sharpness */ + for (i=0; i < 2; i++) + usb_ibmcam_PacketFormat2(dev, sharp_13, 0x1a); /* Level 4 FIXME */ + + /* Default lighting conditions */ + usb_ibmcam_Packet_Format1(dev, light_27, lighting); /* 0=Bright 2=Low */ + + /* Assorted init */ + + switch (videosize) { + case VIDEOSIZE_128x96: + usb_ibmcam_Packet_Format1(dev, 0x2b, 0x1e); + usb_ibmcam_veio(dev, 0, 0xc9, 0x0119); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x80, 0x0109); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x36, 0x0102); + usb_ibmcam_veio(dev, 0, 0x1a, 0x0104); + usb_ibmcam_veio(dev, 0, 0x04, 0x011a); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x2b, 0x011c); + usb_ibmcam_veio(dev, 0, 0x23, 0x012a); /* Same everywhere */ +#if 0 + usb_ibmcam_veio(dev, 0, 0x00, 0x0106); + usb_ibmcam_veio(dev, 0, 0x38, 0x0107); +#else + usb_ibmcam_veio(dev, 0, 0x02, 0x0106); + usb_ibmcam_veio(dev, 0, 0x2a, 0x0107); +#endif + break; + case VIDEOSIZE_176x144: + usb_ibmcam_Packet_Format1(dev, 0x2b, 0x1e); + usb_ibmcam_veio(dev, 0, 0xc9, 0x0119); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x80, 0x0109); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x04, 0x0102); + usb_ibmcam_veio(dev, 0, 0x02, 0x0104); + usb_ibmcam_veio(dev, 0, 0x04, 0x011a); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x2b, 0x011c); + usb_ibmcam_veio(dev, 0, 0x23, 0x012a); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x01, 0x0106); + usb_ibmcam_veio(dev, 0, 0xca, 0x0107); + break; + case VIDEOSIZE_352x288: + usb_ibmcam_Packet_Format1(dev, 0x2b, 0x1f); + usb_ibmcam_veio(dev, 0, 0xc9, 0x0119); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x80, 0x0109); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x08, 0x0102); + usb_ibmcam_veio(dev, 0, 0x01, 0x0104); + usb_ibmcam_veio(dev, 0, 0x04, 0x011a); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x2f, 0x011c); + usb_ibmcam_veio(dev, 0, 0x23, 0x012a); /* Same everywhere */ + usb_ibmcam_veio(dev, 0, 0x03, 0x0106); + usb_ibmcam_veio(dev, 0, 0xf6, 0x0107); + break; + } + return 0; /* TODO: return actual completion status! */ +} + +/* + * usb_ibmcam_setup_after_video_if() + * + * This code adds finishing touches to the video data interface. + * Here we configure the frame rate and turn on the LED. + */ +static void usb_ibmcam_setup_after_video_if(struct usb_device *dev) +{ + unsigned short internal_frame_rate; + + RESTRICT_TO_RANGE(framerate, FRAMERATE_MIN, FRAMERATE_MAX); + internal_frame_rate = FRAMERATE_MAX - framerate; /* 0=Fast 6=Slow */ + usb_ibmcam_veio(dev, 0, 0x01, 0x0100); /* LED On */ + usb_ibmcam_veio(dev, 0, internal_frame_rate, 0x0111); + usb_ibmcam_veio(dev, 0, 0x01, 0x0114); + usb_ibmcam_veio(dev, 0, 0xc0, 0x010c); +} + +/* + * usb_ibmcam_setup_video_stop() + * + * This code tells camera to stop streaming. The interface remains + * configured and bandwidth - claimed. + */ +static void usb_ibmcam_setup_video_stop(struct usb_device *dev) +{ + usb_ibmcam_veio(dev, 0, 0x00, 0x010c); + usb_ibmcam_veio(dev, 0, 0x00, 0x010c); + usb_ibmcam_veio(dev, 0, 0x01, 0x0114); + usb_ibmcam_veio(dev, 0, 0xc0, 0x010c); + usb_ibmcam_veio(dev, 0, 0x00, 0x010c); + usb_ibmcam_send_FF_04_02(dev); + usb_ibmcam_veio(dev, 1, 0x00, 0x0100); + usb_ibmcam_veio(dev, 0, 0x81, 0x0100); /* LED Off */ +} + +/* + * usb_ibmcam_reinit_iso() + * + * This procedure sends couple of commands to the camera and then + * resets the video pipe. This sequence was observed to reinit the + * camera or, at least, to initiate ISO data stream. + * + * History: + * 1/2/00 Created. + */ +static void usb_ibmcam_reinit_iso(struct usb_ibmcam *ibmcam, int do_stop) +{ + if (do_stop) + usb_ibmcam_setup_video_stop(ibmcam->dev); + + usb_ibmcam_veio(ibmcam->dev, 0, 0x0001, 0x0114); + usb_ibmcam_veio(ibmcam->dev, 0, 0x00c0, 0x010c); + usb_clear_halt(ibmcam->dev, ibmcam->video_endp); + usb_ibmcam_setup_after_video_if(ibmcam->dev); +} + +static int ibmcam_init_isoc(struct usb_ibmcam *ibmcam) +{ + struct usb_device *dev = ibmcam->dev; + urb_t *urb; + int fx, err; + + ibmcam->compress = 0; + ibmcam->curframe = -1; + ibmcam->cursbuf = 0; + ibmcam->scratchlen = 0; + + /* Alternate interface 1 is is the biggest frame size */ + if (usb_set_interface(ibmcam->dev, 2, 1) < 0) { + printk(KERN_ERR "usb_set_interface error\n"); + return -EBUSY; + } + usb_ibmcam_change_lighting_conditions(ibmcam); + usb_ibmcam_set_sharpness(ibmcam); + usb_ibmcam_reinit_iso(ibmcam, 0); + + /* We double buffer the Iso lists */ + urb = usb_alloc_urb(FRAMES_PER_DESC); + + if (!urb) { + printk(KERN_ERR "ibmcam_init_isoc: usb_init_isoc ret %d\n", + 0); + return -ENOMEM; + } + ibmcam->sbuf[0].urb = urb; + urb->dev = dev; + urb->context = ibmcam; + urb->pipe = usb_rcvisocpipe(dev, ibmcam->video_endp); + urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_buffer = ibmcam->sbuf[0].data; + urb->complete = ibmcam_isoc_irq; + urb->number_of_packets = FRAMES_PER_DESC; + urb->transfer_buffer_length = ibmcam->iso_packet_len * FRAMES_PER_DESC; + for (fx = 0; fx < FRAMES_PER_DESC; fx++) { + urb->iso_frame_desc[fx].offset = ibmcam->iso_packet_len * fx; + urb->iso_frame_desc[fx].length = ibmcam->iso_packet_len; + } + urb = usb_alloc_urb(FRAMES_PER_DESC); + if (!urb) { + printk(KERN_ERR "ibmcam_init_isoc: usb_init_isoc ret %d\n", + 0); + return -ENOMEM; + } + ibmcam->sbuf[1].urb = urb; + urb->dev = dev; + urb->context = ibmcam; + urb->pipe = usb_rcvisocpipe(dev, ibmcam->video_endp); + urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_buffer = ibmcam->sbuf[1].data; + urb->complete = ibmcam_isoc_irq; + urb->number_of_packets = FRAMES_PER_DESC; + urb->transfer_buffer_length = ibmcam->iso_packet_len * FRAMES_PER_DESC; + for (fx = 0; fx < FRAMES_PER_DESC; fx++) { + urb->iso_frame_desc[fx].offset = ibmcam->iso_packet_len * fx; + urb->iso_frame_desc[fx].length = ibmcam->iso_packet_len; + } + + ibmcam->sbuf[1].urb->next = ibmcam->sbuf[0].urb; + ibmcam->sbuf[0].urb->next = ibmcam->sbuf[1].urb; + + err = usb_submit_urb(ibmcam->sbuf[0].urb); + if (err) + printk(KERN_ERR "ibmcam_init_isoc: usb_run_isoc(0) ret %d\n", + err); + err = usb_submit_urb(ibmcam->sbuf[1].urb); + if (err) + printk(KERN_ERR "ibmcam_init_isoc: usb_run_isoc(1) ret %d\n", + err); + + ibmcam->streaming = 1; + // printk(KERN_DEBUG "streaming=1 ibmcam->video_endp=$%02x\n", ibmcam->video_endp); + return 0; +} + +/* + * ibmcam_stop_isoc() + * + * This procedure stops streaming and deallocates URBs. Then it + * activates zero-bandwidth alt. setting of the video interface. + * + * History: + * 1/22/00 Corrected order of actions to work after surprise removal. + */ +static void ibmcam_stop_isoc(struct usb_ibmcam *ibmcam) +{ + if (!ibmcam->streaming) + return; + + /* Unschedule all of the iso td's */ + usb_unlink_urb(ibmcam->sbuf[1].urb); + usb_unlink_urb(ibmcam->sbuf[0].urb); + + /* printk(KERN_DEBUG "streaming=0\n"); */ + ibmcam->streaming = 0; + + /* Delete them all */ + usb_free_urb(ibmcam->sbuf[1].urb); + usb_free_urb(ibmcam->sbuf[0].urb); + + usb_ibmcam_setup_video_stop(ibmcam->dev); + + /* Set packet size to 0 */ + if (usb_set_interface(ibmcam->dev, 2, 0) < 0) + printk(KERN_ERR "usb_set_interface error\n"); +} + +static int ibmcam_new_frame(struct usb_ibmcam *ibmcam, int framenum) +{ + struct ibmcam_frame *frame; + int n, width, height; + + /* If we're not grabbing a frame right now and the other frame is */ + /* ready to be grabbed into, then use it instead */ + if (ibmcam->curframe != -1) + return 0; + + n = (framenum - 1 + IBMCAM_NUMFRAMES) % IBMCAM_NUMFRAMES; + if (ibmcam->frame[n].grabstate == FRAME_READY) + framenum = n; + + frame = &ibmcam->frame[framenum]; + + frame->grabstate = FRAME_GRABBING; + frame->scanstate = STATE_SCANNING; + frame->scanlength = 0; /* Accumulated in ibmcam_parse_data() */ + ibmcam->curframe = framenum; +#if 0 + /* This provides a "clean" frame but slows things down */ + memset(frame->data, 0, MAX_FRAME_SIZE); +#endif + switch (videosize) { + case VIDEOSIZE_128x96: + frame->frmwidth = 128; + frame->frmheight = 96; + frame->order_uv = 1; /* U Y V Y ... */ + frame->hdr_sig = 0x06; /* 00 FF 00 06 */ + break; + case VIDEOSIZE_176x144: + frame->frmwidth = 176; + frame->frmheight = 144; + frame->order_uv = 1; /* U Y V Y ... */ + frame->hdr_sig = 0x0E; /* 00 FF 00 0E */ + break; + case VIDEOSIZE_352x288: + frame->frmwidth = 352; + frame->frmheight = 288; + frame->order_uv = 0; /* V Y U Y ... */ + frame->hdr_sig = 0x00; /* 00 FF 00 00 */ + break; + } + + width = frame->width; + RESTRICT_TO_RANGE(width, min_imgwidth, imgwidth); + width &= ~7; /* Multiple of 8 */ + + height = frame->height; + RESTRICT_TO_RANGE(height, min_imgheight, imgheight); + height &= ~3; /* Multiple of 4 */ + + return 0; +} + +/* + * ibmcam_open() + * + * This is part of Video 4 Linux API. The driver can be opened by one + * client only (checks internal counter 'ibmcam->user'). The procedure + * then allocates buffers needed for video processing. + * + * History: + * 1/22/00 Rewrote, moved scratch buffer allocation here. Now the + * camera is also initialized here (once per connect), at + * expense of V4L client (it waits on open() call). + */ +static int ibmcam_open(struct video_device *dev, int flags) +{ + struct usb_ibmcam *ibmcam = (struct usb_ibmcam *)dev; + const int nbuffers = 2; + const int sb_size = FRAMES_PER_DESC * ibmcam->iso_packet_len; + int i, err = 0; + + down(&ibmcam->lock); + + if (ibmcam->user) + err = -EBUSY; + else { + /* Clean pointers so we know if we allocated something */ + for (i=0; i < nbuffers; i++) + ibmcam->sbuf[i].data = NULL; + + /* Allocate memory for the frame buffers */ + ibmcam->fbuf_size = nbuffers * MAX_FRAME_SIZE; + ibmcam->fbuf = rvmalloc(ibmcam->fbuf_size); + ibmcam->scratch = kmalloc(scratchbufsize, GFP_KERNEL); + ibmcam->scratchlen = 0; + if ((ibmcam->fbuf == NULL) || (ibmcam->scratch == NULL)) + err = -ENOMEM; + else { + /* Allocate all buffers */ + for (i=0; i < nbuffers; i++) { + ibmcam->frame[i].grabstate = FRAME_UNUSED; + ibmcam->frame[i].data = ibmcam->fbuf + i*MAX_FRAME_SIZE; + + ibmcam->sbuf[i].data = kmalloc(sb_size, GFP_KERNEL); + if (ibmcam->sbuf[i].data == NULL) { + err = -ENOMEM; + break; + } + /* + * Set default sizes in case IOCTL (VIDIOCMCAPTURE) + * is not used (using read() instead). + */ + ibmcam->frame[i].width = imgwidth; + ibmcam->frame[i].height = imgheight; + ibmcam->frame[i].bytes_read = 0; + } + } + if (err) { + /* Have to free all that memory */ + if (ibmcam->fbuf != NULL) { + rvfree(ibmcam->fbuf, ibmcam->fbuf_size); + ibmcam->fbuf = NULL; + } + if (ibmcam->scratch != NULL) { + kfree(ibmcam->scratch); + ibmcam->scratch = NULL; + } + for (i=0; i < nbuffers; i++) { + if (ibmcam->sbuf[i].data != NULL) { + kfree (ibmcam->sbuf[i].data); + ibmcam->sbuf[i].data = NULL; + } + } + } + } + + /* If so far no errors then we shall start the camera */ + if (!err) { + err = ibmcam_init_isoc(ibmcam); + if (!err) { + /* Send init sequence only once, it's large! */ + if (!ibmcam->initialized) { + err = usb_ibmcam_setup(ibmcam); + if (!err) + ibmcam->initialized = 1; + } + if (!err) { + ibmcam->user++; + MOD_INC_USE_COUNT; + } + } + } + + up(&ibmcam->lock); + return err; +} + +/* + * ibmcam_close() + * + * This is part of Video 4 Linux API. The procedure + * stops streaming and deallocates all buffers that were earlier + * allocated in ibmcam_open(). + * + * History: + * 1/22/00 Moved scratch buffer deallocation here. + */ +static void ibmcam_close(struct video_device *dev) +{ + struct usb_ibmcam *ibmcam = (struct usb_ibmcam *)dev; + + down(&ibmcam->lock); + + ibmcam_stop_isoc(ibmcam); + + rvfree(ibmcam->fbuf, ibmcam->fbuf_size); + kfree(ibmcam->scratch); + kfree(ibmcam->sbuf[1].data); + kfree(ibmcam->sbuf[0].data); + + ibmcam->user--; + MOD_DEC_USE_COUNT; + + up(&ibmcam->lock); +} + +static int ibmcam_init_done(struct video_device *dev) +{ + return 0; +} + +static long ibmcam_write(struct video_device *dev, const char *buf, unsigned long count, int noblock) +{ + return -EINVAL; +} + +/* + * ibmcam_ioctl() + * + * This is part of Video 4 Linux API. The procedure handles ioctl() calls. + * + * History: + * 1/22/00 Corrected VIDIOCSPICT to reject unsupported settings. + */ +static int ibmcam_ioctl(struct video_device *dev, unsigned int cmd, void *arg) +{ + struct usb_ibmcam *ibmcam = (struct usb_ibmcam *)dev; + + if (ibmcam->remove_pending) + return -EFAULT; + + switch (cmd) { + case VIDIOCGCAP: + { + if (copy_to_user(arg, &ibmcam->vcap, sizeof(ibmcam->vcap))) + return -EFAULT; + return 0; + } + case VIDIOCGCHAN: + { + if (copy_to_user(arg, &ibmcam->vchan, sizeof(ibmcam->vchan))) + return -EFAULT; + return 0; + } + case VIDIOCSCHAN: + { + int v; + + if (copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if ((v < 0) || (v >= 3)) /* 3 grades of lighting conditions */ + return -EINVAL; + if (v != ibmcam->vchan.channel) { + ibmcam->vchan.channel = v; + usb_ibmcam_change_lighting_conditions(ibmcam); + } + return 0; + } + case VIDIOCGPICT: + { + if (copy_to_user(arg, &ibmcam->vpic, sizeof(ibmcam->vpic))) + return -EFAULT; + return 0; + } + case VIDIOCSPICT: + { + struct video_picture tmp; + /* + * Use temporary 'video_picture' structure to preserve our + * own settings (such as color depth, palette) that we + * aren't allowing everyone (V4L client) to change. + */ + if (copy_from_user(&tmp, arg, sizeof(tmp))) + return -EFAULT; + ibmcam->vpic.brightness = tmp.brightness; + ibmcam->vpic.hue = tmp.hue; + ibmcam->vpic.colour = tmp.colour; + ibmcam->vpic.contrast = tmp.contrast; + usb_ibmcam_adjust_picture(ibmcam); + return 0; + } + case VIDIOCSWIN: + { + struct video_window vw; + + if (copy_from_user(&vw, arg, sizeof(vw))) + return -EFAULT; + if (vw.flags) + return -EINVAL; + if (vw.clipcount) + return -EINVAL; + if (vw.height != imgheight) + return -EINVAL; + if (vw.width != imgwidth) + return -EINVAL; + + ibmcam->compress = 0; + + return 0; + } + case VIDIOCGWIN: + { + struct video_window vw; + + vw.x = 0; + vw.y = 0; + vw.width = imgwidth; + vw.height = imgheight; + vw.chromakey = 0; + vw.flags = usb_ibmcam_calculate_fps(); + + if (copy_to_user(arg, &vw, sizeof(vw))) + return -EFAULT; + + return 0; + } + case VIDIOCGMBUF: + { + struct video_mbuf vm; + + memset(&vm, 0, sizeof(vm)); + vm.size = MAX_FRAME_SIZE * 2; + vm.frames = 2; + vm.offsets[0] = 0; + vm.offsets[1] = MAX_FRAME_SIZE; + + if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm))) + return -EFAULT; + + return 0; + } + case VIDIOCMCAPTURE: + { + struct video_mmap vm; + + if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm))) + return -EFAULT; + + if (debug >= 1) + printk(KERN_DEBUG "frame: %d, size: %dx%d, format: %d\n", + vm.frame, vm.width, vm.height, vm.format); + + if (vm.format != VIDEO_PALETTE_RGB24) + return -EINVAL; + + if ((vm.frame != 0) && (vm.frame != 1)) + return -EINVAL; + + if (ibmcam->frame[vm.frame].grabstate == FRAME_GRABBING) + return -EBUSY; + + /* Don't compress if the size changed */ + if ((ibmcam->frame[vm.frame].width != vm.width) || + (ibmcam->frame[vm.frame].height != vm.height)) + ibmcam->compress = 0; + + ibmcam->frame[vm.frame].width = vm.width; + ibmcam->frame[vm.frame].height = vm.height; + + /* Mark it as ready */ + ibmcam->frame[vm.frame].grabstate = FRAME_READY; + + return ibmcam_new_frame(ibmcam, vm.frame); + } + case VIDIOCSYNC: + { + int frame; + + if (copy_from_user((void *)&frame, arg, sizeof(int))) + return -EFAULT; + + if (debug >= 1) + printk(KERN_DEBUG "ibmcam: syncing to frame %d\n", frame); + + switch (ibmcam->frame[frame].grabstate) { + case FRAME_UNUSED: + return -EINVAL; + case FRAME_READY: + case FRAME_GRABBING: + case FRAME_ERROR: + { + int ntries; + redo: + ntries = 0; + do { + interruptible_sleep_on(&ibmcam->frame[frame].wq); + if (signal_pending(current)) { + if (flags & FLAGS_RETRY_VIDIOCSYNC) { + /* Polling apps will destroy frames with that! */ + ibmcam_new_frame(ibmcam, frame); + usb_ibmcam_testpattern(ibmcam, 1, 0); + ibmcam->curframe = -1; + ibmcam->frame_num++; + + /* This will request another frame. */ + if (waitqueue_active(&ibmcam->frame[frame].wq)) + wake_up_interruptible(&ibmcam->frame[frame].wq); + return 0; + } else { + /* Standard answer: not ready yet! */ + return -EINTR; + } + } + } while (ibmcam->frame[frame].grabstate == FRAME_GRABBING); + + if (ibmcam->frame[frame].grabstate == FRAME_ERROR) { + int ret = ibmcam_new_frame(ibmcam, frame); + if (ret < 0) + return ret; + goto redo; + } + } + case FRAME_DONE: + ibmcam->frame[frame].grabstate = FRAME_UNUSED; + break; + } + + ibmcam->frame[frame].grabstate = FRAME_UNUSED; + + return 0; + } + case VIDIOCGFBUF: + { + struct video_buffer vb; + + memset(&vb, 0, sizeof(vb)); + vb.base = NULL; /* frame buffer not supported, not used */ + + if (copy_to_user((void *)arg, (void *)&vb, sizeof(vb))) + return -EFAULT; + + return 0; + } + case VIDIOCKEY: + return 0; + + case VIDIOCCAPTURE: + return -EINVAL; + + case VIDIOCSFBUF: + + case VIDIOCGTUNER: + case VIDIOCSTUNER: + + case VIDIOCGFREQ: + case VIDIOCSFREQ: + + case VIDIOCGAUDIO: + case VIDIOCSAUDIO: + return -EINVAL; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static long ibmcam_read(struct video_device *dev, char *buf, unsigned long count, int noblock) +{ + struct usb_ibmcam *ibmcam = (struct usb_ibmcam *)dev; + int frmx = -1; + volatile struct ibmcam_frame *frame; + + if (debug >= 1) + printk(KERN_DEBUG "ibmcam_read: %ld bytes, noblock=%d\n", count, noblock); + + if (ibmcam->remove_pending) + return -EFAULT; + + if (!dev || !buf) + return -EFAULT; + + /* See if a frame is completed, then use it. */ + if (ibmcam->frame[0].grabstate >= FRAME_DONE) /* _DONE or _ERROR */ + frmx = 0; + else if (ibmcam->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */ + frmx = 1; + + if (noblock && (frmx == -1)) + return -EAGAIN; + + /* If no FRAME_DONE, look for a FRAME_GRABBING state. */ + /* See if a frame is in process (grabbing), then use it. */ + if (frmx == -1) { + if (ibmcam->frame[0].grabstate == FRAME_GRABBING) + frmx = 0; + else if (ibmcam->frame[1].grabstate == FRAME_GRABBING) + frmx = 1; + } + + /* If no frame is active, start one. */ + if (frmx == -1) + ibmcam_new_frame(ibmcam, frmx = 0); + + frame = &ibmcam->frame[frmx]; + +restart: + while (frame->grabstate == FRAME_GRABBING) { + interruptible_sleep_on((void *)&frame->wq); + if (signal_pending(current)) + return -EINTR; + } + + if (frame->grabstate == FRAME_ERROR) { + frame->bytes_read = 0; + if (ibmcam_new_frame(ibmcam, frmx)) + printk(KERN_ERR "ibmcam_read: ibmcam_new_frame error\n"); + goto restart; + } + + if (debug >= 1) + printk(KERN_DEBUG "ibmcam_read: frmx=%d, bytes_read=%ld, scanlength=%ld\n", + frmx, frame->bytes_read, frame->scanlength); + + /* copy bytes to user space; we allow for partials reads */ + if ((count + frame->bytes_read) > frame->scanlength) + count = frame->scanlength - frame->bytes_read; + + if (copy_to_user(buf, frame->data + frame->bytes_read, count)) + return -EFAULT; + + frame->bytes_read += count; + if (debug >= 1) + printk(KERN_DEBUG "ibmcam_read: {copy} count used=%ld, new bytes_read=%ld\n", + count, frame->bytes_read); + + if (frame->bytes_read >= frame->scanlength) { /* All data has been read */ + frame->bytes_read = 0; + + /* Mark it as available to be used again. */ + ibmcam->frame[frmx].grabstate = FRAME_UNUSED; + if (ibmcam_new_frame(ibmcam, frmx ? 0 : 1)) + printk(KERN_ERR "ibmcam_read: ibmcam_new_frame returned error\n"); + } + + return count; +} + +static int ibmcam_mmap(struct video_device *dev, const char *adr, unsigned long size) +{ + struct usb_ibmcam *ibmcam = (struct usb_ibmcam *)dev; + unsigned long start = (unsigned long)adr; + unsigned long page, pos; + + if (ibmcam->remove_pending) + return -EFAULT; + + if (size > (((2 * MAX_FRAME_SIZE) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) + return -EINVAL; + + pos = (unsigned long)ibmcam->fbuf; + while (size > 0) { + page = kvirt_to_pa(pos); + if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) + return -EAGAIN; + + start += PAGE_SIZE; + pos += PAGE_SIZE; + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; + } + + return 0; +} + +static struct video_device ibmcam_template = { + "CPiA USB Camera", + VID_TYPE_CAPTURE, + VID_HARDWARE_CPIA, + ibmcam_open, + ibmcam_close, + ibmcam_read, + ibmcam_write, + NULL, + ibmcam_ioctl, + ibmcam_mmap, + ibmcam_init_done, + NULL, + 0, + 0 +}; + +static void usb_ibmcam_configure_video(struct usb_ibmcam *ibmcam) +{ + if (ibmcam == NULL) + return; + + RESTRICT_TO_RANGE(init_brightness, 0, 255); + RESTRICT_TO_RANGE(init_contrast, 0, 255); + RESTRICT_TO_RANGE(init_color, 0, 255); + RESTRICT_TO_RANGE(init_hue, 0, 255); + + memset(&ibmcam->vpic, 0, sizeof(ibmcam->vpic)); + memset(&ibmcam->vpic_old, 0x55, sizeof(ibmcam->vpic_old)); + + ibmcam->vpic.colour = init_color << 8; + ibmcam->vpic.hue = init_hue << 8; + ibmcam->vpic.brightness = init_brightness << 8; + ibmcam->vpic.contrast = init_contrast << 8; + ibmcam->vpic.whiteness = 105 << 8; /* This one isn't used */ + ibmcam->vpic.depth = 24; + ibmcam->vpic.palette = VIDEO_PALETTE_RGB24; + + memset(&ibmcam->vcap, 0, sizeof(ibmcam->vcap)); + strcpy(ibmcam->vcap.name, "IBM USB Camera"); + ibmcam->vcap.type = VID_TYPE_CAPTURE /*| VID_TYPE_SUBCAPTURE*/; + ibmcam->vcap.channels = 1; + ibmcam->vcap.audios = 0; + ibmcam->vcap.maxwidth = imgwidth; + ibmcam->vcap.maxheight = imgheight; + ibmcam->vcap.minwidth = min_imgwidth; + ibmcam->vcap.minheight = min_imgheight; + + memset(&ibmcam->vchan, 0, sizeof(ibmcam->vchan)); + ibmcam->vchan.flags = 0; + ibmcam->vchan.tuners = 0; + ibmcam->vchan.channel = 0; + ibmcam->vchan.type = VIDEO_TYPE_CAMERA; + strcpy(ibmcam->vchan.name, "Camera"); +} + +/* + * usb_ibmcam_probe() + * + * This procedure queries device descriptor and accepts the interface + * if it looks like IBM C-it camera. + * + * History: + * 1/22/00 Moved camera init code to ibmcam_open() + */ +static void *usb_ibmcam_probe(struct usb_device *dev, unsigned int ifnum) +{ + struct usb_ibmcam *ibmcam = NULL; + struct usb_interface_descriptor *interface; + + if (debug >= 1) + printk(KERN_DEBUG "ibmcam_probe(%p,%u.)\n", dev, ifnum); + + /* We don't handle multi-config cameras */ + if (dev->descriptor.bNumConfigurations != 1) + return NULL; + + /* Is it an IBM camera? */ + if ((dev->descriptor.idVendor != 0x0545) || + (dev->descriptor.idProduct != 0x8080)) + return NULL; + + /* Camera confirmed. We claim only interface 2 (video data) */ + if (ifnum != 2) + return NULL; + + /* We found an IBM camera */ + printk(KERN_INFO "IBM USB camera found (interface %u.)\n", ifnum); + + if (debug >= 1) + printk(KERN_DEBUG "ibmcam_probe: new ibmcam alloc\n"); + ibmcam = kmalloc(sizeof(*ibmcam), GFP_KERNEL); + if (ibmcam == NULL) { + printk(KERN_ERR "couldn't kmalloc ibmcam struct\n"); + return NULL; + } + memset(ibmcam, 0, sizeof(struct usb_ibmcam)); + ibmcam->dev = dev; + interface = &dev->actconfig->interface[ifnum].altsetting[0]; + ibmcam->iface = interface->bInterfaceNumber; + ibmcam->video_endp = 0x82; + init_waitqueue_head (&ibmcam->remove_ok); + ibmcam->iso_packet_len = 1014; + + memcpy(&ibmcam->vdev, &ibmcam_template, sizeof(ibmcam_template)); + usb_ibmcam_configure_video(ibmcam); + + init_waitqueue_head(&ibmcam->frame[0].wq); + init_waitqueue_head(&ibmcam->frame[1].wq); + + if (video_register_device(&ibmcam->vdev, VFL_TYPE_GRABBER) == -1) { + printk(KERN_ERR "video_register_device failed\n"); + return NULL; + } + if (debug > 1) + printk(KERN_DEBUG "video_register_device() successful\n"); + + ibmcam->compress = 0; + ibmcam->user=0; + init_MUTEX(&ibmcam->lock); /* to 1 == available */ + + return ibmcam; +} + +/* + * usb_ibmcam_disconnect() + * + * This procedure stops all driver activity, deallocates interface-private + * structure (pointed by 'ptr') and after that driver should be removable + * with no ill consequences. + * + * TODO: This code behaves badly on surprise removal! + * + * History: + * 1/22/00 Added polling of MOD_IN_USE to delay removal until all users gone. + */ +static void usb_ibmcam_disconnect(struct usb_device *dev, void *ptr) +{ + static const char proc[] = "usb_ibmcam_disconnect"; + struct usb_ibmcam *ibmcam = (struct usb_ibmcam *) ptr; + wait_queue_head_t wq; /* Wait here until removal is safe */ + + if (debug > 0) + printk(KERN_DEBUG "%s(%p,%p.)\n", proc, dev, ptr); + + init_waitqueue_head(&wq); + ibmcam->remove_pending = 1; /* Now all ISO data will be ignored */ + + /* At this time we ask to cancel outstanding URBs */ + ibmcam_stop_isoc(ibmcam); + + if (MOD_IN_USE) { + printk(KERN_INFO "%s: In use, disconnect pending.\n", proc); + while (MOD_IN_USE) + interruptible_sleep_on_timeout (&wq, HZ); + printk(KERN_INFO "%s: Released, wait.\n", proc); +// interruptible_sleep_on_timeout (&wq, HZ*10); + } + video_unregister_device(&ibmcam->vdev); + printk(KERN_INFO "%s: Video dereg'd, wait.\n", proc); +// interruptible_sleep_on_timeout (&wq, HZ*10); + + /* Free the memory */ + if (debug > 0) + printk(KERN_DEBUG "%s: freeing ibmcam=%p\n", proc, ibmcam); + kfree(ibmcam); + + printk(KERN_INFO "%s: Memory freed, wait.\n", proc); +// interruptible_sleep_on_timeout (&wq, HZ*10); + + printk(KERN_INFO "IBM USB camera disconnected.\n"); +} + +static struct usb_driver ibmcam_driver = { + "ibmcam", + usb_ibmcam_probe, + usb_ibmcam_disconnect, + { NULL, NULL } +}; + +int usb_ibmcam_init(void) +{ + return usb_register(&ibmcam_driver); +} + +void usb_ibmcam_cleanup(void) +{ + usb_deregister(&ibmcam_driver); +} + +#ifdef MODULE +int init_module(void) +{ + return usb_ibmcam_init(); +} + +void cleanup_module(void) +{ + usb_ibmcam_cleanup(); +} +#endif diff -ur --new-file old/linux/drivers/usb/ibmcam.h new/linux/drivers/usb/ibmcam.h --- old/linux/drivers/usb/ibmcam.h Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/usb/ibmcam.h Mon Jan 24 07:39:14 2000 @@ -0,0 +1,222 @@ +/* + * Header file for USB IBM C-It Video Camera driver. + * + * Supports IBM C-It Video Camera. + * + * This driver is based on earlier work of: + * + * (C) Copyright 1999 Johannes Erdfelt + * (C) Copyright 1999 Randy Dunlap + */ + +#ifndef __LINUX_IBMCAM_H +#define __LINUX_IBMCAM_H + +#include + +#define USES_IBMCAM_PUTPIXEL 0 /* 0=Fast/oops 1=Slow/secure */ + +/* Video Size 384 x 288 x 3 bytes for RGB */ +/* 384 because xawtv tries to grab 384 even though we tell it 352 is our max */ +#define V4L_FRAME_WIDTH 384 +#define V4L_FRAME_WIDTH_USED 352 +#define V4L_FRAME_HEIGHT 288 +#define V4L_BYTES_PER_PIXEL 3 +#define MAX_FRAME_SIZE (V4L_FRAME_WIDTH * V4L_FRAME_HEIGHT * V4L_BYTES_PER_PIXEL) + +/* Camera capabilities (maximum) */ +#define CAMERA_IMAGE_WIDTH 352 +#define CAMERA_IMAGE_HEIGHT 288 +#define CAMERA_IMAGE_LINE_SZ ((CAMERA_IMAGE_WIDTH * 3) / 2) /* Bytes */ +#define CAMERA_URB_FRAMES 32 +#define CAMERA_MAX_ISO_PACKET 1023 /* 1022 actually sent by camera */ + +#define IBMCAM_NUMFRAMES 2 +#define IBMCAM_NUMSBUF 2 + +#define FRAMES_PER_DESC (CAMERA_URB_FRAMES) +#define FRAME_SIZE_PER_DESC (CAMERA_MAX_ISO_PACKET) + +/* This macro restricts an int variable to an inclusive range */ +#define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); } + +/* + * This macro performs bounds checking - use it when working with + * new formats, or else you may get oopses all over the place. + * If pixel falls out of bounds then it gets shoved back (as close + * to place of offence as possible) and is painted bright red. + */ +#define IBMCAM_PUTPIXEL(fr, ix, iy, vr, vg, vb) { \ + register unsigned char *pf; \ + int limiter = 0, mx, my; \ + mx = ix; \ + my = iy; \ + if (mx < 0) { \ + mx=0; \ + limiter++; \ + } else if (mx >= 352) { \ + mx=351; \ + limiter++; \ + } \ + if (my < 0) { \ + my = 0; \ + limiter++; \ + } else if (my >= V4L_FRAME_HEIGHT) { \ + my = V4L_FRAME_HEIGHT - 1; \ + limiter++; \ + } \ + pf = (fr)->data + V4L_BYTES_PER_PIXEL*((iy)*352 + (ix)); \ + if (limiter) { \ + *pf++ = 0; \ + *pf++ = 0; \ + *pf++ = 0xFF; \ + } else { \ + *pf++ = (vb); \ + *pf++ = (vg); \ + *pf++ = (vr); \ + } \ +} + +/* + * We use macros to do YUV -> RGB conversion because this is + * very important for speed and totally unimportant for size. + * + * YUV -> RGB Conversion + * --------------------- + * + * B = 1.164*(Y-16) + 2.018*(V-128) + * G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128) + * R = 1.164*(Y-16) + 1.596*(U-128) + * + * If you fancy integer arithmetics (as you should), hear this: + * + * 65536*B = 76284*(Y-16) + 132252*(V-128) + * 65536*G = 76284*(Y-16) - 53281*(U-128) - 25625*(V-128) + * 65536*R = 76284*(Y-16) + 104595*(U-128) + * + * Make sure the output values are within [0..255] range. + */ +#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x))) +#define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \ + int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \ + mm_y = (my) - 16; \ + mm_u = (mu) - 128; \ + mm_v = (mv) - 128; \ + mm_yc= mm_y * 76284; \ + mm_b = (mm_yc + 132252*mm_v ) >> 16; \ + mm_g = (mm_yc - 53281*mm_u - 25625*mm_v ) >> 16; \ + mm_r = (mm_yc + 104595*mm_u ) >> 16; \ + mb = LIMIT_RGB(mm_b); \ + mg = LIMIT_RGB(mm_g); \ + mr = LIMIT_RGB(mm_r); \ +} + +/* Debugging aid */ +#define IBMCAM_SAY_AND_WAIT(what) { \ + wait_queue_head_t wq; \ + init_waitqueue_head(&wq); \ + printk(KERN_INFO "Say: %s\n", what); \ + interruptible_sleep_on_timeout (&wq, HZ*3); \ +} + +enum { + STATE_SCANNING, /* Scanning for header */ + STATE_LINES, /* Parsing lines */ +}; + +enum { + FRAME_UNUSED, /* Unused (no MCAPTURE) */ + FRAME_READY, /* Ready to start grabbing */ + FRAME_GRABBING, /* In the process of being grabbed into */ + FRAME_DONE, /* Finished grabbing, but not been synced yet */ + FRAME_ERROR, /* Something bad happened while processing */ +}; + +struct usb_device; + +struct ibmcam_sbuf { + char *data; + urb_t *urb; +}; + +struct ibmcam_frame { + char *data; /* Frame buffer */ + int order_uv; /* True=UV False=VU */ + unsigned char hdr_sig; /* "00 FF 00 ??" where 'hdr_sig' is '??' */ + + int width; /* Width application is expecting */ + int height; /* Height */ + + int frmwidth; /* Width the frame actually is */ + int frmheight; /* Height */ + + volatile int grabstate; /* State of grabbing */ + int scanstate; /* State of scanning */ + + int curline; /* Line of frame we're working on */ + + long scanlength; /* uncompressed, raw data length of frame */ + long bytes_read; /* amount of scanlength that has been read from *data */ + + wait_queue_head_t wq; /* Processes waiting */ +}; + +struct usb_ibmcam { + struct video_device vdev; + + /* Device structure */ + struct usb_device *dev; + + unsigned char iface; + + struct semaphore lock; + int user; /* user count for exclusive use */ + + int initialized; /* Had we already sent init sequence? */ + int streaming; /* Are we streaming Isochronous? */ + int grabbing; /* Are we grabbing? */ + + int compress; /* Should the next frame be compressed? */ + + char *fbuf; /* Videodev buffer area */ + int fbuf_size; /* Videodev buffer size */ + + int curframe; + struct ibmcam_frame frame[IBMCAM_NUMFRAMES]; /* Double buffering */ + + int cursbuf; /* Current receiving sbuf */ + struct ibmcam_sbuf sbuf[IBMCAM_NUMSBUF]; /* Double buffering */ + volatile int remove_pending; /* If set then about to exit */ + wait_queue_head_t remove_ok; /* Wait here until removal is safe */ + + /* + * Scratch space from the Isochronous pipe. + * Scratch buffer should contain at least one pair of lines + * (CAMERA_IMAGE_LINE_SZ). We set it to two pairs here. + * This will be approximately 2 KB. HOWEVER in reality this + * buffer must be as large as hundred of KB because otherwise + * you'll get lots of overflows because V4L client may request + * frames not as uniformly as USB sources them. + */ + unsigned char *scratch; + int scratchlen; + + struct video_picture vpic, vpic_old; /* Picture settings */ + struct video_capability vcap; /* Video capabilities */ + struct video_channel vchan; /* May be used for tuner support */ + unsigned char video_endp; /* 0x82 for IBM camera */ + int has_hdr; + int frame_num; + int iso_packet_len; /* Videomode-dependent, saves bus bandwidth */ + + /* Statistics that can be overlayed on screen */ + unsigned long urb_count; /* How many URBs we received so far */ + unsigned long urb_length; /* Length of last URB */ + unsigned long data_count; /* How many bytes we received */ + unsigned long header_count; /* How many frame headers we found */ + unsigned long scratch_ovf_count;/* How many times we overflowed scratch */ + unsigned long iso_skip_count; /* How many empty ISO packets received */ + unsigned long iso_err_count; /* How many bad ISO packets received */ +}; + +#endif /* __LINUX_IBMCAM_H */ diff -ur --new-file old/linux/drivers/usb/keybdev.c new/linux/drivers/usb/keybdev.c --- old/linux/drivers/usb/keybdev.c Thu Jan 20 18:48:48 2000 +++ new/linux/drivers/usb/keybdev.c Fri Jan 21 22:03:02 2000 @@ -50,11 +50,11 @@ { 0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48, 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54,128, 1, 2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9, - 11, 45, 46, 43, 47, 44,123, 67, 55, 49, 57,122,120, 99,118, 96, + 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96, 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83, - 84, 85, 82, 65, 42, 0, 10,103,111, 0, 0, 0, 0, 0, 0, 0, + 84, 85, 82, 65, 42,105, 10,103,111, 0, 0, 0, 0, 0, 0, 0, 76,125, 75, 0,124, 0,115, 62,116, 59, 60,119, 61,121,114,117, - 0, 0, 0, 0,127, 81, 0,113 }; + 0, 0, 0, 0,127, 24, 0,113, 0, 0, 0, 0, 0, 55, 55, 0 }; #endif diff -ur --new-file old/linux/drivers/usb/mousedev.c new/linux/drivers/usb/mousedev.c --- old/linux/drivers/usb/mousedev.c Thu Jan 13 22:39:15 2000 +++ new/linux/drivers/usb/mousedev.c Mon Jan 24 07:39:14 2000 @@ -38,6 +38,13 @@ #include #include +#ifndef CONFIG_MOUSEDEV_SCREEN_X +#define CONFIG_MOUSEDEV_SCREEN_X 1024 +#endif +#ifndef CONFIG_MOUSEDEV_SCREEN_Y +#define CONFIG_MOUSEDEV_SCREEN_Y 768 +#endif + struct mousedev { char name[32]; int used; @@ -51,8 +58,8 @@ struct fasync_struct *fasync; struct mousedev *mousedev; struct mousedev_list *next; - int dx, dy, dz; - unsigned char ps2[6]; + int dx, dy, dz, oldx, oldy; + char ps2[6]; unsigned long buttons; unsigned char ready, buffer, bufsiz; unsigned char mode, genseq, impseq; @@ -75,10 +82,26 @@ { struct mousedev *mousedev = handle->private; struct mousedev_list *list = mousedev->list; - int index; + int index, size; while (list) { switch (type) { + case EV_ABS: + if (test_bit(EV_REL, handle->dev->evbit) && test_bit(REL_X, handle->dev->relbit)) + return; + switch (code) { + case ABS_X: + size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X]; + list->dx += (value * CONFIG_MOUSEDEV_SCREEN_X - list->oldx) / size; + list->oldx += list->dx * size; + break; + case ABS_Y: + size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y]; + list->dy += (value * CONFIG_MOUSEDEV_SCREEN_Y - list->oldy) / size; + list->oldy += list->dy * size; + break; + } + break; case EV_REL: switch (code) { case REL_X: list->dx += value; break; @@ -89,12 +112,20 @@ case EV_KEY: switch (code) { + case BTN_0: + case BTN_TOUCH: case BTN_LEFT: index = 0; break; + case BTN_4: case BTN_EXTRA: if (list->mode > 1) { index = 4; break; } + case BTN_STYLUS: + case BTN_1: case BTN_RIGHT: index = 1; break; + case BTN_3: case BTN_SIDE: if (list->mode > 1) { index = 3; break; } + case BTN_2: + case BTN_STYLUS2: case BTN_MIDDLE: index = 2; break; - default: index = 0; + default: return; } switch (value) { case 0: clear_bit(index, &list->buttons); break; @@ -186,7 +217,8 @@ list->ps2[off] = 0x08 | ((list->dx < 0) << 4) | ((list->dy < 0) << 5) | (list->buttons & 0x07); list->ps2[off + 1] = (list->dx > 127 ? 127 : (list->dx < -127 ? -127 : list->dx)); list->ps2[off + 2] = (list->dy > 127 ? 127 : (list->dy < -127 ? -127 : list->dy)); - list->dx = list->dy = 0; + list->dx -= list->ps2[off + 1]; + list->dy -= list->ps2[off + 2]; list->bufsiz = off + 3; if (list->mode > 1) @@ -195,9 +227,9 @@ if (list->mode) { list->ps2[off + 3] = (list->dz > 127 ? 127 : (list->dz < -127 ? -127 : list->dz)); list->bufsiz++; - list->dz = 0; + list->dz -= list->ps2[off + 3]; } - list->ready = 0; + if (!list->dx && !list->dy && (!list->mode || !list->dz)) list->ready = 0; list->buffer = list->bufsiz; } @@ -330,15 +362,14 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev) { - if (!(test_bit(EV_KEY, dev->evbit) && test_bit(EV_REL, dev->evbit))) /* The device must have both rels and keys */ + if (!test_bit(EV_KEY, dev->evbit) || + (!test_bit(BTN_LEFT, dev->keybit) && !test_bit(BTN_TOUCH, dev->keybit))) return -1; - if (!(test_bit(REL_X, dev->relbit) && test_bit(REL_Y, dev->relbit))) /* It must be a pointer device */ + if ((!test_bit(EV_REL, dev->evbit) || !test_bit(REL_X, dev->relbit)) && + (!test_bit(EV_ABS, dev->evbit) || !test_bit(ABS_X, dev->absbit))) return -1; - if (!test_bit(BTN_LEFT, dev->keybit)) /* And have at least one mousebutton */ - return -1; - #ifdef CONFIG_INPUT_MOUSEDEV_MIX { struct input_handle *handle; diff -ur --new-file old/linux/drivers/usb/ohci-hcd.c new/linux/drivers/usb/ohci-hcd.c --- old/linux/drivers/usb/ohci-hcd.c Fri Jan 14 01:04:23 2000 +++ new/linux/drivers/usb/ohci-hcd.c Thu Jan 1 01:00:00 1970 @@ -1,1823 +0,0 @@ -/* - * URB OHCI HCD (Host Controller Driver) for USB. - * - * (C) Copyright 1999 Roman Weissgaerber - * - * [ Initialisation is based on Linus' ] - * [ uhci code and gregs ohci fragments ] - * [ (C) Copyright 1999 Linus Torvalds ] - * [ (C) Copyright 1999 Gregory P. Smith] - * - * - * History: - * - * v5.2 1999/12/07 URB 3rd preview, - * v5.1 1999/11/30 URB 2nd preview, cpia, (usb-scsi) - * v5.0 1999/11/22 URB Technical preview, Paul Mackerras powerbook susp/resume - * i386: HUB, Keyboard, Mouse, Printer - * - * v4.3 1999/10/27 multiple HCs, bulk_request - * v4.2 1999/09/05 ISO API alpha, new dev alloc, neg Error-codes - * v4.1 1999/08/27 Randy Dunlap's - ISO API first impl. - * v4.0 1999/08/18 - * v3.0 1999/06/25 - * v2.1 1999/05/09 code clean up - * v2.0 1999/05/04 - * v1.0 1999/04/27 initial release - * - - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* for in_interrupt() */ - -#include -#include -#include - -#undef DEBUG -#define OHCI_USE_NPS - -#include "usb.h" -#include "ohci-hcd.h" - -#ifdef CONFIG_APM -#include -static int handle_apm_event (apm_event_t event); -#endif - -#ifdef CONFIG_PMAC_PBOOK -#include -#include -#endif - -static DECLARE_WAIT_QUEUE_HEAD (op_wakeup); -static LIST_HEAD (ohci_hcd_list); -spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED; - -/*-------------------------------------------------------------------------* - * URB support functions - *-------------------------------------------------------------------------*/ - -/* free the private part of an URB */ - -static void urb_rm_priv (urb_t * urb) -{ - urb_priv_t * urb_priv = urb->hcpriv; - int i; - void * wait; - - if (!urb_priv) return; - - wait = urb_priv->wait; - - for (i = 0; i < urb_priv->length; i++) { - if (urb_priv->td [i]) { - OHCI_FREE (urb_priv->td [i]); - } - } - kfree (urb->hcpriv); - urb->hcpriv = NULL; - - if (wait) { - add_wait_queue (&op_wakeup, wait); - wake_up (&op_wakeup); - } -} - -/*-------------------------------------------------------------------------*/ - -#ifdef DEBUG -static int sohci_get_current_frame_number (struct usb_device * dev); - -/* debug| print the main components of an URB - * small: 0) header + data packets 1) just header */ - -static void urb_print (urb_t * urb, char * str, int small) -{ - unsigned int pipe= urb->pipe; - int i, len; - - if (!urb->dev || !urb->dev->bus) { - dbg("%s URB: no dev", str); - return; - } - - dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,flags:%4x,len:%d/%d,stat:%d(%x)", - str, - sohci_get_current_frame_number (urb->dev), - usb_pipedevice (pipe), - usb_pipeendpoint (pipe), - usb_pipeout (pipe)? 'O': 'I', - usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"): - (usb_pipecontrol (pipe)? "CTRL": "BULK"), - urb->transfer_flags, - urb->actual_length, - urb->transfer_buffer_length, - urb->status, urb->status); - if (!small) { - if (usb_pipecontrol (pipe)) { - printk (KERN_DEBUG __FILE__ ": cmd(8):"); - for (i = 0; i < 8 ; i++) - printk (" %02x", ((__u8 *) urb->setup_packet) [i]); - printk ("\n"); - } - if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) { - printk (KERN_DEBUG __FILE__ ": data(%d/%d):", - urb->actual_length, - urb->transfer_buffer_length); - len = usb_pipeout (pipe)? - urb->transfer_buffer_length: urb->actual_length; - for (i = 0; i < 16 && i < len; i++) - printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]); - printk ("%s stat:%d\n", i < len? "...": "", urb->status); - } - } - -} -/* just for debugging; prints all 32 branches of the int ed tree inclusive iso eds*/ -void ep_print_int_eds (ohci_t * ohci, char * str) { - int i, j; - __u32 * ed_p; - for (i= 0; i < 32; i++) { - j = 5; - printk (KERN_DEBUG __FILE__ " %s branch int %2d(%2x):", str, i, i); - ed_p = &(ohci->hcca.int_table [i]); - while (*ed_p != 0 && j--) { - ed_t *ed = (ed_t *) bus_to_virt(le32_to_cpup(ed_p)); - printk (" ed: %4x;", ed->hwINFO); - ed_p = &ed->hwNextED; - } - printk ("\n"); - } -} - - -#endif - -/*-------------------------------------------------------------------------* - * Interface functions (URB) - *-------------------------------------------------------------------------*/ - -/* return a request to the completion handler */ - -static int sohci_return_urb (urb_t * urb) -{ - urb_priv_t * urb_priv = urb->hcpriv; - urb_t * urbt; - unsigned long flags; - int i; - - /* just to be sure */ - if (!urb->complete) { - urb_rm_priv (urb); - usb_dec_dev_use (urb->dev); - return -1; - } - - if (!urb_priv) return -1; /* urb already unlinked */ - -#ifdef DEBUG - urb_print (urb, "RET", usb_pipeout (urb->pipe)); -#endif - - switch (usb_pipetype (urb->pipe)) { - case PIPE_INTERRUPT: - urb->complete (urb); /* call complete and requeue URB */ - urb->actual_length = 0; - urb->status = USB_ST_URB_PENDING; - if (urb_priv->state != URB_DEL) - td_submit_urb (urb); - break; - - case PIPE_ISOCHRONOUS: - for (urbt = urb->next; urbt && (urbt != urb); urbt = urbt->next); - if (urbt) { /* send the reply and requeue URB */ - urb->complete (urb); - - spin_lock_irqsave (&usb_ed_lock, flags); - urb->actual_length = 0; - urb->status = USB_ST_URB_PENDING; - urb->start_frame = urb_priv->ed->last_iso + 1; - if (urb_priv->state != URB_DEL) { - for (i = 0; i < urb->number_of_packets; i++) { - urb->iso_frame_desc[i].actual_length = 0; - urb->iso_frame_desc[i].status = -EXDEV; - } - td_submit_urb (urb); - } - spin_unlock_irqrestore (&usb_ed_lock, flags); - - } else { /* unlink URB, call complete */ - urb_rm_priv (urb); - usb_dec_dev_use (urb->dev); - urb->complete (urb); - } - break; - - case PIPE_BULK: - case PIPE_CONTROL: /* unlink URB, call complete */ - urb_rm_priv (urb); - usb_dec_dev_use (urb->dev); - urb->complete (urb); - break; - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* get a transfer request */ - -static int sohci_submit_urb (urb_t * urb) -{ - ohci_t * ohci; - ed_t * ed; - urb_priv_t * urb_priv; - unsigned int pipe = urb->pipe; - int i, size = 0; - unsigned long flags; - - if (!urb->dev || !urb->dev->bus) return -EINVAL; - - if (urb->hcpriv) return -EINVAL; /* urb already in use */ - - usb_inc_dev_use (urb->dev); - ohci = (ohci_t *) urb->dev->bus->hcpriv; - -#ifdef DEBUG - urb_print (urb, "SUB", usb_pipein (pipe)); -#endif - - if (usb_pipedevice (pipe) == ohci->rh.devnum) - return rh_submit_urb (urb); /* a request to the virtual root hub */ - - /* every endpoint has a ed, locate and fill it */ - if (!(ed = ep_add_ed (urb->dev, pipe, urb->interval, 1))) { - usb_dec_dev_use (urb->dev); - return -ENOMEM; - } - - /* for the private part of the URB we need the number of TDs (size) */ - switch (usb_pipetype (pipe)) { - case PIPE_BULK: /* one TD for every 4096 Byte */ - size = (urb->transfer_buffer_length - 1) / 4096 + 1; - break; - case PIPE_ISOCHRONOUS: /* number of packets from URB */ - size = urb->number_of_packets; - for (i = 0; i < urb->number_of_packets; i++) { - urb->iso_frame_desc[i].actual_length = 0; - urb->iso_frame_desc[i].status = -EXDEV; - } - break; - case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */ - size = (urb->transfer_buffer_length == 0)? 2: - (urb->transfer_buffer_length - 1) / 4096 + 3; - break; - case PIPE_INTERRUPT: /* one TD */ - size = 1; - - break; - } - - /* allocate the private part or the URB */ - urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); - if (!urb_priv) { - usb_dec_dev_use (urb->dev); - return -ENOMEM; - } - memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (td_t *)); - - /* fill the private part of the URB */ - urb->hcpriv = urb_priv; - urb_priv->length = size; - urb_priv->td_cnt = 0; - urb_priv->state = 0; - urb_priv->ed = ed; - urb_priv->wait = NULL; - - /* allocate the TDs */ - for (i = 0; i < size; i++) { - OHCI_ALLOC (urb_priv->td[i], sizeof (td_t)); - if (!urb_priv->td[i]) { - usb_dec_dev_use (urb->dev); - urb_rm_priv (urb); - return -ENOMEM; - } - } - spin_lock_irqsave (&usb_ed_lock, flags); - if (ed->state == ED_NEW || (ed->state & ED_DEL)) { - urb_rm_priv(urb); - usb_dec_dev_use (urb->dev); - return -EINVAL; - } - - /* for ISOC transfers calculate start frame index */ - if (urb->transfer_flags & USB_ISO_ASAP) { - urb->start_frame = ((ed->state == ED_OPER)? (ed->last_iso + 1): - (le16_to_cpu (ohci->hcca.frame_no) + 10)) & 0xffff; - } - - td_submit_urb (urb); /* fill the TDs and link it to the ed */ - - if (ed->state != ED_OPER) /* link the ed into a chain if is not already */ - ep_link (ohci, ed); - spin_unlock_irqrestore (&usb_ed_lock, flags); - - urb->status = USB_ST_URB_PENDING; - // queue_urb(s, &urb->urb_list); - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* deactivate all TDs and remove the private part of the URB */ - -static int sohci_unlink_urb (urb_t * urb) -{ - unsigned long flags; - ohci_t * ohci; - DECLARE_WAITQUEUE (wait, current); - - if (!urb) /* just to be sure */ - return -EINVAL; - -#ifdef DEBUG - urb_print (urb, "UNLINK", 1); -#endif - - ohci = (ohci_t *) urb->dev->bus->hcpriv; - - if (usb_pipedevice (urb->pipe) == ohci->rh.devnum) - return rh_unlink_urb (urb); /* a request to the virtual root hub */ - - if (urb->hcpriv) { - if (urb->status == USB_ST_URB_PENDING) { /* URB active? */ - urb_priv_t * urb_priv = urb->hcpriv; - urb_priv->state = URB_DEL; - /* we want to delete the TDs of an URB from an ed - * request the deletion, it will be handled at the next USB-frame */ - urb_priv->wait = &wait; - - spin_lock_irqsave (&usb_ed_lock, flags); - ep_rm_ed (urb->dev, urb_priv->ed); - urb_priv->ed->state |= ED_URB_DEL; - spin_unlock_irqrestore (&usb_ed_lock, flags); - - current->state = TASK_UNINTERRUPTIBLE; - if(schedule_timeout (HZ / 10)) /* wait until all TDs are deleted */ - remove_wait_queue (&op_wakeup, &wait); - else - err("unlink URB timeout!"); - } else - urb_rm_priv (urb); - usb_dec_dev_use (urb->dev); - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* allocate private data space for a usb device */ - -static int sohci_alloc_dev (struct usb_device *usb_dev) -{ - struct ohci_device * dev; - - dev = kmalloc (sizeof (*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - memset (dev, 0, sizeof (*dev)); - - usb_dev->hcpriv = dev; - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* free private data space of usb device */ - -static int sohci_free_dev (struct usb_device * usb_dev) -{ - unsigned long flags; - int i, cnt = 0; - ed_t * ed; - DECLARE_WAITQUEUE (wait, current); - struct ohci_device * dev = usb_to_ohci (usb_dev); - ohci_t * ohci = usb_dev->bus->hcpriv; - - if (!dev) return 0; - - if (usb_dev->devnum >= 0) { - - /* delete all TDs of all EDs */ - spin_lock_irqsave (&usb_ed_lock, flags); - for(i = 0; i < NUM_EDS; i++) { - ed = &(dev->ed[i]); - if (ed->state != ED_NEW) { - if (ed->state == ED_OPER) ep_unlink (ohci, ed); - ep_rm_ed (usb_dev, ed); - ed->state = ED_DEL; - cnt++; - } - } - spin_unlock_irqrestore (&usb_ed_lock, flags); - - if (cnt > 0) { - dev->wait = &wait; - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout (HZ / 10); - remove_wait_queue (&op_wakeup, &wait); - } - } - kfree (dev); - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* tell us the current USB frame number */ - -static int sohci_get_current_frame_number (struct usb_device *usb_dev) -{ - ohci_t * ohci = usb_dev->bus->hcpriv; - - return le16_to_cpu (ohci->hcca.frame_no); -} - -/*-------------------------------------------------------------------------*/ - -struct usb_operations sohci_device_operations = { - sohci_alloc_dev, - sohci_free_dev, - sohci_get_current_frame_number, - sohci_submit_urb, - sohci_unlink_urb -}; - -/*-------------------------------------------------------------------------* - * ED handling functions - *-------------------------------------------------------------------------*/ - -/* search for the right branch to insert an interrupt ed into the int tree - * do some load ballancing; - * returns the branch and - * sets the interval to interval = 2^integer (ld (interval)) */ - -static int ep_int_ballance (ohci_t * ohci, int interval, int load) -{ - int i, branch = 0; - - /* search for the least loaded interrupt endpoint branch of all 32 branches */ - for (i = 0; i < 32; i++) - if (ohci->ohci_int_load [branch] > ohci->ohci_int_load [i]) branch = i; - - branch = branch % interval; - for (i = branch; i < 32; i += interval) ohci->ohci_int_load [i] += load; - - return branch; -} - -/*-------------------------------------------------------------------------*/ - -/* 2^int( ld (inter)) */ - -static int ep_2_n_interval (int inter) -{ - int i; - for (i = 0; ((inter >> i) > 1 ) && (i < 5); i++); - return 1 << i; -} - -/*-------------------------------------------------------------------------*/ - -/* the int tree is a binary tree - * in order to process it sequentially the indexes of the branches have to be mapped - * the mapping reverses the bits of a word of num_bits length */ - -static int ep_rev (int num_bits, int word) -{ - int i, wout = 0; - - for (i = 0; i < num_bits; i++) wout |= (((word >> i) & 1) << (num_bits - i - 1)); - return wout; -} - -/*-------------------------------------------------------------------------*/ - -/* link an ed into one of the HC chains */ - -static int ep_link (ohci_t * ohci, ed_t * edi) -{ - int int_branch; - int i; - int inter; - int interval; - int load; - __u32 * ed_p; - volatile ed_t * ed = edi; - - ed->state = ED_OPER; - - switch (ed->type) { - case CTRL: - ed->hwNextED = 0; - if (ohci->ed_controltail == NULL) { - writel (virt_to_bus (ed), &ohci->regs->ed_controlhead); - } else { - ohci->ed_controltail->hwNextED = cpu_to_le32 (virt_to_bus (ed)); - } - ed->ed_prev = ohci->ed_controltail; - ohci->ed_controltail = ed; - break; - - case BULK: - ed->hwNextED = 0; - if (ohci->ed_bulktail == NULL) { - writel (virt_to_bus (ed), &ohci->regs->ed_bulkhead); - } else { - ohci->ed_bulktail->hwNextED = cpu_to_le32 (virt_to_bus (ed)); - } - ed->ed_prev = ohci->ed_bulktail; - ohci->ed_bulktail = ed; - break; - - case INT: - load = ed->int_load; - interval = ep_2_n_interval (ed->int_period); - ed->int_interval = interval; - int_branch = ep_int_ballance (ohci, interval, load); - ed->int_branch = int_branch; - - for (i = 0; i < ep_rev (6, interval); i += inter) { - inter = 1; - for (ed_p = &(ohci->hcca.int_table[ep_rev (5, i) + int_branch]); - (*ed_p != 0) && (((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval >= interval); - ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED)) - inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval); - ed->hwNextED = *ed_p; - *ed_p = cpu_to_le32 (virt_to_bus (ed)); - } -#ifdef DEBUG - ep_print_int_eds (ohci, "LINK_INT"); -#endif - break; - - case ISO: - ed->hwNextED = 0; - ed->int_interval = 1; - if (ohci->ed_isotail != NULL) { - ohci->ed_isotail->hwNextED = cpu_to_le32 (virt_to_bus (ed)); - ed->ed_prev = ohci->ed_isotail; - } else { - for ( i = 0; i < 32; i += inter) { - inter = 1; - for (ed_p = &(ohci->hcca.int_table[ep_rev (5, i)]); - *ed_p != 0; - ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED)) - inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval); - *ed_p = cpu_to_le32 (virt_to_bus (ed)); - } - ed->ed_prev = NULL; - } - ohci->ed_isotail = ed; -#ifdef DEBUG - ep_print_int_eds (ohci, "LINK_ISO"); -#endif - break; - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* unlink an ed from one of the HC chains. - * just the link to the ed is unlinked. - * the link from the ed still points to another operational ed or 0 - * so the HC can eventually finish the processing of the unlinked ed */ - -static int ep_unlink (ohci_t * ohci, ed_t * ed) -{ - int int_branch; - int i; - int inter; - int interval; - __u32 * ed_p; - - - switch (ed->type) { - case CTRL: - if (ed->ed_prev == NULL) { - writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_controlhead); - } else { - ed->ed_prev->hwNextED = ed->hwNextED; - } - if(ohci->ed_controltail == ed) { - ohci->ed_controltail = ed->ed_prev; - } else { - ((ed_t *) bus_to_virt (le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev; - } - break; - - case BULK: - if (ed->ed_prev == NULL) { - writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_bulkhead); - } else { - ed->ed_prev->hwNextED = ed->hwNextED; - } - if (ohci->ed_bulktail == ed) { - ohci->ed_bulktail = ed->ed_prev; - } else { - ((ed_t *) bus_to_virt (le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev; - } - break; - - case INT: - int_branch = ed->int_branch; - interval = ed->int_interval; - - for (i = 0; i < ep_rev (6, interval); i += inter) { - for (ed_p = &(ohci->hcca.int_table[ep_rev (5, i) + int_branch]), inter = 1; - (*ed_p != 0) && (*ed_p != ed->hwNextED); - ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED), - inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval)) { - if(((ed_t *) bus_to_virt (le32_to_cpup (ed_p))) == ed) { - *ed_p = ed->hwNextED; - break; - } - } - } - for (i = int_branch; i < 32; i += interval) ohci->ohci_int_load[i] -= ed->int_load; -#ifdef DEBUG - ep_print_int_eds (ohci, "UNLINK_INT"); -#endif break; - - case ISO: - if (ohci->ed_isotail == ed) - ohci->ed_isotail = ed->ed_prev; - if (ed->hwNextED != 0) - ((ed_t *) bus_to_virt (le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev; - - if (ed->ed_prev != NULL) { - ed->ed_prev->hwNextED = ed->hwNextED; - } else { - for (i = 0; i < 32; i += inter) { - inter = 1; - for (ed_p = &(ohci->hcca.int_table[ep_rev (5, i)]); - *ed_p != 0; - ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED)) { - inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval); - if(((ed_t *) bus_to_virt (le32_to_cpup (ed_p))) == ed) { - *ed_p = ed->hwNextED; - break; - } - } - } - } -#ifdef DEBUG - ep_print_int_eds (ohci, "UNLINK_ISO"); -#endif - break; - } - ed->state = ED_UNLINK; - return 0; -} - - -/*-------------------------------------------------------------------------*/ - -/* add/reinit an endpoint; this should be done once at the usb_set_configuration command, - * but the USB stack is a little bit stateless so we do it at every transaction - * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK - * in all other cases the state is left unchanged - * the ed info fields are setted anyway even though most of them should not change */ - -static ed_t * ep_add_ed (struct usb_device * usb_dev, unsigned int pipe, int interval, int load) -{ - ohci_t * ohci = usb_dev->bus->hcpriv; - td_t * td; - volatile ed_t * ed; - - - spin_lock (&usb_ed_lock); - - ed = &(usb_to_ohci (usb_dev)->ed[(usb_pipeendpoint (pipe) << 1) | - (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))]); - - if((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) - return NULL; /* pending delete request */ - - if (ed->state == ED_NEW) { - ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); /* skip ed */ - OHCI_ALLOC (td, sizeof (*td)); /* dummy td; end of td list for ed */ - if(!td) return NULL; /* out of memory */ - ed->hwTailP = cpu_to_le32 (virt_to_bus (td)); - ed->hwHeadP = ed->hwTailP; - ed->state = ED_UNLINK; - ed->type = usb_pipetype (pipe); - usb_to_ohci (usb_dev)->ed_cnt++; - } - - ohci->dev[usb_pipedevice (pipe)] = usb_dev; - - ed->hwINFO = cpu_to_le32 (usb_pipedevice (pipe) - | usb_pipeendpoint (pipe) << 7 - | (usb_pipeisoc (pipe)? 0x8000: 0) - | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000)) - | usb_pipeslow (pipe) << 13 - | usb_maxpacket (usb_dev, pipe, usb_pipeout (pipe)) << 16); - - if (ed->type == INT && ed->state == ED_UNLINK) { - ed->int_period = interval; - ed->int_load = load; - } - - spin_unlock(&usb_ed_lock); - return ed; -} - -/*-------------------------------------------------------------------------*/ - -/* request the removal of an endpoint - * put the ep on the rm_list and request a stop of the bulk or ctrl list - * real removal is done at the next start of frame (SOF) hardware interrupt */ - -static void ep_rm_ed (struct usb_device * usb_dev, ed_t * ed) -{ - unsigned int frame; - ohci_t * ohci = usb_dev->bus->hcpriv; - - if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) return; - - ed->hwINFO |= cpu_to_le32 (OHCI_ED_SKIP); - - writel (OHCI_INTR_SF, &ohci->regs->intrstatus); - writel (OHCI_INTR_SF, &ohci->regs->intrenable); /* enable sof interrupt */ - - frame = le16_to_cpu (ohci->hcca.frame_no) & 0x1; - ed->ed_rm_list = ohci->ed_rm_list[frame]; - ohci->ed_rm_list[frame] = ed; - - switch (ed->type) { - case CTRL: /* stop CTRL list */ - writel (ohci->hc_control &= ~(0x01 << 4), &ohci->regs->control); - break; - case BULK: /* stop BULK list */ - writel (ohci->hc_control &= ~(0x01 << 5), &ohci->regs->control); - break; - } -} - -/*-------------------------------------------------------------------------* - * TD handling functions - *-------------------------------------------------------------------------*/ - -/* prepare a TD */ - -static void td_fill (unsigned int info, void * data, int len, urb_t * urb, int type, int index) -{ - volatile td_t * td, * td_pt; - urb_priv_t * urb_priv = urb->hcpriv; - - if (index >= urb_priv->length) { - err("internal OHCI error: TD index > length"); - return; - } - - td_pt = urb_priv->td [index]; - /* fill the old dummy TD */ - td = (td_t *) bus_to_virt (le32_to_cpup (&urb_priv->ed->hwTailP) & 0xfffffff0); - td->ed = urb_priv->ed; - td->index = index; - td->urb = urb; - td->hwINFO = cpu_to_le32 (info); - td->type = type; - if ((td->ed->type & 3) == PIPE_ISOCHRONOUS) { - td->hwCBP = cpu_to_le32 (((!data || !len)? - 0 : virt_to_bus (data)) & 0xFFFFF000); - td->ed->last_iso = info & 0xffff; - } else { - td->hwCBP = cpu_to_le32 (((!data || !len)? 0 : virt_to_bus (data))); - } - td->hwBE = cpu_to_le32 ((!data || !len )? 0: virt_to_bus (data + len - 1)); - td->hwNextTD = cpu_to_le32 (virt_to_bus (td_pt)); - td->hwPSW [0] = cpu_to_le16 ((virt_to_bus (data) & 0x0FFF) | 0xE000); - td_pt->hwNextTD = 0; - td->ed->hwTailP = td->hwNextTD; - urb_priv->td [index] = td; - - td->next_dl_td = NULL; //td_pt; -} - -/*-------------------------------------------------------------------------*/ - -/* prepare all TDs of a transfer */ - -static void td_submit_urb (urb_t * urb) -{ - urb_priv_t * urb_priv = urb->hcpriv; - ohci_t * ohci = (ohci_t *) urb->dev->bus->hcpriv; - void * ctrl = urb->setup_packet; - void * data = urb->transfer_buffer; - int data_len = urb->transfer_buffer_length; - int cnt = 0; - __u32 info = 0; - - - urb_priv->td_cnt = 0; - - switch (usb_pipetype (urb->pipe)) { - case PIPE_BULK: - info = usb_pipeout (urb->pipe)? - TD_CC | TD_DP_OUT | TD_T_TOGGLE: TD_CC | TD_DP_IN | TD_T_TOGGLE; - while(data_len > 4096) { - td_fill (info, data, 4096, urb, (cnt? 0: ST_ADDR) | ADD_LEN, cnt); - data += 4096; data_len -= 4096; cnt++; - } - info = usb_pipeout (urb->pipe)? - TD_CC | TD_DP_OUT | TD_T_TOGGLE: TD_CC | TD_R | TD_DP_IN | TD_T_TOGGLE; - td_fill (info, data, data_len, urb, (cnt? 0: ST_ADDR) | ADD_LEN, cnt); - cnt++; - writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ - break; - - case PIPE_INTERRUPT: - info = usb_pipeout (urb->pipe)? - TD_CC | TD_DP_OUT | TD_T_TOGGLE: TD_CC | TD_R | TD_DP_IN | TD_T_TOGGLE; - td_fill (info, data, data_len, urb, ST_ADDR | ADD_LEN, cnt++); - break; - - case PIPE_CONTROL: - info = TD_CC | TD_DP_SETUP | TD_T_DATA0; - td_fill (info, ctrl, 8, urb, ST_ADDR, cnt++); - if (data_len > 0) { - info = usb_pipeout (urb->pipe)? - TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1; - td_fill (info, data, data_len, urb, ADD_LEN, cnt++); - } - info = usb_pipeout (urb->pipe)? - TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1; - td_fill (info, NULL, 0, urb, 0, cnt++); - writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */ - break; - - case PIPE_ISOCHRONOUS: - for (cnt = 0; cnt < urb->number_of_packets; cnt++) { - td_fill (TD_CC|TD_ISO | ((urb->start_frame + cnt) & 0xffff), - (__u8 *) data + urb->iso_frame_desc[cnt].offset, - urb->iso_frame_desc[cnt].length, urb, (cnt? 0: ST_ADDR) | ADD_LEN, cnt); - } - break; - } - if (urb_priv->length != cnt) - dbg("TD LENGTH %d != CNT %d", urb_priv->length, cnt); -} - -/*-------------------------------------------------------------------------* - * Done List handling functions - *-------------------------------------------------------------------------*/ - -/* replies to the request have to be on a FIFO basis so - * we reverse the reversed done-list */ - -static td_t * dl_reverse_done_list (ohci_t * ohci) -{ - __u32 td_list_hc; - td_t * td_rev = NULL; - td_t * td_list = NULL; - urb_priv_t * urb_priv = NULL; - unsigned long flags; - - spin_lock_irqsave (&usb_ed_lock, flags); - - td_list_hc = le32_to_cpup (&ohci->hcca.done_head) & 0xfffffff0; - ohci->hcca.done_head = 0; - - while (td_list_hc) { - td_list = (td_t *) bus_to_virt (td_list_hc); - - if (TD_CC_GET (le32_to_cpup (&td_list->hwINFO))) { - urb_priv = (urb_priv_t *) td_list->urb->hcpriv; - dbg(" USB-error/status: %x : %p", - TD_CC_GET (le32_to_cpup (&td_list->hwINFO)), td_list); - if (td_list->ed->hwHeadP & cpu_to_le32 (0x1)) { - if (urb_priv && ((td_list->index + 1) < urb_priv->length)) { - td_list->ed->hwHeadP = - (urb_priv->td[urb_priv->length - 1]->hwNextTD & cpu_to_le32 (0xfffffff0)) | - (td_list->ed->hwHeadP & cpu_to_le32 (0x2)); - urb_priv->td_cnt += urb_priv->length - td_list->index - 1; - } else - td_list->ed->hwHeadP &= cpu_to_le32 (0xfffffff2); - } - } - - td_list->next_dl_td = td_rev; - td_rev = td_list; - td_list_hc = le32_to_cpup (&td_list->hwNextTD) & 0xfffffff0; - } - spin_unlock_irqrestore (&usb_ed_lock, flags); - return td_list; -} - -/*-------------------------------------------------------------------------*/ - -/* there are some pending requests to remove - * - some of the eds (if ed->state & ED_DEL (set by sohci_free_dev) - * - some URBs/TDs if urb_priv->state == URB_DEL */ - -static void dl_del_list (ohci_t * ohci, unsigned int frame) -{ - unsigned long flags; - ed_t * ed; - __u32 edINFO; - td_t * td = NULL, * td_next = NULL, * tdHeadP = NULL, * tdTailP; - __u32 * td_p; - int ctrl = 0, bulk = 0; - - spin_lock_irqsave (&usb_ed_lock, flags); - for (ed = ohci->ed_rm_list[frame]; ed != NULL; ed = ed->ed_rm_list) { - - tdTailP = bus_to_virt (le32_to_cpup (&ed->hwTailP) & 0xfffffff0); - tdHeadP = bus_to_virt (le32_to_cpup (&ed->hwHeadP) & 0xfffffff0); - edINFO = le32_to_cpup (&ed->hwINFO); - td_p = &ed->hwHeadP; - - for (td = tdHeadP; td != tdTailP; td = td_next) { - urb_t * urb = td->urb; - urb_priv_t * urb_priv = td->urb->hcpriv; - - td_next = bus_to_virt (le32_to_cpup (&td->hwNextTD) & 0xfffffff0); - if ((urb_priv->state == URB_DEL) || (ed->state & ED_DEL)) { - *td_p = td->hwNextTD | (*td_p & cpu_to_le32 (0x3)); - if(++ (urb_priv->td_cnt) == urb_priv->length) - urb_rm_priv (urb); - } else { - td_p = &td->hwNextTD; - } - - } - if (ed->state & ED_DEL) { /* set by sohci_free_dev */ - struct ohci_device * dev = usb_to_ohci (ohci->dev[edINFO & 0x7F]); - OHCI_FREE (tdTailP); /* free dummy td */ - ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); - ed->state = ED_NEW; - /* if all eds are removed wake up sohci_free_dev */ - if ((! --dev->ed_cnt) && dev->wait) { - add_wait_queue (&op_wakeup, dev->wait); - wake_up (&op_wakeup); - } - } - else { - ed->state &= ~ED_URB_DEL; - ed->hwINFO &= ~cpu_to_le32 (OHCI_ED_SKIP); - } - - if ((ed->type & 3) == CTRL) ctrl |= 1; - if ((ed->type & 3) == BULK) bulk |= 1; - } - - if (ctrl) writel (0, &ohci->regs->ed_controlcurrent); /* reset CTRL list */ - if (bulk) writel (0, &ohci->regs->ed_bulkcurrent); /* reset BULK list */ - if (!ohci->ed_rm_list[!frame]) /* start CTRL u. BULK list */ - writel (ohci->hc_control |= (0x03<<4), &ohci->regs->control); - ohci->ed_rm_list[frame] = NULL; - - spin_unlock_irqrestore (&usb_ed_lock, flags); -} - -/*-------------------------------------------------------------------------*/ - -/* td done list */ - -static void dl_done_list (ohci_t * ohci, td_t * td_list) -{ - td_t * td_list_next = NULL; - ed_t * ed; - int dlen = 0; - int cc = 0; - urb_t * urb; - urb_priv_t * urb_priv; - __u32 tdINFO, tdBE, tdCBP, edHeadP, edTailP; - __u16 tdPSW; - unsigned long flags; - - while (td_list) { - td_list_next = td_list->next_dl_td; - - urb = td_list->urb; - urb_priv = urb->hcpriv; - tdINFO = le32_to_cpup (&td_list->hwINFO); - tdBE = le32_to_cpup (&td_list->hwBE); - tdCBP = le32_to_cpup (&td_list->hwCBP); - - ed = td_list->ed; - - if (td_list->type & ST_ADDR) - urb->actual_length = 0; - - if (td_list->type & ADD_LEN) { /* accumulate length of multi td transfers */ - if (tdINFO & TD_ISO) { - tdPSW = le16_to_cpu (td_list->hwPSW[0]); - cc = (tdPSW >> 12) & 0xF; - if (cc < 0xE) { - if (usb_pipeout(urb->pipe)) { - dlen = urb->iso_frame_desc[td_list->index].length; - } else { - dlen = tdPSW & 0x3ff; - } - urb->actual_length += dlen; - urb->iso_frame_desc[td_list->index].actual_length = dlen; - if (!(urb->transfer_flags & USB_DISABLE_SPD) && (cc == TD_DATAUNDERRUN)) - cc = TD_CC_NOERROR; - - urb->iso_frame_desc[td_list->index].status = cc_to_error[cc]; - } - } else { - if (tdBE != 0) { - dlen = (bus_to_virt (tdBE) - urb->transfer_buffer + 1); - if (td_list->hwCBP == 0) - urb->actual_length += dlen; - else - urb->actual_length += (bus_to_virt(tdCBP) - urb->transfer_buffer); - } - } - } - /* error code of transfer */ - cc = TD_CC_GET (tdINFO); - if (!(urb->transfer_flags & USB_DISABLE_SPD) && (cc == TD_DATAUNDERRUN)) - cc = TD_CC_NOERROR; - if (++(urb_priv->td_cnt) == urb_priv->length) { - if (urb_priv->state != URB_DEL && !(ed->state & ED_DEL) && ed->state != ED_NEW) { - urb->status = cc_to_error[cc]; - sohci_return_urb (urb); - } else { - urb_rm_priv (urb); - } - } - - spin_lock_irqsave (&usb_ed_lock, flags); - if (ed->state != ED_NEW) { - edHeadP = le32_to_cpup (&ed->hwHeadP) & 0xfffffff0; - edTailP = le32_to_cpup (&ed->hwTailP); - - if((edHeadP == edTailP) && (ed->state == ED_OPER)) - ep_unlink (ohci, ed); /* unlink eds if they are not busy */ - - } - spin_unlock_irqrestore (&usb_ed_lock, flags); - - td_list = td_list_next; - } -} - - - - -/*-------------------------------------------------------------------------* - * Virtual Root Hub - *-------------------------------------------------------------------------*/ - -static __u8 root_hub_dev_des[] = -{ - 0x12, /* __u8 bLength; */ - 0x01, /* __u8 bDescriptorType; Device */ - 0x00, /* __u16 bcdUSB; v1.0 */ - 0x01, - 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ - 0x00, /* __u8 bDeviceSubClass; */ - 0x00, /* __u8 bDeviceProtocol; */ - 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ - 0x00, /* __u16 idVendor; */ - 0x00, - 0x00, /* __u16 idProduct; */ - 0x00, - 0x00, /* __u16 bcdDevice; */ - 0x00, - 0x00, /* __u8 iManufacturer; */ - 0x00, /* __u8 iProduct; */ - 0x00, /* __u8 iSerialNumber; */ - 0x01 /* __u8 bNumConfigurations; */ -}; - - -/* Configuration descriptor */ -static __u8 root_hub_config_des[] = -{ - 0x09, /* __u8 bLength; */ - 0x02, /* __u8 bDescriptorType; Configuration */ - 0x19, /* __u16 wTotalLength; */ - 0x00, - 0x01, /* __u8 bNumInterfaces; */ - 0x01, /* __u8 bConfigurationValue; */ - 0x00, /* __u8 iConfiguration; */ - 0x40, /* __u8 bmAttributes; - Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */ - 0x00, /* __u8 MaxPower; */ - - /* interface */ - 0x09, /* __u8 if_bLength; */ - 0x04, /* __u8 if_bDescriptorType; Interface */ - 0x00, /* __u8 if_bInterfaceNumber; */ - 0x00, /* __u8 if_bAlternateSetting; */ - 0x01, /* __u8 if_bNumEndpoints; */ - 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ - 0x00, /* __u8 if_bInterfaceSubClass; */ - 0x00, /* __u8 if_bInterfaceProtocol; */ - 0x00, /* __u8 if_iInterface; */ - - /* endpoint */ - 0x07, /* __u8 ep_bLength; */ - 0x05, /* __u8 ep_bDescriptorType; Endpoint */ - 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ - 0x03, /* __u8 ep_bmAttributes; Interrupt */ - 0x08, /* __u16 ep_wMaxPacketSize; 8 Bytes */ - 0x00, - 0xff /* __u8 ep_bInterval; 255 ms */ -}; - -/* -For OHCI we need just the 2nd Byte, so we -don't need this constant byte-array - -static __u8 root_hub_hub_des[] = -{ - 0x00, * __u8 bLength; * - 0x29, * __u8 bDescriptorType; Hub-descriptor * - 0x02, * __u8 bNbrPorts; * - 0x00, * __u16 wHubCharacteristics; * - 0x00, - 0x01, * __u8 bPwrOn2pwrGood; 2ms * - 0x00, * __u8 bHubContrCurrent; 0 mA * - 0x00, * __u8 DeviceRemovable; *** 8 Ports max *** * - 0xff * __u8 PortPwrCtrlMask; *** 8 ports max *** * -}; -*/ - -/*-------------------------------------------------------------------------*/ - -/* prepare Interrupt pipe data; HUB INTERRUPT ENDPOINT */ - -static int rh_send_irq (ohci_t * ohci, void * rh_data, int rh_len) -{ - int num_ports; - int i; - int ret; - int len; - - __u8 data[8]; - - num_ports = readl (&ohci->regs->roothub.a) & 0xff; - *(__u8 *) data = (readl (&ohci->regs->roothub.status) & 0x00030000) > 0? 1: 0; - ret = *(__u8 *) data; - - for ( i = 0; i < num_ports; i++) { - *(__u8 *) (data + (i + 1) / 8) |= - ((readl (&ohci->regs->roothub.portstatus[i]) & 0x001f0000) > 0? 1: 0) << ((i + 1) % 8); - ret += *(__u8 *) (data + (i + 1) / 8); - } - len = i/8 + 1; - - if (ret > 0) { - memcpy (rh_data, data, min (len, min (rh_len, sizeof(data)))); - return len; - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* Virtual Root Hub INTs are polled by this timer every "intervall" ms */ - -static void rh_int_timer_do (unsigned long ptr) -{ - int len; - - urb_t * urb = (urb_t *) ptr; - ohci_t * ohci = urb->dev->bus->hcpriv; - - if(ohci->rh.send) { - len = rh_send_irq (ohci, urb->transfer_buffer, urb->transfer_buffer_length); - if (len > 0) { - urb->actual_length = len; -#ifdef DEBUG - urb_print (urb, "RET(rh)", usb_pipeout (urb->pipe)); -#endif - if (urb->complete) urb->complete (urb); - } - } - rh_init_int_timer (urb); -} - -/*-------------------------------------------------------------------------*/ - -/* Root Hub INTs are polled by this timer */ - -static int rh_init_int_timer (urb_t * urb) -{ - ohci_t * ohci = urb->dev->bus->hcpriv; - - ohci->rh.interval = urb->interval; - init_timer (&ohci->rh.rh_int_timer); - ohci->rh.rh_int_timer.function = rh_int_timer_do; - ohci->rh.rh_int_timer.data = (unsigned long) urb; - ohci->rh.rh_int_timer.expires = - jiffies + (HZ * (urb->interval < 30? 30: urb->interval)) / 1000; - add_timer (&ohci->rh.rh_int_timer); - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -#define OK(x) len = (x); break -#define WR_RH_STAT(x) writel((x), &ohci->regs->roothub.status) -#define WR_RH_PORTSTAT(x) writel((x), &ohci->regs->roothub.portstatus[wIndex-1]) -#define RD_RH_STAT readl(&ohci->regs->roothub.status) -#define RD_RH_PORTSTAT readl(&ohci->regs->roothub.portstatus[wIndex-1]) - -/* request to virtual root hub */ - -static int rh_submit_urb (urb_t * urb) -{ - struct usb_device * usb_dev = urb->dev; - ohci_t * ohci = usb_dev->bus->hcpriv; - unsigned int pipe = urb->pipe; - devrequest * cmd = (devrequest *) urb->setup_packet; - void * data = urb->transfer_buffer; - int leni = urb->transfer_buffer_length; - int len = 0; - int status = TD_CC_NOERROR; - - __u8 datab[16]; - __u8 * data_buf = datab; - - __u16 bmRType_bReq; - __u16 wValue; - __u16 wIndex; - __u16 wLength; - - if (usb_pipeint(pipe)) { - - ohci->rh.urb = urb; - ohci->rh.send = 1; - ohci->rh.interval = urb->interval; - rh_init_int_timer(urb); - urb->status = cc_to_error [TD_CC_NOERROR]; - - return 0; - } - - bmRType_bReq = cmd->requesttype | (cmd->request << 8); - wValue = le16_to_cpu (cmd->value); - wIndex = le16_to_cpu (cmd->index); - wLength = le16_to_cpu (cmd->length); - switch (bmRType_bReq) { - /* Request Destination: - without flags: Device, - RH_INTERFACE: interface, - RH_ENDPOINT: endpoint, - RH_CLASS means HUB here, - RH_OTHER | RH_CLASS almost ever means HUB_PORT here - */ - - case RH_GET_STATUS: - *(__u16 *) data_buf = cpu_to_le16 (1); OK (2); - case RH_GET_STATUS | RH_INTERFACE: - *(__u16 *) data_buf = cpu_to_le16 (0); OK (2); - case RH_GET_STATUS | RH_ENDPOINT: - *(__u16 *) data_buf = cpu_to_le16 (0); OK (2); - case RH_GET_STATUS | RH_CLASS: - *(__u32 *) data_buf = cpu_to_le32 (RD_RH_STAT & 0x7fff7fff); OK (4); - case RH_GET_STATUS | RH_OTHER | RH_CLASS: - *(__u32 *) data_buf = cpu_to_le32 (RD_RH_PORTSTAT); OK (4); - - case RH_CLEAR_FEATURE | RH_ENDPOINT: - switch (wValue) { - case (RH_ENDPOINT_STALL): OK (0); - } - break; - - case RH_CLEAR_FEATURE | RH_CLASS: - switch (wValue) { - case RH_C_HUB_LOCAL_POWER: - OK(0); - case (RH_C_HUB_OVER_CURRENT): - WR_RH_STAT(RH_HS_OCIC); OK (0); - } - break; - - case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: - switch (wValue) { - case (RH_PORT_ENABLE): - WR_RH_PORTSTAT (RH_PS_CCS ); OK (0); - case (RH_PORT_SUSPEND): - WR_RH_PORTSTAT (RH_PS_POCI); OK (0); - case (RH_PORT_POWER): - WR_RH_PORTSTAT (RH_PS_LSDA); OK (0); - case (RH_C_PORT_CONNECTION): - WR_RH_PORTSTAT (RH_PS_CSC ); OK (0); - case (RH_C_PORT_ENABLE): - WR_RH_PORTSTAT (RH_PS_PESC); OK (0); - case (RH_C_PORT_SUSPEND): - WR_RH_PORTSTAT (RH_PS_PSSC); OK (0); - case (RH_C_PORT_OVER_CURRENT): - WR_RH_PORTSTAT (RH_PS_OCIC); OK (0); - case (RH_C_PORT_RESET): - WR_RH_PORTSTAT (RH_PS_PRSC); OK (0); - } - break; - - case RH_SET_FEATURE | RH_OTHER | RH_CLASS: - switch (wValue) { - case (RH_PORT_SUSPEND): - WR_RH_PORTSTAT (RH_PS_PSS ); OK (0); - case (RH_PORT_RESET): /* BUG IN HUP CODE *********/ - if((RD_RH_PORTSTAT &1) != 0) WR_RH_PORTSTAT (RH_PS_PRS ); OK (0); - case (RH_PORT_POWER): - WR_RH_PORTSTAT (RH_PS_PPS ); OK (0); - case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/ - if((RD_RH_PORTSTAT &1) != 0) WR_RH_PORTSTAT (RH_PS_PES ); OK (0); - } - break; - - case RH_SET_ADDRESS: ohci->rh.devnum = wValue; OK(0); - - case RH_GET_DESCRIPTOR: - switch ((wValue & 0xff00) >> 8) { - case (0x01): /* device descriptor */ - len = min (leni, min (sizeof (root_hub_dev_des), wLength)); - data_buf = root_hub_dev_des; OK(len); - case (0x02): /* configuration descriptor */ - len = min (leni, min (sizeof (root_hub_config_des), wLength)); - data_buf = root_hub_config_des; OK(len); - case (0x03): /* string descriptors */ - default: - status = TD_CC_STALL; - } - break; - - case RH_GET_DESCRIPTOR | RH_CLASS: - *(__u8 *) (data_buf+1) = 0x29; - *(__u32 *) (data_buf+2) = cpu_to_le32 (readl (&ohci->regs->roothub.a)); - *(__u8 *) data_buf = (*(__u8 *) (data_buf + 2) / 8) * 2 + 9; /* length of descriptor */ - - len = min (leni, min(*(__u8 *) data_buf, wLength)); - *(__u8 *) (data_buf+6) = 0; /* Root Hub needs no current from bus */ - if (*(__u8 *) (data_buf+2) < 8) { /* less than 8 Ports */ - *(__u8 *) (data_buf+7) = readl (&ohci->regs->roothub.b) & 0xff; - *(__u8 *) (data_buf+8) = (readl (&ohci->regs->roothub.b) & 0xff0000) >> 16; - } else { - *(__u32 *) (data_buf+7) = cpu_to_le32 (readl(&ohci->regs->roothub.b)); - } - OK (len); - - case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK (1); - - case RH_SET_CONFIGURATION: WR_RH_STAT (0x10000); OK (0); - - default: - status = TD_CC_STALL; - } - - dbg("USB HC roothubstat1: %x", readl ( &(ohci->regs->roothub.portstatus[0]) )); - dbg("USB HC roothubstat2: %x", readl ( &(ohci->regs->roothub.portstatus[1]) )); - - len = min(len, leni); - memcpy (data, data_buf, len); - urb->actual_length = len; - urb->status = cc_to_error [status]; - -#ifdef DEBUG - urb_print (urb, "RET(rh)", usb_pipeout (urb->pipe)); -#endif - - if (urb->complete) urb->complete (urb); - return 0; -} - -/*-------------------------------------------------------------------------*/ - -static int rh_unlink_urb (urb_t * urb) -{ - ohci_t * ohci = urb->dev->bus->hcpriv; - - ohci->rh.send = 0; - del_timer (&ohci->rh.rh_int_timer); - return 0; -} - -/*-------------------------------------------------------------------------* - * HC functions - *-------------------------------------------------------------------------*/ - -/* reset the HC not the BUS */ - -static void hc_reset (ohci_t * ohci) -{ - int timeout = 30; - int smm_timeout = 50; /* 0,5 sec */ - - if (readl (&ohci->regs->control) & 0x100) { /* SMM owns the HC */ - writel (0x08, &ohci->regs->cmdstatus); /* request ownership */ - dbg("USB HC TakeOver from SMM"); - while (readl (&ohci->regs->control) & 0x100) { - wait_ms (10); - if (--smm_timeout == 0) { - err("USB HC TakeOver failed!"); - break; - } - } - } - - writel ((1 << 31), &ohci->regs->intrdisable); /* Disable HC interrupts */ - dbg("USB HC reset_hc: %x ;", readl (&ohci->regs->control)); - /* this seems to be needed for the lucent controller on powerbooks.. */ - writel (0, &ohci->regs->control); /* Move USB to reset state */ - - writel (1, &ohci->regs->cmdstatus); /* HC Reset */ - while ((readl (&ohci->regs->cmdstatus) & 0x01) != 0) { /* 10us Reset */ - if (--timeout == 0) { - err("USB HC reset timed out!"); - return; - } - udelay (1); - } -} - -/*-------------------------------------------------------------------------*/ - -/* Start an OHCI controller, set the BUS operational - * enable interrupts - * connect the virtual root hub */ - -static int hc_start (ohci_t * ohci) -{ - unsigned int mask; - unsigned int fminterval; - struct usb_device * usb_dev; - struct ohci_device * dev; - - /* Tell the controller where the control and bulk lists are - * The lists are empty now. */ - - writel (0, &ohci->regs->ed_controlhead); - writel (0, &ohci->regs->ed_bulkhead); - - writel (virt_to_bus (&ohci->hcca), &ohci->regs->hcca); /* a reset clears this */ - - fminterval = 0x2edf; - writel ((fminterval * 9) / 10, &ohci->regs->periodicstart); - fminterval |= ((((fminterval - 210) * 6) / 7) << 16); - writel (fminterval, &ohci->regs->fminterval); - writel (0x628, &ohci->regs->lsthresh); - - /* Choose the interrupts we care about now, others later on demand */ - mask = OHCI_INTR_MIE | OHCI_INTR_WDH | OHCI_INTR_SO; - - writel (ohci->hc_control = 0xBF, &ohci->regs->control); /* USB Operational */ - writel (mask, &ohci->regs->intrenable); - writel (mask, &ohci->regs->intrstatus); - -#ifdef OHCI_USE_NPS - writel ((readl(&ohci->regs->roothub.a) | 0x200) & ~0x100, - &ohci->regs->roothub.a); - writel (0x10000, &ohci->regs->roothub.status); - mdelay ((readl(&ohci->regs->roothub.a) >> 23) & 0x1fe); -#endif /* OHCI_USE_NPS */ - - /* connect the virtual root hub */ - - usb_dev = usb_alloc_dev (NULL, ohci->bus); - if (!usb_dev) return -1; - - dev = usb_to_ohci (usb_dev); - ohci->bus->root_hub = usb_dev; - usb_connect (usb_dev); - if (usb_new_device (usb_dev) != 0) { - usb_free_dev (usb_dev); - return -1; - } - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* an interrupt happens */ - -static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r) -{ - ohci_t * ohci = __ohci; - struct ohci_regs * regs = ohci->regs; - int ints; - - if ((ohci->hcca.done_head != 0) && !(le32_to_cpup (&ohci->hcca.done_head) & 0x01)) { - ints = OHCI_INTR_WDH; - } else { - if ((ints = (readl (®s->intrstatus) & readl (®s->intrenable))) == 0) - return; - } - - dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca.frame_no)); - - if (ints & OHCI_INTR_WDH) { - writel (OHCI_INTR_WDH, ®s->intrdisable); - dl_done_list (ohci, dl_reverse_done_list (ohci)); - writel (OHCI_INTR_WDH, ®s->intrenable); - } - - if (ints & OHCI_INTR_SO) { - dbg("USB Schedule overrun"); - writel (OHCI_INTR_SO, ®s->intrenable); - } - - if (ints & OHCI_INTR_SF) { - unsigned int frame = le16_to_cpu (ohci->hcca.frame_no) & 1; - writel (OHCI_INTR_SF, ®s->intrdisable); - if (ohci->ed_rm_list[!frame] != NULL) { - dl_del_list (ohci, !frame); - } - if (ohci->ed_rm_list[frame] != NULL) writel (OHCI_INTR_SF, ®s->intrenable); - } - writel (ints, ®s->intrstatus); - writel (OHCI_INTR_MIE, ®s->intrenable); -} - -/*-------------------------------------------------------------------------*/ - -/* allocate OHCI */ - -static ohci_t * hc_alloc_ohci (void * mem_base) -{ - int i; - ohci_t * ohci; - struct usb_bus * bus; - - ohci = (ohci_t *) __get_free_pages (GFP_KERNEL, 1); - if (!ohci) - return NULL; - - memset (ohci, 0, sizeof (ohci_t)); - - ohci->irq = -1; - ohci->regs = mem_base; - - /* for load ballancing of the interrupt branches */ - for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0; - for (i = 0; i < NUM_INTS; i++) ohci->hcca.int_table[i] = 0; - - /* end of control and bulk lists */ - ohci->ed_isotail = NULL; - ohci->ed_controltail = NULL; - ohci->ed_bulktail = NULL; - - bus = usb_alloc_bus (&sohci_device_operations); - if (!bus) { - free_pages ((unsigned long) ohci, 1); - return NULL; - } - - ohci->bus = bus; - bus->hcpriv = (void *) ohci; - - return ohci; -} - -/*-------------------------------------------------------------------------*/ - -/* De-allocate all resources.. */ - -static void hc_release_ohci (ohci_t * ohci) -{ - dbg("USB HC release ohci"); - - /* disconnect all devices */ - if (ohci->bus->root_hub) usb_disconnect (&ohci->bus->root_hub); - - hc_reset (ohci); - writel (OHCI_USB_RESET, &ohci->regs->control); - wait_ms (10); - - if (ohci->irq >= 0) { - free_irq (ohci->irq, ohci); - ohci->irq = -1; - } - - usb_deregister_bus (ohci->bus); - usb_free_bus (ohci->bus); - - /* unmap the IO address space */ - iounmap (ohci->regs); - - free_pages ((unsigned long) ohci, 1); -} - -/*-------------------------------------------------------------------------*/ - -/* Increment the module usage count, start the control thread and - * return success. */ - -static int hc_found_ohci (int irq, void * mem_base) -{ - ohci_t * ohci; - dbg("USB HC found: irq= %d membase= %lx", irq, (unsigned long) mem_base); - - ohci = hc_alloc_ohci (mem_base); - if (!ohci) { - return -ENOMEM; - } - - INIT_LIST_HEAD (&ohci->ohci_hcd_list); - list_add (&ohci->ohci_hcd_list, &ohci_hcd_list); - - hc_reset (ohci); - writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control); - wait_ms (10); - usb_register_bus (ohci->bus); - - if (request_irq (irq, hc_interrupt, SA_SHIRQ, "ohci-usb", ohci) == 0) { - ohci->irq = irq; - hc_start (ohci); - return 0; - } - err("request interrupt %d failed", irq); - hc_release_ohci (ohci); - return -EBUSY; -} - -/*-------------------------------------------------------------------------*/ - -static int hc_start_ohci (struct pci_dev * dev) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - unsigned long mem_base = dev->resource[0].start; -#else - unsigned long mem_base = dev->base_address[0]; - if (mem_base & PCI_BASE_ADDRESS_SPACE_IO) return -ENODEV; - mem_base &= PCI_BASE_ADDRESS_MEM_MASK; -#endif - - pci_set_master (dev); - mem_base = (unsigned long) ioremap_nocache (mem_base, 4096); - - if (!mem_base) { - err("Error mapping OHCI memory"); - return -EFAULT; - } - return hc_found_ohci (dev->irq, (void *) mem_base); -} - -/*-------------------------------------------------------------------------*/ - -#ifdef CONFIG_PMAC_PBOOK - -/* On Powerbooks, put the controller into suspend mode when going - * to sleep, and do a resume when waking up. */ - -static int ohci_sleep_notify (struct pmu_sleep_notifier * self, int when) -{ - struct list_head * ohci_l; - ohci_t * ohci; - - for (ohci_l = ohci_hcd_list.next; ohci_l != &ohci_hcd_list; ohci_l = ohci_l->next) { - ohci = list_entry (ohci_l, ohci_t, ohci_hcd_list); - - switch (when) { - case PBOOK_SLEEP_NOW: - disable_irq (ohci->irq); - writel (ohci->hc_control = OHCI_USB_SUSPEND, &ohci->regs->control); - wait_ms (10); - break; - case PBOOK_WAKE: - writel (ohci->hc_control = OHCI_USB_RESUME, &ohci->regs->control); - wait_ms (20); - writel (ohci->hc_control = 0xBF, &ohci->regs->control); - enable_irq (ohci->irq); - break; - } - } - return PBOOK_SLEEP_OK; -} - -static struct pmu_sleep_notifier ohci_sleep_notifier = { - ohci_sleep_notify, SLEEP_LEVEL_MISC, -}; -#endif /* CONFIG_PMAC_PBOOK */ - -/*-------------------------------------------------------------------------*/ - -#ifdef CONFIG_APM -static int handle_apm_event (apm_event_t event) -{ - static int down = 0; - ohci_t * ohci; - struct list_head * ohci_l; - - switch (event) { - case APM_SYS_SUSPEND: - case APM_USER_SUSPEND: - if (down) { - dbg("received extra suspend event"); - break; - } - for (ohci_l = ohci_hcd_list.next; ohci_l != &ohci_hcd_list; ohci_l = ohci_l->next) { - ohci = list_entry (ohci_l, ohci_t, ohci_hcd_list); - dbg("USB-Bus suspend: %p", ohci); - writel (ohci->hc_control = 0xFF, &ohci->regs->control); - } - wait_ms (10); - down = 1; - break; - case APM_NORMAL_RESUME: - case APM_CRITICAL_RESUME: - if (!down) { - dbg("received bogus resume event"); - break; - } - for (ohci_l = ohci_hcd_list.next; ohci_l != &ohci_hcd_list; ohci_l = ohci_l->next) { - ohci = list_entry(ohci_l, ohci_t, ohci_hcd_list); - dbg("USB-Bus resume: %p", ohci); - writel (ohci->hc_control = 0x7F, &ohci->regs->control); - } - wait_ms (20); - for (ohci_l = ohci_hcd_list.next; ohci_l != &ohci_hcd_list; ohci_l = ohci_l->next) { - ohci = list_entry (ohci_l, ohci_t, ohci_hcd_list); - writel (ohci->hc_control = 0xBF, &ohci->regs->control); - } - down = 0; - break; - } - return 0; -} -#endif - -/*-------------------------------------------------------------------------*/ - -#define PCI_CLASS_SERIAL_USB_OHCI 0x0C0310 - -int ohci_hcd_init (void) -{ - int ret = -ENODEV; - struct pci_dev * dev = NULL; - - while ((dev = pci_find_class (PCI_CLASS_SERIAL_USB_OHCI, dev))) { - if (hc_start_ohci(dev) >= 0) ret = 0; - } - -#ifdef CONFIG_APM - apm_register_callback (&handle_apm_event); -#endif - -#ifdef CONFIG_PMAC_PBOOK - pmu_register_sleep_notifier (&ohci_sleep_notifier); -#endif - return ret; -} - -/*-------------------------------------------------------------------------*/ - -#ifdef MODULE -int init_module (void) -{ - return ohci_hcd_init (); -} - -/*-------------------------------------------------------------------------*/ - -void cleanup_module (void) -{ - ohci_t * ohci; - -#ifdef CONFIG_APM - apm_unregister_callback (&handle_apm_event); -#endif - -#ifdef CONFIG_PMAC_PBOOK - pmu_unregister_sleep_notifier (&ohci_sleep_notifier); -#endif - - while (!list_empty (&ohci_hcd_list)) { - ohci = list_entry (ohci_hcd_list.next, ohci_t, ohci_hcd_list); - list_del (&ohci->ohci_hcd_list); - INIT_LIST_HEAD (&ohci->ohci_hcd_list); - hc_release_ohci (ohci); - } -} -#endif //MODULE - diff -ur --new-file old/linux/drivers/usb/ohci-hcd.h new/linux/drivers/usb/ohci-hcd.h --- old/linux/drivers/usb/ohci-hcd.h Thu Jan 13 22:43:04 2000 +++ new/linux/drivers/usb/ohci-hcd.h Thu Jan 1 01:00:00 1970 @@ -1,407 +0,0 @@ - /* - * URB OHCI HCD (Host Controller Driver) for USB. - * - *(C) Copyright 1999 Roman Weissgaerber - * - * ohci-hcd.h - * - */ - - -#define MODSTR "ohci: " - - -static int cc_to_error[16] = { - -/* mapping of the OHCI CC status to error codes */ -#ifdef USB_ST_CRC /* status codes */ - /* No Error */ USB_ST_NOERROR, - /* CRC Error */ USB_ST_CRC, - /* Bit Stuff */ USB_ST_BITSTUFF, - /* Data Togg */ USB_ST_CRC, - /* Stall */ USB_ST_STALL, - /* DevNotResp */ USB_ST_NORESPONSE, - /* PIDCheck */ USB_ST_BITSTUFF, - /* UnExpPID */ USB_ST_BITSTUFF, - /* DataOver */ USB_ST_DATAOVERRUN, - /* DataUnder */ USB_ST_DATAUNDERRUN, - /* reservd */ USB_ST_NORESPONSE, - /* reservd */ USB_ST_NORESPONSE, - /* BufferOver */ USB_ST_BUFFEROVERRUN, - /* BuffUnder */ USB_ST_BUFFERUNDERRUN, - /* Not Access */ USB_ST_NORESPONSE, - /* Not Access */ USB_ST_NORESPONSE -}; - -#else /* error codes */ - /* No Error */ 0, - /* CRC Error */ -EILSEQ, - /* Bit Stuff */ -EPROTO, - /* Data Togg */ -EILSEQ, - /* Stall */ -EPIPE, - /* DevNotResp */ -ETIMEDOUT, - /* PIDCheck */ -EPROTO, - /* UnExpPID */ -EPROTO, - /* DataOver */ -EOVERFLOW, - /* DataUnder */ -EREMOTEIO, - /* reservd */ -ETIMEDOUT, - /* reservd */ -ETIMEDOUT, - /* BufferOver */ -ECOMM, - /* BuffUnder */ -ECOMM, - /* Not Access */ -ETIMEDOUT, - /* Not Access */ -ETIMEDOUT -}; -#define USB_ST_URB_PENDING -EINPROGRESS -#endif - - - -struct ed; -struct td; -/* for ED and TD structures */ - -/* ED States */ - -#define ED_NEW 0x00 -#define ED_UNLINK 0x01 -#define ED_OPER 0x02 -#define ED_DEL 0x04 -#define ED_URB_DEL 0x08 - -/* usb_ohci_ed */ -typedef struct ed { - __u32 hwINFO; - __u32 hwTailP; - __u32 hwHeadP; - __u32 hwNextED; - - struct ed * ed_prev; - __u8 int_period; - __u8 int_branch; - __u8 int_load; - __u8 int_interval; - __u8 state; - __u8 type; - __u16 last_iso; - struct ed * ed_rm_list; - -} ed_t; - - -/* TD info field */ -#define TD_CC 0xf0000000 -#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f) -#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28) -#define TD_EC 0x0C000000 -#define TD_T 0x03000000 -#define TD_T_DATA0 0x02000000 -#define TD_T_DATA1 0x03000000 -#define TD_T_TOGGLE 0x00000000 -#define TD_R 0x00040000 -#define TD_DI 0x00E00000 -#define TD_DI_SET(X) (((X) & 0x07)<< 21) -#define TD_DP 0x00180000 -#define TD_DP_SETUP 0x00000000 -#define TD_DP_IN 0x00100000 -#define TD_DP_OUT 0x00080000 - -#define TD_ISO 0x00010000 -#define TD_DEL 0x00020000 - -/* CC Codes */ -#define TD_CC_NOERROR 0x00 -#define TD_CC_CRC 0x01 -#define TD_CC_BITSTUFFING 0x02 -#define TD_CC_DATATOGGLEM 0x03 -#define TD_CC_STALL 0x04 -#define TD_DEVNOTRESP 0x05 -#define TD_PIDCHECKFAIL 0x06 -#define TD_UNEXPECTEDPID 0x07 -#define TD_DATAOVERRUN 0x08 -#define TD_DATAUNDERRUN 0x09 -#define TD_BUFFEROVERRUN 0x0C -#define TD_BUFFERUNDERRUN 0x0D -#define TD_NOTACCESSED 0x0F - - -#define MAXPSW 1 - -typedef struct td { - __u32 hwINFO; - __u32 hwCBP; /* Current Buffer Pointer */ - __u32 hwNextTD; /* Next TD Pointer */ - __u32 hwBE; /* Memory Buffer End Pointer */ - __u16 hwPSW[MAXPSW]; - - __u8 type; - __u8 index; - struct ed * ed; - struct td * next_dl_td; - urb_t * urb; -} td_t; - - -/* TD types */ -#define BULK 0x03 -#define INT 0x01 -#define CTRL 0x02 -#define ISO 0x00 - -#define SEND 0x01 -#define ST_ADDR 0x02 -#define ADD_LEN 0x04 -#define DEL 0x08 - - -#define OHCI_ED_SKIP (1 << 14) - -/* - * The HCCA (Host Controller Communications Area) is a 256 byte - * structure defined in the OHCI spec. that the host controller is - * told the base address of. It must be 256-byte aligned. - */ - -#define NUM_INTS 32 /* part of the OHCI standard */ -struct ohci_hcca { - __u32 int_table[NUM_INTS]; /* Interrupt ED table */ - __u16 frame_no; /* current frame number */ - __u16 pad1; /* set to 0 on each frame_no change */ - __u32 done_head; /* info returned for an interrupt */ - u8 reserved_for_hc[116]; -} __attribute((aligned(256))); - - -/* - * Maximum number of root hub ports. - */ -#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */ - -/* - * This is the structure of the OHCI controller's memory mapped I/O - * region. This is Memory Mapped I/O. You must use the readl() and - * writel() macros defined in asm/io.h to access these!! - */ -struct ohci_regs { - /* control and status registers */ - __u32 revision; - __u32 control; - __u32 cmdstatus; - __u32 intrstatus; - __u32 intrenable; - __u32 intrdisable; - /* memory pointers */ - __u32 hcca; - __u32 ed_periodcurrent; - __u32 ed_controlhead; - __u32 ed_controlcurrent; - __u32 ed_bulkhead; - __u32 ed_bulkcurrent; - __u32 donehead; - /* frame counters */ - __u32 fminterval; - __u32 fmremaining; - __u32 fmnumber; - __u32 periodicstart; - __u32 lsthresh; - /* Root hub ports */ - struct ohci_roothub_regs { - __u32 a; - __u32 b; - __u32 status; - __u32 portstatus[MAX_ROOT_PORTS]; - } roothub; -} __attribute((aligned(32))); - -/* - * cmdstatus register */ -#define OHCI_CLF 0x02 -#define OHCI_BLF 0x04 - -/* - * Interrupt register masks - */ -#define OHCI_INTR_SO (1) -#define OHCI_INTR_WDH (1 << 1) -#define OHCI_INTR_SF (1 << 2) -#define OHCI_INTR_RD (1 << 3) -#define OHCI_INTR_UE (1 << 4) -#define OHCI_INTR_FNO (1 << 5) -#define OHCI_INTR_RHSC (1 << 6) -#define OHCI_INTR_OC (1 << 30) -#define OHCI_INTR_MIE (1 << 31) - -/* - * Control register masks - */ -#define OHCI_USB_RESET 0 -#define OHCI_USB_RESUME (1 << 6) -#define OHCI_USB_OPER (2 << 6) -#define OHCI_USB_SUSPEND (3 << 6) - - -/* Virtual Root HUB */ -struct virt_root_hub { - int devnum; /* Address of Root Hub endpoint */ - void * urb; - void * int_addr; - int send; - int interval; - struct timer_list rh_int_timer; -}; - -/* destination of request */ -#define RH_INTERFACE 0x01 -#define RH_ENDPOINT 0x02 -#define RH_OTHER 0x03 - -#define RH_CLASS 0x20 -#define RH_VENDOR 0x40 - -/* Requests: bRequest << 8 | bmRequestType */ -#define RH_GET_STATUS 0x0080 -#define RH_CLEAR_FEATURE 0x0100 -#define RH_SET_FEATURE 0x0300 -#define RH_SET_ADDRESS 0x0500 -#define RH_GET_DESCRIPTOR 0x0680 -#define RH_SET_DESCRIPTOR 0x0700 -#define RH_GET_CONFIGURATION 0x0880 -#define RH_SET_CONFIGURATION 0x0900 -#define RH_GET_STATE 0x0280 -#define RH_GET_INTERFACE 0x0A80 -#define RH_SET_INTERFACE 0x0B00 -#define RH_SYNC_FRAME 0x0C80 -/* Our Vendor Specific Request */ -#define RH_SET_EP 0x2000 - - -/* Hub port features */ -#define RH_PORT_CONNECTION 0x00 -#define RH_PORT_ENABLE 0x01 -#define RH_PORT_SUSPEND 0x02 -#define RH_PORT_OVER_CURRENT 0x03 -#define RH_PORT_RESET 0x04 -#define RH_PORT_POWER 0x08 -#define RH_PORT_LOW_SPEED 0x09 -#define RH_C_PORT_CONNECTION 0x10 -#define RH_C_PORT_ENABLE 0x11 -#define RH_C_PORT_SUSPEND 0x12 -#define RH_C_PORT_OVER_CURRENT 0x13 -#define RH_C_PORT_RESET 0x14 - -/* Hub features */ -#define RH_C_HUB_LOCAL_POWER 0x00 -#define RH_C_HUB_OVER_CURRENT 0x01 - -#define RH_DEVICE_REMOTE_WAKEUP 0x00 -#define RH_ENDPOINT_STALL 0x01 - -#define RH_ACK 0x01 -#define RH_REQ_ERR -1 -#define RH_NACK 0x00 - -/* Root-Hub Register info */ - -#define RH_PS_CCS 0x00000001 -#define RH_PS_PES 0x00000002 -#define RH_PS_PSS 0x00000004 -#define RH_PS_POCI 0x00000008 -#define RH_PS_PRS 0x00000010 -#define RH_PS_PPS 0x00000100 -#define RH_PS_LSDA 0x00000200 -#define RH_PS_CSC 0x00010000 -#define RH_PS_PESC 0x00020000 -#define RH_PS_PSSC 0x00040000 -#define RH_PS_OCIC 0x00080000 -#define RH_PS_PRSC 0x00100000 - -/* Root hub status bits */ -#define RH_HS_LPS 0x00000001 -#define RH_HS_OCI 0x00000002 -#define RH_HS_DRWE 0x00008000 -#define RH_HS_LPSC 0x00010000 -#define RH_HS_OCIC 0x00020000 -#define RH_HS_CRWE 0x80000000 - -#define min(a,b) (((a)<(b))?(a):(b)) - - -/* urb */ -typedef struct -{ - ed_t * ed; - __u16 length; // number of tds associated with this request - __u16 td_cnt; // number of tds already serviced - int state; - void * wait; - td_t * td[0]; // list pointer to all corresponding TDs associated with this request - -} urb_priv_t; -#define URB_DEL 1 - -/* - * This is the full ohci controller description - * - * Note how the "proper" USB information is just - * a subset of what the full implementation needs. (Linus) - */ - - -typedef struct ohci { - struct ohci_hcca hcca; /* hcca */ - - int irq; - struct ohci_regs * regs; /* OHCI controller's memory */ - struct list_head ohci_hcd_list; /* list of all ohci_hcd */ - - struct ohci * next; // chain of uhci device contexts - struct list_head urb_list; // list of all pending urbs - spinlock_t urb_list_lock; // lock to keep consistency - - int ohci_int_load[32]; /* load of the 32 Interrupt Chains (for load ballancing)*/ - ed_t * ed_rm_list[2]; /* lists of all endpoints to be removed */ - ed_t * ed_bulktail; /* last endpoint of bulk list */ - ed_t * ed_controltail; /* last endpoint of control list */ - ed_t * ed_isotail; /* last endpoint of iso list */ - int intrstatus; - __u32 hc_control; /* copy of the hc control reg */ - struct usb_bus * bus; - struct usb_device * dev[128]; - struct virt_root_hub rh; -} ohci_t; - - -#define NUM_TDS 0 /* num of preallocated transfer descriptors */ -#define NUM_EDS 32 /* num of preallocated endpoint descriptors */ - -struct ohci_device { - ed_t ed[NUM_EDS]; - int ed_cnt; - void * wait; -}; - -// #define ohci_to_usb(ohci) ((ohci)->usb) -#define usb_to_ohci(usb) ((struct ohci_device *)(usb)->hcpriv) - -/* hcd */ -/* endpoint */ -static int ep_link(ohci_t * ohci, ed_t * ed); -static int ep_unlink(ohci_t * ohci, ed_t * ed); -static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned int pipe, int interval, int load); -static void ep_rm_ed(struct usb_device * usb_dev, ed_t * ed); -/* td */ -static void td_fill(unsigned int info, void * data, int len, urb_t * urb, int type, int index); -static void td_submit_urb(urb_t * urb); -/* root hub */ -static int rh_submit_urb(urb_t * urb); -static int rh_unlink_urb(urb_t * urb); -static int rh_init_int_timer(urb_t * urb); - -#ifdef DEBUG -#define OHCI_FREE(x) kfree(x); printk("OHCI FREE: %d: %4x\n", -- __ohci_free_cnt, (unsigned int) x) -#define OHCI_ALLOC(x,size) (x) = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); printk("OHCI ALLO: %d: %4x\n", ++ __ohci_free_cnt,(unsigned int) x) -static int __ohci_free_cnt = 0; -#else -#define OHCI_FREE(x) kfree(x) -#define OHCI_ALLOC(x,size) (x) = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL) -#endif - diff -ur --new-file old/linux/drivers/usb/ov511.c new/linux/drivers/usb/ov511.c --- old/linux/drivers/usb/ov511.c Tue Jan 18 01:24:48 2000 +++ new/linux/drivers/usb/ov511.c Mon Jan 24 07:39:14 2000 @@ -1,6 +1,6 @@ /* * OmniVision OV511 Camera-to-USB Bridge Driver - * Copyright 1999 Mark W. McClelland + * Copyright 1999/2000 Mark W. McClelland * * Based on the Linux CPiA driver. * @@ -11,7 +11,7 @@ * DEBUG - Debugging code. * FIXME - Something that is broken or needs improvement. * - * Version: 1.05 + * Version: 1.06 * * Please see the file: linux/Documentation/usb/ov511.txt * and the website at: http://people.delphi.com/mmcclelland/linux/ @@ -533,7 +533,7 @@ ov511_i2c_write(dev, 0x20, 0x1c); ov511_i2c_write(dev, 0x24, 0x2e); /* 10 */ ov511_i2c_write(dev, 0x25, 0x7c); /* 8a */ - ov511_i2c_write(dev, 0x26, 0x70); + ov511_i2c_write(dev, 0x26, 0x00); /* was 0x70 */ ov511_i2c_write(dev, 0x28, 0x24); /* 24 */ ov511_i2c_write(dev, 0x2b, 0xac); ov511_i2c_write(dev, 0x2c, 0xfe); @@ -737,20 +737,16 @@ int aPackNum[10]; struct ov511_frame *frame; - if (ov511->curframe == -1) { - return 0; - } - for (i = 0; i < urb->number_of_packets; i++) { int n = urb->iso_frame_desc[i].actual_length; int st = urb->iso_frame_desc[i].status; - + urb->iso_frame_desc[i].actual_length = 0; + urb->iso_frame_desc[i].status = 0; cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset; - if (!n) continue; - aPackNum[i] = n ? cdata[992] : -1; + if (!n || ov511->curframe == -1) continue; if (st) PDEBUG("data error: [%d] len=%d, status=%d", i, n, st); @@ -767,14 +763,27 @@ #endif if (frame->scanstate == STATE_LINES) { + int iFrameNext; if (waitqueue_active(&frame->wq)) { #if 0 PDEBUG("About to wake up waiting processes"); #endif frame->grabstate = FRAME_DONE; - ov511->curframe = -1; wake_up_interruptible(&frame->wq); } + /* If next frame is ready or grabbing, point to it */ + iFrameNext = (ov511->curframe + 1) % OV511_NUMFRAMES; + if (ov511->frame[iFrameNext].grabstate== FRAME_READY || + ov511->frame[iFrameNext].grabstate== FRAME_GRABBING) { + ov511->curframe = iFrameNext; + frame->scanstate = STATE_SCANNING; + } else { +#if 0 + PDEBUG("Frame not ready? state = %d", + ov511->frame[iFrameNext].grabstate); +#endif + ov511->curframe = -1; + } } } @@ -1623,6 +1632,9 @@ break; case 102: printk("ov511: Camera is a AverMedia InterCam Elite\n"); + break; + case 112: + printk("ov511: Camera is a MediaForte MV300\n"); break; default: err("Specific camera type (%d) not recognized", rc); diff -ur --new-file old/linux/drivers/usb/scanner.c new/linux/drivers/usb/scanner.c --- old/linux/drivers/usb/scanner.c Fri Jan 14 20:25:21 2000 +++ new/linux/drivers/usb/scanner.c Fri Jan 28 01:40:53 2000 @@ -1,7 +1,11 @@ /* -*- linux-c -*- */ /* - * Driver for USB Scanners (linux-2.3.33) + * Driver for USB Scanners (linux-2.3.41) + * + * Copyright (C) 1999, 2000 David E. Nelson + * + * Portions may be copyright Brad Keryan and Michael Gee. * * David E. Nelson (dnelson@jump.net) * @@ -19,9 +23,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * Based upon mouse.c (Brad Keryan) and printer.c (Michael Gee). + * Originally based upon mouse.c (Brad Keryan) and printer.c (Michael Gee). * * History + * * 0.1 8/31/1999 * * Developed/tested using linux-2.3.15 with minor ohci.c changes to @@ -30,18 +35,18 @@ * testing was performed with uhci but I was unable to get it to * work. Initial relase to the linux-usb development effort. * + * * 0.2 10/16/1999 * - * FIXED: * - Device can't be opened unless a scanner is plugged into the USB. * - Finally settled on a reasonable value for the I/O buffer's. * - Cleaned up write_scanner() * - Disabled read/write stats * - A little more code cleanup * + * * 0.3 10/18/1999 * - * FIXED: * - Device registration changed to reflect new device * allocation/registration for linux-2.3.22+. * - Adopted David Brownell's technique for @@ -52,19 +57,21 @@ * - Added user specified verdor:product USB ID's which can be passed * as module parameters. * + * * 0.3.1 - * FIXED: + * * - Applied patches for linux-2.3.25. * - Error number reporting changed to reflect negative return codes. * + * * 0.3.2 - * FIXED: + * * - Applied patches for linux-2.3.26 to scanner_init(). * - Debug read/write stats now report values as signed decimal. * * * 0.3.3 - * FIXED: + * * - Updated the bulk_msg() calls to usb usb_bulk_msg(). * - Added a small delay in the write_scanner() method to aid in * avoiding NULL data reads on HP scanners. We'll see how this works. @@ -75,13 +82,42 @@ * - kfree()'d the pointer after using usb_string() as documented in * linux-usb-api.txt. * - Added usb_set_configuration(). It got lost in version 0.3 -- ack! - * - Added the HP 5200C USB Vendor/Product ID's + * - Added the HP 5200C USB Vendor/Product ID's. + * + * + * 0.3.4 + * + * - Added Greg K-H's patch for better handling of + * Product/Vendor detection. + * - The driver now autoconfigures its endpoints including interrupt + * endpoints if one is detected. The concept was originally based + * upon David Brownell's method. + * - Added some Seiko/Epson ID's. Thanks to Karl Heinz + * Kremer . + * - Added some preliminary ioctl() calls for the PV8630 which is used + * by the HP4200. The ioctl()'s still have to be registered. Thanks + * to Adrian Perez Jorge . + * - Moved/migrated stuff to scanner.h + * - Removed the usb_set_configuration() since this is handled by + * the usb_new_device() routine in usb.c. + * - Added the HP 3300C. Thanks to Bruce Tenison. + * - Changed user specified vendor/product id so that root hub doesn't + * get falsely attached to. Thanks to Greg K-H. + * - Added some Mustek ID's. Thanks to Gernot Hoyler + * . + * - Modified the usb_string() reporting. See kfree() comment above. + * - Added Umax Astra 2000U. Thanks to Doug Alcorn. + * - Updated the printk()'s to use the info/warn/dbg macros. + * - Updated usb_bulk_msg() argument types to correct gcc warnings. + * * * TODO + * * - Simultaneous multiple device attachment - * - ioctl()'s ? + * * * Thanks to: + * * - All the folks on the linux-usb list who put up with me. :) This * has been a great learning experience for me. * - To Linus Torvalds for this great OS. @@ -90,58 +126,28 @@ * - And anybody else who chimed in with reports and suggestions. * * Performance: + * * System: Pentium 120, 80 MB RAM, OHCI, Linux 2.3.23, HP 4100C USB Scanner * 300 dpi scan of the entire bed * 24 Bit Color ~ 70 secs - 3.6 Mbit/sec * 8 Bit Gray ~ 17 secs - 4.2 Mbit/sec * */ -#include -#include -#include -#include -#include -#include - -#undef DEBUG /* Enable to print results of read/write_scanner() calls */ -#undef RD_DATA_DUMP /* Enable to dump data - limited to 24 bytes */ -#undef WR_DATA_DUMP - -#include "usb.h" - -#define IBUF_SIZE 32768 -#define OBUF_SIZE 4096 - -struct hpscan_usb_data { - struct usb_device *hpscan_dev; - int isopen; /* Not zero if the device is open */ - int present; /* Device is present on the bus */ - char *obuf, *ibuf; /* transfer buffers */ - char iep, oep; /* I/O Endpoints */ -}; - -static struct hpscan_usb_data hpscan; - -MODULE_AUTHOR("David E. Nelson, dnelson@jump.net, http://www.jump.net/~dnelson"); -MODULE_DESCRIPTION("USB Scanner Driver"); - -static __u16 vendor=0x05f9, product=0xffff; -MODULE_PARM(vendor, "i"); -MODULE_PARM_DESC(vendor, "User specified USB idVendor"); - -MODULE_PARM(product, "i"); -MODULE_PARM_DESC(product, "User specified USB idProduct"); +#include "scanner.h" static int open_scanner(struct inode * inode, struct file * file) { struct hpscan_usb_data *hps = &hpscan; + struct usb_device *dev; - if (!hps->present) { + dev = hps->hpscan_dev; + + if (!dev) { return -ENODEV; } - if (!hps->hpscan_dev) { + if (!hps->present) { return -ENODEV; } @@ -173,18 +179,18 @@ size_t count, loff_t *ppos) { struct hpscan_usb_data *hps = &hpscan; - - unsigned long copy_size; - unsigned long bytes_written = 0; - unsigned long partial; - + struct usb_device *dev; + + ssize_t bytes_written = 0; ssize_t ret = 0; + int copy_size; + int partial; int result = 0; char *obuf = hps->obuf; - set_current_state(TASK_INTERRUPTIBLE); + dev = hps->hpscan_dev; while (count > 0) { @@ -200,8 +206,8 @@ break; } - result = usb_bulk_msg(hps->hpscan_dev,usb_sndbulkpipe(hps->hpscan_dev, hps->oep), obuf, copy_size, &partial, 30*HZ); - dbg("write stats: result:%d copy_size:%lu partial:%lu", (int)result, copy_size, partial); + result = usb_bulk_msg(dev,usb_sndbulkpipe(dev, hps->bulk_out_ep), obuf, copy_size, &partial, 60*HZ); + dbg("write stats: result:%d copy_size:%d partial:%d", result, copy_size, partial); if (result == USB_ST_TIMEOUT) { /* NAK -- shouldn't happen */ warn("write_scanner: NAK recieved."); @@ -217,7 +223,7 @@ if (partial) { unsigned char cnt, cnt_max; cnt_max = (partial > 24) ? 24 : partial; - printk(KERN_DEBUG __FILE__ ": dump: "); + printk(KERN_DEBUG "dump: "); for (cnt=0; cnt < cnt_max; cnt++) { printk("%X ", obuf[cnt]); } @@ -239,8 +245,7 @@ break; } } -// mdelay(5); - set_current_state(TASK_RUNNING); + mdelay(5); return ret ? ret : bytes_written; } @@ -249,18 +254,19 @@ size_t count, loff_t *ppos) { struct hpscan_usb_data *hps = &hpscan; + struct usb_device *dev; ssize_t read_count, ret = 0; - unsigned long partial; - + int partial; int this_read; int result; char *ibuf = hps->ibuf; + dev = hps->hpscan_dev; + read_count = 0; - set_current_state(TASK_INTERRUPTIBLE); while (count) { if (signal_pending(current)) { @@ -270,8 +276,8 @@ this_read = (count > IBUF_SIZE) ? IBUF_SIZE : count; - result = usb_bulk_msg(hps->hpscan_dev, usb_rcvbulkpipe(hps->hpscan_dev, hps->iep), ibuf, this_read, &partial, 60*HZ); - dbg("read stats: result:%d this_read:%u partial:%lu", (int)result, this_read, partial); + result = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, hps->bulk_in_ep), ibuf, this_read, &partial, 60*HZ); + dbg("read stats: result:%d this_read:%d partial:%d", result, this_read, partial); if (result == USB_ST_TIMEOUT) { /* NAK -- shouldn't happen */ warn("read_scanner: NAK received"); @@ -287,7 +293,7 @@ if (partial) { unsigned char cnt, cnt_max; cnt_max = (partial > 24) ? 24 : partial; - printk(KERN_DEBUG __FILE__ ": dump: "); + printk(KERN_DEBUG "dump: "); for (cnt=0; cnt < cnt_max; cnt++) { printk("%X ", ibuf[cnt]); } @@ -313,7 +319,6 @@ buffer += this_read; } } - set_current_state(TASK_RUNNING); return ret ? ret : read_count; } @@ -321,103 +326,174 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum) { struct hpscan_usb_data *hps = &hpscan; + struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; + + int ep_cnt; char *ident; + char valid_device = 0; + char have_bulk_in, have_bulk_out, have_intr; hps->present = 0; - if (vendor != 0 || product != 0) - info("USB Scanner Vendor:Product - %x:%x\n", vendor, product); + if (vendor != -1 && product != -1) { + info("probe_scanner: User specified USB scanner -- Vendor:Product - %x:%x", vendor, product); + } + +/* + * 1. Check Vendor/Product + * 2. Determine/Assign Bulk Endpoints + * 3. Determine/Assign Intr Endpoint + */ -/* There doesn't seem to be an imaging class defined in the USB +/* + * There doesn't seem to be an imaging class defined in the USB * Spec. (yet). If there is, HP isn't following it and it doesn't * look like anybody else is either. Therefore, we have to test the - * Vendor and Product ID's to see what we have. This makes this - * driver a high maintenance driver since it has to be updated with - * each release of a product. Also, other scanners may be able to use - * this driver but again, their Vendor and Product ID's must be added. + * Vendor and Product ID's to see what we have. Also, other scanners + * may be able to use this driver by specifying both vendor and + * product ID's as options to the scanner module in conf.modules. * * NOTE: Just because a product is supported here does not mean that * applications exist that support the product. It's in the hopes * that this will allow developers a means to produce applications * that will support USB products. * - * Until we detect a device which is pleasing, we silently punt. - * */ + * Until we detect a device which is pleasing, we silently punt. */ - if (dev->descriptor.idVendor != 0x03f0 && /* Hewlett Packard */ - dev->descriptor.idVendor != 0x06bd && /* AGFA */ - dev->descriptor.idVendor != 0x1606 && /* UMAX */ - dev->descriptor.idVendor != vendor ) { /* User specified */ - return NULL; - } + do { + if (dev->descriptor.idVendor == 0x03f0) { /* Hewlett Packard */ + if (dev->descriptor.idProduct == 0x0205 || /* 3300C */ + dev->descriptor.idProduct == 0x0101 || /* 4100C */ + dev->descriptor.idProduct == 0x0105 || /* 4200C */ + dev->descriptor.idProduct == 0x0202 || /* PhotoSmart S20 */ + dev->descriptor.idProduct == 0x0401 || /* 5200C */ + dev->descriptor.idProduct == 0x0201 || /* 6200C */ + dev->descriptor.idProduct == 0x0601) { /* 6300C */ + valid_device = 1; + break; + } + } + + if (dev->descriptor.idVendor == 0x06bd && /* AGFA */ + dev->descriptor.idProduct == 0x0001) { /* SnapScan 1212U */ + valid_device = 1; + break; + } + + if (dev->descriptor.idVendor == 0x1606 && /* Umax */ + dev->descriptor.idProduct == 0x0030) { /* Astra 2000U */ + valid_device = 1; + break; + } + + if (dev->descriptor.idVendor == 0x04b8) { /* Seiko/Epson Corp. */ + if (dev->descriptor.idProduct == 0x0101 || /* Perfection 636 */ + dev->descriptor.idProduct == 0x0104) { /* Perfection 1200U */ + valid_device = 1; + break; + } + } - if (dev->descriptor.idProduct != 0x0101 && /* HP 4100C */ - dev->descriptor.idProduct != 0x0102 && /* HP 4200C & PhotoSmart S20? */ - dev->descriptor.idProduct != 0x0202 && /* HP 5100C */ - dev->descriptor.idProduct != 0x0401 && /* HP 5200C */ - dev->descriptor.idProduct != 0x0201 && /* HP 6200C */ - dev->descriptor.idProduct != 0x0601 && /* HP 6300C */ - dev->descriptor.idProduct != 0x0001 && /* AGFA SnapScan 1212U */ - dev->descriptor.idProduct != 0x0030 && /* Umax 2000U */ - dev->descriptor.idProduct != product) { /* User specified */ + if (dev->descriptor.idVendor == 0x055f) { /* Mustek */ + if (dev->descriptor.idProduct == 0x0001) { /* 1200 CU */ + valid_device = 1; + break; + } + } + + if (dev->descriptor.idVendor == vendor && /* User specified */ + dev->descriptor.idProduct == product) { /* User specified */ + valid_device = 1; + break; + } + } while (0); + + if (!valid_device) return NULL; - } -/* After this point we can be a little noisy about what we are trying to - * configure. */ - if (dev->descriptor.bNumConfigurations != 1 || - dev->config[0].bNumInterfaces != 1) { - dbg("probe_scanner: only simple configurations supported"); +/* + * After this point we can be a little noisy about what we are trying to + * configure. + */ + + if (dev->descriptor.bNumConfigurations != 1) { + info("probe_scanner: Only one configuration is supported."); return NULL; } - endpoint = dev->config[0].interface[0].altsetting[0].endpoint; - - if (endpoint[0].bmAttributes != USB_ENDPOINT_XFER_BULK - || endpoint [1].bmAttributes != USB_ENDPOINT_XFER_BULK) { - dbg("probe_scanner: invalid bulk endpoints"); + if (dev->config[0].bNumInterfaces != 1) { + info("probe_scanner: Only one interface is supported."); return NULL; } - if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) { - dbg("probe_scanner: failed usb_set_configuration"); - hps->hpscan_dev = NULL; - return NULL; - } + interface = dev->config[0].interface[0].altsetting; + endpoint = interface[0].endpoint; -/* By the time we get here, we should be dealing with a fairly simple - * device that supports at least two bulk endpoints on endpoints 1 and - * 2. - * - * We determine the bulk endpoints so that the read_*() and write_*() - * procedures can recv/send data to the correct endpoint. - * */ +/* + * Start checking for two bulk endpoints OR two bulk endpoints *and* one + * interrupt endpoint. If we have an interrupt endpoint go ahead and + * setup the handler. FIXME: This is a future enhancement... + */ - hps->iep = hps->oep = 0; - if ((endpoint[0].bEndpointAddress & 0x80) == 0x80) { - hps->iep = endpoint[0].bEndpointAddress & 0x7f; - } else { - hps->oep = endpoint[0].bEndpointAddress; - } + dbg("probe_scanner: Number of Endpoints: %d", (int) interface->bNumEndpoints); - if ((endpoint[1].bEndpointAddress & 0x80) == 0x80) { - hps->iep = endpoint[1].bEndpointAddress & 0x7f; - } else { - hps->oep = endpoint[1].bEndpointAddress; + if ((interface->bNumEndpoints != 2) && (interface->bNumEndpoints != 3)) { + info("probe_scanner: Only two or three endpoints supported."); + return NULL; } - ident = kmalloc(256, GFP_KERNEL); - if (ident) { - usb_string(dev, dev->descriptor.iProduct, ident, 256); - info("USB Scanner (%s) found at address %d", ident, dev->devnum); - kfree(ident); + ep_cnt = have_bulk_in = have_bulk_out = have_intr = 0; + + while (ep_cnt < interface->bNumEndpoints) { + + if (!have_bulk_in && IS_EP_BULK_IN(endpoint[ep_cnt])) { + have_bulk_in = 1; + hps->bulk_in_ep = ep_cnt + 1; + ep_cnt++; + dbg("probe_scanner: bulk_in_ep: %d", (int)hps->bulk_in_ep); + continue; + } + + if (!have_bulk_out && IS_EP_BULK_OUT(endpoint[ep_cnt])) { + have_bulk_out = 1; + hps->bulk_out_ep = ep_cnt + 1; + ep_cnt++; + dbg("probe_scanner: bulk_out_ep: %d", (int)hps->bulk_out_ep); + continue; + } + + if (!have_intr && IS_EP_INTR(endpoint[ep_cnt])) { + have_intr = 1; + hps->intr_ep = ep_cnt + 1; + ep_cnt++; + dbg("probe_scanner: intr_ep: %d", (int)hps->intr_ep); + continue; + } + info("probe_scanner: Undetected endpoint. Notify the maintainer."); + return NULL; /* Shouldn't ever get here unless we have something weird */ } - dbg("probe_scanner: using bulk endpoints - In: %x Out: %x", hps->iep, hps->oep); + switch(interface->bNumEndpoints) { + case 2: + if (!have_bulk_in || !have_bulk_out) { + info("probe_scanner: Two bulk endpoints required."); + return NULL; + } + break; + case 3: + if (!have_bulk_in || !have_bulk_out || !have_intr) { + info("probe_scanner: Two bulk endpoints and one interrupt endpoint required."); + return NULL; + } + break; + default: + info("probe_scanner: Endpoint determination failed. Notify the maintainer."); + return NULL; + } hps->present = 1; hps->hpscan_dev = dev; @@ -449,6 +525,71 @@ hps->present = 0; } +static int +ioctl_scanner(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct hpscan_usb_data *hps = &hpscan; + struct usb_device *dev; + + int result; + + dev = hps->hpscan_dev; + + switch (cmd) + { + case PV8630_RECEIVE : + { + struct { + unsigned char data; + __u16 value; + __u16 index; + } args; + + if (copy_from_user(&args, (void *)arg, sizeof(args))) + return -EFAULT; + + result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x0, + USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN, + args.value, args.index, &args.data, 1, HZ); + + dbg("ioctl_scanner recv: args.data:%x args.value:%x args.index:%x", + args.data, args.value, args.index); + + if (copy_to_user((void *)arg, &args, sizeof(args))) + return -EFAULT; + + dbg("ioctl_scanner recv: result:%d", result); + + return result; + } + case PV8630_SEND : + { + struct { + __u16 value; + __u16 index; + } args; + + if (copy_from_user(&args, (void *)arg, sizeof(args))) + return -EFAULT; + + dbg("ioctl_scanner send: args.value:%x args.index:%x", args.value, args.index); + + result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x1 /* Vendor Specific bRequest */, + USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_OUT /* 0x40 */, + args.value, args.index, NULL, 0, HZ); + + dbg("ioctl_scanner send: result:%d", result); + + + return result; + } + default: + return -ENOIOCTLCMD; + } + return 0; +} + static struct file_operations usb_scanner_fops = { NULL, /* seek */ @@ -456,7 +597,7 @@ write_scanner, NULL, /* readdir */ NULL, /* poll */ - NULL, /* ioctl */ + ioctl_scanner, /* ioctl */ NULL, /* mmap */ open_scanner, NULL, /* flush */ diff -ur --new-file old/linux/drivers/usb/scanner.h new/linux/drivers/usb/scanner.h --- old/linux/drivers/usb/scanner.h Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/usb/scanner.h Mon Jan 24 07:39:14 2000 @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include +#include + +// #define DEBUG + +#include "usb.h" + +// #define RD_DATA_DUMP /* Enable to dump data - limited to 24 bytes */ +// #define WR_DATA_DUMP /* DEBUG does not have to be defined. */ + +#define IS_EP_BULK(ep) ((ep).bmAttributes == USB_ENDPOINT_XFER_BULK ? 1 : 0) +#define IS_EP_BULK_IN(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) +#define IS_EP_BULK_OUT(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) +#define IS_EP_INTR(ep) ((ep).bmAttributes == USB_ENDPOINT_XFER_INT ? 1 : 0) + +#ifdef DEBUG +#define SCN_DEBUG(X) X +#else +#define SCN_DEBUG(X) +#endif + +#define IBUF_SIZE 32768 +#define OBUF_SIZE 4096 + + +/* FIXME: These are NOT registered ioctls()'s */ + +#define PV8630_RECEIVE 69 +#define PV8630_SEND 70 + +struct hpscan_usb_data { + struct usb_device *hpscan_dev; + int isopen; /* Not zero if the device is open */ + int present; /* Device is present on the bus */ + char *obuf, *ibuf; /* transfer buffers */ + char bulk_in_ep, bulk_out_ep, intr_ep; /* Endpoint assignments */ + char *button; /* Front panel button buffer */ +}; + +static struct hpscan_usb_data hpscan; + +MODULE_AUTHOR("David E. Nelson, dnelson@jump.net, http://www.jump.net/~dnelson"); +MODULE_DESCRIPTION("USB Scanner Driver"); + +static __s32 vendor=-1, product=-1; +MODULE_PARM(vendor, "i"); +MODULE_PARM_DESC(vendor, "User specified USB idVendor"); + +MODULE_PARM(product, "i"); +MODULE_PARM_DESC(product, "User specified USB idProduct"); diff -ur --new-file old/linux/drivers/usb/uhci-debug.c new/linux/drivers/usb/uhci-debug.c --- old/linux/drivers/usb/uhci-debug.c Fri Jan 7 01:17:18 2000 +++ new/linux/drivers/usb/uhci-debug.c Thu Jan 1 01:00:00 1970 @@ -1,245 +0,0 @@ -/* - * $Id: uhci-debug.c,v 1.12 1999/12/13 15:24:42 fliegl Exp $ - */ - -#include -#include -#include - -#define DEBUG - -#include "usb.h" -#include "uhci.h" - -void dump_urb (purb_t purb) -{ - dbg("urb :%p", purb); - dbg("next :%p", purb->next); - dbg("dev :%p", purb->dev); - dbg("pipe :%08X", purb->pipe); - dbg("status :%d", purb->status); - dbg("transfer_flags :%08X", purb->transfer_flags); - dbg("transfer_buffer :%p", purb->transfer_buffer); - dbg("transfer_buffer_length:%d", purb->transfer_buffer_length); - dbg("actual_length :%d", purb->actual_length); - dbg("setup_packet :%p", purb->setup_packet); - dbg("start_frame :%d", purb->start_frame); - dbg("number_of_packets :%d", purb->number_of_packets); - dbg("interval :%d", purb->interval); - dbg("error_count :%d", purb->error_count); - dbg("context :%p", purb->context); - dbg("complete :%p", purb->complete); -} - -void beep (long freq) -{ - long v; - char low, high; - - if (!freq) - outb (inb (0x61) & 252, 0x61); - else { - outb (inb (0x61) | 0x3, 0x61); - - v = 1193180L / freq; - - low = (char) (v & 255); - high = (char) ((v >> 8) & 255); - - outb (182, 0x43); - outb (low, 0x42); - outb (high, 0x42); - } -} - -void uhci_show_qh (puhci_desc_t qh) -{ - if (qh->type != QH_TYPE) { - dbg("qh has not QH_TYPE"); - return; - } - dbg("uhci_show_qh %p (%08lX):", qh, virt_to_bus (qh)); - - if (qh->hw.qh.head & UHCI_PTR_TERM) - dbg("Head Terminate"); - else { - if (qh->hw.qh.head & UHCI_PTR_QH) - dbg("Head points to QH"); - else - dbg("Head points to TD"); - - dbg("head: %08X", qh->hw.qh.head & ~UHCI_PTR_BITS); - } - if (qh->hw.qh.element & UHCI_PTR_TERM) - dbg("Element Terminate"); - else { - - if (qh->hw.qh.element & UHCI_PTR_QH) - dbg("Element points to QH"); - else - dbg("Element points to TD"); - dbg("element: %08X", qh->hw.qh.element & ~UHCI_PTR_BITS); - } -} - -void uhci_show_td (puhci_desc_t td) -{ - char *spid; - - switch (td->hw.td.info & 0xff) { - case USB_PID_SETUP: - spid = "SETUP"; - break; - case USB_PID_OUT: - spid = " OUT "; - break; - case USB_PID_IN: - spid = " IN "; - break; - default: - spid = " ? "; - break; - } - - dbg("uhci_show_td %p (%08lX) MaxLen=%02x DT%d EndPt=%x Dev=%x, PID=%x(%s) (buf=%08x)", - td, - virt_to_bus(td), - td->hw.td.info >> 21, - ((td->hw.td.info >> 19) & 1), - (td->hw.td.info >> 15) & 15, - (td->hw.td.info >> 8) & 127, - (td->hw.td.info & 0xff), - spid, - td->hw.td.buffer); - - dbg("Len=%02x e%d %s%s%s%s%s%s%s%s%s%s", - td->hw.td.status & 0x7ff, - ((td->hw.td.status >> 27) & 3), - (td->hw.td.status & TD_CTRL_SPD) ? "SPD " : "", - (td->hw.td.status & TD_CTRL_LS) ? "LS " : "", - (td->hw.td.status & TD_CTRL_IOC) ? "IOC " : "", - (td->hw.td.status & TD_CTRL_ACTIVE) ? "Active " : "", - (td->hw.td.status & TD_CTRL_STALLED) ? "Stalled " : "", - (td->hw.td.status & TD_CTRL_DBUFERR) ? "DataBufErr " : "", - (td->hw.td.status & TD_CTRL_BABBLE) ? "Babble " : "", - (td->hw.td.status & TD_CTRL_NAK) ? "NAK " : "", - (td->hw.td.status & TD_CTRL_CRCTIMEO) ? "CRC/Timeo " : "", - (td->hw.td.status & TD_CTRL_BITSTUFF) ? "BitStuff " : "" - ); - - if (td->hw.td.link & UHCI_PTR_TERM) - dbg("Link Terminate"); - else { - if (td->hw.td.link & UHCI_PTR_QH) - dbg("%s, link points to QH @ %08x", - (td->hw.td.link & UHCI_PTR_DEPTH ? "Depth first" : " Breadth first"), - td->hw.td.link & ~UHCI_PTR_BITS); - else - dbg("%s, link points to TD @ %08x", - (td->hw.td.link & UHCI_PTR_DEPTH ? "Depth first" : " Breadth first"), - td->hw.td.link & ~UHCI_PTR_BITS); - } -} - -void uhci_show_td_queue (puhci_desc_t td) -{ - dbg("uhci_show_td_queue %p (%08lX):", td, virt_to_bus (td)); - while (1) { - uhci_show_td (td); - if (td->hw.td.link & UHCI_PTR_TERM) - break; - //if(!(td->hw.td.link&UHCI_PTR_DEPTH)) - // break; - if (td != bus_to_virt (td->hw.td.link & ~UHCI_PTR_BITS)) - td = bus_to_virt (td->hw.td.link & ~UHCI_PTR_BITS); - else { - dbg("td points to itself!"); - break; - } -// schedule(); - } -} - -void uhci_show_queue (puhci_desc_t qh) -{ - dbg("uhci_show_queue %p:", qh); - while (1) { - uhci_show_qh (qh); - - if (qh->hw.qh.element & UHCI_PTR_QH) - dbg("Warning: qh->element points to qh!"); - else if (!(qh->hw.qh.element & UHCI_PTR_TERM)) - uhci_show_td_queue (bus_to_virt (qh->hw.qh.element & ~UHCI_PTR_BITS)); - - if (qh->hw.qh.head & UHCI_PTR_TERM) - break; - - if (qh != bus_to_virt (qh->hw.qh.head & ~UHCI_PTR_BITS)) - qh = bus_to_virt (qh->hw.qh.head & ~UHCI_PTR_BITS); - else { - dbg("qh points to itself!"); - break; - } - } -} - -static void uhci_show_sc (int port, unsigned short status) -{ - dbg(" stat%d = %04x %s%s%s%s%s%s%s%s", - port, - status, - (status & USBPORTSC_SUSP) ? "PortSuspend " : "", - (status & USBPORTSC_PR) ? "PortReset " : "", - (status & USBPORTSC_LSDA) ? "LowSpeed " : "", - (status & USBPORTSC_RD) ? "ResumeDetect " : "", - (status & USBPORTSC_PEC) ? "EnableChange " : "", - (status & USBPORTSC_PE) ? "PortEnabled " : "", - (status & USBPORTSC_CSC) ? "ConnectChange " : "", - (status & USBPORTSC_CCS) ? "PortConnected " : ""); -} - -void uhci_show_status (puhci_t s) -{ - unsigned int io_addr = s->io_addr; - unsigned short usbcmd, usbstat, usbint, usbfrnum; - unsigned int flbaseadd; - unsigned char sof; - unsigned short portsc1, portsc2; - - usbcmd = inw (io_addr + 0); - usbstat = inw (io_addr + 2); - usbint = inw (io_addr + 4); - usbfrnum = inw (io_addr + 6); - flbaseadd = inl (io_addr + 8); - sof = inb (io_addr + 12); - portsc1 = inw (io_addr + 16); - portsc2 = inw (io_addr + 18); - - dbg(" usbcmd = %04x %s%s%s%s%s%s%s%s", - usbcmd, - (usbcmd & USBCMD_MAXP) ? "Maxp64 " : "Maxp32 ", - (usbcmd & USBCMD_CF) ? "CF " : "", - (usbcmd & USBCMD_SWDBG) ? "SWDBG " : "", - (usbcmd & USBCMD_FGR) ? "FGR " : "", - (usbcmd & USBCMD_EGSM) ? "EGSM " : "", - (usbcmd & USBCMD_GRESET) ? "GRESET " : "", - (usbcmd & USBCMD_HCRESET) ? "HCRESET " : "", - (usbcmd & USBCMD_RS) ? "RS " : ""); - - dbg(" usbstat = %04x %s%s%s%s%s%s", - usbstat, - (usbstat & USBSTS_HCH) ? "HCHalted " : "", - (usbstat & USBSTS_HCPE) ? "HostControllerProcessError " : "", - (usbstat & USBSTS_HSE) ? "HostSystemError " : "", - (usbstat & USBSTS_RD) ? "ResumeDetect " : "", - (usbstat & USBSTS_ERROR) ? "USBError " : "", - (usbstat & USBSTS_USBINT) ? "USBINT " : ""); - - dbg(" usbint = %04x", usbint); - dbg(" usbfrnum = (%d)%03x", (usbfrnum >> 10) & 1, - 0xfff & (4 * (unsigned int) usbfrnum)); - dbg(" flbaseadd = %08x", flbaseadd); - dbg(" sof = %02x", sof); - uhci_show_sc (1, portsc1); - uhci_show_sc (2, portsc2); -} diff -ur --new-file old/linux/drivers/usb/uhci-debug.h new/linux/drivers/usb/uhci-debug.h --- old/linux/drivers/usb/uhci-debug.h Thu Dec 16 10:27:42 1999 +++ new/linux/drivers/usb/uhci-debug.h Mon Jan 24 07:39:14 2000 @@ -1,7 +1,195 @@ -void uhci_show_qh(puhci_desc_t qh); -void uhci_show_td(puhci_desc_t td); -void uhci_show_td_queue(puhci_desc_t td); -void uhci_show_queue(puhci_desc_t qh); -void uhci_show_status(puhci_t s); -void beep(long freq); -void dump_urb (purb_t purb); \ No newline at end of file +#ifdef DEBUG + +static void uhci_show_qh (puhci_desc_t qh) +{ + if (qh->type != QH_TYPE) { + dbg("qh has not QH_TYPE"); + return; + } + dbg("uhci_show_qh %p (%08lX):", qh, virt_to_bus (qh)); + + if (qh->hw.qh.head & UHCI_PTR_TERM) + dbg("Head Terminate"); + else { + if (qh->hw.qh.head & UHCI_PTR_QH) + dbg("Head points to QH"); + else + dbg("Head points to TD"); + + dbg("head: %08X", qh->hw.qh.head & ~UHCI_PTR_BITS); + } + if (qh->hw.qh.element & UHCI_PTR_TERM) + dbg("Element Terminate"); + else { + + if (qh->hw.qh.element & UHCI_PTR_QH) + dbg("Element points to QH"); + else + dbg("Element points to TD"); + dbg("element: %08X", qh->hw.qh.element & ~UHCI_PTR_BITS); + } +} +#endif + +static void uhci_show_td (puhci_desc_t td) +{ + char *spid; + warn("uhci_show_td %p (%08lX) ", td, virt_to_bus (td)); + + switch (td->hw.td.info & 0xff) { + case USB_PID_SETUP: + spid = "SETUP"; + break; + case USB_PID_OUT: + spid = " OUT "; + break; + case USB_PID_IN: + spid = " IN "; + break; + default: + spid = " ? "; + break; + } + + warn("MaxLen=%02x DT%d EndPt=%x Dev=%x, PID=%x(%s) (buf=%08x)", + td->hw.td.info >> 21, + ((td->hw.td.info >> 19) & 1), + (td->hw.td.info >> 15) & 15, + (td->hw.td.info >> 8) & 127, + (td->hw.td.info & 0xff), + spid, + td->hw.td.buffer); + + warn("Len=%02x e%d %s%s%s%s%s%s%s%s%s%s", + td->hw.td.status & 0x7ff, + ((td->hw.td.status >> 27) & 3), + (td->hw.td.status & TD_CTRL_SPD) ? "SPD " : "", + (td->hw.td.status & TD_CTRL_LS) ? "LS " : "", + (td->hw.td.status & TD_CTRL_IOC) ? "IOC " : "", + (td->hw.td.status & TD_CTRL_ACTIVE) ? "Active " : "", + (td->hw.td.status & TD_CTRL_STALLED) ? "Stalled " : "", + (td->hw.td.status & TD_CTRL_DBUFERR) ? "DataBufErr " : "", + (td->hw.td.status & TD_CTRL_BABBLE) ? "Babble " : "", + (td->hw.td.status & TD_CTRL_NAK) ? "NAK " : "", + (td->hw.td.status & TD_CTRL_CRCTIMEO) ? "CRC/Timeo " : "", + (td->hw.td.status & TD_CTRL_BITSTUFF) ? "BitStuff " : "" + ); +#if 1 + if (td->hw.td.link & UHCI_PTR_TERM) + warn("Link Terminate"); + else { + if (td->hw.td.link & UHCI_PTR_QH) + warn("%s, link points to QH @ %08x", + (td->hw.td.link & UHCI_PTR_DEPTH ? "Depth first" : " Breadth first"), + td->hw.td.link & ~UHCI_PTR_BITS); + else + warn("%s, link points to TD @ %08x", + (td->hw.td.link & UHCI_PTR_DEPTH ? "Depth first" : " Breadth first"), + td->hw.td.link & ~UHCI_PTR_BITS); + } +#endif +} +#ifdef DEBUG +static void uhci_show_td_queue (puhci_desc_t td) +{ + dbg("uhci_show_td_queue %p (%08lX):", td, virt_to_bus (td)); + while (1) { + uhci_show_td (td); + if (td->hw.td.link & UHCI_PTR_TERM) + break; + //if(!(td->hw.td.link&UHCI_PTR_DEPTH)) + // break; + if (td != bus_to_virt (td->hw.td.link & ~UHCI_PTR_BITS)) + td = bus_to_virt (td->hw.td.link & ~UHCI_PTR_BITS); + else { + dbg("td points to itself!"); + break; + } +// schedule(); + } +} + +static void uhci_show_queue (puhci_desc_t qh) +{ + dbg("uhci_show_queue %p:", qh); + while (1) { + uhci_show_qh (qh); + + if (qh->hw.qh.element & UHCI_PTR_QH) + dbg("Warning: qh->element points to qh!"); + else if (!(qh->hw.qh.element & UHCI_PTR_TERM)) + uhci_show_td_queue (bus_to_virt (qh->hw.qh.element & ~UHCI_PTR_BITS)); + + if (qh->hw.qh.head & UHCI_PTR_TERM) + break; + + if (qh != bus_to_virt (qh->hw.qh.head & ~UHCI_PTR_BITS)) + qh = bus_to_virt (qh->hw.qh.head & ~UHCI_PTR_BITS); + else { + dbg("qh points to itself!"); + break; + } + } +} + +static void uhci_show_sc (int port, unsigned short status) +{ + dbg(" stat%d = %04x %s%s%s%s%s%s%s%s", + port, + status, + (status & USBPORTSC_SUSP) ? "PortSuspend " : "", + (status & USBPORTSC_PR) ? "PortReset " : "", + (status & USBPORTSC_LSDA) ? "LowSpeed " : "", + (status & USBPORTSC_RD) ? "ResumeDetect " : "", + (status & USBPORTSC_PEC) ? "EnableChange " : "", + (status & USBPORTSC_PE) ? "PortEnabled " : "", + (status & USBPORTSC_CSC) ? "ConnectChange " : "", + (status & USBPORTSC_CCS) ? "PortConnected " : ""); +} + +void uhci_show_status (puhci_t s) +{ + unsigned int io_addr = s->io_addr; + unsigned short usbcmd, usbstat, usbint, usbfrnum; + unsigned int flbaseadd; + unsigned char sof; + unsigned short portsc1, portsc2; + + usbcmd = inw (io_addr + 0); + usbstat = inw (io_addr + 2); + usbint = inw (io_addr + 4); + usbfrnum = inw (io_addr + 6); + flbaseadd = inl (io_addr + 8); + sof = inb (io_addr + 12); + portsc1 = inw (io_addr + 16); + portsc2 = inw (io_addr + 18); + + dbg(" usbcmd = %04x %s%s%s%s%s%s%s%s", + usbcmd, + (usbcmd & USBCMD_MAXP) ? "Maxp64 " : "Maxp32 ", + (usbcmd & USBCMD_CF) ? "CF " : "", + (usbcmd & USBCMD_SWDBG) ? "SWDBG " : "", + (usbcmd & USBCMD_FGR) ? "FGR " : "", + (usbcmd & USBCMD_EGSM) ? "EGSM " : "", + (usbcmd & USBCMD_GRESET) ? "GRESET " : "", + (usbcmd & USBCMD_HCRESET) ? "HCRESET " : "", + (usbcmd & USBCMD_RS) ? "RS " : ""); + + dbg(" usbstat = %04x %s%s%s%s%s%s", + usbstat, + (usbstat & USBSTS_HCH) ? "HCHalted " : "", + (usbstat & USBSTS_HCPE) ? "HostControllerProcessError " : "", + (usbstat & USBSTS_HSE) ? "HostSystemError " : "", + (usbstat & USBSTS_RD) ? "ResumeDetect " : "", + (usbstat & USBSTS_ERROR) ? "USBError " : "", + (usbstat & USBSTS_USBINT) ? "USBINT " : ""); + + dbg(" usbint = %04x", usbint); + dbg(" usbfrnum = (%d)%03x", (usbfrnum >> 10) & 1, + 0xfff & (4 * (unsigned int) usbfrnum)); + dbg(" flbaseadd = %08x", flbaseadd); + dbg(" sof = %02x", sof); + uhci_show_sc (1, portsc1); + uhci_show_sc (2, portsc2); +} +#endif diff -ur --new-file old/linux/drivers/usb/uhci.c new/linux/drivers/usb/uhci.c --- old/linux/drivers/usb/uhci.c Fri Jan 7 01:17:19 2000 +++ new/linux/drivers/usb/uhci.c Thu Jan 1 01:00:00 1970 @@ -1,2336 +0,0 @@ -/* - * Universal Host Controller Interface driver for USB (take II). - * - * (c) 1999 Georg Acher, acher@in.tum.de (executive slave) (base guitar) - * Deti Fliegl, deti@fliegl.de (executive slave) (lead voice) - * Thomas Sailer, sailer@ife.ee.ethz.ch (chief consultant) (cheer leader) - * Roman Weissgaerber, weissg@vienna.at (virt root hub) (studio porter) - * - * HW-initalization based on material of - * - * (C) Copyright 1999 Linus Torvalds - * (C) Copyright 1999 Johannes Erdfelt - * (C) Copyright 1999 Randy Dunlap - * - * $Id: uhci.c,v 1.149 1999/12/26 20:57:14 acher Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* for in_interrupt() */ -#include - -#include -#include -#include -#include - -#undef DEBUG - -#include "usb.h" -#include "uhci.h" -#include "uhci-debug.h" - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) -#define __init -#define __exit -#endif - -#ifdef __alpha -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) -extern long __kernel_thread (unsigned long, int (*)(void *), void *); -static inline long kernel_thread (int (*fn) (void *), void *arg, unsigned long flags) -{ - return __kernel_thread (flags | CLONE_VM, fn, arg); -} -#undef CONFIG_APM -#endif -#endif - -#ifdef CONFIG_APM -#include -static int handle_apm_event (apm_event_t event); -#endif - -/* We added an UHCI_SLAB slab support just for debugging purposes. In real - life this compile option is NOT recommended, because slab caches are not - suitable for modules. -*/ - -// #define _UHCI_SLAB -#ifdef _UHCI_SLAB -static kmem_cache_t *uhci_desc_kmem; -static kmem_cache_t *urb_priv_kmem; -#endif - -static int rh_submit_urb (purb_t purb); -static int rh_unlink_urb (purb_t purb); -static puhci_t devs = NULL; - -/*-------------------------------------------------------------------*/ -static void queue_urb (puhci_t s, struct list_head *p, int do_lock) -{ - unsigned long flags=0; - - if (do_lock) - spin_lock_irqsave (&s->urb_list_lock, flags); - - list_add_tail (p, &s->urb_list); - - if (do_lock) - spin_unlock_irqrestore (&s->urb_list_lock, flags); -} - -/*-------------------------------------------------------------------*/ -static void dequeue_urb (puhci_t s, struct list_head *p, int do_lock) -{ - unsigned long flags=0; - - if (do_lock) - spin_lock_irqsave (&s->urb_list_lock, flags); - - list_del (p); - - if (do_lock) - spin_unlock_irqrestore (&s->urb_list_lock, flags); -} - -/*-------------------------------------------------------------------*/ -static int alloc_td (puhci_desc_t * new, int flags) -{ -#ifdef _UHCI_SLAB - *new= kmem_cache_alloc(uhci_desc_kmem, in_interrupt ()? SLAB_ATOMIC : SLAB_KERNEL); -#else - *new = (uhci_desc_t *) kmalloc (sizeof (uhci_desc_t), in_interrupt ()? GFP_ATOMIC : GFP_KERNEL); -#endif - if (!*new) - return -ENOMEM; - - memset (*new, 0, sizeof (uhci_desc_t)); - (*new)->hw.td.link = UHCI_PTR_TERM | (flags & UHCI_PTR_BITS); // last by default - - (*new)->type = TD_TYPE; - INIT_LIST_HEAD (&(*new)->vertical); - INIT_LIST_HEAD (&(*new)->horizontal); - - return 0; -} -/*-------------------------------------------------------------------*/ -/* insert td at last position in td-list of qh (vertical) */ -static int insert_td (puhci_t s, puhci_desc_t qh, puhci_desc_t new, int flags) -{ - uhci_desc_t *prev; - unsigned long xxx; - - spin_lock_irqsave (&s->td_lock, xxx); - - list_add_tail (&new->vertical, &qh->vertical); - - if (qh->hw.qh.element & UHCI_PTR_TERM) { - // virgin qh without any tds - qh->hw.qh.element = virt_to_bus (new); /* QH's cannot have the DEPTH bit set */ - } - else { - // already tds inserted - prev = list_entry (new->vertical.prev, uhci_desc_t, vertical); - // implicitely remove TERM bit of prev - prev->hw.td.link = virt_to_bus (new) | (flags & UHCI_PTR_DEPTH); - } - - spin_unlock_irqrestore (&s->td_lock, xxx); - - return 0; -} -/*-------------------------------------------------------------------*/ -/* insert new_td after td (horizontal) */ -static int insert_td_horizontal (puhci_t s, puhci_desc_t td, puhci_desc_t new, int flags) -{ - uhci_desc_t *next; - unsigned long xxx; - - spin_lock_irqsave (&s->td_lock, xxx); - - next = list_entry (td->horizontal.next, uhci_desc_t, horizontal); - new->hw.td.link = td->hw.td.link; - list_add (&new->horizontal, &td->horizontal); - td->hw.td.link = virt_to_bus (new); - - spin_unlock_irqrestore (&s->td_lock, xxx); - - return 0; -} -/*-------------------------------------------------------------------*/ -static int unlink_td (puhci_t s, puhci_desc_t element) -{ - uhci_desc_t *next, *prev; - int dir = 0; - unsigned long xxx; - - spin_lock_irqsave (&s->td_lock, xxx); - - next = list_entry (element->vertical.next, uhci_desc_t, vertical); - - if (next == element) { - dir = 1; - next = list_entry (element->horizontal.next, uhci_desc_t, horizontal); - prev = list_entry (element->horizontal.prev, uhci_desc_t, horizontal); - } - else { - prev = list_entry (element->vertical.prev, uhci_desc_t, vertical); - } - - if (prev->type == TD_TYPE) - prev->hw.td.link = element->hw.td.link; - else - prev->hw.qh.element = element->hw.td.link; - - wmb (); - - if (dir == 0) - list_del (&element->vertical); - else - list_del (&element->horizontal); - - spin_unlock_irqrestore (&s->td_lock, xxx); - - return 0; -} -/*-------------------------------------------------------------------*/ -static int delete_desc (puhci_desc_t element) -{ -#ifdef _UHCI_SLAB - kmem_cache_free(uhci_desc_kmem, element); -#else - kfree (element); -#endif - return 0; -} -/*-------------------------------------------------------------------*/ -// Allocates qh element -static int alloc_qh (puhci_desc_t * new) -{ -#ifdef _UHCI_SLAB - *new= kmem_cache_alloc(uhci_desc_kmem, in_interrupt ()? SLAB_ATOMIC : SLAB_KERNEL); -#else - *new = (uhci_desc_t *) kmalloc (sizeof (uhci_desc_t), in_interrupt ()? GFP_ATOMIC : GFP_KERNEL); -#endif - if (!*new) - return -ENOMEM; - - memset (*new, 0, sizeof (uhci_desc_t)); - (*new)->hw.qh.head = UHCI_PTR_TERM; - (*new)->hw.qh.element = UHCI_PTR_TERM; - (*new)->type = QH_TYPE; - INIT_LIST_HEAD (&(*new)->horizontal); - INIT_LIST_HEAD (&(*new)->vertical); - - dbg("Allocated qh @ %p", *new); - - return 0; -} -/*-------------------------------------------------------------------*/ -// inserts new qh before/after the qh at pos -// flags: 0: insert before pos, 1: insert after pos (for low speed transfers) -static int insert_qh (puhci_t s, puhci_desc_t pos, puhci_desc_t new, int flags) -{ - puhci_desc_t old; - unsigned long xxx; - - spin_lock_irqsave (&s->qh_lock, xxx); - - if (!flags) { - // (OLD) (POS) -> (OLD) (NEW) (POS) - old = list_entry (pos->horizontal.prev, uhci_desc_t, horizontal); - list_add_tail (&new->horizontal, &pos->horizontal); - new->hw.qh.head = MAKE_QH_ADDR (pos) ; - - if (!(old->hw.qh.head & UHCI_PTR_TERM)) - old->hw.qh.head = MAKE_QH_ADDR (new) ; - } - else { - // (POS) (OLD) -> (POS) (NEW) (OLD) - old = list_entry (pos->horizontal.next, uhci_desc_t, horizontal); - list_add (&new->horizontal, &pos->horizontal); - pos->hw.qh.head = MAKE_QH_ADDR (new) ; - new->hw.qh.head = MAKE_QH_ADDR (old); - } - - wmb (); - - spin_unlock_irqrestore (&s->qh_lock, xxx); - - return 0; -} -/*-------------------------------------------------------------------*/ -static int unlink_qh (puhci_t s, puhci_desc_t element) -{ - puhci_desc_t next, prev; - unsigned long xxx; - - spin_lock_irqsave (&s->qh_lock, xxx); - - next = list_entry (element->horizontal.next, uhci_desc_t, horizontal); - prev = list_entry (element->horizontal.prev, uhci_desc_t, horizontal); - prev->hw.qh.head = element->hw.qh.head; - wmb (); - list_del (&element->horizontal); - - spin_unlock_irqrestore (&s->qh_lock, xxx); - - return 0; -} -/*-------------------------------------------------------------------*/ -static int delete_qh (puhci_t s, puhci_desc_t qh) -{ - puhci_desc_t td; - struct list_head *p; - - list_del (&qh->horizontal); - - while ((p = qh->vertical.next) != &qh->vertical) { - td = list_entry (p, uhci_desc_t, vertical); - unlink_td (s, td); - delete_desc (td); - } - - delete_desc (qh); - - return 0; -} -/*-------------------------------------------------------------------*/ -void clean_td_chain (puhci_desc_t td) -{ - struct list_head *p; - puhci_desc_t td1; - - if (!td) - return; - - while ((p = td->horizontal.next) != &td->horizontal) { - td1 = list_entry (p, uhci_desc_t, horizontal); - delete_desc (td1); - } - - delete_desc (td); -} -/*-------------------------------------------------------------------*/ -// Removes ALL qhs in chain (paranoia!) -static void cleanup_skel (puhci_t s) -{ - unsigned int n; - puhci_desc_t td; - - dbg("cleanup_skel"); - - for (n = 0; n < 8; n++) { - td = s->int_chain[n]; - clean_td_chain (td); - } - - if (s->iso_td) { - for (n = 0; n < 1024; n++) { - td = s->iso_td[n]; - clean_td_chain (td); - } - kfree (s->iso_td); - } - - if (s->framelist) - free_page ((unsigned long) s->framelist); - - if (s->control_chain) { - // completed init_skel? - struct list_head *p; - puhci_desc_t qh, qh1; - - qh = s->control_chain; - while ((p = qh->horizontal.next) != &qh->horizontal) { - qh1 = list_entry (p, uhci_desc_t, horizontal); - delete_qh (s, qh1); - } - delete_qh (s, qh); - } - else { - if (s->control_chain) - kfree (s->control_chain); - if (s->bulk_chain) - kfree (s->bulk_chain); - if (s->chain_end) - kfree (s->chain_end); - } -} -/*-------------------------------------------------------------------*/ -// allocates framelist and qh-skeletons -// only HW-links provide continous linking, SW-links stay in their domain (ISO/INT) -static int init_skel (puhci_t s) -{ - int n, ret; - puhci_desc_t qh, td; - - dbg("init_skel"); - - s->framelist = (__u32 *) get_free_page (GFP_KERNEL); - - if (!s->framelist) - return -ENOMEM; - - memset (s->framelist, 0, 4096); - - dbg("allocating iso desc pointer list"); - s->iso_td = (puhci_desc_t *) kmalloc (1024 * sizeof (puhci_desc_t), GFP_KERNEL); - - if (!s->iso_td) - goto init_skel_cleanup; - - s->control_chain = NULL; - s->bulk_chain = NULL; - s->chain_end = NULL; - - dbg("allocating iso descs"); - for (n = 0; n < 1024; n++) { - // allocate skeleton iso/irq-tds - ret = alloc_td (&td, 0); - if (ret) - goto init_skel_cleanup; - s->iso_td[n] = td; - s->framelist[n] = ((__u32) virt_to_bus (td)); - } - - dbg("allocating qh: chain_end"); - ret = alloc_qh (&qh); - - if (ret) - goto init_skel_cleanup; - - s->chain_end = qh; - - dbg("allocating qh: bulk_chain"); - ret = alloc_qh (&qh); - - if (ret) - goto init_skel_cleanup; - - insert_qh (s, s->chain_end, qh, 0); - s->bulk_chain = qh; - dbg("allocating qh: control_chain"); - ret = alloc_qh (&qh); - - if (ret) - goto init_skel_cleanup; - - insert_qh (s, s->bulk_chain, qh, 0); - s->control_chain = qh; - for (n = 0; n < 8; n++) - s->int_chain[n] = 0; - - dbg("allocating skeleton INT-TDs"); - - for (n = 0; n < 8; n++) { - puhci_desc_t td; - - alloc_td (&td, 0); - if (!td) - goto init_skel_cleanup; - s->int_chain[n] = td; - if (n == 0) { - s->int_chain[0]->hw.td.link = virt_to_bus (s->control_chain); - } - else { - s->int_chain[n]->hw.td.link = virt_to_bus (s->int_chain[0]); - } - } - - dbg("linking skeleton INT-TDs"); - - for (n = 0; n < 1024; n++) { - // link all iso-tds to the interrupt chains - int m, o; - //dbg("framelist[%i]=%x",n,s->framelist[n]); - for (o = 1, m = 2; m <= 128; o++, m += m) { - // n&(m-1) = n%m - if ((n & (m - 1)) == ((m - 1) / 2)) { - ((puhci_desc_t) s->iso_td[n])->hw.td.link = virt_to_bus (s->int_chain[o]); - } - } - } - - //uhci_show_queue(s->control_chain); - dbg("init_skel exit"); - return 0; // OK - - init_skel_cleanup: - cleanup_skel (s); - return -ENOMEM; -} - -/*-------------------------------------------------------------------*/ -static void fill_td (puhci_desc_t td, int status, int info, __u32 buffer) -{ - td->hw.td.status = status; - td->hw.td.info = info; - td->hw.td.buffer = buffer; -} - -/*-------------------------------------------------------------------*/ -// LOW LEVEL STUFF -// assembles QHs und TDs for control, bulk and iso -/*-------------------------------------------------------------------*/ -static int uhci_submit_control_urb (purb_t purb) -{ - puhci_desc_t qh, td; - puhci_t s = (puhci_t) purb->dev->bus->hcpriv; - purb_priv_t purb_priv = purb->hcpriv; - unsigned long destination, status; - int maxsze = usb_maxpacket (purb->dev, purb->pipe, usb_pipeout (purb->pipe)); - unsigned long len, bytesrequested; - char *data; - - dbg("uhci_submit_control start"); - alloc_qh (&qh); // alloc qh for this request - - if (!qh) - return -ENOMEM; - - alloc_td (&td, UHCI_PTR_DEPTH); // get td for setup stage - - if (!td) { - delete_qh (s, qh); - return -ENOMEM; - } - - /* The "pipe" thing contains the destination in bits 8--18 */ - destination = (purb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; - - /* 3 errors */ - status = (purb->pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | - (purb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27); - - /* Build the TD for the control request, try forever, 8 bytes of data */ - fill_td (td, status, destination | (7 << 21), virt_to_bus (purb->setup_packet)); - - /* If direction is "send", change the frame from SETUP (0x2D) - to OUT (0xE1). Else change it from SETUP to IN (0x69). */ - - destination ^= (USB_PID_SETUP ^ USB_PID_IN); /* SETUP -> IN */ - - if (usb_pipeout (purb->pipe)) - destination ^= (USB_PID_IN ^ USB_PID_OUT); /* IN -> OUT */ - - insert_td (s, qh, td, 0); // queue 'setup stage'-td in qh -#if 0 - dbg("SETUP to pipe %x: %x %x %x %x %x %x %x %x", purb->pipe, - purb->setup_packet[0], purb->setup_packet[1], purb->setup_packet[2], purb->setup_packet[3], - purb->setup_packet[4], purb->setup_packet[5], purb->setup_packet[6], purb->setup_packet[7]); - //uhci_show_td(td); -#endif - /* Build the DATA TD's */ - len = purb->transfer_buffer_length; - bytesrequested = len; - data = purb->transfer_buffer; - - while (len > 0) { - int pktsze = len; - - alloc_td (&td, UHCI_PTR_DEPTH); - if (!td) { - delete_qh (s, qh); - return -ENOMEM; - } - - if (pktsze > maxsze) - pktsze = maxsze; - - destination ^= 1 << TD_TOKEN_TOGGLE; // toggle DATA0/1 - - fill_td (td, status, destination | ((pktsze - 1) << 21), - virt_to_bus (data)); // Status, pktsze bytes of data - - insert_td (s, qh, td, UHCI_PTR_DEPTH); // queue 'data stage'-td in qh - - data += pktsze; - len -= pktsze; - } - - /* Build the final TD for control status */ - /* It's only IN if the pipe is out AND we aren't expecting data */ - destination &= ~0xFF; - - if (usb_pipeout (purb->pipe) | (bytesrequested == 0)) - destination |= USB_PID_IN; - else - destination |= USB_PID_OUT; - - destination |= 1 << TD_TOKEN_TOGGLE; /* End in Data1 */ - - alloc_td (&td, UHCI_PTR_DEPTH); - - if (!td) { - delete_qh (s, qh); - return -ENOMEM; - } - - /* no limit on errors on final packet , 0 bytes of data */ - fill_td (td, status | TD_CTRL_IOC, destination | (UHCI_NULL_DATA_SIZE << 21), - 0); - - insert_td (s, qh, td, UHCI_PTR_DEPTH); // queue status td - - - list_add (&qh->desc_list, &purb_priv->desc_list); - - /* Start it up... put low speed first */ - if (purb->pipe & TD_CTRL_LS) - insert_qh (s, s->control_chain, qh, 1); // insert after control chain - else - insert_qh (s, s->bulk_chain, qh, 0); // insert before bulk chain - //uhci_show_queue(s->control_chain); - - dbg("uhci_submit_control end"); - return 0; -} -/*-------------------------------------------------------------------*/ -static int uhci_submit_bulk_urb (purb_t purb) -{ - puhci_t s = (puhci_t) purb->dev->bus->hcpriv; - purb_priv_t purb_priv = purb->hcpriv; - puhci_desc_t qh, td; - unsigned long destination, status; - char *data; - unsigned int pipe = purb->pipe; - int maxsze = usb_maxpacket (purb->dev, pipe, usb_pipeout (pipe)); - int info, len; - - /* shouldn't the clear_halt be done in the USB core or in the client driver? - Thomas */ - if (usb_endpoint_halted (purb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)) && - usb_clear_halt (purb->dev, usb_pipeendpoint (pipe) | (pipe & USB_DIR_IN))) - return -EPIPE; - - if (!maxsze) - return -EMSGSIZE; - /* FIXME: should tell the client that the endpoint is invalid, i.e. not in the descriptor */ - - alloc_qh (&qh); // get qh for this request - - if (!qh) - return -ENOMEM; - - /* The "pipe" thing contains the destination in bits 8--18. */ - destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid (pipe); - - /* 3 errors */ - status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | - ((purb->transfer_flags & USB_DISABLE_SPD) ? 0 : TD_CTRL_SPD) | (3 << 27); - - /* Build the TDs for the bulk request */ - len = purb->transfer_buffer_length; - data = purb->transfer_buffer; - dbg("uhci_submit_bulk_urb: pipe %x, len %d", pipe, len); - - while (len > 0) { - int pktsze = len; - - alloc_td (&td, UHCI_PTR_DEPTH); - - if (!td) { - delete_qh (s, qh); - return -ENOMEM; - } - - if (pktsze > maxsze) - pktsze = maxsze; - - // pktsze bytes of data - info = destination | ((pktsze - 1) << 21) | - (usb_gettoggle (purb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)) << TD_TOKEN_TOGGLE); - - fill_td (td, status, info, virt_to_bus (data)); - - data += pktsze; - len -= pktsze; - - if (!len) - td->hw.td.status |= TD_CTRL_IOC; // last one generates INT - //dbg("insert td %p, len %i",td,pktsze); - - insert_td (s, qh, td, UHCI_PTR_DEPTH); - - /* Alternate Data0/1 (start with Data0) */ - usb_dotoggle (purb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)); - } - - list_add (&qh->desc_list, &purb_priv->desc_list); - - insert_qh (s, s->chain_end, qh, 0); // insert before end marker - //uhci_show_queue(s->bulk_chain); - - dbg("uhci_submit_bulk_urb: exit"); - return 0; -} -/*-------------------------------------------------------------------*/ -// unlinks an urb by dequeuing its qh, waits some frames and forgets it -// Problem: unlinking in interrupt requires waiting for one frame (udelay) -// to allow the whole structures to be safely removed -static int uhci_unlink_urb (purb_t purb) -{ - puhci_t s; - puhci_desc_t qh; - puhci_desc_t td; - purb_priv_t purb_priv; - unsigned long flags=0; - struct list_head *p; - - if (!purb) // you never know... - return -1; - - s = (puhci_t) purb->dev->bus->hcpriv; // get pointer to uhci struct - - if (usb_pipedevice (purb->pipe) == s->rh.devnum) - return rh_unlink_urb (purb); - - if(!in_interrupt()) { - // is the following really necessary? dequeue_urb has its own spinlock (GA) - spin_lock_irqsave (&s->unlink_urb_lock, flags); // do not allow interrupts - } - - //dbg("unlink_urb called %p",purb); - if (purb->status == USB_ST_URB_PENDING) { - // URB probably still in work - purb_priv = purb->hcpriv; - dequeue_urb (s, &purb->urb_list,1); - purb->status = USB_ST_URB_KILLED; // mark urb as killed - - if(!in_interrupt()) { - spin_unlock_irqrestore (&s->unlink_urb_lock, flags); // allow interrupts from here - } - - switch (usb_pipetype (purb->pipe)) { - case PIPE_ISOCHRONOUS: - case PIPE_INTERRUPT: - for (p = purb_priv->desc_list.next; p != &purb_priv->desc_list; p = p->next) { - td = list_entry (p, uhci_desc_t, desc_list); - unlink_td (s, td); - } - // wait at least 1 Frame - if (in_interrupt ()) - udelay (1000); - else - schedule_timeout (1 + 1 * HZ / 1000); - while ((p = purb_priv->desc_list.next) != &purb_priv->desc_list) { - td = list_entry (p, uhci_desc_t, desc_list); - list_del (p); - delete_desc (td); - } - break; - - case PIPE_BULK: - case PIPE_CONTROL: - qh = list_entry (purb_priv->desc_list.next, uhci_desc_t, desc_list); - - unlink_qh (s, qh); // remove this qh from qh-list - // wait at least 1 Frame - - if (in_interrupt ()) - udelay (1000); - else - schedule_timeout (1 + 1 * HZ / 1000); - delete_qh (s, qh); // remove it physically - - } - -#ifdef _UHCI_SLAB - kmem_cache_free(urb_priv_kmem, purb->hcpriv); -#else - kfree (purb->hcpriv); -#endif - if (purb->complete) { - dbg("unlink_urb: calling completion"); - purb->complete ((struct urb *) purb); - usb_dec_dev_use (purb->dev); - } - return 0; - } - else { - if(!in_interrupt()) - spin_unlock_irqrestore (&s->unlink_urb_lock, flags); // allow interrupts from here - } - - return 0; -} -/*-------------------------------------------------------------------*/ -// In case of ASAP iso transfer, search the URB-list for already queued URBs -// for this EP and calculate the earliest start frame for the new -// URB (easy seamless URB continuation!) -static int find_iso_limits (purb_t purb, unsigned int *start, unsigned int *end) -{ - purb_t u, last_urb = NULL; - puhci_t s = (puhci_t) purb->dev->bus->hcpriv; - struct list_head *p = s->urb_list.next; - int ret=-1; - unsigned long flags; - - spin_lock_irqsave (&s->urb_list_lock, flags); - - for (; p != &s->urb_list; p = p->next) { - u = list_entry (p, urb_t, urb_list); - // look for pending URBs with identical pipe handle - // works only because iso doesn't toggle the data bit! - if ((purb->pipe == u->pipe) && (purb->dev == u->dev) && (u->status == USB_ST_URB_PENDING)) { - if (!last_urb) - *start = u->start_frame; - last_urb = u; - } - } - - if (last_urb) { - *end = (last_urb->start_frame + last_urb->number_of_packets) & 1023; - ret=0; - } - - spin_unlock_irqrestore(&s->urb_list_lock, flags); - - return ret; // no previous urb found - -} -/*-------------------------------------------------------------------*/ -// adjust start_frame according to scheduling constraints (ASAP etc) - -static void jnx_show_desc (puhci_desc_t d) -{ - switch (d->type) { - case TD_TYPE: - dbg("td @ 0x%08lx: link 0x%08x status 0x%08x info 0x%08x buffer 0x%08x", - (unsigned long) d, d->hw.td.link, d->hw.td.status, d->hw.td.info, d->hw.td.buffer); - if (!(d->hw.td.link & UHCI_PTR_TERM)) - jnx_show_desc ((puhci_desc_t) bus_to_virt (d->hw.td.link & ~UHCI_PTR_BITS)); - break; - - case QH_TYPE: - dbg("qh @ 0x%08lx: head 0x%08x element 0x%08x", - (unsigned long) d, d->hw.qh.head, d->hw.qh.element); - if (!(d->hw.qh.element & UHCI_PTR_TERM)) - jnx_show_desc ((puhci_desc_t) bus_to_virt (d->hw.qh.element & ~UHCI_PTR_BITS)); - if (!(d->hw.qh.head & UHCI_PTR_TERM)) - jnx_show_desc ((puhci_desc_t) bus_to_virt (d->hw.qh.head & ~UHCI_PTR_BITS)); - break; - - default: - dbg("desc @ 0x%08lx: invalid type %u", (unsigned long) d, d->type); - } -} - -/*-------------------------------------------------------------------*/ -static int iso_find_start (purb_t purb) -{ - puhci_t s = (puhci_t) purb->dev->bus->hcpriv; - unsigned int now; - unsigned int start_limit = 0, stop_limit = 0, queued_size; - int limits; - - now = UHCI_GET_CURRENT_FRAME (s) & 1023; - - if ((unsigned) purb->number_of_packets > 900) - return -EFBIG; - - limits = find_iso_limits (purb, &start_limit, &stop_limit); - queued_size = (stop_limit - start_limit) & 1023; - - if (purb->transfer_flags & USB_ISO_ASAP) { - // first iso - if (limits) { - // 10ms setup should be enough //FIXME! - purb->start_frame = (now + 10) & 1023; - } - else { - purb->start_frame = stop_limit; //seamless linkage - - if (((now - purb->start_frame) & 1023) <= (unsigned) purb->number_of_packets) { - dbg("iso_find_start: warning, ASAP gap, should not happen"); - dbg("iso_find_start: now %u start_frame %u number_of_packets %u pipe 0x%08x", - now, purb->start_frame, purb->number_of_packets, purb->pipe); - { - puhci_t s = (puhci_t) purb->dev->bus->hcpriv; - struct list_head *p; - purb_t u; - int a = -1, b = -1; - unsigned long flags; - - spin_lock_irqsave (&s->urb_list_lock, flags); - p=s->urb_list.next; - - for (; p != &s->urb_list; p = p->next) { - u = list_entry (p, urb_t, urb_list); - if (purb->dev != u->dev) - continue; - dbg("urb: pipe 0x%08x status %d start_frame %u number_of_packets %u", - u->pipe, u->status, u->start_frame, u->number_of_packets); - if (!usb_pipeisoc (u->pipe)) - continue; - if (a == -1) - a = u->start_frame; - b = (u->start_frame + u->number_of_packets - 1) & 1023; - } - spin_unlock_irqrestore(&s->urb_list_lock, flags); -#if 0 - if (a != -1 && b != -1) { - do { - jnx_show_desc (s->iso_td[a]); - a = (a + 1) & 1023; - } - while (a != b); - } -#endif - } - purb->start_frame = (now + 5) & 1023; // 5ms setup should be enough //FIXME! - //return -EAGAIN; //FIXME - - } - } - } - else { - purb->start_frame &= 1023; - if (((now - purb->start_frame) & 1023) < (unsigned) purb->number_of_packets) { - dbg("iso_find_start: now between start_frame and end"); - return -EAGAIN; - } - } - - /* check if either start_frame or start_frame+number_of_packets-1 lies between start_limit and stop_limit */ - if (limits) - return 0; - if (((purb->start_frame - start_limit) & 1023) < queued_size || - ((purb->start_frame + purb->number_of_packets - 1 - start_limit) & 1023) < queued_size) { - dbg("iso_find_start: start_frame %u number_of_packets %u start_limit %u stop_limit %u", - purb->start_frame, purb->number_of_packets, start_limit, stop_limit); - return -EAGAIN; - } - - return 0; -} -/*-------------------------------------------------------------------*/ -// submits USB interrupt (ie. polling ;-) -// ASAP-flag set implicitely -// if period==0, the the transfer is only done once (usb_scsi need this...) - -static int uhci_submit_int_urb (purb_t purb) -{ - puhci_t s = (puhci_t) purb->dev->bus->hcpriv; - purb_priv_t purb_priv = purb->hcpriv; - int nint, n, ret; - puhci_desc_t td; - int status, destination; - int now; - int info; - unsigned int pipe = purb->pipe; - - //dbg("SUBMIT INT"); - - if (purb->interval < 0 || purb->interval >= 256) - return -EINVAL; - - if (purb->interval == 0) - nint = 0; - else { - for (nint = 0, n = 1; nint <= 8; nint++, n += n) // round interval down to 2^n - { - if (purb->interval < n) { - purb->interval = n / 2; - break; - } - } - nint--; - } - dbg("Rounded interval to %i, chain %i", purb->interval, nint); - - now = UHCI_GET_CURRENT_FRAME (s) & 1023; - purb->start_frame = now; // remember start frame, just in case... - - purb->number_of_packets = 1; - - // INT allows only one packet - if (purb->transfer_buffer_length > usb_maxpacket (purb->dev, pipe, usb_pipeout (pipe))) - return -EINVAL; - - ret = alloc_td (&td, UHCI_PTR_DEPTH); - - if (ret) - return -ENOMEM; - - status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC | - (purb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (1 << 27); - - destination = (purb->pipe & PIPE_DEVEP_MASK) | usb_packetid (purb->pipe) | - (((purb->transfer_buffer_length - 1) & 0x7ff) << 21); - - - info = destination | (usb_gettoggle (purb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)) << TD_TOKEN_TOGGLE); - - fill_td (td, status, info, virt_to_bus (purb->transfer_buffer)); - list_add_tail (&td->desc_list, &purb_priv->desc_list); - insert_td_horizontal (s, s->int_chain[nint], td, UHCI_PTR_DEPTH); // store in INT-TDs - - usb_dotoggle (purb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)); - -#if 0 - td = tdm[purb->number_of_packets]; - fill_td (td, TD_CTRL_IOC, 0, 0); - insert_td_horizontal (s, s->iso_td[(purb->start_frame + (purb->number_of_packets) * purb->interval + 1) & 1023], td, UHCI_PTR_DEPTH); - list_add_tail (&td->desc_list, &purb_priv->desc_list); -#endif - - return 0; -} -/*-------------------------------------------------------------------*/ -static int uhci_submit_iso_urb (purb_t purb) -{ - puhci_t s = (puhci_t) purb->dev->bus->hcpriv; - purb_priv_t purb_priv = purb->hcpriv; - int n, ret; - puhci_desc_t td, *tdm; - int status, destination; - unsigned long flags; - spinlock_t lock; - - spin_lock_init (&lock); - spin_lock_irqsave (&lock, flags); // Disable IRQs to schedule all ISO-TDs in time - - ret = iso_find_start (purb); // adjusts purb->start_frame for later use - - if (ret) - goto err; - - tdm = (puhci_desc_t *) kmalloc (purb->number_of_packets * sizeof (puhci_desc_t), in_interrupt ()? GFP_ATOMIC : GFP_KERNEL); - - if (!tdm) { - ret = -ENOMEM; - goto err; - } - - // First try to get all TDs - for (n = 0; n < purb->number_of_packets; n++) { - dbg("n:%d purb->iso_frame_desc[n].length:%d", n, purb->iso_frame_desc[n].length); - if (!purb->iso_frame_desc[n].length) { - // allows ISO striping by setting length to zero in iso_descriptor - tdm[n] = 0; - continue; - } - ret = alloc_td (&td, UHCI_PTR_DEPTH); - if (ret) { - int i; // Cleanup allocated TDs - - for (i = 0; i < n; n++) - if (tdm[i]) - kfree (tdm[i]); - kfree (tdm); - ret = -ENOMEM; - goto err; - } - tdm[n] = td; - } - - status = TD_CTRL_ACTIVE | TD_CTRL_IOS; //| (purb->transfer_flags&USB_DISABLE_SPD?0:TD_CTRL_SPD); - - destination = (purb->pipe & PIPE_DEVEP_MASK) | usb_packetid (purb->pipe); - - // Queue all allocated TDs - for (n = 0; n < purb->number_of_packets; n++) { - td = tdm[n]; - if (!td) - continue; - if (n + 1 >= purb->number_of_packets) - status |= TD_CTRL_IOC; - - fill_td (td, status, destination | (((purb->iso_frame_desc[n].length - 1) & 0x7ff) << 21), - virt_to_bus (purb->transfer_buffer + purb->iso_frame_desc[n].offset)); - list_add_tail (&td->desc_list, &purb_priv->desc_list); - insert_td_horizontal (s, s->iso_td[(purb->start_frame + n) & 1023], td, UHCI_PTR_DEPTH); // store in iso-tds - //uhci_show_td(td); - - } - - kfree (tdm); - dbg("ISO-INT# %i, start %i, now %i", purb->number_of_packets, purb->start_frame, UHCI_GET_CURRENT_FRAME (s) & 1023); - ret = 0; - - err: - spin_unlock_irqrestore (&lock, flags); - return ret; - -} -/*-------------------------------------------------------------------*/ -static int search_dev_ep (puhci_t s, purb_t purb) -{ - unsigned long flags; - struct list_head *p = s->urb_list.next; - purb_t tmp; - - dbg("search_dev_ep:"); - spin_lock_irqsave (&s->urb_list_lock, flags); - - for (; p != &s->urb_list; p = p->next) { - tmp = list_entry (p, urb_t, urb_list); - dbg("urb: %p", tmp); - // we can accept this urb if it is not queued at this time - // or if non-iso transfer requests should be scheduled for the same device and pipe - if ((usb_pipetype (purb->pipe) != PIPE_ISOCHRONOUS && - tmp->dev == purb->dev && tmp->pipe == purb->pipe) || (purb == tmp)) { - spin_unlock_irqrestore (&s->urb_list_lock, flags); - return 1; // found another urb already queued for processing - } - } - - spin_unlock_irqrestore (&s->urb_list_lock, flags); - - return 0; -} -/*-------------------------------------------------------------------*/ -static int uhci_submit_urb (purb_t purb) -{ - puhci_t s; - purb_priv_t purb_priv; - int ret = 0; - - if (!purb->dev || !purb->dev->bus) - return -ENODEV; - - s = (puhci_t) purb->dev->bus->hcpriv; - //dbg("submit_urb: %p type %d",purb,usb_pipetype(purb->pipe)); - - if (usb_pipedevice (purb->pipe) == s->rh.devnum) - return rh_submit_urb (purb); /* virtual root hub */ - - usb_inc_dev_use (purb->dev); - - if (search_dev_ep (s, purb)) { - usb_dec_dev_use (purb->dev); - return -ENXIO; // urb already queued - - } - -#ifdef _UHCI_SLAB - purb_priv = kmem_cache_alloc(urb_priv_kmem, in_interrupt ()? SLAB_ATOMIC : SLAB_KERNEL); -#else - purb_priv = kmalloc (sizeof (urb_priv_t), in_interrupt ()? GFP_ATOMIC : GFP_KERNEL); -#endif - if (!purb_priv) { - usb_dec_dev_use (purb->dev); - return -ENOMEM; - } - - purb->hcpriv = purb_priv; - INIT_LIST_HEAD (&purb_priv->desc_list); - purb_priv->short_control_packet=0; - dbg("submit_urb: scheduling %p", purb); - - switch (usb_pipetype (purb->pipe)) { - case PIPE_ISOCHRONOUS: - ret = uhci_submit_iso_urb (purb); - break; - case PIPE_INTERRUPT: - ret = uhci_submit_int_urb (purb); - break; - case PIPE_CONTROL: - //dump_urb (purb); - ret = uhci_submit_control_urb (purb); - break; - case PIPE_BULK: - ret = uhci_submit_bulk_urb (purb); - break; - default: - ret = -EINVAL; - } - - dbg("submit_urb: scheduled with ret: %d", ret); - - if (ret != USB_ST_NOERROR) { - usb_dec_dev_use (purb->dev); -#ifdef _UHCI_SLAB - kmem_cache_free(urb_priv_kmem, purb_priv); -#else - kfree (purb_priv); -#endif - return ret; - } - - purb->status = USB_ST_URB_PENDING; - queue_urb (s, &purb->urb_list,1); - dbg("submit_urb: exit"); - - return 0; -} -/*------------------------------------------------------------------- - Virtual Root Hub - -------------------------------------------------------------------*/ - -static __u8 root_hub_dev_des[] = -{ - 0x12, /* __u8 bLength; */ - 0x01, /* __u8 bDescriptorType; Device */ - 0x00, /* __u16 bcdUSB; v1.0 */ - 0x01, - 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ - 0x00, /* __u8 bDeviceSubClass; */ - 0x00, /* __u8 bDeviceProtocol; */ - 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ - 0x00, /* __u16 idVendor; */ - 0x00, - 0x00, /* __u16 idProduct; */ - 0x00, - 0x00, /* __u16 bcdDevice; */ - 0x00, - 0x00, /* __u8 iManufacturer; */ - 0x00, /* __u8 iProduct; */ - 0x00, /* __u8 iSerialNumber; */ - 0x01 /* __u8 bNumConfigurations; */ -}; - - -/* Configuration descriptor */ -static __u8 root_hub_config_des[] = -{ - 0x09, /* __u8 bLength; */ - 0x02, /* __u8 bDescriptorType; Configuration */ - 0x19, /* __u16 wTotalLength; */ - 0x00, - 0x01, /* __u8 bNumInterfaces; */ - 0x01, /* __u8 bConfigurationValue; */ - 0x00, /* __u8 iConfiguration; */ - 0x40, /* __u8 bmAttributes; - Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */ - 0x00, /* __u8 MaxPower; */ - - /* interface */ - 0x09, /* __u8 if_bLength; */ - 0x04, /* __u8 if_bDescriptorType; Interface */ - 0x00, /* __u8 if_bInterfaceNumber; */ - 0x00, /* __u8 if_bAlternateSetting; */ - 0x01, /* __u8 if_bNumEndpoints; */ - 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ - 0x00, /* __u8 if_bInterfaceSubClass; */ - 0x00, /* __u8 if_bInterfaceProtocol; */ - 0x00, /* __u8 if_iInterface; */ - - /* endpoint */ - 0x07, /* __u8 ep_bLength; */ - 0x05, /* __u8 ep_bDescriptorType; Endpoint */ - 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ - 0x03, /* __u8 ep_bmAttributes; Interrupt */ - 0x08, /* __u16 ep_wMaxPacketSize; 8 Bytes */ - 0x00, - 0xff /* __u8 ep_bInterval; 255 ms */ -}; - - -static __u8 root_hub_hub_des[] = -{ - 0x09, /* __u8 bLength; */ - 0x29, /* __u8 bDescriptorType; Hub-descriptor */ - 0x02, /* __u8 bNbrPorts; */ - 0x00, /* __u16 wHubCharacteristics; */ - 0x00, - 0x01, /* __u8 bPwrOn2pwrGood; 2ms */ - 0x00, /* __u8 bHubContrCurrent; 0 mA */ - 0x00, /* __u8 DeviceRemovable; *** 7 Ports max *** */ - 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */ -}; - -/*-------------------------------------------------------------------------*/ -/* prepare Interrupt pipe transaction data; HUB INTERRUPT ENDPOINT */ -static int rh_send_irq (purb_t purb) -{ - - int len = 1; - int i; - puhci_t uhci = purb->dev->bus->hcpriv; - unsigned int io_addr = uhci->io_addr; - __u16 data = 0; - - for (i = 0; i < uhci->rh.numports; i++) { - data |= ((inw (io_addr + USBPORTSC1 + i * 2) & 0xa) > 0 ? (1 << (i + 1)) : 0); - len = (i + 1) / 8 + 1; - } - - *(__u16 *) purb->transfer_buffer = cpu_to_le16 (data); - purb->actual_length = len; - purb->status = USB_ST_NOERROR; - - if ((data > 0) && (uhci->rh.send != 0)) { - dbg("Root-Hub INT complete: port1: %x port2: %x data: %x", - inw (io_addr + USBPORTSC1), inw (io_addr + USBPORTSC2), data); - purb->complete (purb); - - } - return USB_ST_NOERROR; -} - -/*-------------------------------------------------------------------------*/ -/* Virtual Root Hub INTs are polled by this timer every "intervall" ms */ -static int rh_init_int_timer (purb_t purb); - -static void rh_int_timer_do (unsigned long ptr) -{ - int len; - - purb_t purb = (purb_t) ptr; - puhci_t uhci = purb->dev->bus->hcpriv; - - if (uhci->rh.send) { - len = rh_send_irq (purb); - if (len > 0) { - purb->actual_length = len; - if (purb->complete) - purb->complete (purb); - } - } - rh_init_int_timer (purb); -} - -/*-------------------------------------------------------------------------*/ -/* Root Hub INTs are polled by this timer */ -static int rh_init_int_timer (purb_t purb) -{ - puhci_t uhci = purb->dev->bus->hcpriv; - - uhci->rh.interval = purb->interval; - init_timer (&uhci->rh.rh_int_timer); - uhci->rh.rh_int_timer.function = rh_int_timer_do; - uhci->rh.rh_int_timer.data = (unsigned long) purb; - uhci->rh.rh_int_timer.expires = jiffies + (HZ * (purb->interval < 30 ? 30 : purb->interval)) / 1000; - add_timer (&uhci->rh.rh_int_timer); - - return 0; -} - -/*-------------------------------------------------------------------------*/ -#define OK(x) len = (x); break - -#define CLR_RH_PORTSTAT(x) \ - status = inw(io_addr+USBPORTSC1+2*(wIndex-1)); \ - status = (status & 0xfff5) & ~(x); \ - outw(status, io_addr+USBPORTSC1+2*(wIndex-1)) - -#define SET_RH_PORTSTAT(x) \ - status = inw(io_addr+USBPORTSC1+2*(wIndex-1)); \ - status = (status & 0xfff5) | (x); \ - outw(status, io_addr+USBPORTSC1+2*(wIndex-1)) - - -/*-------------------------------------------------------------------------*/ -/**** - ** Root Hub Control Pipe - *************************/ - - -static int rh_submit_urb (purb_t purb) -{ - struct usb_device *usb_dev = purb->dev; - puhci_t uhci = usb_dev->bus->hcpriv; - unsigned int pipe = purb->pipe; - devrequest *cmd = (devrequest *) purb->setup_packet; - void *data = purb->transfer_buffer; - int leni = purb->transfer_buffer_length; - int len = 0; - int status = 0; - int stat = USB_ST_NOERROR; - int i; - unsigned int io_addr = uhci->io_addr; - __u16 cstatus; - - __u16 bmRType_bReq; - __u16 wValue; - __u16 wIndex; - __u16 wLength; - - if (usb_pipetype (pipe) == PIPE_INTERRUPT) { - dbg("Root-Hub submit IRQ: every %d ms", purb->interval); - uhci->rh.urb = purb; - uhci->rh.send = 1; - uhci->rh.interval = purb->interval; - rh_init_int_timer (purb); - - return USB_ST_NOERROR; - } - - - bmRType_bReq = cmd->requesttype | cmd->request << 8; - wValue = le16_to_cpu (cmd->value); - wIndex = le16_to_cpu (cmd->index); - wLength = le16_to_cpu (cmd->length); - - for (i = 0; i < 8; i++) - uhci->rh.c_p_r[i] = 0; - - dbg("Root-Hub: adr: %2x cmd(%1x): %04x %04x %04x %04x", - uhci->rh.devnum, 8, bmRType_bReq, wValue, wIndex, wLength); - - switch (bmRType_bReq) { - /* Request Destination: - without flags: Device, - RH_INTERFACE: interface, - RH_ENDPOINT: endpoint, - RH_CLASS means HUB here, - RH_OTHER | RH_CLASS almost ever means HUB_PORT here - */ - - case RH_GET_STATUS: - *(__u16 *) data = cpu_to_le16 (1); - OK (2); - case RH_GET_STATUS | RH_INTERFACE: - *(__u16 *) data = cpu_to_le16 (0); - OK (2); - case RH_GET_STATUS | RH_ENDPOINT: - *(__u16 *) data = cpu_to_le16 (0); - OK (2); - case RH_GET_STATUS | RH_CLASS: - *(__u32 *) data = cpu_to_le32 (0); - OK (4); /* hub power ** */ - case RH_GET_STATUS | RH_OTHER | RH_CLASS: - status = inw (io_addr + USBPORTSC1 + 2 * (wIndex - 1)); - cstatus = ((status & USBPORTSC_CSC) >> (1 - 0)) | - ((status & USBPORTSC_PEC) >> (3 - 1)) | - (uhci->rh.c_p_r[wIndex - 1] << (0 + 4)); - status = (status & USBPORTSC_CCS) | - ((status & USBPORTSC_PE) >> (2 - 1)) | - ((status & USBPORTSC_SUSP) >> (12 - 2)) | - ((status & USBPORTSC_PR) >> (9 - 4)) | - (1 << 8) | /* power on ** */ - ((status & USBPORTSC_LSDA) << (-8 + 9)); - - *(__u16 *) data = cpu_to_le16 (status); - *(__u16 *) (data + 2) = cpu_to_le16 (cstatus); - OK (4); - - case RH_CLEAR_FEATURE | RH_ENDPOINT: - switch (wValue) { - case (RH_ENDPOINT_STALL): - OK (0); - } - break; - - case RH_CLEAR_FEATURE | RH_CLASS: - switch (wValue) { - case (RH_C_HUB_OVER_CURRENT): - OK (0); /* hub power over current ** */ - } - break; - - case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: - switch (wValue) { - case (RH_PORT_ENABLE): - CLR_RH_PORTSTAT (USBPORTSC_PE); - OK (0); - case (RH_PORT_SUSPEND): - CLR_RH_PORTSTAT (USBPORTSC_SUSP); - OK (0); - case (RH_PORT_POWER): - OK (0); /* port power ** */ - case (RH_C_PORT_CONNECTION): - SET_RH_PORTSTAT (USBPORTSC_CSC); - OK (0); - case (RH_C_PORT_ENABLE): - SET_RH_PORTSTAT (USBPORTSC_PEC); - OK (0); - case (RH_C_PORT_SUSPEND): -/*** WR_RH_PORTSTAT(RH_PS_PSSC); */ - OK (0); - case (RH_C_PORT_OVER_CURRENT): - OK (0); /* port power over current ** */ - case (RH_C_PORT_RESET): - uhci->rh.c_p_r[wIndex - 1] = 0; - OK (0); - } - break; - - case RH_SET_FEATURE | RH_OTHER | RH_CLASS: - switch (wValue) { - case (RH_PORT_SUSPEND): - SET_RH_PORTSTAT (USBPORTSC_SUSP); - OK (0); - case (RH_PORT_RESET): - SET_RH_PORTSTAT (USBPORTSC_PR); - wait_ms (10); - uhci->rh.c_p_r[wIndex - 1] = 1; - CLR_RH_PORTSTAT (USBPORTSC_PR); - udelay (10); - SET_RH_PORTSTAT (USBPORTSC_PE); - wait_ms (10); - SET_RH_PORTSTAT (0xa); - OK (0); - case (RH_PORT_POWER): - OK (0); /* port power ** */ - case (RH_PORT_ENABLE): - SET_RH_PORTSTAT (USBPORTSC_PE); - OK (0); - } - break; - - case RH_SET_ADDRESS: - uhci->rh.devnum = wValue; - OK (0); - - case RH_GET_DESCRIPTOR: - switch ((wValue & 0xff00) >> 8) { - case (0x01): /* device descriptor */ - len = min (leni, min (sizeof (root_hub_dev_des), wLength)); - memcpy (data, root_hub_dev_des, len); - OK (len); - case (0x02): /* configuration descriptor */ - len = min (leni, min (sizeof (root_hub_config_des), wLength)); - memcpy (data, root_hub_config_des, len); - OK (len); - case (0x03): /*string descriptors */ - stat = -EPIPE; - } - break; - - case RH_GET_DESCRIPTOR | RH_CLASS: - root_hub_hub_des[2] = uhci->rh.numports; - len = min (leni, min (sizeof (root_hub_hub_des), wLength)); - memcpy (data, root_hub_hub_des, len); - OK (len); - - case RH_GET_CONFIGURATION: - *(__u8 *) data = 0x01; - OK (1); - - case RH_SET_CONFIGURATION: - OK (0); - default: - stat = -EPIPE; - } - - - dbg("Root-Hub stat port1: %x port2: %x", - inw (io_addr + USBPORTSC1), inw (io_addr + USBPORTSC2)); - - purb->actual_length = len; - purb->status = stat; - if (purb->complete) - purb->complete (purb); - return USB_ST_NOERROR; -} -/*-------------------------------------------------------------------------*/ - -static int rh_unlink_urb (purb_t purb) -{ - puhci_t uhci = purb->dev->bus->hcpriv; - - dbg("Root-Hub unlink IRQ"); - uhci->rh.send = 0; - del_timer (&uhci->rh.rh_int_timer); - return 0; -} -/*-------------------------------------------------------------------*/ - -#define UHCI_DEBUG - -/* - * Map status to standard result codes - * - * is (td->status & 0xFE0000) [a.k.a. uhci_status_bits(td->status) - * is True for output TDs and False for input TDs. - */ -static int uhci_map_status (int status, int dir_out) -{ - if (!status) - return USB_ST_NOERROR; - if (status & TD_CTRL_BITSTUFF) /* Bitstuff error */ - return USB_ST_BITSTUFF; - if (status & TD_CTRL_CRCTIMEO) { /* CRC/Timeout */ - if (dir_out) - return USB_ST_NORESPONSE; - else - return USB_ST_CRC; - } - if (status & TD_CTRL_NAK) /* NAK */ - return USB_ST_TIMEOUT; - if (status & TD_CTRL_BABBLE) /* Babble */ - return -EPIPE; - if (status & TD_CTRL_DBUFERR) /* Buffer error */ - return USB_ST_BUFFERUNDERRUN; - if (status & TD_CTRL_STALLED) /* Stalled */ - return -EPIPE; - if (status & TD_CTRL_ACTIVE) /* Active */ - return USB_ST_NOERROR; - - return USB_ST_INTERNALERROR; -} - -/* - * Only the USB core should call uhci_alloc_dev and uhci_free_dev - */ -static int uhci_alloc_dev (struct usb_device *usb_dev) -{ - return 0; -} - -static int uhci_free_dev (struct usb_device *usb_dev) -{ - return 0; -} - -/* - * uhci_get_current_frame_number() - * - * returns the current frame number for a USB bus/controller. - */ -static int uhci_get_current_frame_number (struct usb_device *usb_dev) -{ - return UHCI_GET_CURRENT_FRAME ((puhci_t) usb_dev->bus->hcpriv); -} - -struct usb_operations uhci_device_operations = -{ - uhci_alloc_dev, - uhci_free_dev, - uhci_get_current_frame_number, - uhci_submit_urb, - uhci_unlink_urb -}; - -/* - * For IN-control transfers, process_transfer gets a bit more complicated, - * since there are devices that return less data (eg. strings) than they - * have announced. This leads to a queue abort due to the short packet, - * the status stage is not executed. If this happens, the status stage - * is manually re-executed. - * FIXME: Stall-condition may override 'nearly' successful CTRL-IN-transfer - * when the transfered length fits exactly in maxsze-packets. A bit - * more intelligence is needed to detect this and finish without error. - */ -static int process_transfer (puhci_t s, purb_t purb) -{ - int ret = USB_ST_NOERROR; - purb_priv_t purb_priv = purb->hcpriv; - struct list_head *qhl = purb_priv->desc_list.next; - puhci_desc_t qh = list_entry (qhl, uhci_desc_t, desc_list); - struct list_head *p = qh->vertical.next; - puhci_desc_t desc= list_entry (purb_priv->desc_list.prev, uhci_desc_t, desc_list); - puhci_desc_t last_desc = list_entry (desc->vertical.prev, uhci_desc_t, vertical); - int data_toggle = usb_gettoggle (purb->dev, usb_pipeendpoint (purb->pipe), usb_pipeout (purb->pipe)); // save initial data_toggle - - - // extracted and remapped info from TD - int maxlength; - int actual_length; - int status = USB_ST_NOERROR; - - dbg("process_transfer: urb contains bulk/control request"); - - - /* if the status phase has been retriggered and the - queue is empty or the last status-TD is inactive, the retriggered - status stage is completed - */ -#if 1 - if (purb_priv->short_control_packet && - ((qh->hw.qh.element == UHCI_PTR_TERM) ||(!(last_desc->hw.td.status & TD_CTRL_ACTIVE)))) - goto transfer_finished; -#endif - purb->actual_length=0; - - for (; p != &qh->vertical; p = p->next) { - desc = list_entry (p, uhci_desc_t, vertical); - - if (desc->hw.td.status & TD_CTRL_ACTIVE) // do not process active TDs - return ret; - - // extract transfer parameters from TD - actual_length = (desc->hw.td.status + 1) & 0x7ff; - maxlength = (((desc->hw.td.info >> 21) & 0x7ff) + 1) & 0x7ff; - status = uhci_map_status (uhci_status_bits (desc->hw.td.status), usb_pipeout (purb->pipe)); - - // see if EP is stalled - if (status == -EPIPE) { - // set up stalled condition - usb_endpoint_halt (purb->dev, usb_pipeendpoint (purb->pipe), usb_pipeout (purb->pipe)); - } - - // if any error occured stop processing of further TDs - if (status != USB_ST_NOERROR) { - // only set ret if status returned an error - uhci_show_td (desc); - ret = status; - purb->error_count++; - break; - } - else if ((desc->hw.td.info & 0xff) != USB_PID_SETUP) - purb->actual_length += actual_length; - -#if 0 - if (i++==0) - uhci_show_td (desc); // show first TD of each transfer -#endif - - // got less data than requested - if ( (actual_length < maxlength)) { - if (purb->transfer_flags & USB_DISABLE_SPD) { - ret = USB_ST_SHORT_PACKET; // treat as real error - dbg("process_transfer: SPD!!"); - break; // exit after this TD because SP was detected - } - - // short read during control-IN: re-start status stage - if ((usb_pipetype (purb->pipe) == PIPE_CONTROL)) { - if (uhci_packetid(last_desc->hw.td.info) == USB_PID_OUT) { - uhci_show_td (last_desc); - qh->hw.qh.element = virt_to_bus (last_desc); // re-trigger status stage - info("short packet during control transfer, retrigger status stage @ %p",last_desc); - purb_priv->short_control_packet=1; - return 0; - } - } - // all other cases: short read is OK - data_toggle = uhci_toggle (desc->hw.td.info); - break; - } - - data_toggle = uhci_toggle (desc->hw.td.info); - //dbg("process_transfer: len:%d status:%x mapped:%x toggle:%d", actual_length, desc->hw.td.status,status, data_toggle); - - } - usb_settoggle (purb->dev, usb_pipeendpoint (purb->pipe), usb_pipeout (purb->pipe), !data_toggle); - transfer_finished: - - /* APC BackUPS Pro kludge */ - /* It tries to send all of the descriptor instead of */ - /* the amount we requested */ - if (desc->hw.td.status & TD_CTRL_IOC && - status & TD_CTRL_ACTIVE && - status & TD_CTRL_NAK ) - { - ret=0; - status=0; - } - - unlink_qh (s, qh); - delete_qh (s, qh); - - purb->status = status; - - dbg("process_transfer: urb %p, wanted len %d, len %d status %x err %d", - purb,purb->transfer_buffer_length,purb->actual_length, purb->status, purb->error_count); - //dbg("process_transfer: exit"); - return ret; -} - -static int process_interrupt (puhci_t s, purb_t purb) -{ - int i, ret = USB_ST_URB_PENDING; - purb_priv_t purb_priv = purb->hcpriv; - struct list_head *p = purb_priv->desc_list.next; - puhci_desc_t desc = list_entry (purb_priv->desc_list.prev, uhci_desc_t, desc_list); - int data_toggle = usb_gettoggle (purb->dev, usb_pipeendpoint (purb->pipe), - usb_pipeout (purb->pipe)); // save initial data_toggle - // extracted and remapped info from TD - - int actual_length; - int status = USB_ST_NOERROR; - - //dbg("urb contains interrupt request"); - - for (i = 0; p != &purb_priv->desc_list; p = p->next, i++) // Maybe we allow more than one TD later ;-) - { - desc = list_entry (p, uhci_desc_t, desc_list); - - if (desc->hw.td.status & TD_CTRL_ACTIVE) { - // do not process active TDs - //dbg("TD ACT Status @%p %08x",desc,desc->hw.td.status); - break; - } - - if (!desc->hw.td.status & TD_CTRL_IOC) { - // do not process one-shot TDs, no recycling - break; - } - // extract transfer parameters from TD - - actual_length = (desc->hw.td.status + 1) & 0x7ff; - status = uhci_map_status (uhci_status_bits (desc->hw.td.status), usb_pipeout (purb->pipe)); - - // see if EP is stalled - if (status == -EPIPE) { - // set up stalled condition - usb_endpoint_halt (purb->dev, usb_pipeendpoint (purb->pipe), usb_pipeout (purb->pipe)); - } - - // if any error occured: ignore this td, and continue - if (status != USB_ST_NOERROR) { - purb->error_count++; - goto recycle; - } - else - purb->actual_length = actual_length; - - // FIXME: SPD? - - data_toggle = uhci_toggle (desc->hw.td.info); - - if (purb->complete && status != USB_ST_TIMEOUT) { - // for last td, no user completion is needed - dbg("process_interrupt: calling completion"); - purb->status = status; - purb->complete ((struct urb *) purb); - purb->status = USB_ST_URB_PENDING; - } - recycle: - // Recycle INT-TD if interval!=0, else mark TD as one-shot - if (purb->interval) { - desc->hw.td.status |= TD_CTRL_ACTIVE; - desc->hw.td.info &= ~(1 << TD_TOKEN_TOGGLE); - desc->hw.td.info |= (usb_gettoggle (purb->dev, usb_pipeendpoint (purb->pipe), - usb_pipeout (purb->pipe)) << TD_TOKEN_TOGGLE); - usb_dotoggle (purb->dev, usb_pipeendpoint (purb->pipe), usb_pipeout (purb->pipe)); - } - else { - desc->hw.td.status &= ~TD_CTRL_IOC; // inactivate TD - } - } - - return ret; -} - - -static int process_iso (puhci_t s, purb_t purb) -{ - int i; - int ret = USB_ST_NOERROR; - purb_priv_t purb_priv = purb->hcpriv; - struct list_head *p = purb_priv->desc_list.next; - puhci_desc_t desc = list_entry (purb_priv->desc_list.prev, uhci_desc_t, desc_list); - - dbg("urb contains iso request"); - if (desc->hw.td.status & TD_CTRL_ACTIVE) - return USB_ST_PARTIAL_ERROR; // last TD not finished - - purb->error_count = 0; - purb->actual_length = 0; - purb->status = USB_ST_NOERROR; - - for (i = 0; p != &purb_priv->desc_list; p = p->next, i++) { - desc = list_entry (p, uhci_desc_t, desc_list); - - //uhci_show_td(desc); - if (desc->hw.td.status & TD_CTRL_ACTIVE) { - // means we have completed the last TD, but not the TDs before - dbg("TD still active (%x)- grrr. paranoia!", desc->hw.td.status); - ret = USB_ST_PARTIAL_ERROR; - purb->iso_frame_desc[i].status = ret; - unlink_td (s, desc); - goto err; - } - - unlink_td (s, desc); - - if (purb->number_of_packets <= i) { - dbg("purb->number_of_packets (%d)<=(%d)", purb->number_of_packets, i); - ret = USB_ST_URB_INVALID_ERROR; - goto err; - } - - if (purb->iso_frame_desc[i].offset + purb->transfer_buffer != bus_to_virt (desc->hw.td.buffer)) { - // Hm, something really weird is going on - dbg("Pointer Paranoia: %p!=%p", purb->iso_frame_desc[i].offset + purb->transfer_buffer, bus_to_virt (desc->hw.td.buffer)); - ret = USB_ST_URB_INVALID_ERROR; - purb->iso_frame_desc[i].status = ret; - goto err; - } - purb->iso_frame_desc[i].actual_length = (desc->hw.td.status + 1) & 0x7ff; - purb->iso_frame_desc[i].status = uhci_map_status (uhci_status_bits (desc->hw.td.status), usb_pipeout (purb->pipe)); - purb->actual_length += purb->iso_frame_desc[i].actual_length; - - err: - - if (purb->iso_frame_desc[i].status != USB_ST_NOERROR) { - purb->error_count++; - purb->status = purb->iso_frame_desc[i].status; - } - dbg("process_iso: len:%d status:%x", - purb->iso_frame_desc[i].length, purb->iso_frame_desc[i].status); - - delete_desc (desc); - list_del (p); - } - dbg("process_iso: exit %i (%d)", i, ret); - return ret; -} - - -static int process_urb (puhci_t s, struct list_head *p) -{ - int ret = USB_ST_NOERROR; - purb_t purb; - - spin_lock(&s->urb_list_lock); - purb=list_entry (p, urb_t, urb_list); - dbg("found queued urb: %p", purb); - - switch (usb_pipetype (purb->pipe)) { - case PIPE_CONTROL: - case PIPE_BULK: - ret = process_transfer (s, purb); - break; - case PIPE_ISOCHRONOUS: - ret = process_iso (s, purb); - break; - case PIPE_INTERRUPT: - ret = process_interrupt (s, purb); - break; - } - - spin_unlock(&s->urb_list_lock); - - if (purb->status != USB_ST_URB_PENDING) { - int proceed = 0; - dbg("dequeued urb: %p", purb); - dequeue_urb (s, p, 1); - -#ifdef _UHCI_SLAB - kmem_cache_free(urb_priv_kmem, purb->hcpriv); -#else - kfree (purb->hcpriv); -#endif - - if ((usb_pipetype (purb->pipe) != PIPE_INTERRUPT)) { - purb_t tmp = purb->next; // pointer to first urb - int is_ring = 0; - - if (purb->next) { - do { - if (tmp->status != USB_ST_URB_PENDING) { - proceed = 1; - break; - } - tmp = tmp->next; - } - while (tmp != NULL && tmp != purb->next); - if (tmp == purb->next) - is_ring = 1; - } - - // In case you need the current URB status for your completion handler - if (purb->complete && (!proceed || (purb->transfer_flags & USB_URB_EARLY_COMPLETE))) { - dbg("process_transfer: calling early completion"); - purb->complete ((struct urb *) purb); - if (!proceed && is_ring && (purb->status != USB_ST_URB_KILLED)) - uhci_submit_urb (purb); - } - - if (proceed && purb->next) { - // if there are linked urbs - handle submitting of them right now. - tmp = purb->next; // pointer to first urb - - do { - if ((tmp->status != USB_ST_URB_PENDING) && (tmp->status != USB_ST_URB_KILLED) && uhci_submit_urb (tmp) != USB_ST_NOERROR) - break; - tmp = tmp->next; - } - while (tmp != NULL && tmp != purb->next); // submit until we reach NULL or our own pointer or submit fails - - if (purb->complete && !(purb->transfer_flags & USB_URB_EARLY_COMPLETE)) { - dbg("process_transfer: calling completion"); - purb->complete ((struct urb *) purb); - } - } - usb_dec_dev_use (purb->dev); - } - } - - return ret; -} - -static void uhci_interrupt (int irq, void *__uhci, struct pt_regs *regs) -{ - puhci_t s = __uhci; - unsigned int io_addr = s->io_addr; - unsigned short status; - struct list_head *p, *p2; - - /* - * Read the interrupt status, and write it back to clear the - * interrupt cause - */ - dbg("interrupt"); - status = inw (io_addr + USBSTS); - - if (!status) /* shared interrupt, not mine */ - return; - - if (status != 1) { - dbg("interrupt, status %x", status); - //uhci_show_status (s); - } - //beep(1000); - /* - * the following is very subtle and was blatantly wrong before - * traverse the list in *reverse* direction, because new entries - * may be added at the end. - * also, because process_urb may unlink the current urb, - * we need to advance the list before - * - Thomas Sailer - */ - - spin_lock(&s->unlink_urb_lock); - spin_lock (&s->urb_list_lock); - p = s->urb_list.prev; - spin_unlock (&s->urb_list_lock); - - while (p != &s->urb_list) { - p2 = p; - p = p->prev; - process_urb (s, p2); - } - - spin_unlock(&s->unlink_urb_lock); - - outw (status, io_addr + USBSTS); -#ifdef __alpha - mb (); // ? -#endif - dbg("done"); -} - -static void reset_hc (puhci_t s) -{ - unsigned int io_addr = s->io_addr; - - s->apm_state = 0; - /* Global reset for 50ms */ - outw (USBCMD_GRESET, io_addr + USBCMD); - wait_ms (50); - outw (0, io_addr + USBCMD); - wait_ms (10); -} - -static void start_hc (puhci_t s) -{ - unsigned int io_addr = s->io_addr; - int timeout = 1000; - - /* - * Reset the HC - this will force us to get a - * new notification of any already connected - * ports due to the virtual disconnect that it - * implies. - */ - outw (USBCMD_HCRESET, io_addr + USBCMD); - - while (inw (io_addr + USBCMD) & USBCMD_HCRESET) { - if (!--timeout) { - err("USBCMD_HCRESET timed out!"); - break; - } - } - - /* Turn on all interrupts */ - outw (USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP, io_addr + USBINTR); - - /* Start at frame 0 */ - outw (0, io_addr + USBFRNUM); - outl (virt_to_bus (s->framelist), io_addr + USBFLBASEADD); - - /* Run and mark it configured with a 64-byte max packet */ - outw (USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD); - s->apm_state = 1; -} - -static void __exit uhci_cleanup_dev(puhci_t s) -{ - struct usb_device *root_hub = s->bus->root_hub; - if (root_hub) - usb_disconnect (&root_hub); - - usb_deregister_bus (s->bus); - - reset_hc (s); - release_region (s->io_addr, s->io_size); - free_irq (s->irq, s); - usb_free_bus (s->bus); - cleanup_skel (s); - kfree (s); - -} - -static int __init uhci_start_usb (puhci_t s) -{ /* start it up */ - /* connect the virtual root hub */ - struct usb_device *usb_dev; - - usb_dev = usb_alloc_dev (NULL, s->bus); - if (!usb_dev) - return -1; - - s->bus->root_hub = usb_dev; - usb_connect (usb_dev); - - if (usb_new_device (usb_dev) != 0) { - usb_free_dev (usb_dev); - return -1; - } - - return 0; -} - -static int __init alloc_uhci (int irq, unsigned int io_addr, unsigned int io_size) -{ - puhci_t s; - struct usb_bus *bus; - - s = kmalloc (sizeof (uhci_t), GFP_KERNEL); - if (!s) - return -1; - - memset (s, 0, sizeof (uhci_t)); - INIT_LIST_HEAD (&s->urb_list); - spin_lock_init (&s->urb_list_lock); - spin_lock_init (&s->qh_lock); - spin_lock_init (&s->td_lock); - spin_lock_init (&s->unlink_urb_lock); - s->irq = -1; - s->io_addr = io_addr; - s->io_size = io_size; - s->next = devs; //chain new uhci device into global list - - bus = usb_alloc_bus (&uhci_device_operations); - if (!bus) { - kfree (s); - return -1; - } - - s->bus = bus; - bus->hcpriv = s; - - /* UHCI specs says devices must have 2 ports, but goes on to say */ - /* they may have more but give no way to determine how many they */ - /* have, so default to 2 */ - /* According to the UHCI spec, Bit 7 is always set to 1. So we try */ - /* to use this to our advantage */ - - for (s->maxports = 0; s->maxports < (io_size - 0x10) / 2; s->maxports++) { - unsigned int portstatus; - - portstatus = inw (io_addr + 0x10 + (s->maxports * 2)); - dbg("port %i, adr %x status %x", s->maxports, - io_addr + 0x10 + (s->maxports * 2), portstatus); - if (!(portstatus & 0x0080)) - break; - } - dbg("Detected %d ports", s->maxports); - - /* This is experimental so anything less than 2 or greater than 8 is */ - /* something weird and we'll ignore it */ - if (s->maxports < 2 || s->maxports > 8) { - dbg("Port count misdetected, forcing to 2 ports"); - s->maxports = 2; - } - - s->rh.numports = s->maxports; - - if (init_skel (s)) { - usb_free_bus (bus); - kfree(s); - return -1; - } - - request_region (s->io_addr, io_size, MODNAME); - reset_hc (s); - usb_register_bus (s->bus); - - start_hc (s); - - if (request_irq (irq, uhci_interrupt, SA_SHIRQ, MODNAME, s)) { - err("request_irq %d failed!",irq); - usb_free_bus (bus); - reset_hc (s); - release_region (s->io_addr, s->io_size); - cleanup_skel(s); - kfree(s); - return -1; - } - - s->irq = irq; - - if(uhci_start_usb (s) < 0) { - uhci_cleanup_dev(s); - return -1; - } - - //chain new uhci device into global list - devs = s; - - return 0; -} - -static int __init start_uhci (struct pci_dev *dev) -{ - int i; - - /* Search for the IO base address.. */ - for (i = 0; i < 6; i++) { -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,8) - unsigned int io_addr = dev->resource[i].start; - unsigned int io_size = - dev->resource[i].end - dev->resource[i].start + 1; - if (!(dev->resource[i].flags & 1)) - continue; -#else - unsigned int io_addr = dev->base_address[i]; - unsigned int io_size = 0x14; - if (!(io_addr & 1)) - continue; - io_addr &= ~1; -#endif - - /* Is it already in use? */ - if (check_region (io_addr, io_size)) - break; - /* disable legacy emulation */ - pci_write_config_word (dev, USBLEGSUP, USBLEGSUP_DEFAULT); - - return alloc_uhci(dev->irq, io_addr, io_size); - } - return -1; -} - -#ifdef CONFIG_APM -static int handle_apm_event (apm_event_t event) -{ - static int down = 0; - puhci_t s = devs; - dbg("handle_apm_event(%d)", event); - switch (event) { - case APM_SYS_SUSPEND: - case APM_USER_SUSPEND: - if (down) { - dbg("received extra suspend event"); - break; - } - while (s) { - reset_hc (s); - s = s->next; - } - down = 1; - break; - case APM_NORMAL_RESUME: - case APM_CRITICAL_RESUME: - if (!down) { - dbg("received bogus resume event"); - break; - } - down = 0; - while (s) { - start_hc (s); - s = s->next; - } - break; - } - return 0; -} -#endif - -int __init uhci_init (void) -{ - int retval = -ENODEV; - struct pci_dev *dev = NULL; - u8 type; - int i=0; - -#ifdef _UHCI_SLAB - char *slabname=kmalloc(16, GFP_KERNEL); - - if(!slabname) - return -ENOMEM; - - strcpy(slabname, "uhci_desc"); - uhci_desc_kmem = kmem_cache_create(slabname, sizeof(uhci_desc_t), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); - - if(!uhci_desc_kmem) { - err("kmem_cache_create for uhci_desc failed (out of memory)"); - return -ENOMEM; - } - - slabname=kmalloc(16, GFP_KERNEL); - - if(!slabname) - return -ENOMEM; - - strcpy(slabname, "urb_priv"); - urb_priv_kmem = kmem_cache_create(slabname, sizeof(urb_priv_t), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); - - if(!urb_priv_kmem) { - err("kmem_cache_create for urb_priv_t failed (out of memory)"); - return -ENOMEM; - } -#endif - info(VERSTR); - - for (;;) { - dev = pci_find_class (PCI_CLASS_SERIAL_USB << 8, dev); - if (!dev) - break; - - /* Is it UHCI */ - pci_read_config_byte (dev, PCI_CLASS_PROG, &type); - if (type != 0) - continue; - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,8) - pci_enable_device (dev); -#endif - if(!dev->irq) - { - err("Found UHCI device with no IRQ assigned. Check BIOS settings!"); - continue; - } - - /* Ok set it up */ - retval = start_uhci (dev); - - if (!retval) - i++; - - } - -#ifdef CONFIG_APM - if(i) - apm_register_callback (&handle_apm_event); -#endif - return retval; -} - -void __exit uhci_cleanup (void) -{ - puhci_t s; - while ((s = devs)) { - devs = devs->next; - uhci_cleanup_dev(s); - } -#ifdef _UHCI_SLAB - kmem_cache_shrink(uhci_desc_kmem); - kmem_cache_shrink(urb_priv_kmem); -#endif -} - -#ifdef MODULE -int init_module (void) -{ - return uhci_init (); -} - -void cleanup_module (void) -{ -#ifdef CONFIG_APM - apm_unregister_callback (&handle_apm_event); -#endif - uhci_cleanup (); -} - -#endif //MODULE diff -ur --new-file old/linux/drivers/usb/uhci.h new/linux/drivers/usb/uhci.h --- old/linux/drivers/usb/uhci.h Fri Jan 7 01:17:19 2000 +++ new/linux/drivers/usb/uhci.h Thu Jan 1 01:00:00 1970 @@ -1,251 +0,0 @@ -#ifndef __LINUX_UHCI_H -#define __LINUX_UHCI_H - -/* - $Id: uhci.h,v 1.30 1999/12/15 17:57:25 fliegl Exp $ - */ -#define MODNAME "usb-uhci" -#define VERSTR "version v0.9 time " __TIME__ " " __DATE__ - -/* Command register */ -#define USBCMD 0 -#define USBCMD_RS 0x0001 /* Run/Stop */ -#define USBCMD_HCRESET 0x0002 /* Host reset */ -#define USBCMD_GRESET 0x0004 /* Global reset */ -#define USBCMD_EGSM 0x0008 /* Global Suspend Mode */ -#define USBCMD_FGR 0x0010 /* Force Global Resume */ -#define USBCMD_SWDBG 0x0020 /* SW Debug mode */ -#define USBCMD_CF 0x0040 /* Config Flag (sw only) */ -#define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */ - -/* Status register */ -#define USBSTS 2 -#define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */ -#define USBSTS_ERROR 0x0002 /* Interrupt due to error */ -#define USBSTS_RD 0x0004 /* Resume Detect */ -#define USBSTS_HSE 0x0008 /* Host System Error - basically PCI problems */ -#define USBSTS_HCPE 0x0010 /* Host Controller Process Error - the scripts were buggy */ -#define USBSTS_HCH 0x0020 /* HC Halted */ - -/* Interrupt enable register */ -#define USBINTR 4 -#define USBINTR_TIMEOUT 0x0001 /* Timeout/CRC error enable */ -#define USBINTR_RESUME 0x0002 /* Resume interrupt enable */ -#define USBINTR_IOC 0x0004 /* Interrupt On Complete enable */ -#define USBINTR_SP 0x0008 /* Short packet interrupt enable */ - -#define USBFRNUM 6 -#define USBFLBASEADD 8 -#define USBSOF 12 - -/* USB port status and control registers */ -#define USBPORTSC1 16 -#define USBPORTSC2 18 -#define USBPORTSC_CCS 0x0001 /* Current Connect Status ("device present") */ -#define USBPORTSC_CSC 0x0002 /* Connect Status Change */ -#define USBPORTSC_PE 0x0004 /* Port Enable */ -#define USBPORTSC_PEC 0x0008 /* Port Enable Change */ -#define USBPORTSC_LS 0x0030 /* Line Status */ -#define USBPORTSC_RD 0x0040 /* Resume Detect */ -#define USBPORTSC_LSDA 0x0100 /* Low Speed Device Attached */ -#define USBPORTSC_PR 0x0200 /* Port Reset */ -#define USBPORTSC_SUSP 0x1000 /* Suspend */ - -/* Legacy support register */ -#define USBLEGSUP 0xc0 -#define USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */ - -#define UHCI_NULL_DATA_SIZE 0x7ff /* for UHCI controller TD */ - -#define UHCI_PTR_BITS 0x000F -#define UHCI_PTR_TERM 0x0001 -#define UHCI_PTR_QH 0x0002 -#define UHCI_PTR_DEPTH 0x0004 - -#define UHCI_NUMFRAMES 1024 /* in the frame list [array] */ -#define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ -#define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */ - -/* - * for TD : - */ -#define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */ -#define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */ -#define TD_CTRL_LS (1 << 26) /* Low Speed Device */ -#define TD_CTRL_IOS (1 << 25) /* Isochronous Select */ -#define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */ -#define TD_CTRL_ACTIVE (1 << 23) /* TD Active */ -#define TD_CTRL_STALLED (1 << 22) /* TD Stalled */ -#define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */ -#define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */ -#define TD_CTRL_NAK (1 << 19) /* NAK Received */ -#define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */ -#define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */ -#define TD_CTRL_ACTLEN_MASK 0x7ff /* actual length, encoded as n - 1 */ - -#define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \ - TD_CTRL_BABBLE | TD_CTRL_CRCTIME | TD_CTRL_BITSTUFF) - -#define uhci_status_bits(ctrl_sts) (ctrl_sts & 0xFE0000) -#define uhci_actual_length(ctrl_sts) ((ctrl_sts + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */ -#define uhci_ptr_to_virt(x) bus_to_virt(x & ~UHCI_PTR_BITS) - -/* - * for TD : - */ -#define UHCI_TD_REMOVE 0x0001 /* Remove when done */ - -/* - * for TD : (a.k.a. Token) - */ -#define TD_TOKEN_TOGGLE 19 - -#define uhci_maxlen(token) ((token) >> 21) -#define uhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE) & 1) -#define uhci_endpoint(token) (((token) >> 15) & 0xf) -#define uhci_devaddr(token) (((token) >> 8) & 0x7f) -#define uhci_devep(token) (((token) >> 8) & 0x7ff) -#define uhci_packetid(token) ((token) & 0xff) -#define uhci_packetout(token) (uhci_packetid(token) != USB_PID_IN) -#define uhci_packetin(token) (uhci_packetid(token) == USB_PID_IN) - -/* ------------------------------------------------------------------------------------ - New TD/QH-structures - ------------------------------------------------------------------------------------ */ -typedef enum { - TD_TYPE, QH_TYPE -} uhci_desc_type_t; - -typedef struct { - __u32 link; - __u32 status; - __u32 info; - __u32 buffer; -} uhci_td_t, *puhci_td_t; - -typedef struct { - __u32 head; - __u32 element; /* Queue element pointer */ -} uhci_qh_t, *puhci_qh_t; - -typedef struct { - union { - uhci_td_t td; - uhci_qh_t qh; - } hw; - uhci_desc_type_t type; - struct list_head horizontal; - struct list_head vertical; - struct list_head desc_list; -} uhci_desc_t, *puhci_desc_t; - -typedef struct { - struct list_head desc_list; // list pointer to all corresponding TDs/QHs associated with this request - int short_control_packet; -} urb_priv_t, *purb_priv_t; - -struct virt_root_hub { - int devnum; /* Address of Root Hub endpoint */ - void *urb; - void *int_addr; - int send; - int interval; - int numports; - int c_p_r[8]; - struct timer_list rh_int_timer; -}; - -typedef struct uhci { - int irq; - unsigned int io_addr; - unsigned int io_size; - unsigned int maxports; - - int apm_state; - - struct uhci *next; // chain of uhci device contexts - - struct list_head urb_list; // list of all pending urbs - - spinlock_t urb_list_lock; // lock to keep consistency - - struct usb_bus *bus; // our bus - - spinlock_t unlink_urb_lock; // lock for unlink_urb - - __u32 *framelist; - uhci_desc_t **iso_td; - uhci_desc_t *int_chain[8]; - uhci_desc_t *control_chain; - uhci_desc_t *bulk_chain; - uhci_desc_t *chain_end; - spinlock_t qh_lock; - spinlock_t td_lock; - struct virt_root_hub rh; //private data of the virtual root hub -} uhci_t, *puhci_t; - - -#define MAKE_TD_ADDR(a) (virt_to_bus(a)&~UHCI_PTR_QH) -#define MAKE_QH_ADDR(a) (virt_to_bus(a)|UHCI_PTR_QH) -#define UHCI_GET_CURRENT_FRAME(uhci) (inw ((uhci)->io_addr + USBFRNUM)) - -/* ------------------------------------------------------------------------------------ - Virtual Root HUB - ------------------------------------------------------------------------------------ */ -/* destination of request */ -#define RH_INTERFACE 0x01 -#define RH_ENDPOINT 0x02 -#define RH_OTHER 0x03 - -#define RH_CLASS 0x20 -#define RH_VENDOR 0x40 - -/* Requests: bRequest << 8 | bmRequestType */ -#define RH_GET_STATUS 0x0080 -#define RH_CLEAR_FEATURE 0x0100 -#define RH_SET_FEATURE 0x0300 -#define RH_SET_ADDRESS 0x0500 -#define RH_GET_DESCRIPTOR 0x0680 -#define RH_SET_DESCRIPTOR 0x0700 -#define RH_GET_CONFIGURATION 0x0880 -#define RH_SET_CONFIGURATION 0x0900 -#define RH_GET_STATE 0x0280 -#define RH_GET_INTERFACE 0x0A80 -#define RH_SET_INTERFACE 0x0B00 -#define RH_SYNC_FRAME 0x0C80 -/* Our Vendor Specific Request */ -#define RH_SET_EP 0x2000 - - -/* Hub port features */ -#define RH_PORT_CONNECTION 0x00 -#define RH_PORT_ENABLE 0x01 -#define RH_PORT_SUSPEND 0x02 -#define RH_PORT_OVER_CURRENT 0x03 -#define RH_PORT_RESET 0x04 -#define RH_PORT_POWER 0x08 -#define RH_PORT_LOW_SPEED 0x09 -#define RH_C_PORT_CONNECTION 0x10 -#define RH_C_PORT_ENABLE 0x11 -#define RH_C_PORT_SUSPEND 0x12 -#define RH_C_PORT_OVER_CURRENT 0x13 -#define RH_C_PORT_RESET 0x14 - -/* Hub features */ -#define RH_C_HUB_LOCAL_POWER 0x00 -#define RH_C_HUB_OVER_CURRENT 0x01 - -#define RH_DEVICE_REMOTE_WAKEUP 0x00 -#define RH_ENDPOINT_STALL 0x01 - -/* Our Vendor Specific feature */ -#define RH_REMOVE_EP 0x00 - - -#define RH_ACK 0x01 -#define RH_REQ_ERR -1 -#define RH_NACK 0x00 - -#define min(a,b) (((a)<(b))?(a):(b)) - -#endif diff -ur --new-file old/linux/drivers/usb/usb-core.c new/linux/drivers/usb/usb-core.c --- old/linux/drivers/usb/usb-core.c Fri Jan 21 00:00:16 2000 +++ new/linux/drivers/usb/usb-core.c Thu Jan 27 16:40:16 2000 @@ -32,6 +32,7 @@ int usb_acm_init(void); int usb_audio_init(void); int usb_cpia_init(void); +int usb_ibmcam_init(void); int usb_ov511_init(void); int usb_dc2xx_init(void); int usb_scanner_init(void); @@ -98,13 +99,16 @@ #ifdef CONFIG_USB_CPIA usb_cpia_init(); #endif +#ifdef CONFIG_USB_IBMCAM + usb_ibmcam_init(); +#endif #ifdef CONFIG_USB_OV511 usb_ov511_init(); #endif #ifdef CONFIG_USB_DC2XX usb_dc2xx_init(); #endif -#ifdef CONFIG_USB_SCSI +#ifdef CONFIG_USB_STORAGE usb_stor_init(); #endif #ifdef CONFIG_USB_DABUSB @@ -128,7 +132,7 @@ #ifdef CONFIG_USB_UHCI uhci_init(); #endif -#ifdef CONFIG_USB_OHCI_HCD +#ifdef CONFIG_USB_OHCI ohci_hcd_init(); #endif #endif diff -ur --new-file old/linux/drivers/usb/usb-debug.c new/linux/drivers/usb/usb-debug.c --- old/linux/drivers/usb/usb-debug.c Tue Jan 18 01:24:48 2000 +++ new/linux/drivers/usb/usb-debug.c Fri Jan 28 01:40:53 2000 @@ -6,8 +6,8 @@ */ #include #include -#include - +#include +#include #define DEBUG #include "usb.h" @@ -59,6 +59,11 @@ */ void usb_show_device_descriptor(struct usb_device_descriptor *desc) { + if (!desc) + { + printk("Invalid USB device descriptor (NULL POINTER)\n"); + return; + } printk(" Length = %2d%s\n", desc->bLength, desc->bLength == USB_DT_DEVICE_SIZE ? "" : " (!!!)"); printk(" DescriptorType = %02x\n", desc->bDescriptorType); @@ -160,10 +165,32 @@ { char *buf; + if (!index) + return; if (!(buf = kmalloc(256, GFP_KERNEL))) return; if (usb_string(dev, index, buf, 256) > 0) printk(KERN_INFO "%s: %s\n", id, buf); kfree(buf); +} + +void usb_dump_urb (purb_t purb) +{ + printk ("urb :%p\n", purb); + printk ("next :%p\n", purb->next); + printk ("dev :%p\n", purb->dev); + printk ("pipe :%08X\n", purb->pipe); + printk ("status :%d\n", purb->status); + printk ("transfer_flags :%08X\n", purb->transfer_flags); + printk ("transfer_buffer :%p\n", purb->transfer_buffer); + printk ("transfer_buffer_length:%d\n", purb->transfer_buffer_length); + printk ("actual_length :%d\n", purb->actual_length); + printk ("setup_packet :%p\n", purb->setup_packet); + printk ("start_frame :%d\n", purb->start_frame); + printk ("number_of_packets :%d\n", purb->number_of_packets); + printk ("interval :%d\n", purb->interval); + printk ("error_count :%d\n", purb->error_count); + printk ("context :%p\n", purb->context); + printk ("complete :%p\n", purb->complete); } diff -ur --new-file old/linux/drivers/usb/usb-ohci.c new/linux/drivers/usb/usb-ohci.c --- old/linux/drivers/usb/usb-ohci.c Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/usb/usb-ohci.c Mon Jan 24 07:39:14 2000 @@ -0,0 +1,1822 @@ +/* + * URB OHCI HCD (Host Controller Driver) for USB. + * + * (C) Copyright 1999 Roman Weissgaerber + * + * [ Initialisation is based on Linus' ] + * [ uhci code and gregs ohci fragments ] + * [ (C) Copyright 1999 Linus Torvalds ] + * [ (C) Copyright 1999 Gregory P. Smith] + * + * + * History: + * + * v5.2 1999/12/07 URB 3rd preview, + * v5.1 1999/11/30 URB 2nd preview, cpia, (usb-scsi) + * v5.0 1999/11/22 URB Technical preview, Paul Mackerras powerbook susp/resume + * i386: HUB, Keyboard, Mouse, Printer + * + * v4.3 1999/10/27 multiple HCs, bulk_request + * v4.2 1999/09/05 ISO API alpha, new dev alloc, neg Error-codes + * v4.1 1999/08/27 Randy Dunlap's - ISO API first impl. + * v4.0 1999/08/18 + * v3.0 1999/06/25 + * v2.1 1999/05/09 code clean up + * v2.0 1999/05/04 + * v1.0 1999/04/27 initial release + * + + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for in_interrupt() */ + +#include +#include +#include + +#undef DEBUG +#define OHCI_USE_NPS + +#include "usb.h" +#include "usb-ohci.h" + +#ifdef CONFIG_APM +#include +static int handle_apm_event (apm_event_t event); +#endif + +#ifdef CONFIG_PMAC_PBOOK +#include +#include +#endif + +static DECLARE_WAIT_QUEUE_HEAD (op_wakeup); +static LIST_HEAD (ohci_hcd_list); +spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED; + +/*-------------------------------------------------------------------------* + * URB support functions + *-------------------------------------------------------------------------*/ + +/* free the private part of an URB */ + +static void urb_rm_priv (urb_t * urb) +{ + urb_priv_t * urb_priv = urb->hcpriv; + int i; + void * wait; + + if (!urb_priv) return; + + wait = urb_priv->wait; + + for (i = 0; i < urb_priv->length; i++) { + if (urb_priv->td [i]) { + OHCI_FREE (urb_priv->td [i]); + } + } + kfree (urb->hcpriv); + urb->hcpriv = NULL; + + if (wait) { + add_wait_queue (&op_wakeup, wait); + wake_up (&op_wakeup); + } +} + +/*-------------------------------------------------------------------------*/ + +#ifdef DEBUG +static int sohci_get_current_frame_number (struct usb_device * dev); + +/* debug| print the main components of an URB + * small: 0) header + data packets 1) just header */ + +static void urb_print (urb_t * urb, char * str, int small) +{ + unsigned int pipe= urb->pipe; + int i, len; + + if (!urb->dev || !urb->dev->bus) { + dbg("%s URB: no dev", str); + return; + } + + dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,flags:%4x,len:%d/%d,stat:%d(%x)", + str, + sohci_get_current_frame_number (urb->dev), + usb_pipedevice (pipe), + usb_pipeendpoint (pipe), + usb_pipeout (pipe)? 'O': 'I', + usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"): + (usb_pipecontrol (pipe)? "CTRL": "BULK"), + urb->transfer_flags, + urb->actual_length, + urb->transfer_buffer_length, + urb->status, urb->status); + if (!small) { + if (usb_pipecontrol (pipe)) { + printk (KERN_DEBUG __FILE__ ": cmd(8):"); + for (i = 0; i < 8 ; i++) + printk (" %02x", ((__u8 *) urb->setup_packet) [i]); + printk ("\n"); + } + if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) { + printk (KERN_DEBUG __FILE__ ": data(%d/%d):", + urb->actual_length, + urb->transfer_buffer_length); + len = usb_pipeout (pipe)? + urb->transfer_buffer_length: urb->actual_length; + for (i = 0; i < 16 && i < len; i++) + printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]); + printk ("%s stat:%d\n", i < len? "...": "", urb->status); + } + } + +} +/* just for debugging; prints all 32 branches of the int ed tree inclusive iso eds*/ +void ep_print_int_eds (ohci_t * ohci, char * str) { + int i, j; + __u32 * ed_p; + for (i= 0; i < 32; i++) { + j = 5; + printk (KERN_DEBUG __FILE__ " %s branch int %2d(%2x):", str, i, i); + ed_p = &(ohci->hcca.int_table [i]); + while (*ed_p != 0 && j--) { + ed_t *ed = (ed_t *) bus_to_virt(le32_to_cpup(ed_p)); + printk (" ed: %4x;", ed->hwINFO); + ed_p = &ed->hwNextED; + } + printk ("\n"); + } +} + + +#endif + +/*-------------------------------------------------------------------------* + * Interface functions (URB) + *-------------------------------------------------------------------------*/ + +/* return a request to the completion handler */ + +static int sohci_return_urb (urb_t * urb) +{ + urb_priv_t * urb_priv = urb->hcpriv; + urb_t * urbt; + unsigned long flags; + int i; + + /* just to be sure */ + if (!urb->complete) { + urb_rm_priv (urb); + usb_dec_dev_use (urb->dev); + return -1; + } + + if (!urb_priv) return -1; /* urb already unlinked */ + +#ifdef DEBUG + urb_print (urb, "RET", usb_pipeout (urb->pipe)); +#endif + + switch (usb_pipetype (urb->pipe)) { + case PIPE_INTERRUPT: + urb->complete (urb); /* call complete and requeue URB */ + urb->actual_length = 0; + urb->status = USB_ST_URB_PENDING; + if (urb_priv->state != URB_DEL) + td_submit_urb (urb); + break; + + case PIPE_ISOCHRONOUS: + for (urbt = urb->next; urbt && (urbt != urb); urbt = urbt->next); + if (urbt) { /* send the reply and requeue URB */ + urb->complete (urb); + + spin_lock_irqsave (&usb_ed_lock, flags); + urb->actual_length = 0; + urb->status = USB_ST_URB_PENDING; + urb->start_frame = urb_priv->ed->last_iso + 1; + if (urb_priv->state != URB_DEL) { + for (i = 0; i < urb->number_of_packets; i++) { + urb->iso_frame_desc[i].actual_length = 0; + urb->iso_frame_desc[i].status = -EXDEV; + } + td_submit_urb (urb); + } + spin_unlock_irqrestore (&usb_ed_lock, flags); + + } else { /* unlink URB, call complete */ + urb_rm_priv (urb); + usb_dec_dev_use (urb->dev); + urb->complete (urb); + } + break; + + case PIPE_BULK: + case PIPE_CONTROL: /* unlink URB, call complete */ + urb_rm_priv (urb); + usb_dec_dev_use (urb->dev); + urb->complete (urb); + break; + } + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* get a transfer request */ + +static int sohci_submit_urb (urb_t * urb) +{ + ohci_t * ohci; + ed_t * ed; + urb_priv_t * urb_priv; + unsigned int pipe = urb->pipe; + int i, size = 0; + unsigned long flags; + + if (!urb->dev || !urb->dev->bus) return -EINVAL; + + if (urb->hcpriv) return -EINVAL; /* urb already in use */ + + usb_inc_dev_use (urb->dev); + ohci = (ohci_t *) urb->dev->bus->hcpriv; + +#ifdef DEBUG + urb_print (urb, "SUB", usb_pipein (pipe)); +#endif + + if (usb_pipedevice (pipe) == ohci->rh.devnum) + return rh_submit_urb (urb); /* a request to the virtual root hub */ + + /* every endpoint has a ed, locate and fill it */ + if (!(ed = ep_add_ed (urb->dev, pipe, urb->interval, 1))) { + usb_dec_dev_use (urb->dev); + return -ENOMEM; + } + + /* for the private part of the URB we need the number of TDs (size) */ + switch (usb_pipetype (pipe)) { + case PIPE_BULK: /* one TD for every 4096 Byte */ + size = (urb->transfer_buffer_length - 1) / 4096 + 1; + break; + case PIPE_ISOCHRONOUS: /* number of packets from URB */ + size = urb->number_of_packets; + for (i = 0; i < urb->number_of_packets; i++) { + urb->iso_frame_desc[i].actual_length = 0; + urb->iso_frame_desc[i].status = -EXDEV; + } + break; + case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */ + size = (urb->transfer_buffer_length == 0)? 2: + (urb->transfer_buffer_length - 1) / 4096 + 3; + break; + case PIPE_INTERRUPT: /* one TD */ + size = 1; + + break; + } + + /* allocate the private part or the URB */ + urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), + in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + if (!urb_priv) { + usb_dec_dev_use (urb->dev); + return -ENOMEM; + } + memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (td_t *)); + + /* fill the private part of the URB */ + urb->hcpriv = urb_priv; + urb_priv->length = size; + urb_priv->td_cnt = 0; + urb_priv->state = 0; + urb_priv->ed = ed; + urb_priv->wait = NULL; + + /* allocate the TDs */ + for (i = 0; i < size; i++) { + OHCI_ALLOC (urb_priv->td[i], sizeof (td_t)); + if (!urb_priv->td[i]) { + usb_dec_dev_use (urb->dev); + urb_rm_priv (urb); + return -ENOMEM; + } + } + spin_lock_irqsave (&usb_ed_lock, flags); + if (ed->state == ED_NEW || (ed->state & ED_DEL)) { + urb_rm_priv(urb); + usb_dec_dev_use (urb->dev); + return -EINVAL; + } + + /* for ISOC transfers calculate start frame index */ + if (urb->transfer_flags & USB_ISO_ASAP) { + urb->start_frame = ((ed->state == ED_OPER)? (ed->last_iso + 1): + (le16_to_cpu (ohci->hcca.frame_no) + 10)) & 0xffff; + } + + td_submit_urb (urb); /* fill the TDs and link it to the ed */ + + if (ed->state != ED_OPER) /* link the ed into a chain if is not already */ + ep_link (ohci, ed); + spin_unlock_irqrestore (&usb_ed_lock, flags); + + urb->status = USB_ST_URB_PENDING; + // queue_urb(s, &urb->urb_list); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* deactivate all TDs and remove the private part of the URB */ + +static int sohci_unlink_urb (urb_t * urb) +{ + unsigned long flags; + ohci_t * ohci; + DECLARE_WAITQUEUE (wait, current); + + if (!urb) /* just to be sure */ + return -EINVAL; + +#ifdef DEBUG + urb_print (urb, "UNLINK", 1); +#endif + + ohci = (ohci_t *) urb->dev->bus->hcpriv; + + if (usb_pipedevice (urb->pipe) == ohci->rh.devnum) + return rh_unlink_urb (urb); /* a request to the virtual root hub */ + + if (urb->hcpriv) { + if (urb->status == USB_ST_URB_PENDING) { /* URB active? */ + urb_priv_t * urb_priv = urb->hcpriv; + urb_priv->state = URB_DEL; + /* we want to delete the TDs of an URB from an ed + * request the deletion, it will be handled at the next USB-frame */ + urb_priv->wait = &wait; + + spin_lock_irqsave (&usb_ed_lock, flags); + ep_rm_ed (urb->dev, urb_priv->ed); + urb_priv->ed->state |= ED_URB_DEL; + spin_unlock_irqrestore (&usb_ed_lock, flags); + + current->state = TASK_UNINTERRUPTIBLE; + if(schedule_timeout (HZ / 10)) /* wait until all TDs are deleted */ + remove_wait_queue (&op_wakeup, &wait); + else + err("unlink URB timeout!"); + } else + urb_rm_priv (urb); + usb_dec_dev_use (urb->dev); + } + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* allocate private data space for a usb device */ + +static int sohci_alloc_dev (struct usb_device *usb_dev) +{ + struct ohci_device * dev; + + dev = kmalloc (sizeof (*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + memset (dev, 0, sizeof (*dev)); + + usb_dev->hcpriv = dev; + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* free private data space of usb device */ + +static int sohci_free_dev (struct usb_device * usb_dev) +{ + unsigned long flags; + int i, cnt = 0; + ed_t * ed; + DECLARE_WAITQUEUE (wait, current); + struct ohci_device * dev = usb_to_ohci (usb_dev); + ohci_t * ohci = usb_dev->bus->hcpriv; + + if (!dev) return 0; + + if (usb_dev->devnum >= 0) { + + /* delete all TDs of all EDs */ + spin_lock_irqsave (&usb_ed_lock, flags); + for(i = 0; i < NUM_EDS; i++) { + ed = &(dev->ed[i]); + if (ed->state != ED_NEW) { + if (ed->state == ED_OPER) ep_unlink (ohci, ed); + ep_rm_ed (usb_dev, ed); + ed->state = ED_DEL; + cnt++; + } + } + spin_unlock_irqrestore (&usb_ed_lock, flags); + + if (cnt > 0) { + dev->wait = &wait; + current->state = TASK_UNINTERRUPTIBLE; + schedule_timeout (HZ / 10); + remove_wait_queue (&op_wakeup, &wait); + } + } + kfree (dev); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* tell us the current USB frame number */ + +static int sohci_get_current_frame_number (struct usb_device *usb_dev) +{ + ohci_t * ohci = usb_dev->bus->hcpriv; + + return le16_to_cpu (ohci->hcca.frame_no); +} + +/*-------------------------------------------------------------------------*/ + +struct usb_operations sohci_device_operations = { + sohci_alloc_dev, + sohci_free_dev, + sohci_get_current_frame_number, + sohci_submit_urb, + sohci_unlink_urb +}; + +/*-------------------------------------------------------------------------* + * ED handling functions + *-------------------------------------------------------------------------*/ + +/* search for the right branch to insert an interrupt ed into the int tree + * do some load ballancing; + * returns the branch and + * sets the interval to interval = 2^integer (ld (interval)) */ + +static int ep_int_ballance (ohci_t * ohci, int interval, int load) +{ + int i, branch = 0; + + /* search for the least loaded interrupt endpoint branch of all 32 branches */ + for (i = 0; i < 32; i++) + if (ohci->ohci_int_load [branch] > ohci->ohci_int_load [i]) branch = i; + + branch = branch % interval; + for (i = branch; i < 32; i += interval) ohci->ohci_int_load [i] += load; + + return branch; +} + +/*-------------------------------------------------------------------------*/ + +/* 2^int( ld (inter)) */ + +static int ep_2_n_interval (int inter) +{ + int i; + for (i = 0; ((inter >> i) > 1 ) && (i < 5); i++); + return 1 << i; +} + +/*-------------------------------------------------------------------------*/ + +/* the int tree is a binary tree + * in order to process it sequentially the indexes of the branches have to be mapped + * the mapping reverses the bits of a word of num_bits length */ + +static int ep_rev (int num_bits, int word) +{ + int i, wout = 0; + + for (i = 0; i < num_bits; i++) wout |= (((word >> i) & 1) << (num_bits - i - 1)); + return wout; +} + +/*-------------------------------------------------------------------------*/ + +/* link an ed into one of the HC chains */ + +static int ep_link (ohci_t * ohci, ed_t * edi) +{ + int int_branch; + int i; + int inter; + int interval; + int load; + __u32 * ed_p; + volatile ed_t * ed = edi; + + ed->state = ED_OPER; + + switch (ed->type) { + case CTRL: + ed->hwNextED = 0; + if (ohci->ed_controltail == NULL) { + writel (virt_to_bus (ed), &ohci->regs->ed_controlhead); + } else { + ohci->ed_controltail->hwNextED = cpu_to_le32 (virt_to_bus (ed)); + } + ed->ed_prev = ohci->ed_controltail; + ohci->ed_controltail = edi; + break; + + case BULK: + ed->hwNextED = 0; + if (ohci->ed_bulktail == NULL) { + writel (virt_to_bus (ed), &ohci->regs->ed_bulkhead); + } else { + ohci->ed_bulktail->hwNextED = cpu_to_le32 (virt_to_bus (ed)); + } + ed->ed_prev = ohci->ed_bulktail; + ohci->ed_bulktail = edi; + break; + + case INT: + load = ed->int_load; + interval = ep_2_n_interval (ed->int_period); + ed->int_interval = interval; + int_branch = ep_int_ballance (ohci, interval, load); + ed->int_branch = int_branch; + + for (i = 0; i < ep_rev (6, interval); i += inter) { + inter = 1; + for (ed_p = &(ohci->hcca.int_table[ep_rev (5, i) + int_branch]); + (*ed_p != 0) && (((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval >= interval); + ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED)) + inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval); + ed->hwNextED = *ed_p; + *ed_p = cpu_to_le32 (virt_to_bus (ed)); + } +#ifdef DEBUG + ep_print_int_eds (ohci, "LINK_INT"); +#endif + break; + + case ISO: + ed->hwNextED = 0; + ed->int_interval = 1; + if (ohci->ed_isotail != NULL) { + ohci->ed_isotail->hwNextED = cpu_to_le32 (virt_to_bus (ed)); + ed->ed_prev = ohci->ed_isotail; + } else { + for ( i = 0; i < 32; i += inter) { + inter = 1; + for (ed_p = &(ohci->hcca.int_table[ep_rev (5, i)]); + *ed_p != 0; + ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED)) + inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval); + *ed_p = cpu_to_le32 (virt_to_bus (ed)); + } + ed->ed_prev = NULL; + } + ohci->ed_isotail = edi; +#ifdef DEBUG + ep_print_int_eds (ohci, "LINK_ISO"); +#endif + break; + } + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* unlink an ed from one of the HC chains. + * just the link to the ed is unlinked. + * the link from the ed still points to another operational ed or 0 + * so the HC can eventually finish the processing of the unlinked ed */ + +static int ep_unlink (ohci_t * ohci, ed_t * ed) +{ + int int_branch; + int i; + int inter; + int interval; + __u32 * ed_p; + + + switch (ed->type) { + case CTRL: + if (ed->ed_prev == NULL) { + writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_controlhead); + } else { + ed->ed_prev->hwNextED = ed->hwNextED; + } + if(ohci->ed_controltail == ed) { + ohci->ed_controltail = ed->ed_prev; + } else { + ((ed_t *) bus_to_virt (le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev; + } + break; + + case BULK: + if (ed->ed_prev == NULL) { + writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_bulkhead); + } else { + ed->ed_prev->hwNextED = ed->hwNextED; + } + if (ohci->ed_bulktail == ed) { + ohci->ed_bulktail = ed->ed_prev; + } else { + ((ed_t *) bus_to_virt (le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev; + } + break; + + case INT: + int_branch = ed->int_branch; + interval = ed->int_interval; + + for (i = 0; i < ep_rev (6, interval); i += inter) { + for (ed_p = &(ohci->hcca.int_table[ep_rev (5, i) + int_branch]), inter = 1; + (*ed_p != 0) && (*ed_p != ed->hwNextED); + ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED), + inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval)) { + if(((ed_t *) bus_to_virt (le32_to_cpup (ed_p))) == ed) { + *ed_p = ed->hwNextED; + break; + } + } + } + for (i = int_branch; i < 32; i += interval) ohci->ohci_int_load[i] -= ed->int_load; +#ifdef DEBUG + ep_print_int_eds (ohci, "UNLINK_INT"); +#endif break; + + case ISO: + if (ohci->ed_isotail == ed) + ohci->ed_isotail = ed->ed_prev; + if (ed->hwNextED != 0) + ((ed_t *) bus_to_virt (le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev; + + if (ed->ed_prev != NULL) { + ed->ed_prev->hwNextED = ed->hwNextED; + } else { + for (i = 0; i < 32; i += inter) { + inter = 1; + for (ed_p = &(ohci->hcca.int_table[ep_rev (5, i)]); + *ed_p != 0; + ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED)) { + inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval); + if(((ed_t *) bus_to_virt (le32_to_cpup (ed_p))) == ed) { + *ed_p = ed->hwNextED; + break; + } + } + } + } +#ifdef DEBUG + ep_print_int_eds (ohci, "UNLINK_ISO"); +#endif + break; + } + ed->state = ED_UNLINK; + return 0; +} + + +/*-------------------------------------------------------------------------*/ + +/* add/reinit an endpoint; this should be done once at the usb_set_configuration command, + * but the USB stack is a little bit stateless so we do it at every transaction + * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK + * in all other cases the state is left unchanged + * the ed info fields are setted anyway even though most of them should not change */ + +static ed_t * ep_add_ed (struct usb_device * usb_dev, unsigned int pipe, int interval, int load) +{ + ohci_t * ohci = usb_dev->bus->hcpriv; + td_t * td; + ed_t * ed_ret; + volatile ed_t * ed; + + + spin_lock (&usb_ed_lock); + + ed = ed_ret = &(usb_to_ohci (usb_dev)->ed[(usb_pipeendpoint (pipe) << 1) | + (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))]); + + if((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) + return NULL; /* pending delete request */ + + if (ed->state == ED_NEW) { + ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); /* skip ed */ + OHCI_ALLOC (td, sizeof (*td)); /* dummy td; end of td list for ed */ + if(!td) return NULL; /* out of memory */ + ed->hwTailP = cpu_to_le32 (virt_to_bus (td)); + ed->hwHeadP = ed->hwTailP; + ed->state = ED_UNLINK; + ed->type = usb_pipetype (pipe); + usb_to_ohci (usb_dev)->ed_cnt++; + } + + ohci->dev[usb_pipedevice (pipe)] = usb_dev; + + ed->hwINFO = cpu_to_le32 (usb_pipedevice (pipe) + | usb_pipeendpoint (pipe) << 7 + | (usb_pipeisoc (pipe)? 0x8000: 0) + | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000)) + | usb_pipeslow (pipe) << 13 + | usb_maxpacket (usb_dev, pipe, usb_pipeout (pipe)) << 16); + + if (ed->type == INT && ed->state == ED_UNLINK) { + ed->int_period = interval; + ed->int_load = load; + } + + spin_unlock(&usb_ed_lock); + return ed_ret; +} + +/*-------------------------------------------------------------------------*/ + +/* request the removal of an endpoint + * put the ep on the rm_list and request a stop of the bulk or ctrl list + * real removal is done at the next start of frame (SOF) hardware interrupt */ + +static void ep_rm_ed (struct usb_device * usb_dev, ed_t * ed) +{ + unsigned int frame; + ohci_t * ohci = usb_dev->bus->hcpriv; + + if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) return; + + ed->hwINFO |= cpu_to_le32 (OHCI_ED_SKIP); + + writel (OHCI_INTR_SF, &ohci->regs->intrstatus); + writel (OHCI_INTR_SF, &ohci->regs->intrenable); /* enable sof interrupt */ + + frame = le16_to_cpu (ohci->hcca.frame_no) & 0x1; + ed->ed_rm_list = ohci->ed_rm_list[frame]; + ohci->ed_rm_list[frame] = ed; + + switch (ed->type) { + case CTRL: /* stop CTRL list */ + writel (ohci->hc_control &= ~(0x01 << 4), &ohci->regs->control); + break; + case BULK: /* stop BULK list */ + writel (ohci->hc_control &= ~(0x01 << 5), &ohci->regs->control); + break; + } +} + +/*-------------------------------------------------------------------------* + * TD handling functions + *-------------------------------------------------------------------------*/ + +/* prepare a TD */ + +static void td_fill (unsigned int info, void * data, int len, urb_t * urb, int type, int index) +{ + volatile td_t * td, * td_pt; + urb_priv_t * urb_priv = urb->hcpriv; + + if (index >= urb_priv->length) { + err("internal OHCI error: TD index > length"); + return; + } + + td_pt = urb_priv->td [index]; + /* fill the old dummy TD */ + td = urb_priv->td [index] = (td_t *) bus_to_virt (le32_to_cpup (&urb_priv->ed->hwTailP) & 0xfffffff0); + td->ed = urb_priv->ed; + td->index = index; + td->urb = urb; + td->hwINFO = cpu_to_le32 (info); + td->type = type; + if ((td->ed->type & 3) == PIPE_ISOCHRONOUS) { + td->hwCBP = cpu_to_le32 (((!data || !len)? + 0 : virt_to_bus (data)) & 0xFFFFF000); + td->ed->last_iso = info & 0xffff; + } else { + td->hwCBP = cpu_to_le32 (((!data || !len)? 0 : virt_to_bus (data))); + } + td->hwBE = cpu_to_le32 ((!data || !len )? 0: virt_to_bus (data + len - 1)); + td->hwNextTD = cpu_to_le32 (virt_to_bus (td_pt)); + td->hwPSW [0] = cpu_to_le16 ((virt_to_bus (data) & 0x0FFF) | 0xE000); + td_pt->hwNextTD = 0; + td->ed->hwTailP = td->hwNextTD; + + td->next_dl_td = NULL; //td_pt; +} + +/*-------------------------------------------------------------------------*/ + +/* prepare all TDs of a transfer */ + +static void td_submit_urb (urb_t * urb) +{ + urb_priv_t * urb_priv = urb->hcpriv; + ohci_t * ohci = (ohci_t *) urb->dev->bus->hcpriv; + void * ctrl = urb->setup_packet; + void * data = urb->transfer_buffer; + int data_len = urb->transfer_buffer_length; + int cnt = 0; + __u32 info = 0; + + + urb_priv->td_cnt = 0; + + switch (usb_pipetype (urb->pipe)) { + case PIPE_BULK: + info = usb_pipeout (urb->pipe)? + TD_CC | TD_DP_OUT | TD_T_TOGGLE: TD_CC | TD_DP_IN | TD_T_TOGGLE; + while(data_len > 4096) { + td_fill (info, data, 4096, urb, (cnt? 0: ST_ADDR) | ADD_LEN, cnt); + data += 4096; data_len -= 4096; cnt++; + } + info = usb_pipeout (urb->pipe)? + TD_CC | TD_DP_OUT | TD_T_TOGGLE: TD_CC | TD_R | TD_DP_IN | TD_T_TOGGLE; + td_fill (info, data, data_len, urb, (cnt? 0: ST_ADDR) | ADD_LEN, cnt); + cnt++; + writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ + break; + + case PIPE_INTERRUPT: + info = usb_pipeout (urb->pipe)? + TD_CC | TD_DP_OUT | TD_T_TOGGLE: TD_CC | TD_R | TD_DP_IN | TD_T_TOGGLE; + td_fill (info, data, data_len, urb, ST_ADDR | ADD_LEN, cnt++); + break; + + case PIPE_CONTROL: + info = TD_CC | TD_DP_SETUP | TD_T_DATA0; + td_fill (info, ctrl, 8, urb, ST_ADDR, cnt++); + if (data_len > 0) { + info = usb_pipeout (urb->pipe)? + TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1; + td_fill (info, data, data_len, urb, ADD_LEN, cnt++); + } + info = usb_pipeout (urb->pipe)? + TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1; + td_fill (info, NULL, 0, urb, 0, cnt++); + writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */ + break; + + case PIPE_ISOCHRONOUS: + for (cnt = 0; cnt < urb->number_of_packets; cnt++) { + td_fill (TD_CC|TD_ISO | ((urb->start_frame + cnt) & 0xffff), + (__u8 *) data + urb->iso_frame_desc[cnt].offset, + urb->iso_frame_desc[cnt].length, urb, (cnt? 0: ST_ADDR) | ADD_LEN, cnt); + } + break; + } + if (urb_priv->length != cnt) + dbg("TD LENGTH %d != CNT %d", urb_priv->length, cnt); +} + +/*-------------------------------------------------------------------------* + * Done List handling functions + *-------------------------------------------------------------------------*/ + +/* replies to the request have to be on a FIFO basis so + * we reverse the reversed done-list */ + +static td_t * dl_reverse_done_list (ohci_t * ohci) +{ + __u32 td_list_hc; + td_t * td_rev = NULL; + td_t * td_list = NULL; + urb_priv_t * urb_priv = NULL; + unsigned long flags; + + spin_lock_irqsave (&usb_ed_lock, flags); + + td_list_hc = le32_to_cpup (&ohci->hcca.done_head) & 0xfffffff0; + ohci->hcca.done_head = 0; + + while (td_list_hc) { + td_list = (td_t *) bus_to_virt (td_list_hc); + + if (TD_CC_GET (le32_to_cpup (&td_list->hwINFO))) { + urb_priv = (urb_priv_t *) td_list->urb->hcpriv; + dbg(" USB-error/status: %x : %p", + TD_CC_GET (le32_to_cpup (&td_list->hwINFO)), td_list); + if (td_list->ed->hwHeadP & cpu_to_le32 (0x1)) { + if (urb_priv && ((td_list->index + 1) < urb_priv->length)) { + td_list->ed->hwHeadP = + (urb_priv->td[urb_priv->length - 1]->hwNextTD & cpu_to_le32 (0xfffffff0)) | + (td_list->ed->hwHeadP & cpu_to_le32 (0x2)); + urb_priv->td_cnt += urb_priv->length - td_list->index - 1; + } else + td_list->ed->hwHeadP &= cpu_to_le32 (0xfffffff2); + } + } + + td_list->next_dl_td = td_rev; + td_rev = td_list; + td_list_hc = le32_to_cpup (&td_list->hwNextTD) & 0xfffffff0; + } + spin_unlock_irqrestore (&usb_ed_lock, flags); + return td_list; +} + +/*-------------------------------------------------------------------------*/ + +/* there are some pending requests to remove + * - some of the eds (if ed->state & ED_DEL (set by sohci_free_dev) + * - some URBs/TDs if urb_priv->state == URB_DEL */ + +static void dl_del_list (ohci_t * ohci, unsigned int frame) +{ + unsigned long flags; + ed_t * ed; + __u32 edINFO; + td_t * td = NULL, * td_next = NULL, * tdHeadP = NULL, * tdTailP; + __u32 * td_p; + int ctrl = 0, bulk = 0; + + spin_lock_irqsave (&usb_ed_lock, flags); + for (ed = ohci->ed_rm_list[frame]; ed != NULL; ed = ed->ed_rm_list) { + + tdTailP = bus_to_virt (le32_to_cpup (&ed->hwTailP) & 0xfffffff0); + tdHeadP = bus_to_virt (le32_to_cpup (&ed->hwHeadP) & 0xfffffff0); + edINFO = le32_to_cpup (&ed->hwINFO); + td_p = &ed->hwHeadP; + + for (td = tdHeadP; td != tdTailP; td = td_next) { + urb_t * urb = td->urb; + urb_priv_t * urb_priv = td->urb->hcpriv; + + td_next = bus_to_virt (le32_to_cpup (&td->hwNextTD) & 0xfffffff0); + if ((urb_priv->state == URB_DEL) || (ed->state & ED_DEL)) { + *td_p = td->hwNextTD | (*td_p & cpu_to_le32 (0x3)); + if(++ (urb_priv->td_cnt) == urb_priv->length) + urb_rm_priv (urb); + } else { + td_p = &td->hwNextTD; + } + + } + if (ed->state & ED_DEL) { /* set by sohci_free_dev */ + struct ohci_device * dev = usb_to_ohci (ohci->dev[edINFO & 0x7F]); + OHCI_FREE (tdTailP); /* free dummy td */ + ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); + ed->state = ED_NEW; + /* if all eds are removed wake up sohci_free_dev */ + if ((! --dev->ed_cnt) && dev->wait) { + add_wait_queue (&op_wakeup, dev->wait); + wake_up (&op_wakeup); + } + } + else { + ed->state &= ~ED_URB_DEL; + ed->hwINFO &= ~cpu_to_le32 (OHCI_ED_SKIP); + } + + if ((ed->type & 3) == CTRL) ctrl |= 1; + if ((ed->type & 3) == BULK) bulk |= 1; + } + + if (ctrl) writel (0, &ohci->regs->ed_controlcurrent); /* reset CTRL list */ + if (bulk) writel (0, &ohci->regs->ed_bulkcurrent); /* reset BULK list */ + if (!ohci->ed_rm_list[!frame]) /* start CTRL u. BULK list */ + writel (ohci->hc_control |= (0x03<<4), &ohci->regs->control); + ohci->ed_rm_list[frame] = NULL; + + spin_unlock_irqrestore (&usb_ed_lock, flags); +} + +/*-------------------------------------------------------------------------*/ + +/* td done list */ + +static void dl_done_list (ohci_t * ohci, td_t * td_list) +{ + td_t * td_list_next = NULL; + ed_t * ed; + int dlen = 0; + int cc = 0; + urb_t * urb; + urb_priv_t * urb_priv; + __u32 tdINFO, tdBE, tdCBP, edHeadP, edTailP; + __u16 tdPSW; + unsigned long flags; + + while (td_list) { + td_list_next = td_list->next_dl_td; + + urb = td_list->urb; + urb_priv = urb->hcpriv; + tdINFO = le32_to_cpup (&td_list->hwINFO); + tdBE = le32_to_cpup (&td_list->hwBE); + tdCBP = le32_to_cpup (&td_list->hwCBP); + + ed = td_list->ed; + + if (td_list->type & ST_ADDR) + urb->actual_length = 0; + + if (td_list->type & ADD_LEN) { /* accumulate length of multi td transfers */ + if (tdINFO & TD_ISO) { + tdPSW = le16_to_cpu (td_list->hwPSW[0]); + cc = (tdPSW >> 12) & 0xF; + if (cc < 0xE) { + if (usb_pipeout(urb->pipe)) { + dlen = urb->iso_frame_desc[td_list->index].length; + } else { + dlen = tdPSW & 0x3ff; + } + urb->actual_length += dlen; + urb->iso_frame_desc[td_list->index].actual_length = dlen; + if (!(urb->transfer_flags & USB_DISABLE_SPD) && (cc == TD_DATAUNDERRUN)) + cc = TD_CC_NOERROR; + + urb->iso_frame_desc[td_list->index].status = cc_to_error[cc]; + } + } else { + if (tdBE != 0) { + if (td_list->hwCBP == 0) + urb->actual_length = bus_to_virt (tdBE) - urb->transfer_buffer + 1; + else + urb->actual_length = bus_to_virt (tdCBP) - urb->transfer_buffer; + } + } + } + /* error code of transfer */ + cc = TD_CC_GET (tdINFO); + if (!(urb->transfer_flags & USB_DISABLE_SPD) && (cc == TD_DATAUNDERRUN)) + cc = TD_CC_NOERROR; + if (++(urb_priv->td_cnt) == urb_priv->length) { + if (urb_priv->state != URB_DEL && !(ed->state & ED_DEL) && ed->state != ED_NEW) { + urb->status = cc_to_error[cc]; + sohci_return_urb (urb); + } else { + urb_rm_priv (urb); + } + } + + spin_lock_irqsave (&usb_ed_lock, flags); + if (ed->state != ED_NEW) { + edHeadP = le32_to_cpup (&ed->hwHeadP) & 0xfffffff0; + edTailP = le32_to_cpup (&ed->hwTailP); + + if((edHeadP == edTailP) && (ed->state == ED_OPER)) + ep_unlink (ohci, ed); /* unlink eds if they are not busy */ + + } + spin_unlock_irqrestore (&usb_ed_lock, flags); + + td_list = td_list_next; + } +} + + + + +/*-------------------------------------------------------------------------* + * Virtual Root Hub + *-------------------------------------------------------------------------*/ + +static __u8 root_hub_dev_des[] = +{ + 0x12, /* __u8 bLength; */ + 0x01, /* __u8 bDescriptorType; Device */ + 0x00, /* __u16 bcdUSB; v1.0 */ + 0x01, + 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ + 0x00, /* __u8 bDeviceSubClass; */ + 0x00, /* __u8 bDeviceProtocol; */ + 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ + 0x00, /* __u16 idVendor; */ + 0x00, + 0x00, /* __u16 idProduct; */ + 0x00, + 0x00, /* __u16 bcdDevice; */ + 0x00, + 0x00, /* __u8 iManufacturer; */ + 0x00, /* __u8 iProduct; */ + 0x00, /* __u8 iSerialNumber; */ + 0x01 /* __u8 bNumConfigurations; */ +}; + + +/* Configuration descriptor */ +static __u8 root_hub_config_des[] = +{ + 0x09, /* __u8 bLength; */ + 0x02, /* __u8 bDescriptorType; Configuration */ + 0x19, /* __u16 wTotalLength; */ + 0x00, + 0x01, /* __u8 bNumInterfaces; */ + 0x01, /* __u8 bConfigurationValue; */ + 0x00, /* __u8 iConfiguration; */ + 0x40, /* __u8 bmAttributes; + Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */ + 0x00, /* __u8 MaxPower; */ + + /* interface */ + 0x09, /* __u8 if_bLength; */ + 0x04, /* __u8 if_bDescriptorType; Interface */ + 0x00, /* __u8 if_bInterfaceNumber; */ + 0x00, /* __u8 if_bAlternateSetting; */ + 0x01, /* __u8 if_bNumEndpoints; */ + 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ + 0x00, /* __u8 if_bInterfaceSubClass; */ + 0x00, /* __u8 if_bInterfaceProtocol; */ + 0x00, /* __u8 if_iInterface; */ + + /* endpoint */ + 0x07, /* __u8 ep_bLength; */ + 0x05, /* __u8 ep_bDescriptorType; Endpoint */ + 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ + 0x03, /* __u8 ep_bmAttributes; Interrupt */ + 0x08, /* __u16 ep_wMaxPacketSize; 8 Bytes */ + 0x00, + 0xff /* __u8 ep_bInterval; 255 ms */ +}; + +/* +For OHCI we need just the 2nd Byte, so we +don't need this constant byte-array + +static __u8 root_hub_hub_des[] = +{ + 0x00, * __u8 bLength; * + 0x29, * __u8 bDescriptorType; Hub-descriptor * + 0x02, * __u8 bNbrPorts; * + 0x00, * __u16 wHubCharacteristics; * + 0x00, + 0x01, * __u8 bPwrOn2pwrGood; 2ms * + 0x00, * __u8 bHubContrCurrent; 0 mA * + 0x00, * __u8 DeviceRemovable; *** 8 Ports max *** * + 0xff * __u8 PortPwrCtrlMask; *** 8 ports max *** * +}; +*/ + +/*-------------------------------------------------------------------------*/ + +/* prepare Interrupt pipe data; HUB INTERRUPT ENDPOINT */ + +static int rh_send_irq (ohci_t * ohci, void * rh_data, int rh_len) +{ + int num_ports; + int i; + int ret; + int len; + + __u8 data[8]; + + num_ports = readl (&ohci->regs->roothub.a) & 0xff; + *(__u8 *) data = (readl (&ohci->regs->roothub.status) & 0x00030000) > 0? 1: 0; + ret = *(__u8 *) data; + + for ( i = 0; i < num_ports; i++) { + *(__u8 *) (data + (i + 1) / 8) |= + ((readl (&ohci->regs->roothub.portstatus[i]) & 0x001f0000) > 0? 1: 0) << ((i + 1) % 8); + ret += *(__u8 *) (data + (i + 1) / 8); + } + len = i/8 + 1; + + if (ret > 0) { + memcpy (rh_data, data, min (len, min (rh_len, sizeof(data)))); + return len; + } + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* Virtual Root Hub INTs are polled by this timer every "intervall" ms */ + +static void rh_int_timer_do (unsigned long ptr) +{ + int len; + + urb_t * urb = (urb_t *) ptr; + ohci_t * ohci = urb->dev->bus->hcpriv; + + if(ohci->rh.send) { + len = rh_send_irq (ohci, urb->transfer_buffer, urb->transfer_buffer_length); + if (len > 0) { + urb->actual_length = len; +#ifdef DEBUG + urb_print (urb, "RET(rh)", usb_pipeout (urb->pipe)); +#endif + if (urb->complete) urb->complete (urb); + } + } + rh_init_int_timer (urb); +} + +/*-------------------------------------------------------------------------*/ + +/* Root Hub INTs are polled by this timer */ + +static int rh_init_int_timer (urb_t * urb) +{ + ohci_t * ohci = urb->dev->bus->hcpriv; + + ohci->rh.interval = urb->interval; + init_timer (&ohci->rh.rh_int_timer); + ohci->rh.rh_int_timer.function = rh_int_timer_do; + ohci->rh.rh_int_timer.data = (unsigned long) urb; + ohci->rh.rh_int_timer.expires = + jiffies + (HZ * (urb->interval < 30? 30: urb->interval)) / 1000; + add_timer (&ohci->rh.rh_int_timer); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +#define OK(x) len = (x); break +#define WR_RH_STAT(x) writel((x), &ohci->regs->roothub.status) +#define WR_RH_PORTSTAT(x) writel((x), &ohci->regs->roothub.portstatus[wIndex-1]) +#define RD_RH_STAT readl(&ohci->regs->roothub.status) +#define RD_RH_PORTSTAT readl(&ohci->regs->roothub.portstatus[wIndex-1]) + +/* request to virtual root hub */ + +static int rh_submit_urb (urb_t * urb) +{ + struct usb_device * usb_dev = urb->dev; + ohci_t * ohci = usb_dev->bus->hcpriv; + unsigned int pipe = urb->pipe; + devrequest * cmd = (devrequest *) urb->setup_packet; + void * data = urb->transfer_buffer; + int leni = urb->transfer_buffer_length; + int len = 0; + int status = TD_CC_NOERROR; + + __u8 datab[16]; + __u8 * data_buf = datab; + + __u16 bmRType_bReq; + __u16 wValue; + __u16 wIndex; + __u16 wLength; + + if (usb_pipeint(pipe)) { + + ohci->rh.urb = urb; + ohci->rh.send = 1; + ohci->rh.interval = urb->interval; + rh_init_int_timer(urb); + urb->status = cc_to_error [TD_CC_NOERROR]; + + return 0; + } + + bmRType_bReq = cmd->requesttype | (cmd->request << 8); + wValue = le16_to_cpu (cmd->value); + wIndex = le16_to_cpu (cmd->index); + wLength = le16_to_cpu (cmd->length); + switch (bmRType_bReq) { + /* Request Destination: + without flags: Device, + RH_INTERFACE: interface, + RH_ENDPOINT: endpoint, + RH_CLASS means HUB here, + RH_OTHER | RH_CLASS almost ever means HUB_PORT here + */ + + case RH_GET_STATUS: + *(__u16 *) data_buf = cpu_to_le16 (1); OK (2); + case RH_GET_STATUS | RH_INTERFACE: + *(__u16 *) data_buf = cpu_to_le16 (0); OK (2); + case RH_GET_STATUS | RH_ENDPOINT: + *(__u16 *) data_buf = cpu_to_le16 (0); OK (2); + case RH_GET_STATUS | RH_CLASS: + *(__u32 *) data_buf = cpu_to_le32 (RD_RH_STAT & 0x7fff7fff); OK (4); + case RH_GET_STATUS | RH_OTHER | RH_CLASS: + *(__u32 *) data_buf = cpu_to_le32 (RD_RH_PORTSTAT); OK (4); + + case RH_CLEAR_FEATURE | RH_ENDPOINT: + switch (wValue) { + case (RH_ENDPOINT_STALL): OK (0); + } + break; + + case RH_CLEAR_FEATURE | RH_CLASS: + switch (wValue) { + case RH_C_HUB_LOCAL_POWER: + OK(0); + case (RH_C_HUB_OVER_CURRENT): + WR_RH_STAT(RH_HS_OCIC); OK (0); + } + break; + + case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: + switch (wValue) { + case (RH_PORT_ENABLE): + WR_RH_PORTSTAT (RH_PS_CCS ); OK (0); + case (RH_PORT_SUSPEND): + WR_RH_PORTSTAT (RH_PS_POCI); OK (0); + case (RH_PORT_POWER): + WR_RH_PORTSTAT (RH_PS_LSDA); OK (0); + case (RH_C_PORT_CONNECTION): + WR_RH_PORTSTAT (RH_PS_CSC ); OK (0); + case (RH_C_PORT_ENABLE): + WR_RH_PORTSTAT (RH_PS_PESC); OK (0); + case (RH_C_PORT_SUSPEND): + WR_RH_PORTSTAT (RH_PS_PSSC); OK (0); + case (RH_C_PORT_OVER_CURRENT): + WR_RH_PORTSTAT (RH_PS_OCIC); OK (0); + case (RH_C_PORT_RESET): + WR_RH_PORTSTAT (RH_PS_PRSC); OK (0); + } + break; + + case RH_SET_FEATURE | RH_OTHER | RH_CLASS: + switch (wValue) { + case (RH_PORT_SUSPEND): + WR_RH_PORTSTAT (RH_PS_PSS ); OK (0); + case (RH_PORT_RESET): /* BUG IN HUP CODE *********/ + if((RD_RH_PORTSTAT &1) != 0) WR_RH_PORTSTAT (RH_PS_PRS ); OK (0); + case (RH_PORT_POWER): + WR_RH_PORTSTAT (RH_PS_PPS ); OK (0); + case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/ + if((RD_RH_PORTSTAT &1) != 0) WR_RH_PORTSTAT (RH_PS_PES ); OK (0); + } + break; + + case RH_SET_ADDRESS: ohci->rh.devnum = wValue; OK(0); + + case RH_GET_DESCRIPTOR: + switch ((wValue & 0xff00) >> 8) { + case (0x01): /* device descriptor */ + len = min (leni, min (sizeof (root_hub_dev_des), wLength)); + data_buf = root_hub_dev_des; OK(len); + case (0x02): /* configuration descriptor */ + len = min (leni, min (sizeof (root_hub_config_des), wLength)); + data_buf = root_hub_config_des; OK(len); + case (0x03): /* string descriptors */ + default: + status = TD_CC_STALL; + } + break; + + case RH_GET_DESCRIPTOR | RH_CLASS: + *(__u8 *) (data_buf+1) = 0x29; + *(__u32 *) (data_buf+2) = cpu_to_le32 (readl (&ohci->regs->roothub.a)); + *(__u8 *) data_buf = (*(__u8 *) (data_buf + 2) / 8) * 2 + 9; /* length of descriptor */ + + len = min (leni, min(*(__u8 *) data_buf, wLength)); + *(__u8 *) (data_buf+6) = 0; /* Root Hub needs no current from bus */ + if (*(__u8 *) (data_buf+2) < 8) { /* less than 8 Ports */ + *(__u8 *) (data_buf+7) = readl (&ohci->regs->roothub.b) & 0xff; + *(__u8 *) (data_buf+8) = (readl (&ohci->regs->roothub.b) & 0xff0000) >> 16; + } else { + *(__u32 *) (data_buf+7) = cpu_to_le32 (readl(&ohci->regs->roothub.b)); + } + OK (len); + + case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK (1); + + case RH_SET_CONFIGURATION: WR_RH_STAT (0x10000); OK (0); + + default: + status = TD_CC_STALL; + } + + dbg("USB HC roothubstat1: %x", readl ( &(ohci->regs->roothub.portstatus[0]) )); + dbg("USB HC roothubstat2: %x", readl ( &(ohci->regs->roothub.portstatus[1]) )); + + len = min(len, leni); + memcpy (data, data_buf, len); + urb->actual_length = len; + urb->status = cc_to_error [status]; + +#ifdef DEBUG + urb_print (urb, "RET(rh)", usb_pipeout (urb->pipe)); +#endif + + if (urb->complete) urb->complete (urb); + return 0; +} + +/*-------------------------------------------------------------------------*/ + +static int rh_unlink_urb (urb_t * urb) +{ + ohci_t * ohci = urb->dev->bus->hcpriv; + + ohci->rh.send = 0; + del_timer (&ohci->rh.rh_int_timer); + return 0; +} + +/*-------------------------------------------------------------------------* + * HC functions + *-------------------------------------------------------------------------*/ + +/* reset the HC not the BUS */ + +static void hc_reset (ohci_t * ohci) +{ + int timeout = 30; + int smm_timeout = 50; /* 0,5 sec */ + + if (readl (&ohci->regs->control) & 0x100) { /* SMM owns the HC */ + writel (0x08, &ohci->regs->cmdstatus); /* request ownership */ + dbg("USB HC TakeOver from SMM"); + while (readl (&ohci->regs->control) & 0x100) { + wait_ms (10); + if (--smm_timeout == 0) { + err("USB HC TakeOver failed!"); + break; + } + } + } + + writel ((1 << 31), &ohci->regs->intrdisable); /* Disable HC interrupts */ + dbg("USB HC reset_hc: %x ;", readl (&ohci->regs->control)); + /* this seems to be needed for the lucent controller on powerbooks.. */ + writel (0, &ohci->regs->control); /* Move USB to reset state */ + + writel (1, &ohci->regs->cmdstatus); /* HC Reset */ + while ((readl (&ohci->regs->cmdstatus) & 0x01) != 0) { /* 10us Reset */ + if (--timeout == 0) { + err("USB HC reset timed out!"); + return; + } + udelay (1); + } +} + +/*-------------------------------------------------------------------------*/ + +/* Start an OHCI controller, set the BUS operational + * enable interrupts + * connect the virtual root hub */ + +static int hc_start (ohci_t * ohci) +{ + unsigned int mask; + unsigned int fminterval; + struct usb_device * usb_dev; + struct ohci_device * dev; + + /* Tell the controller where the control and bulk lists are + * The lists are empty now. */ + + writel (0, &ohci->regs->ed_controlhead); + writel (0, &ohci->regs->ed_bulkhead); + + writel (virt_to_bus (&ohci->hcca), &ohci->regs->hcca); /* a reset clears this */ + + fminterval = 0x2edf; + writel ((fminterval * 9) / 10, &ohci->regs->periodicstart); + fminterval |= ((((fminterval - 210) * 6) / 7) << 16); + writel (fminterval, &ohci->regs->fminterval); + writel (0x628, &ohci->regs->lsthresh); + + /* Choose the interrupts we care about now, others later on demand */ + mask = OHCI_INTR_MIE | OHCI_INTR_WDH | OHCI_INTR_SO; + + writel (ohci->hc_control = 0xBF, &ohci->regs->control); /* USB Operational */ + writel (mask, &ohci->regs->intrenable); + writel (mask, &ohci->regs->intrstatus); + +#ifdef OHCI_USE_NPS + writel ((readl(&ohci->regs->roothub.a) | 0x200) & ~0x100, + &ohci->regs->roothub.a); + writel (0x10000, &ohci->regs->roothub.status); + mdelay ((readl(&ohci->regs->roothub.a) >> 23) & 0x1fe); +#endif /* OHCI_USE_NPS */ + + /* connect the virtual root hub */ + + usb_dev = usb_alloc_dev (NULL, ohci->bus); + if (!usb_dev) return -1; + + dev = usb_to_ohci (usb_dev); + ohci->bus->root_hub = usb_dev; + usb_connect (usb_dev); + if (usb_new_device (usb_dev) != 0) { + usb_free_dev (usb_dev); + return -1; + } + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* an interrupt happens */ + +static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r) +{ + ohci_t * ohci = __ohci; + struct ohci_regs * regs = ohci->regs; + int ints; + + if ((ohci->hcca.done_head != 0) && !(le32_to_cpup (&ohci->hcca.done_head) & 0x01)) { + ints = OHCI_INTR_WDH; + } else { + if ((ints = (readl (®s->intrstatus) & readl (®s->intrenable))) == 0) + return; + } + + dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca.frame_no)); + + if (ints & OHCI_INTR_WDH) { + writel (OHCI_INTR_WDH, ®s->intrdisable); + dl_done_list (ohci, dl_reverse_done_list (ohci)); + writel (OHCI_INTR_WDH, ®s->intrenable); + } + + if (ints & OHCI_INTR_SO) { + dbg("USB Schedule overrun"); + writel (OHCI_INTR_SO, ®s->intrenable); + } + + if (ints & OHCI_INTR_SF) { + unsigned int frame = le16_to_cpu (ohci->hcca.frame_no) & 1; + writel (OHCI_INTR_SF, ®s->intrdisable); + if (ohci->ed_rm_list[!frame] != NULL) { + dl_del_list (ohci, !frame); + } + if (ohci->ed_rm_list[frame] != NULL) writel (OHCI_INTR_SF, ®s->intrenable); + } + writel (ints, ®s->intrstatus); + writel (OHCI_INTR_MIE, ®s->intrenable); +} + +/*-------------------------------------------------------------------------*/ + +/* allocate OHCI */ + +static ohci_t * hc_alloc_ohci (void * mem_base) +{ + int i; + ohci_t * ohci; + struct usb_bus * bus; + + ohci = (ohci_t *) __get_free_pages (GFP_KERNEL, 1); + if (!ohci) + return NULL; + + memset (ohci, 0, sizeof (ohci_t)); + + ohci->irq = -1; + ohci->regs = mem_base; + + /* for load ballancing of the interrupt branches */ + for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0; + for (i = 0; i < NUM_INTS; i++) ohci->hcca.int_table[i] = 0; + + /* end of control and bulk lists */ + ohci->ed_isotail = NULL; + ohci->ed_controltail = NULL; + ohci->ed_bulktail = NULL; + + bus = usb_alloc_bus (&sohci_device_operations); + if (!bus) { + free_pages ((unsigned long) ohci, 1); + return NULL; + } + + ohci->bus = bus; + bus->hcpriv = (void *) ohci; + + return ohci; +} + +/*-------------------------------------------------------------------------*/ + +/* De-allocate all resources.. */ + +static void hc_release_ohci (ohci_t * ohci) +{ + dbg("USB HC release ohci"); + + /* disconnect all devices */ + if (ohci->bus->root_hub) usb_disconnect (&ohci->bus->root_hub); + + hc_reset (ohci); + writel (OHCI_USB_RESET, &ohci->regs->control); + wait_ms (10); + + if (ohci->irq >= 0) { + free_irq (ohci->irq, ohci); + ohci->irq = -1; + } + + usb_deregister_bus (ohci->bus); + usb_free_bus (ohci->bus); + + /* unmap the IO address space */ + iounmap (ohci->regs); + + free_pages ((unsigned long) ohci, 1); +} + +/*-------------------------------------------------------------------------*/ + +/* Increment the module usage count, start the control thread and + * return success. */ + +static int hc_found_ohci (int irq, void * mem_base) +{ + ohci_t * ohci; + dbg("USB HC found: irq= %d membase= %lx", irq, (unsigned long) mem_base); + + ohci = hc_alloc_ohci (mem_base); + if (!ohci) { + return -ENOMEM; + } + + INIT_LIST_HEAD (&ohci->ohci_hcd_list); + list_add (&ohci->ohci_hcd_list, &ohci_hcd_list); + + hc_reset (ohci); + writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control); + wait_ms (10); + usb_register_bus (ohci->bus); + + if (request_irq (irq, hc_interrupt, SA_SHIRQ, "ohci-usb", ohci) == 0) { + ohci->irq = irq; + hc_start (ohci); + return 0; + } + err("request interrupt %d failed", irq); + hc_release_ohci (ohci); + return -EBUSY; +} + +/*-------------------------------------------------------------------------*/ + +static int hc_start_ohci (struct pci_dev * dev) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + unsigned long mem_base = dev->resource[0].start; +#else + unsigned long mem_base = dev->base_address[0]; + if (mem_base & PCI_BASE_ADDRESS_SPACE_IO) return -ENODEV; + mem_base &= PCI_BASE_ADDRESS_MEM_MASK; +#endif + + pci_set_master (dev); + mem_base = (unsigned long) ioremap_nocache (mem_base, 4096); + + if (!mem_base) { + err("Error mapping OHCI memory"); + return -EFAULT; + } + return hc_found_ohci (dev->irq, (void *) mem_base); +} + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_PMAC_PBOOK + +/* On Powerbooks, put the controller into suspend mode when going + * to sleep, and do a resume when waking up. */ + +static int ohci_sleep_notify (struct pmu_sleep_notifier * self, int when) +{ + struct list_head * ohci_l; + ohci_t * ohci; + + for (ohci_l = ohci_hcd_list.next; ohci_l != &ohci_hcd_list; ohci_l = ohci_l->next) { + ohci = list_entry (ohci_l, ohci_t, ohci_hcd_list); + + switch (when) { + case PBOOK_SLEEP_NOW: + disable_irq (ohci->irq); + writel (ohci->hc_control = OHCI_USB_SUSPEND, &ohci->regs->control); + wait_ms (10); + break; + case PBOOK_WAKE: + writel (ohci->hc_control = OHCI_USB_RESUME, &ohci->regs->control); + wait_ms (20); + writel (ohci->hc_control = 0xBF, &ohci->regs->control); + enable_irq (ohci->irq); + break; + } + } + return PBOOK_SLEEP_OK; +} + +static struct pmu_sleep_notifier ohci_sleep_notifier = { + ohci_sleep_notify, SLEEP_LEVEL_MISC, +}; +#endif /* CONFIG_PMAC_PBOOK */ + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_APM +static int handle_apm_event (apm_event_t event) +{ + static int down = 0; + ohci_t * ohci; + struct list_head * ohci_l; + + switch (event) { + case APM_SYS_SUSPEND: + case APM_USER_SUSPEND: + if (down) { + dbg("received extra suspend event"); + break; + } + for (ohci_l = ohci_hcd_list.next; ohci_l != &ohci_hcd_list; ohci_l = ohci_l->next) { + ohci = list_entry (ohci_l, ohci_t, ohci_hcd_list); + dbg("USB-Bus suspend: %p", ohci); + writel (ohci->hc_control = 0xFF, &ohci->regs->control); + } + wait_ms (10); + down = 1; + break; + case APM_NORMAL_RESUME: + case APM_CRITICAL_RESUME: + if (!down) { + dbg("received bogus resume event"); + break; + } + for (ohci_l = ohci_hcd_list.next; ohci_l != &ohci_hcd_list; ohci_l = ohci_l->next) { + ohci = list_entry(ohci_l, ohci_t, ohci_hcd_list); + dbg("USB-Bus resume: %p", ohci); + writel (ohci->hc_control = 0x7F, &ohci->regs->control); + } + wait_ms (20); + for (ohci_l = ohci_hcd_list.next; ohci_l != &ohci_hcd_list; ohci_l = ohci_l->next) { + ohci = list_entry (ohci_l, ohci_t, ohci_hcd_list); + writel (ohci->hc_control = 0xBF, &ohci->regs->control); + } + down = 0; + break; + } + return 0; +} +#endif + +/*-------------------------------------------------------------------------*/ + +#define PCI_CLASS_SERIAL_USB_OHCI 0x0C0310 + +int ohci_hcd_init (void) +{ + int ret = -ENODEV; + struct pci_dev * dev = NULL; + + while ((dev = pci_find_class (PCI_CLASS_SERIAL_USB_OHCI, dev))) { + if (hc_start_ohci(dev) >= 0) ret = 0; + } + +#ifdef CONFIG_APM + apm_register_callback (&handle_apm_event); +#endif + +#ifdef CONFIG_PMAC_PBOOK + pmu_register_sleep_notifier (&ohci_sleep_notifier); +#endif + return ret; +} + +/*-------------------------------------------------------------------------*/ + +#ifdef MODULE +int init_module (void) +{ + return ohci_hcd_init (); +} + +/*-------------------------------------------------------------------------*/ + +void cleanup_module (void) +{ + ohci_t * ohci; + +#ifdef CONFIG_APM + apm_unregister_callback (&handle_apm_event); +#endif + +#ifdef CONFIG_PMAC_PBOOK + pmu_unregister_sleep_notifier (&ohci_sleep_notifier); +#endif + + while (!list_empty (&ohci_hcd_list)) { + ohci = list_entry (ohci_hcd_list.next, ohci_t, ohci_hcd_list); + list_del (&ohci->ohci_hcd_list); + INIT_LIST_HEAD (&ohci->ohci_hcd_list); + hc_release_ohci (ohci); + } +} +#endif //MODULE + diff -ur --new-file old/linux/drivers/usb/usb-ohci.h new/linux/drivers/usb/usb-ohci.h --- old/linux/drivers/usb/usb-ohci.h Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/usb/usb-ohci.h Sat Jan 22 03:17:56 2000 @@ -0,0 +1,407 @@ + /* + * URB OHCI HCD (Host Controller Driver) for USB. + * + *(C) Copyright 1999 Roman Weissgaerber + * + * usb-ohci.h + * + */ + + +#define MODSTR "ohci: " + + +static int cc_to_error[16] = { + +/* mapping of the OHCI CC status to error codes */ +#ifdef USB_ST_CRC /* status codes */ + /* No Error */ USB_ST_NOERROR, + /* CRC Error */ USB_ST_CRC, + /* Bit Stuff */ USB_ST_BITSTUFF, + /* Data Togg */ USB_ST_CRC, + /* Stall */ USB_ST_STALL, + /* DevNotResp */ USB_ST_NORESPONSE, + /* PIDCheck */ USB_ST_BITSTUFF, + /* UnExpPID */ USB_ST_BITSTUFF, + /* DataOver */ USB_ST_DATAOVERRUN, + /* DataUnder */ USB_ST_DATAUNDERRUN, + /* reservd */ USB_ST_NORESPONSE, + /* reservd */ USB_ST_NORESPONSE, + /* BufferOver */ USB_ST_BUFFEROVERRUN, + /* BuffUnder */ USB_ST_BUFFERUNDERRUN, + /* Not Access */ USB_ST_NORESPONSE, + /* Not Access */ USB_ST_NORESPONSE +}; + +#else /* error codes */ + /* No Error */ 0, + /* CRC Error */ -EILSEQ, + /* Bit Stuff */ -EPROTO, + /* Data Togg */ -EILSEQ, + /* Stall */ -EPIPE, + /* DevNotResp */ -ETIMEDOUT, + /* PIDCheck */ -EPROTO, + /* UnExpPID */ -EPROTO, + /* DataOver */ -EOVERFLOW, + /* DataUnder */ -EREMOTEIO, + /* reservd */ -ETIMEDOUT, + /* reservd */ -ETIMEDOUT, + /* BufferOver */ -ECOMM, + /* BuffUnder */ -ECOMM, + /* Not Access */ -ETIMEDOUT, + /* Not Access */ -ETIMEDOUT +}; +#define USB_ST_URB_PENDING -EINPROGRESS +#endif + + + +struct ed; +struct td; +/* for ED and TD structures */ + +/* ED States */ + +#define ED_NEW 0x00 +#define ED_UNLINK 0x01 +#define ED_OPER 0x02 +#define ED_DEL 0x04 +#define ED_URB_DEL 0x08 + +/* usb_ohci_ed */ +typedef struct ed { + __u32 hwINFO; + __u32 hwTailP; + __u32 hwHeadP; + __u32 hwNextED; + + struct ed * ed_prev; + __u8 int_period; + __u8 int_branch; + __u8 int_load; + __u8 int_interval; + __u8 state; + __u8 type; + __u16 last_iso; + struct ed * ed_rm_list; + +} ed_t; + + +/* TD info field */ +#define TD_CC 0xf0000000 +#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f) +#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28) +#define TD_EC 0x0C000000 +#define TD_T 0x03000000 +#define TD_T_DATA0 0x02000000 +#define TD_T_DATA1 0x03000000 +#define TD_T_TOGGLE 0x00000000 +#define TD_R 0x00040000 +#define TD_DI 0x00E00000 +#define TD_DI_SET(X) (((X) & 0x07)<< 21) +#define TD_DP 0x00180000 +#define TD_DP_SETUP 0x00000000 +#define TD_DP_IN 0x00100000 +#define TD_DP_OUT 0x00080000 + +#define TD_ISO 0x00010000 +#define TD_DEL 0x00020000 + +/* CC Codes */ +#define TD_CC_NOERROR 0x00 +#define TD_CC_CRC 0x01 +#define TD_CC_BITSTUFFING 0x02 +#define TD_CC_DATATOGGLEM 0x03 +#define TD_CC_STALL 0x04 +#define TD_DEVNOTRESP 0x05 +#define TD_PIDCHECKFAIL 0x06 +#define TD_UNEXPECTEDPID 0x07 +#define TD_DATAOVERRUN 0x08 +#define TD_DATAUNDERRUN 0x09 +#define TD_BUFFEROVERRUN 0x0C +#define TD_BUFFERUNDERRUN 0x0D +#define TD_NOTACCESSED 0x0F + + +#define MAXPSW 1 + +typedef struct td { + __u32 hwINFO; + __u32 hwCBP; /* Current Buffer Pointer */ + __u32 hwNextTD; /* Next TD Pointer */ + __u32 hwBE; /* Memory Buffer End Pointer */ + __u16 hwPSW[MAXPSW]; + + __u8 type; + __u8 index; + struct ed * ed; + struct td * next_dl_td; + urb_t * urb; +} td_t; + + +/* TD types */ +#define BULK 0x03 +#define INT 0x01 +#define CTRL 0x02 +#define ISO 0x00 + +#define SEND 0x01 +#define ST_ADDR 0x02 +#define ADD_LEN 0x04 +#define DEL 0x08 + + +#define OHCI_ED_SKIP (1 << 14) + +/* + * The HCCA (Host Controller Communications Area) is a 256 byte + * structure defined in the OHCI spec. that the host controller is + * told the base address of. It must be 256-byte aligned. + */ + +#define NUM_INTS 32 /* part of the OHCI standard */ +struct ohci_hcca { + __u32 int_table[NUM_INTS]; /* Interrupt ED table */ + __u16 frame_no; /* current frame number */ + __u16 pad1; /* set to 0 on each frame_no change */ + __u32 done_head; /* info returned for an interrupt */ + u8 reserved_for_hc[116]; +} __attribute((aligned(256))); + + +/* + * Maximum number of root hub ports. + */ +#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */ + +/* + * This is the structure of the OHCI controller's memory mapped I/O + * region. This is Memory Mapped I/O. You must use the readl() and + * writel() macros defined in asm/io.h to access these!! + */ +struct ohci_regs { + /* control and status registers */ + __u32 revision; + __u32 control; + __u32 cmdstatus; + __u32 intrstatus; + __u32 intrenable; + __u32 intrdisable; + /* memory pointers */ + __u32 hcca; + __u32 ed_periodcurrent; + __u32 ed_controlhead; + __u32 ed_controlcurrent; + __u32 ed_bulkhead; + __u32 ed_bulkcurrent; + __u32 donehead; + /* frame counters */ + __u32 fminterval; + __u32 fmremaining; + __u32 fmnumber; + __u32 periodicstart; + __u32 lsthresh; + /* Root hub ports */ + struct ohci_roothub_regs { + __u32 a; + __u32 b; + __u32 status; + __u32 portstatus[MAX_ROOT_PORTS]; + } roothub; +} __attribute((aligned(32))); + +/* + * cmdstatus register */ +#define OHCI_CLF 0x02 +#define OHCI_BLF 0x04 + +/* + * Interrupt register masks + */ +#define OHCI_INTR_SO (1) +#define OHCI_INTR_WDH (1 << 1) +#define OHCI_INTR_SF (1 << 2) +#define OHCI_INTR_RD (1 << 3) +#define OHCI_INTR_UE (1 << 4) +#define OHCI_INTR_FNO (1 << 5) +#define OHCI_INTR_RHSC (1 << 6) +#define OHCI_INTR_OC (1 << 30) +#define OHCI_INTR_MIE (1 << 31) + +/* + * Control register masks + */ +#define OHCI_USB_RESET 0 +#define OHCI_USB_RESUME (1 << 6) +#define OHCI_USB_OPER (2 << 6) +#define OHCI_USB_SUSPEND (3 << 6) + + +/* Virtual Root HUB */ +struct virt_root_hub { + int devnum; /* Address of Root Hub endpoint */ + void * urb; + void * int_addr; + int send; + int interval; + struct timer_list rh_int_timer; +}; + +/* destination of request */ +#define RH_INTERFACE 0x01 +#define RH_ENDPOINT 0x02 +#define RH_OTHER 0x03 + +#define RH_CLASS 0x20 +#define RH_VENDOR 0x40 + +/* Requests: bRequest << 8 | bmRequestType */ +#define RH_GET_STATUS 0x0080 +#define RH_CLEAR_FEATURE 0x0100 +#define RH_SET_FEATURE 0x0300 +#define RH_SET_ADDRESS 0x0500 +#define RH_GET_DESCRIPTOR 0x0680 +#define RH_SET_DESCRIPTOR 0x0700 +#define RH_GET_CONFIGURATION 0x0880 +#define RH_SET_CONFIGURATION 0x0900 +#define RH_GET_STATE 0x0280 +#define RH_GET_INTERFACE 0x0A80 +#define RH_SET_INTERFACE 0x0B00 +#define RH_SYNC_FRAME 0x0C80 +/* Our Vendor Specific Request */ +#define RH_SET_EP 0x2000 + + +/* Hub port features */ +#define RH_PORT_CONNECTION 0x00 +#define RH_PORT_ENABLE 0x01 +#define RH_PORT_SUSPEND 0x02 +#define RH_PORT_OVER_CURRENT 0x03 +#define RH_PORT_RESET 0x04 +#define RH_PORT_POWER 0x08 +#define RH_PORT_LOW_SPEED 0x09 +#define RH_C_PORT_CONNECTION 0x10 +#define RH_C_PORT_ENABLE 0x11 +#define RH_C_PORT_SUSPEND 0x12 +#define RH_C_PORT_OVER_CURRENT 0x13 +#define RH_C_PORT_RESET 0x14 + +/* Hub features */ +#define RH_C_HUB_LOCAL_POWER 0x00 +#define RH_C_HUB_OVER_CURRENT 0x01 + +#define RH_DEVICE_REMOTE_WAKEUP 0x00 +#define RH_ENDPOINT_STALL 0x01 + +#define RH_ACK 0x01 +#define RH_REQ_ERR -1 +#define RH_NACK 0x00 + +/* Root-Hub Register info */ + +#define RH_PS_CCS 0x00000001 +#define RH_PS_PES 0x00000002 +#define RH_PS_PSS 0x00000004 +#define RH_PS_POCI 0x00000008 +#define RH_PS_PRS 0x00000010 +#define RH_PS_PPS 0x00000100 +#define RH_PS_LSDA 0x00000200 +#define RH_PS_CSC 0x00010000 +#define RH_PS_PESC 0x00020000 +#define RH_PS_PSSC 0x00040000 +#define RH_PS_OCIC 0x00080000 +#define RH_PS_PRSC 0x00100000 + +/* Root hub status bits */ +#define RH_HS_LPS 0x00000001 +#define RH_HS_OCI 0x00000002 +#define RH_HS_DRWE 0x00008000 +#define RH_HS_LPSC 0x00010000 +#define RH_HS_OCIC 0x00020000 +#define RH_HS_CRWE 0x80000000 + +#define min(a,b) (((a)<(b))?(a):(b)) + + +/* urb */ +typedef struct +{ + ed_t * ed; + __u16 length; // number of tds associated with this request + __u16 td_cnt; // number of tds already serviced + int state; + void * wait; + td_t * td[0]; // list pointer to all corresponding TDs associated with this request + +} urb_priv_t; +#define URB_DEL 1 + +/* + * This is the full ohci controller description + * + * Note how the "proper" USB information is just + * a subset of what the full implementation needs. (Linus) + */ + + +typedef struct ohci { + struct ohci_hcca hcca; /* hcca */ + + int irq; + struct ohci_regs * regs; /* OHCI controller's memory */ + struct list_head ohci_hcd_list; /* list of all ohci_hcd */ + + struct ohci * next; // chain of uhci device contexts + struct list_head urb_list; // list of all pending urbs + spinlock_t urb_list_lock; // lock to keep consistency + + int ohci_int_load[32]; /* load of the 32 Interrupt Chains (for load ballancing)*/ + ed_t * ed_rm_list[2]; /* lists of all endpoints to be removed */ + ed_t * ed_bulktail; /* last endpoint of bulk list */ + ed_t * ed_controltail; /* last endpoint of control list */ + ed_t * ed_isotail; /* last endpoint of iso list */ + int intrstatus; + __u32 hc_control; /* copy of the hc control reg */ + struct usb_bus * bus; + struct usb_device * dev[128]; + struct virt_root_hub rh; +} ohci_t; + + +#define NUM_TDS 0 /* num of preallocated transfer descriptors */ +#define NUM_EDS 32 /* num of preallocated endpoint descriptors */ + +struct ohci_device { + ed_t ed[NUM_EDS]; + int ed_cnt; + void * wait; +}; + +// #define ohci_to_usb(ohci) ((ohci)->usb) +#define usb_to_ohci(usb) ((struct ohci_device *)(usb)->hcpriv) + +/* hcd */ +/* endpoint */ +static int ep_link(ohci_t * ohci, ed_t * ed); +static int ep_unlink(ohci_t * ohci, ed_t * ed); +static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned int pipe, int interval, int load); +static void ep_rm_ed(struct usb_device * usb_dev, ed_t * ed); +/* td */ +static void td_fill(unsigned int info, void * data, int len, urb_t * urb, int type, int index); +static void td_submit_urb(urb_t * urb); +/* root hub */ +static int rh_submit_urb(urb_t * urb); +static int rh_unlink_urb(urb_t * urb); +static int rh_init_int_timer(urb_t * urb); + +#ifdef DEBUG +#define OHCI_FREE(x) kfree(x); printk("OHCI FREE: %d: %4x\n", -- __ohci_free_cnt, (unsigned int) x) +#define OHCI_ALLOC(x,size) (x) = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); printk("OHCI ALLO: %d: %4x\n", ++ __ohci_free_cnt,(unsigned int) x) +static int __ohci_free_cnt = 0; +#else +#define OHCI_FREE(x) kfree(x) +#define OHCI_ALLOC(x,size) (x) = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL) +#endif + diff -ur --new-file old/linux/drivers/usb/usb-serial.c new/linux/drivers/usb/usb-serial.c --- old/linux/drivers/usb/usb-serial.c Thu Jan 20 18:48:48 2000 +++ new/linux/drivers/usb/usb-serial.c Wed Jan 26 22:15:02 2000 @@ -14,6 +14,24 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (01/25/2000) gkh + * Added initial framework for FTDI serial converter so that Bill Ryder + * has a place to put his code. + * Added the vendor specific info from Handspring. Now we can print out + * informational debug messages as well as understand what is happening. + * + * (01/23/2000) gkh + * Fixed problem of crash when trying to open a port that didn't have a + * device assigned to it. Made the minor node finding a little smarter, + * now it looks to find a continous space for the new device. + * + * (01/21/2000) gkh + * Fixed bug in visor_startup with patch from Miles Lott (milos@insync.net) + * Fixed get_serial_by_minor which was all messed up for multi port + * devices. Fixed multi port problem for generic devices. Now the number + * of ports is determined by the number of bulk out endpoints for the + * generic device. + * * (01/19/2000) gkh * Removed lots of cruft that was around from the old (pre urb) driver * interface. @@ -141,15 +159,16 @@ /* USB Serial devices vendor ids and device ids that this driver supports */ #define BELKIN_VENDOR_ID 0x056c -#define BELKIN_SERIAL_CONVERTER 0x8007 +#define BELKIN_SERIAL_CONVERTER_ID 0x8007 #define PERACOM_VENDOR_ID 0x0565 -#define PERACOM_SERIAL_CONVERTER 0x0001 +#define PERACOM_SERIAL_CONVERTER_ID 0x0001 #define CONNECT_TECH_VENDOR_ID 0x0710 #define CONNECT_TECH_FAKE_WHITE_HEAT_ID 0x0001 #define CONNECT_TECH_WHITE_HEAT_ID 0x8001 #define HANDSPRING_VENDOR_ID 0x082d #define HANDSPRING_VISOR_ID 0x0100 - +#define FTDI_VENDOR_ID 0x0403 +#define FTDI_SERIAL_CONVERTER_ID 0x8372 #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ #define SERIAL_TTY_MINORS 16 /* Actually we are allowed 255, but this is good for now */ @@ -267,7 +286,7 @@ #ifdef CONFIG_USB_SERIAL_BELKIN /* All of the device info needed for the Belkin Serial Converter */ static __u16 belkin_vendor_id = BELKIN_VENDOR_ID; -static __u16 belkin_product_id = BELKIN_SERIAL_CONVERTER; +static __u16 belkin_product_id = BELKIN_SERIAL_CONVERTER_ID; static struct usb_serial_device_type belkin_device = { name: "Belkin", idVendor: &belkin_vendor_id, /* the Belkin vendor id */ @@ -291,7 +310,7 @@ #ifdef CONFIG_USB_SERIAL_PERACOM /* All of the device info needed for the Peracom Serial Converter */ static __u16 peracom_vendor_id = PERACOM_VENDOR_ID; -static __u16 peracom_product_id = PERACOM_SERIAL_CONVERTER; +static __u16 peracom_product_id = PERACOM_SERIAL_CONVERTER_ID; static struct usb_serial_device_type peracom_device = { name: "Peracom", idVendor: &peracom_vendor_id, /* the Peracom vendor id */ @@ -359,6 +378,58 @@ #ifdef CONFIG_USB_SERIAL_VISOR + +/**************************************************************************** + * Handspring Visor Vendor specific request codes (bRequest values) + * A big thank you to Handspring for providing the following information. + * If anyone wants the original file where these values and structures came + * from, send email to . + ****************************************************************************/ + +/**************************************************************************** + * VISOR_REQUEST_BYTES_AVAILABLE asks the visor for the number of bytes that + * are available to be transfered to the host for the specified endpoint. + * Currently this is not used, and always returns 0x0001 + ****************************************************************************/ +#define VISOR_REQUEST_BYTES_AVAILABLE 0x01 + +/**************************************************************************** + * VISOR_CLOSE_NOTIFICATION is set to the device to notify it that the host + * is now closing the pipe. An empty packet is sent in response. + ****************************************************************************/ +#define VISOR_CLOSE_NOTIFICATION 0x02 + +/**************************************************************************** + * VISOR_GET_CONNECTION_INFORMATION is sent by the host during enumeration to + * get the endpoints used by the connection. + ****************************************************************************/ +#define VISOR_GET_CONNECTION_INFORMATION 0x03 + + +/**************************************************************************** + * VISOR_GET_CONNECTION_INFORMATION returns data in the following format + ****************************************************************************/ +struct visor_connection_info { + __u16 num_ports; + struct { + __u8 port_function_id; + __u8 port; + } connections[2]; +}; + + +/* struct visor_connection_info.connection[x].port defines: */ +#define VISOR_ENDPOINT_1 0x01 +#define VISOR_ENDPOINT_2 0x02 + +/* struct visor_connection_info.connection[x].port_function_id defines: */ +#define VISOR_FUNCTION_GENERIC 0x00 +#define VISOR_FUNCTION_DEBUGGER 0x01 +#define VISOR_FUNCTION_HOTSYNC 0x02 +#define VISOR_FUNCTION_CONSOLE 0x03 +#define VISOR_FUNCTION_REMOTE_FILE_SYS 0x04 + + /* function prototypes for a handspring visor */ static int visor_serial_open (struct tty_struct *tty, struct file *filp); static void visor_serial_close (struct tty_struct *tty, struct file *filp); @@ -391,6 +462,34 @@ }; #endif + +#ifdef CONFIG_USB_SERIAL_FTDI +/* function prototypes for a FTDI serial converter */ +static int ftdi_serial_open (struct tty_struct *tty, struct file *filp); +static void ftdi_serial_close (struct tty_struct *tty, struct file *filp); + +/* All of the device info needed for the Handspring Visor */ +static __u16 ftdi_vendor_id = FTDI_VENDOR_ID; +static __u16 ftdi_product_id = FTDI_SERIAL_CONVERTER_ID; +static struct usb_serial_device_type ftdi_device = { + name: "FTDI", + idVendor: &ftdi_vendor_id, /* the FTDI vendor ID */ + idProduct: &ftdi_product_id, /* the FTDI product id */ + needs_interrupt_in: MUST_HAVE_NOT, /* this device must not have an interrupt in endpoint */ + needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */ + needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */ + num_interrupt_in: 0, + num_bulk_in: 1, + num_bulk_out: 1, + num_ports: 1, + open: ftdi_serial_open, + close: ftdi_serial_close, + write: generic_serial_write, + write_room: generic_write_room, + chars_in_buffer: generic_chars_in_buffer +}; +#endif + /* To add support for another serial converter, create a usb_serial_device_type structure for that device, and add it to this list, making sure that the last entry is NULL. */ @@ -411,6 +510,9 @@ #ifdef CONFIG_USB_SERIAL_VISOR &handspring_device, #endif +#ifdef CONFIG_USB_SERIAL_FTDI + &ftdi_device, +#endif NULL }; @@ -438,20 +540,27 @@ dbg("get_serial_by_minor %d", minor); - for (i = 0; i < SERIAL_TTY_MINORS; ++i) - if (serial_table[i]) - if (serial_table[i] != SERIAL_PTR_EMPTY) - if (serial_table[i]->minor == minor) - return (serial_table[i]); + if (serial_table[minor] == NULL) + return (NULL); - return (NULL); + if (serial_table[minor] != SERIAL_PTR_EMPTY) + return (serial_table[minor]); + + i = minor; + while (serial_table[i] == SERIAL_PTR_EMPTY) { + if (i == 0) + return (NULL); + --i; + } + return (serial_table[i]); } static struct usb_serial *get_free_serial (int num_ports, int *minor) { struct usb_serial *serial = NULL; - int i; + int i, j; + int good_spot; dbg("get_free_serial %d", num_ports); @@ -459,6 +568,14 @@ for (i = 0; i < SERIAL_TTY_MINORS; ++i) { if (serial_table[i]) continue; + + good_spot = 1; + for (j = 0; j < num_ports-1; ++j) + if (serial_table[i+j]) + good_spot = 0; + if (good_spot == 0) + continue; + if (!(serial = kmalloc(sizeof(struct usb_serial), GFP_KERNEL))) { err("Out of memory"); return NULL; @@ -467,7 +584,7 @@ serial_table[i] = serial; *minor = i; dbg("minor base = %d", *minor); - for (i = *minor+1; (i < num_ports) && (i < SERIAL_TTY_MINORS); ++i) + for (i = *minor+1; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) serial_table[i] = SERIAL_PTR_EMPTY; return (serial); } @@ -538,6 +655,9 @@ dbg("serial_open"); + /* initialize the pointer incase something fails */ + tty->driver_data = NULL; + /* get the serial object associated with this tty pointer */ serial = get_serial_by_minor (MINOR(tty->device)); @@ -567,15 +687,20 @@ static void serial_close(struct tty_struct *tty, struct file * filp) { struct usb_serial *serial = (struct usb_serial *) tty->driver_data; - int port = MINOR(tty->device) - serial->minor; + int port; + + dbg("serial_close"); - dbg("serial_close port %d", port); - - /* do some sanity checking that we really have a device present */ if (!serial) { dbg("serial == NULL!"); return; } + + port = MINOR(tty->device) - serial->minor; + + dbg("serial_close port %d", port); + + /* do some sanity checking that we really have a device present */ if (!serial->type) { dbg("serial->type == NULL!"); return; @@ -997,9 +1122,18 @@ { struct usb_serial *serial = (struct usb_serial *) tty->driver_data; int port = MINOR(tty->device) - serial->minor; + unsigned char *transfer_buffer = kmalloc (0x12, GFP_KERNEL); dbg("visor_serial_close port %d", port); + if (!transfer_buffer) { + err("visor_serial_close: kmalloc(%d) failed.\n", 0x12); + } else { + /* send a shutdown message to the device */ + usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_CLOSE_NOTIFICATION, + 0xc2, 0x0000, 0x0000, transfer_buffer, 0x12, 300); + } + /* shutdown our bulk reads and writes */ usb_unlink_urb (&serial->write_urb[port]); usb_unlink_urb (&serial->read_urb[port]); @@ -1034,51 +1168,10 @@ } -/* - Here's the raw dump of the vendor specific command data that the Visor sends on Win98 -______________________________________________________________________ -SETUP(0xB4) ADDR(0x02) ENDP(0x0) CRC5(0x15) -______________________________________________________________________ -DATA0(0xC3) DATA(C2 03 00 00 00 00 12 00 ) CRC16(0xB0BB) -______________________________________________________________________ -ACK(0x4B) -______________________________________________________________________ -IN(0x96) ADDR(0x02) ENDP(0x0) CRC5(0x15) -______________________________________________________________________ -DATA1(0xD2) DATA(02 00 00 01 02 02 ) CRC16(0xF4E6) -______________________________________________________________________ -ACK(0x4B) -______________________________________________________________________ -OUT(0x87) ADDR(0x02) ENDP(0x0) CRC5(0x15) -______________________________________________________________________ -DATA1(0xD2) DATA() CRC16(0x0000) -______________________________________________________________________ -ACK(0x4B) -______________________________________________________________________ -SETUP(0xB4) ADDR(0x02) ENDP(0x0) CRC5(0x15) -______________________________________________________________________ -DATA0(0xC3) DATA(C2 01 00 00 05 00 02 00 ) CRC16(0xC488) -______________________________________________________________________ -ACK(0x4B) -______________________________________________________________________ -IN(0x96) ADDR(0x02) ENDP(0x0) CRC5(0x15) -______________________________________________________________________ -DATA1(0xD2) DATA(01 00 ) CRC16(0xFFFB) -______________________________________________________________________ -ACK(0x4B) -______________________________________________________________________ -OUT(0x87) ADDR(0x02) ENDP(0x0) CRC5(0x15) -______________________________________________________________________ -DATA1(0xD2) DATA() CRC16(0x0000) -______________________________________________________________________ -ACK(0x4B) -______________________________________________________________________ -*/ - static int visor_startup (struct usb_serial *serial) { - /* send out two unknown commands that I found by looking at a Win98 trace */ int response; + int i; unsigned char *transfer_buffer = kmalloc (256, GFP_KERNEL); if (!transfer_buffer) { @@ -1091,18 +1184,44 @@ dbg("visor_setup: Set config to 1"); usb_set_configuration (serial->dev, 1); - response = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), 0x03, 0xc2, 0x0000, 0x0000, transfer_buffer, 0x12, 300); + /* send a get connection info request */ + response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_GET_CONNECTION_INFORMATION, + 0xc2, 0x0000, 0x0000, transfer_buffer, 0x12, 300); if (response < 0) { - err("visor_startup: error getting first vendor specific message"); + err("visor_startup: error getting connection information"); } else { - dbg("visor_startup: First vendor specific message successful"); +#ifdef DEBUG + struct visor_connection_info *connection_info = (struct visor_connection_info *)transfer_buffer; + char *string; + dbg("%s: Number of ports: %d", serial->type->name, connection_info->num_ports); + for (i = 0; i < connection_info->num_ports; ++i) { + switch (connection_info->connections[i].port_function_id) { + case VISOR_FUNCTION_GENERIC: + string = "Generic"; + break; + case VISOR_FUNCTION_DEBUGGER: + string = "Debugger"; + break; + case VISOR_FUNCTION_HOTSYNC: + string = "HotSync"; + break; + case VISOR_FUNCTION_REMOTE_FILE_SYS: + string = "Remote File System"; + break; + default: + string = "unknown"; + break; + } + dbg("%s: port %d, is for %s", serial->type->name, connection_info->connections[i].port, string); + } +#endif } - response = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), 0x01, 0xc2, 0x0000, 0x0005, transfer_buffer, 0x02, 300); + /* ask for the number of bytes available, but ignore the response as it is broken */ + response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_REQUEST_BYTES_AVAILABLE, + 0xc2, 0x0000, 0x0005, transfer_buffer, 0x02, 300); if (response < 0) { - err("visor_startup: error getting second vendor specific message"); - } else { - dbg("visor_startup: Second vendor specific message successful"); + err("visor_startup: error getting bytes available request"); } kfree (transfer_buffer); @@ -1115,6 +1234,54 @@ #endif /* CONFIG_USB_SERIAL_VISOR*/ +#ifdef CONFIG_USB_SERIAL_FTDI +/****************************************************************************** + * FTDI Serial Converter specific driver functions + ******************************************************************************/ +static int ftdi_serial_open (struct tty_struct *tty, struct file *filp) +{ + struct usb_serial *serial = (struct usb_serial *) tty->driver_data; + int port = MINOR(tty->device) - serial->minor; + + dbg("ftdi_serial_open port %d", port); + + if (serial->active[port]) { + dbg ("device already open"); + return -EINVAL; + } + serial->active[port] = 1; + + /*Start reading from the device*/ + if (usb_submit_urb(&serial->read_urb[port])) + dbg("usb_submit_urb(read bulk) failed"); + + /* Need to do device specific setup here (control lines, baud rate, etc.) */ + /* FIXME!!! */ + + return (0); +} + + +static void ftdi_serial_close (struct tty_struct *tty, struct file *filp) +{ + struct usb_serial *serial = (struct usb_serial *) tty->driver_data; + int port = MINOR(tty->device) - serial->minor; + + dbg("ftdi_serial_close port %d", port); + + /* Need to change the control lines here */ + /* FIXME */ + + /* shutdown our bulk reads and writes */ + usb_unlink_urb (&serial->write_urb[port]); + usb_unlink_urb (&serial->read_urb[port]); + serial->active[port] = 0; +} + + +#endif + + /***************************************************************************** * generic devices specific driver functions *****************************************************************************/ @@ -1260,6 +1427,7 @@ int num_interrupt_in = 0; int num_bulk_in = 0; int num_bulk_out = 0; + int num_ports; /* loop through our list of known serial converters, and see if this device matches */ device_num = 0; @@ -1317,7 +1485,14 @@ /* found all that we need */ info("%s converter detected", type->name); - serial = get_free_serial (type->num_ports, &minor); +#ifdef CONFIG_USB_SERIAL_GENERIC + if (type == &generic_device) + num_ports = num_bulk_out; + else +#endif + num_ports = type->num_ports; + + serial = get_free_serial (num_ports, &minor); if (serial == NULL) { err("No more free serial devices"); return NULL; @@ -1326,7 +1501,7 @@ serial->dev = dev; serial->type = type; serial->minor = minor; - serial->num_ports = type->num_ports; + serial->num_ports = num_ports; serial->num_bulk_in = num_bulk_in; serial->num_bulk_out = num_bulk_out; serial->num_interrupt_in = num_interrupt_in; @@ -1350,7 +1525,7 @@ } for (i = 0; i < num_bulk_out; ++i) { - serial->bulk_out_size[i] = bulk_out_endpoint[i]->wMaxPacketSize; + serial->bulk_out_size[i] = bulk_out_endpoint[i]->wMaxPacketSize * 2; serial->bulk_out_buffer[i] = kmalloc (serial->bulk_out_size[i], GFP_KERNEL); if (!serial->bulk_out_buffer[i]) { err("Couldn't allocate bulk_out_buffer"); @@ -1417,6 +1592,7 @@ usb_unlink_urb (&serial->write_urb[i]); usb_unlink_urb (&serial->read_urb[i]); serial->active[i] = 0; + serial_table[serial->minor + i] = NULL; } /* free up any memory that we allocated */ @@ -1434,7 +1610,6 @@ info("%s converter now disconnected from ttyUSB%d", serial->type->name, serial->minor + i); } - serial_table[serial->minor] = NULL; kfree (serial); } else { diff -ur --new-file old/linux/drivers/usb/usb-uhci.c new/linux/drivers/usb/usb-uhci.c --- old/linux/drivers/usb/usb-uhci.c Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/usb/usb-uhci.c Mon Jan 24 07:39:14 2000 @@ -0,0 +1,2359 @@ +/* + * Universal Host Controller Interface driver for USB (take II). + * + * (c) 1999 Georg Acher, acher@in.tum.de (executive slave) (base guitar) + * Deti Fliegl, deti@fliegl.de (executive slave) (lead voice) + * Thomas Sailer, sailer@ife.ee.ethz.ch (chief consultant) (cheer leader) + * Roman Weissgaerber, weissg@vienna.at (virt root hub) (studio porter) + * + * HW-initalization based on material of + * + * (C) Copyright 1999 Linus Torvalds + * (C) Copyright 1999 Johannes Erdfelt + * (C) Copyright 1999 Randy Dunlap + * + * $Id: usb-uhci.c,v 1.169 2000/01/20 19:50:11 acher Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for in_interrupt() */ +#include + +#include +#include +#include +#include + +/* This enables debug printks */ +//#define DEBUG +/* This enables all symbols to be exported, to ease debugging oopses */ +#define DEBUG_SYMBOLS +/* This enables an extra UHCI slab for memory debugging */ +//#define DEBUG_SLAB + +#include "usb.h" +#include "usb-uhci.h" +#include "uhci-debug.h" + +#ifdef CONFIG_APM +#include +static int handle_apm_event (apm_event_t event); +#endif + +#ifdef DEBUG_SYMBOLS +#define _static +#ifndef EXPORT_SYMTAB +#define EXPORT_SYMTAB +#endif +#else +#define _static static +#endif + +#ifdef DEBUG_SLAB +static kmem_cache_t *uhci_desc_kmem; +static kmem_cache_t *urb_priv_kmem; +#endif + +_static int rh_submit_urb (purb_t purb); +_static int rh_unlink_urb (purb_t purb); +static puhci_t devs = NULL; + +/* used by userspace UHCI data structure dumper */ +puhci_t *uhci_devices = &devs; + +/*-------------------------------------------------------------------*/ +_static void queue_urb (puhci_t s, struct list_head *p, int do_lock) +{ + unsigned long flags=0; + + if (do_lock) + spin_lock_irqsave (&s->urb_list_lock, flags); + + list_add_tail (p, &s->urb_list); + + if (do_lock) + spin_unlock_irqrestore (&s->urb_list_lock, flags); +} + +/*-------------------------------------------------------------------*/ +_static void dequeue_urb (puhci_t s, struct list_head *p, int do_lock) +{ + unsigned long flags=0; + + if (do_lock) + spin_lock_irqsave (&s->urb_list_lock, flags); + + list_del (p); + + if (do_lock) + spin_unlock_irqrestore (&s->urb_list_lock, flags); +} + +/*-------------------------------------------------------------------*/ +_static int alloc_td (puhci_desc_t * new, int flags) +{ +#ifdef DEBUG_SLAB + *new= kmem_cache_alloc(uhci_desc_kmem, in_interrupt ()? SLAB_ATOMIC : SLAB_KERNEL); +#else + *new = (uhci_desc_t *) kmalloc (sizeof (uhci_desc_t), in_interrupt ()? GFP_ATOMIC : GFP_KERNEL); +#endif + if (!*new) + return -ENOMEM; + + memset (*new, 0, sizeof (uhci_desc_t)); + (*new)->hw.td.link = UHCI_PTR_TERM | (flags & UHCI_PTR_BITS); // last by default + + (*new)->type = TD_TYPE; + mb(); + INIT_LIST_HEAD (&(*new)->vertical); + INIT_LIST_HEAD (&(*new)->horizontal); + + return 0; +} +/*-------------------------------------------------------------------*/ +/* insert td at last position in td-list of qh (vertical) */ +_static int insert_td (puhci_t s, puhci_desc_t qh, puhci_desc_t new, int flags) +{ + uhci_desc_t *prev; + unsigned long xxx; + + spin_lock_irqsave (&s->td_lock, xxx); + + list_add_tail (&new->vertical, &qh->vertical); + + if (qh->hw.qh.element & UHCI_PTR_TERM) { + // virgin qh without any tds + qh->hw.qh.element = virt_to_bus (new); /* QH's cannot have the DEPTH bit set */ + } + else { + // already tds inserted + prev = list_entry (new->vertical.prev, uhci_desc_t, vertical); + // implicitely remove TERM bit of prev + prev->hw.td.link = virt_to_bus (new) | (flags & UHCI_PTR_DEPTH); + } + mb(); + spin_unlock_irqrestore (&s->td_lock, xxx); + + return 0; +} +/*-------------------------------------------------------------------*/ +/* insert new_td after td (horizontal) */ +_static int insert_td_horizontal (puhci_t s, puhci_desc_t td, puhci_desc_t new, int flags) +{ + uhci_desc_t *next; + unsigned long xxx; + + spin_lock_irqsave (&s->td_lock, xxx); + + next = list_entry (td->horizontal.next, uhci_desc_t, horizontal); + new->hw.td.link = td->hw.td.link; + mb(); + list_add (&new->horizontal, &td->horizontal); + td->hw.td.link = virt_to_bus (new); + mb(); + spin_unlock_irqrestore (&s->td_lock, xxx); + + return 0; +} +/*-------------------------------------------------------------------*/ +_static int unlink_td (puhci_t s, puhci_desc_t element) +{ + uhci_desc_t *next, *prev; + int dir = 0; + unsigned long xxx; + + spin_lock_irqsave (&s->td_lock, xxx); + + next = list_entry (element->vertical.next, uhci_desc_t, vertical); + + if (next == element) { + dir = 1; + next = list_entry (element->horizontal.next, uhci_desc_t, horizontal); + prev = list_entry (element->horizontal.prev, uhci_desc_t, horizontal); + } + else { + prev = list_entry (element->vertical.prev, uhci_desc_t, vertical); + } + + if (prev->type == TD_TYPE) + prev->hw.td.link = element->hw.td.link; + else + prev->hw.qh.element = element->hw.td.link; + + mb (); + + if (dir == 0) + list_del (&element->vertical); + else + list_del (&element->horizontal); + + spin_unlock_irqrestore (&s->td_lock, xxx); + + return 0; +} +/*-------------------------------------------------------------------*/ +_static int delete_desc (puhci_desc_t element) +{ +#ifdef DEBUG_SLAB + kmem_cache_free(uhci_desc_kmem, element); +#else + kfree (element); +#endif + return 0; +} +/*-------------------------------------------------------------------*/ +// Allocates qh element +_static int alloc_qh (puhci_desc_t * new) +{ +#ifdef DEBUG_SLAB + *new= kmem_cache_alloc(uhci_desc_kmem, in_interrupt ()? SLAB_ATOMIC : SLAB_KERNEL); +#else + *new = (uhci_desc_t *) kmalloc (sizeof (uhci_desc_t), in_interrupt ()? GFP_ATOMIC : GFP_KERNEL); +#endif + if (!*new) + return -ENOMEM; + + memset (*new, 0, sizeof (uhci_desc_t)); + (*new)->hw.qh.head = UHCI_PTR_TERM; + (*new)->hw.qh.element = UHCI_PTR_TERM; + (*new)->type = QH_TYPE; + mb(); + INIT_LIST_HEAD (&(*new)->horizontal); + INIT_LIST_HEAD (&(*new)->vertical); + + dbg("Allocated qh @ %p", *new); + + return 0; +} +/*-------------------------------------------------------------------*/ +// inserts new qh before/after the qh at pos +// flags: 0: insert before pos, 1: insert after pos (for low speed transfers) +_static int insert_qh (puhci_t s, puhci_desc_t pos, puhci_desc_t new, int flags) +{ + puhci_desc_t old; + unsigned long xxx; + + spin_lock_irqsave (&s->qh_lock, xxx); + + if (!flags) { + // (OLD) (POS) -> (OLD) (NEW) (POS) + old = list_entry (pos->horizontal.prev, uhci_desc_t, horizontal); + list_add_tail (&new->horizontal, &pos->horizontal); + new->hw.qh.head = MAKE_QH_ADDR (pos) ; + mb(); + if (!(old->hw.qh.head & UHCI_PTR_TERM)) + old->hw.qh.head = MAKE_QH_ADDR (new) ; + } + else { + // (POS) (OLD) -> (POS) (NEW) (OLD) + old = list_entry (pos->horizontal.next, uhci_desc_t, horizontal); + list_add (&new->horizontal, &pos->horizontal); + new->hw.qh.head = MAKE_QH_ADDR (old); + mb(); + pos->hw.qh.head = MAKE_QH_ADDR (new) ; + } + + mb (); + + spin_unlock_irqrestore (&s->qh_lock, xxx); + + return 0; +} +/*-------------------------------------------------------------------*/ +_static int unlink_qh (puhci_t s, puhci_desc_t element) +{ + puhci_desc_t next, prev; + unsigned long xxx; + + spin_lock_irqsave (&s->qh_lock, xxx); + + next = list_entry (element->horizontal.next, uhci_desc_t, horizontal); + prev = list_entry (element->horizontal.prev, uhci_desc_t, horizontal); + prev->hw.qh.head = element->hw.qh.head; + mb (); + list_del (&element->horizontal); + + spin_unlock_irqrestore (&s->qh_lock, xxx); + + return 0; +} +/*-------------------------------------------------------------------*/ +_static int delete_qh (puhci_t s, puhci_desc_t qh) +{ + puhci_desc_t td; + struct list_head *p; + + list_del (&qh->horizontal); + + while ((p = qh->vertical.next) != &qh->vertical) { + td = list_entry (p, uhci_desc_t, vertical); + unlink_td (s, td); + delete_desc (td); + } + + delete_desc (qh); + + return 0; +} +/*-------------------------------------------------------------------*/ +_static void clean_td_chain (puhci_desc_t td) +{ + struct list_head *p; + puhci_desc_t td1; + + if (!td) + return; + + while ((p = td->horizontal.next) != &td->horizontal) { + td1 = list_entry (p, uhci_desc_t, horizontal); + delete_desc (td1); + } + + delete_desc (td); +} +/*-------------------------------------------------------------------*/ +// Removes ALL qhs in chain (paranoia!) +_static void cleanup_skel (puhci_t s) +{ + unsigned int n; + puhci_desc_t td; + + dbg("cleanup_skel"); + + for (n = 0; n < 8; n++) { + td = s->int_chain[n]; + clean_td_chain (td); + } + + if (s->iso_td) { + for (n = 0; n < 1024; n++) { + td = s->iso_td[n]; + clean_td_chain (td); + } + kfree (s->iso_td); + } + + if (s->framelist) + free_page ((unsigned long) s->framelist); + + if (s->control_chain) { + // completed init_skel? + struct list_head *p; + puhci_desc_t qh, qh1; + + qh = s->control_chain; + while ((p = qh->horizontal.next) != &qh->horizontal) { + qh1 = list_entry (p, uhci_desc_t, horizontal); + delete_qh (s, qh1); + } + delete_qh (s, qh); + } + else { + if (s->control_chain) + kfree (s->control_chain); + if (s->bulk_chain) + kfree (s->bulk_chain); + if (s->chain_end) + kfree (s->chain_end); + } + dbg("cleanup_skel finished"); +} +/*-------------------------------------------------------------------*/ +// allocates framelist and qh-skeletons +// only HW-links provide continous linking, SW-links stay in their domain (ISO/INT) +_static int init_skel (puhci_t s) +{ + int n, ret; + puhci_desc_t qh, td; + + dbg("init_skel"); + + s->framelist = (__u32 *) get_free_page (GFP_KERNEL); + + if (!s->framelist) + return -ENOMEM; + + memset (s->framelist, 0, 4096); + + dbg("allocating iso desc pointer list"); + s->iso_td = (puhci_desc_t *) kmalloc (1024 * sizeof (puhci_desc_t), GFP_KERNEL); + + if (!s->iso_td) + goto init_skel_cleanup; + + s->control_chain = NULL; + s->bulk_chain = NULL; + s->chain_end = NULL; + + dbg("allocating iso descs"); + for (n = 0; n < 1024; n++) { + // allocate skeleton iso/irq-tds + ret = alloc_td (&td, 0); + if (ret) + goto init_skel_cleanup; + s->iso_td[n] = td; + s->framelist[n] = ((__u32) virt_to_bus (td)); + } + + dbg("allocating qh: chain_end"); + ret = alloc_qh (&qh); + + if (ret) + goto init_skel_cleanup; + + s->chain_end = qh; + + dbg("allocating qh: bulk_chain"); + ret = alloc_qh (&qh); + + if (ret) + goto init_skel_cleanup; + + insert_qh (s, s->chain_end, qh, 0); + s->bulk_chain = qh; + dbg("allocating qh: control_chain"); + ret = alloc_qh (&qh); + + if (ret) + goto init_skel_cleanup; + + insert_qh (s, s->bulk_chain, qh, 0); + s->control_chain = qh; + for (n = 0; n < 8; n++) + s->int_chain[n] = 0; + + dbg("allocating skeleton INT-TDs"); + + for (n = 0; n < 8; n++) { + puhci_desc_t td; + + alloc_td (&td, 0); + if (!td) + goto init_skel_cleanup; + s->int_chain[n] = td; + if (n == 0) { + s->int_chain[0]->hw.td.link = virt_to_bus (s->control_chain) | UHCI_PTR_QH; + } + else { + s->int_chain[n]->hw.td.link = virt_to_bus (s->int_chain[0]); + } + } + + dbg("Linking skeleton INT-TDs"); + + for (n = 0; n < 1024; n++) { + // link all iso-tds to the interrupt chains + int m, o; + dbg("framelist[%i]=%x",n,s->framelist[n]); + if ((n&127)==127) + ((puhci_desc_t) s->iso_td[n])->hw.td.link = virt_to_bus(s->int_chain[0]); + else { + for (o = 1, m = 2; m <= 128; o++, m += m) { + // n&(m-1) = n%m + if ((n & (m - 1)) == ((m - 1) / 2)) { + ((puhci_desc_t) s->iso_td[n])->hw.td.link = virt_to_bus (s->int_chain[o]); + } + } + } + } + + mb(); + //uhci_show_queue(s->control_chain); + dbg("init_skel exit"); + return 0; // OK + + init_skel_cleanup: + cleanup_skel (s); + return -ENOMEM; +} + +/*-------------------------------------------------------------------*/ +_static void fill_td (puhci_desc_t td, int status, int info, __u32 buffer) +{ + td->hw.td.status = status; + td->hw.td.info = info; + td->hw.td.buffer = buffer; +} + +/*-------------------------------------------------------------------*/ +// LOW LEVEL STUFF +// assembles QHs und TDs for control, bulk and iso +/*-------------------------------------------------------------------*/ +_static int uhci_submit_control_urb (purb_t purb) +{ + puhci_desc_t qh, td; + puhci_t s = (puhci_t) purb->dev->bus->hcpriv; + purb_priv_t purb_priv = purb->hcpriv; + unsigned long destination, status; + int maxsze = usb_maxpacket (purb->dev, purb->pipe, usb_pipeout (purb->pipe)); + unsigned long len, bytesrequested; + char *data; + + dbg("uhci_submit_control start"); + alloc_qh (&qh); // alloc qh for this request + + if (!qh) + return -ENOMEM; + + alloc_td (&td, UHCI_PTR_DEPTH); // get td for setup stage + + if (!td) { + delete_qh (s, qh); + return -ENOMEM; + } + + /* The "pipe" thing contains the destination in bits 8--18 */ + destination = (purb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; + + /* 3 errors */ + status = (purb->pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | + (purb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27); + + /* Build the TD for the control request, try forever, 8 bytes of data */ + fill_td (td, status, destination | (7 << 21), virt_to_bus (purb->setup_packet)); + + /* If direction is "send", change the frame from SETUP (0x2D) + to OUT (0xE1). Else change it from SETUP to IN (0x69). */ + + destination ^= (USB_PID_SETUP ^ USB_PID_IN); /* SETUP -> IN */ + + if (usb_pipeout (purb->pipe)) + destination ^= (USB_PID_IN ^ USB_PID_OUT); /* IN -> OUT */ + + insert_td (s, qh, td, 0); // queue 'setup stage'-td in qh +#if 0 + dbg("SETUP to pipe %x: %x %x %x %x %x %x %x %x", purb->pipe, + purb->setup_packet[0], purb->setup_packet[1], purb->setup_packet[2], purb->setup_packet[3], + purb->setup_packet[4], purb->setup_packet[5], purb->setup_packet[6], purb->setup_packet[7]); + //uhci_show_td(td); +#endif + + /* Build the DATA TD's */ + len = purb->transfer_buffer_length; + bytesrequested = len; + data = purb->transfer_buffer; + + while (len > 0) { + int pktsze = len; + + alloc_td (&td, UHCI_PTR_DEPTH); + if (!td) { + delete_qh (s, qh); + return -ENOMEM; + } + + if (pktsze > maxsze) + pktsze = maxsze; + + destination ^= 1 << TD_TOKEN_TOGGLE; // toggle DATA0/1 + + fill_td (td, status, destination | ((pktsze - 1) << 21), + virt_to_bus (data)); // Status, pktsze bytes of data + + insert_td (s, qh, td, UHCI_PTR_DEPTH); // queue 'data stage'-td in qh + + data += pktsze; + len -= pktsze; + } + + /* Build the final TD for control status */ + /* It's only IN if the pipe is out AND we aren't expecting data */ + destination &= ~0xFF; + + if (usb_pipeout (purb->pipe) | (bytesrequested == 0)) + destination |= USB_PID_IN; + else + destination |= USB_PID_OUT; + + destination |= 1 << TD_TOKEN_TOGGLE; /* End in Data1 */ + + alloc_td (&td, UHCI_PTR_DEPTH); + + if (!td) { + delete_qh (s, qh); + return -ENOMEM; + } + + /* no limit on errors on final packet , 0 bytes of data */ + fill_td (td, status | TD_CTRL_IOC, destination | (UHCI_NULL_DATA_SIZE << 21), + 0); + + insert_td (s, qh, td, UHCI_PTR_DEPTH); // queue status td + + + list_add (&qh->desc_list, &purb_priv->desc_list); + + purb->status = USB_ST_URB_PENDING; + queue_urb (s, &purb->urb_list,1); // queue before inserting in desc chain + + //uhci_show_queue(qh); + + /* Start it up... put low speed first */ + if (purb->pipe & TD_CTRL_LS) + insert_qh (s, s->control_chain, qh, 1); // insert after control chain + else + insert_qh (s, s->bulk_chain, qh, 0); // insert before bulk chain + + //uhci_show_queue(qh); + dbg("uhci_submit_control end"); + return 0; +} +/*-------------------------------------------------------------------*/ +_static int uhci_submit_bulk_urb (purb_t purb) +{ + puhci_t s = (puhci_t) purb->dev->bus->hcpriv; + purb_priv_t purb_priv = purb->hcpriv; + puhci_desc_t qh, td; + unsigned long destination, status; + char *data; + unsigned int pipe = purb->pipe; + int maxsze = usb_maxpacket (purb->dev, pipe, usb_pipeout (pipe)); + int info, len; + + /* shouldn't the clear_halt be done in the USB core or in the client driver? - Thomas */ + if (usb_endpoint_halted (purb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)) && + usb_clear_halt (purb->dev, usb_pipeendpoint (pipe) | (pipe & USB_DIR_IN))) + return -EPIPE; + + if (!maxsze) + return -EMSGSIZE; + /* FIXME: should tell the client that the endpoint is invalid, i.e. not in the descriptor */ + + alloc_qh (&qh); // get qh for this request + + if (!qh) + return -ENOMEM; + + /* The "pipe" thing contains the destination in bits 8--18. */ + destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid (pipe); + + /* 3 errors */ + status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | + ((purb->transfer_flags & USB_DISABLE_SPD) ? 0 : TD_CTRL_SPD) | (3 << 27); + + /* Build the TDs for the bulk request */ + len = purb->transfer_buffer_length; + data = purb->transfer_buffer; + dbg("uhci_submit_bulk_urb: pipe %x, len %d", pipe, len); + + while (len > 0) { + int pktsze = len; + + alloc_td (&td, UHCI_PTR_DEPTH); + + if (!td) { + delete_qh (s, qh); + return -ENOMEM; + } + + if (pktsze > maxsze) + pktsze = maxsze; + + // pktsze bytes of data + info = destination | ((pktsze - 1) << 21) | + (usb_gettoggle (purb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)) << TD_TOKEN_TOGGLE); + + fill_td (td, status, info, virt_to_bus (data)); + + data += pktsze; + len -= pktsze; + + if (!len) + td->hw.td.status |= TD_CTRL_IOC; // last one generates INT + //dbg("insert td %p, len %i",td,pktsze); + + insert_td (s, qh, td, UHCI_PTR_DEPTH); + + /* Alternate Data0/1 (start with Data0) */ + usb_dotoggle (purb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)); + } + + list_add (&qh->desc_list, &purb_priv->desc_list); + + purb->status = USB_ST_URB_PENDING; + queue_urb (s, &purb->urb_list,1); + + insert_qh (s, s->chain_end, qh, 0); // insert before end marker + //uhci_show_queue(s->bulk_chain); + + dbg("uhci_submit_bulk_urb: exit"); + return 0; +} +/*-------------------------------------------------------------------*/ +// unlinks an urb by dequeuing its qh, waits some frames and forgets it +// Problem: unlinking in interrupt requires waiting for one frame (udelay) +// to allow the whole structures to be safely removed +_static int uhci_unlink_urb (purb_t purb) +{ + puhci_t s; + puhci_desc_t qh; + puhci_desc_t td; + purb_priv_t purb_priv; + unsigned long flags=0; + struct list_head *p; + + if (!purb) // you never know... + return -1; + + s = (puhci_t) purb->dev->bus->hcpriv; // get pointer to uhci struct + + if (usb_pipedevice (purb->pipe) == s->rh.devnum) + return rh_unlink_urb (purb); + + if(!in_interrupt()) { + spin_lock_irqsave (&s->unlink_urb_lock, flags); // do not allow interrupts + } + + //dbg("unlink_urb called %p",purb); + if (purb->status == USB_ST_URB_PENDING) { + // URB probably still in work + purb_priv = purb->hcpriv; + dequeue_urb (s, &purb->urb_list,1); + purb->status = USB_ST_URB_KILLED; // mark urb as killed + + if(!in_interrupt()) { + spin_unlock_irqrestore (&s->unlink_urb_lock, flags); // allow interrupts from here + } + + switch (usb_pipetype (purb->pipe)) { + case PIPE_ISOCHRONOUS: + case PIPE_INTERRUPT: + for (p = purb_priv->desc_list.next; p != &purb_priv->desc_list; p = p->next) { + td = list_entry (p, uhci_desc_t, desc_list); + unlink_td (s, td); + } + // wait at least 1 Frame + if (in_interrupt ()) + udelay (1000); + else + wait_ms(1); + while ((p = purb_priv->desc_list.next) != &purb_priv->desc_list) { + td = list_entry (p, uhci_desc_t, desc_list); + list_del (p); + delete_desc (td); + } + break; + + case PIPE_BULK: + case PIPE_CONTROL: + qh = list_entry (purb_priv->desc_list.next, uhci_desc_t, desc_list); + + unlink_qh (s, qh); // remove this qh from qh-list + // wait at least 1 Frame + + if (in_interrupt ()) + udelay (1000); + else + wait_ms(1); + delete_qh (s, qh); // remove it physically + + } + +#ifdef DEBUG_SLAB + kmem_cache_free(urb_priv_kmem, purb->hcpriv); +#else + kfree (purb->hcpriv); +#endif + if (purb->complete) { + dbg("unlink_urb: calling completion"); + purb->complete ((struct urb *) purb); + usb_dec_dev_use (purb->dev); + } + return 0; + } + else { + if(!in_interrupt()) + spin_unlock_irqrestore (&s->unlink_urb_lock, flags); // allow interrupts from here + } + + return 0; +} +/*-------------------------------------------------------------------*/ +// In case of ASAP iso transfer, search the URB-list for already queued URBs +// for this EP and calculate the earliest start frame for the new +// URB (easy seamless URB continuation!) +_static int find_iso_limits (purb_t purb, unsigned int *start, unsigned int *end) +{ + purb_t u, last_urb = NULL; + puhci_t s = (puhci_t) purb->dev->bus->hcpriv; + struct list_head *p = s->urb_list.next; + int ret=-1; + unsigned long flags; + + spin_lock_irqsave (&s->urb_list_lock, flags); + + for (; p != &s->urb_list; p = p->next) { + u = list_entry (p, urb_t, urb_list); + // look for pending URBs with identical pipe handle + // works only because iso doesn't toggle the data bit! + if ((purb->pipe == u->pipe) && (purb->dev == u->dev) && (u->status == USB_ST_URB_PENDING)) { + if (!last_urb) + *start = u->start_frame; + last_urb = u; + } + } + + if (last_urb) { + *end = (last_urb->start_frame + last_urb->number_of_packets) & 1023; + ret=0; + } + + spin_unlock_irqrestore(&s->urb_list_lock, flags); + + return ret; // no previous urb found + +} +/*-------------------------------------------------------------------*/ +// adjust start_frame according to scheduling constraints (ASAP etc) + +_static int iso_find_start (purb_t purb) +{ + puhci_t s = (puhci_t) purb->dev->bus->hcpriv; + unsigned int now; + unsigned int start_limit = 0, stop_limit = 0, queued_size; + int limits; + + now = UHCI_GET_CURRENT_FRAME (s) & 1023; + + if ((unsigned) purb->number_of_packets > 900) + return -EFBIG; + + limits = find_iso_limits (purb, &start_limit, &stop_limit); + queued_size = (stop_limit - start_limit) & 1023; + + if (purb->transfer_flags & USB_ISO_ASAP) { + // first iso + if (limits) { + // 10ms setup should be enough //FIXME! + purb->start_frame = (now + 10) & 1023; + } + else { + purb->start_frame = stop_limit; //seamless linkage + + if (((now - purb->start_frame) & 1023) <= (unsigned) purb->number_of_packets) { + dbg("iso_find_start: warning, ASAP gap, should not happen"); + dbg("iso_find_start: now %u start_frame %u number_of_packets %u pipe 0x%08x", + now, purb->start_frame, purb->number_of_packets, purb->pipe); +// The following code is only for debugging purposes... +#if 0 + { + puhci_t s = (puhci_t) purb->dev->bus->hcpriv; + struct list_head *p; + purb_t u; + int a = -1, b = -1; + unsigned long flags; + + spin_lock_irqsave (&s->urb_list_lock, flags); + p=s->urb_list.next; + + for (; p != &s->urb_list; p = p->next) { + u = list_entry (p, urb_t, urb_list); + if (purb->dev != u->dev) + continue; + dbg("urb: pipe 0x%08x status %d start_frame %u number_of_packets %u", + u->pipe, u->status, u->start_frame, u->number_of_packets); + if (!usb_pipeisoc (u->pipe)) + continue; + if (a == -1) + a = u->start_frame; + b = (u->start_frame + u->number_of_packets - 1) & 1023; + } + spin_unlock_irqrestore(&s->urb_list_lock, flags); + } +#endif + purb->start_frame = (now + 5) & 1023; // 5ms setup should be enough //FIXME! + //return -EAGAIN; //FIXME + } + } + } + else { + purb->start_frame &= 1023; + if (((now - purb->start_frame) & 1023) < (unsigned) purb->number_of_packets) { + dbg("iso_find_start: now between start_frame and end"); + return -EAGAIN; + } + } + + /* check if either start_frame or start_frame+number_of_packets-1 lies between start_limit and stop_limit */ + if (limits) + return 0; + + if (((purb->start_frame - start_limit) & 1023) < queued_size || + ((purb->start_frame + purb->number_of_packets - 1 - start_limit) & 1023) < queued_size) { + dbg("iso_find_start: start_frame %u number_of_packets %u start_limit %u stop_limit %u", + purb->start_frame, purb->number_of_packets, start_limit, stop_limit); + return -EAGAIN; + } + + return 0; +} +/*-------------------------------------------------------------------*/ +// submits USB interrupt (ie. polling ;-) +// ASAP-flag set implicitely +// if period==0, the the transfer is only done once (usb_scsi need this...) + +_static int uhci_submit_int_urb (purb_t purb) +{ + puhci_t s = (puhci_t) purb->dev->bus->hcpriv; + purb_priv_t purb_priv = purb->hcpriv; + int nint, n, ret; + puhci_desc_t td; + int status, destination; + int now; + int info; + unsigned int pipe = purb->pipe; + + //dbg("SUBMIT INT"); + + if (purb->interval < 0 || purb->interval >= 256) + return -EINVAL; + + if (purb->interval == 0) + nint = 0; + else { + for (nint = 0, n = 1; nint <= 8; nint++, n += n) // round interval down to 2^n + { + if (purb->interval < n) { + purb->interval = n / 2; + break; + } + } + nint--; + } + dbg("Rounded interval to %i, chain %i", purb->interval, nint); + + now = UHCI_GET_CURRENT_FRAME (s) & 1023; + purb->start_frame = now; // remember start frame, just in case... + + purb->number_of_packets = 1; + + // INT allows only one packet + if (purb->transfer_buffer_length > usb_maxpacket (purb->dev, pipe, usb_pipeout (pipe))) + return -EINVAL; + + ret = alloc_td (&td, UHCI_PTR_DEPTH); + + if (ret) + return -ENOMEM; + + status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC | + (purb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27); + + destination = (purb->pipe & PIPE_DEVEP_MASK) | usb_packetid (purb->pipe) | + (((purb->transfer_buffer_length - 1) & 0x7ff) << 21); + + + info = destination | (usb_gettoggle (purb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)) << TD_TOKEN_TOGGLE); + + fill_td (td, status, info, virt_to_bus (purb->transfer_buffer)); + list_add_tail (&td->desc_list, &purb_priv->desc_list); + + purb->status = USB_ST_URB_PENDING; + queue_urb (s, &purb->urb_list,1); + + insert_td_horizontal (s, s->int_chain[nint], td, UHCI_PTR_DEPTH); // store in INT-TDs + + usb_dotoggle (purb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)); + +#if 0 + td = tdm[purb->number_of_packets]; + fill_td (td, TD_CTRL_IOC, 0, 0); + insert_td_horizontal (s, s->iso_td[(purb->start_frame + (purb->number_of_packets) * purb->interval + 1) & 1023], td, UHCI_PTR_DEPTH); + list_add_tail (&td->desc_list, &purb_priv->desc_list); +#endif + + return 0; +} +/*-------------------------------------------------------------------*/ +_static int uhci_submit_iso_urb (purb_t purb) +{ + puhci_t s = (puhci_t) purb->dev->bus->hcpriv; + purb_priv_t purb_priv = purb->hcpriv; + int pipe=purb->pipe; + int maxsze = usb_maxpacket (purb->dev, pipe, usb_pipeout (pipe)); + int n, ret, last=0; + puhci_desc_t td, *tdm; + int status, destination; + unsigned long flags; + spinlock_t lock; + + spin_lock_init (&lock); + spin_lock_irqsave (&lock, flags); // Disable IRQs to schedule all ISO-TDs in time + + ret = iso_find_start (purb); // adjusts purb->start_frame for later use + + if (ret) + goto err; + + tdm = (puhci_desc_t *) kmalloc (purb->number_of_packets * sizeof (puhci_desc_t), in_interrupt ()? GFP_ATOMIC : GFP_KERNEL); + + if (!tdm) { + ret = -ENOMEM; + goto err; + } + + // First try to get all TDs + for (n = 0; n < purb->number_of_packets; n++) { + dbg("n:%d purb->iso_frame_desc[n].length:%d", n, purb->iso_frame_desc[n].length); + if (!purb->iso_frame_desc[n].length) { + // allows ISO striping by setting length to zero in iso_descriptor + tdm[n] = 0; + continue; + } + if(purb->iso_frame_desc[n].length > maxsze) { + err("submit_iso: purb->iso_frame_desc[%d].length(%d)>%d",n , purb->iso_frame_desc[n].length, maxsze); + tdm[n] = 0; + continue; + } + ret = alloc_td (&td, UHCI_PTR_DEPTH); + if (ret) { + int i; // Cleanup allocated TDs + + for (i = 0; i < n; n++) + if (tdm[i]) + kfree (tdm[i]); + kfree (tdm); + ret = -ENOMEM; + goto err; + } + last=n; + tdm[n] = td; + } + + status = TD_CTRL_ACTIVE | TD_CTRL_IOS; //| (purb->transfer_flags&USB_DISABLE_SPD?0:TD_CTRL_SPD); + + destination = (purb->pipe & PIPE_DEVEP_MASK) | usb_packetid (purb->pipe); + + + // Queue all allocated TDs + for (n = 0; n < purb->number_of_packets; n++) { + td = tdm[n]; + if (!td) + continue; + + if (n == last) + status |= TD_CTRL_IOC; + + fill_td (td, status, destination | (((purb->iso_frame_desc[n].length - 1) & 0x7ff) << 21), + virt_to_bus (purb->transfer_buffer + purb->iso_frame_desc[n].offset)); + list_add_tail (&td->desc_list, &purb_priv->desc_list); + + if (n == last) { + purb->status = USB_ST_URB_PENDING; + queue_urb (s, &purb->urb_list,1); + } + insert_td_horizontal (s, s->iso_td[(purb->start_frame + n) & 1023], td, UHCI_PTR_DEPTH); // store in iso-tds + //uhci_show_td(td); + + } + + kfree (tdm); + dbg("ISO-INT# %i, start %i, now %i", purb->number_of_packets, purb->start_frame, UHCI_GET_CURRENT_FRAME (s) & 1023); + ret = 0; + + err: + spin_unlock_irqrestore (&lock, flags); + return ret; + +} +/*-------------------------------------------------------------------*/ +_static int search_dev_ep (puhci_t s, purb_t purb) +{ + unsigned long flags; + struct list_head *p = s->urb_list.next; + purb_t tmp; + unsigned int mask = usb_pipecontrol(purb->pipe) ? (~USB_DIR_IN) : (~0); + + dbg("search_dev_ep:"); + spin_lock_irqsave (&s->urb_list_lock, flags); + for (; p != &s->urb_list; p = p->next) { + tmp = list_entry (p, urb_t, urb_list); + dbg("urb: %p", tmp); + // we can accept this urb if it is not queued at this time + // or if non-iso transfer requests should be scheduled for the same device and pipe + if ((!usb_pipeisoc(purb->pipe) && tmp->dev == purb->dev && !((tmp->pipe ^ purb->pipe) & mask)) || + (purb == tmp)) { + spin_unlock_irqrestore (&s->urb_list_lock, flags); + return 1; // found another urb already queued for processing + } + } + spin_unlock_irqrestore (&s->urb_list_lock, flags); + return 0; +} +/*-------------------------------------------------------------------*/ +_static int uhci_submit_urb (purb_t purb) +{ + puhci_t s; + purb_priv_t purb_priv; + int ret = 0; + + if (!purb->dev || !purb->dev->bus) + return -ENODEV; + + s = (puhci_t) purb->dev->bus->hcpriv; + //dbg("submit_urb: %p type %d",purb,usb_pipetype(purb->pipe)); + + if (usb_pipedevice (purb->pipe) == s->rh.devnum) + return rh_submit_urb (purb); /* virtual root hub */ + + usb_inc_dev_use (purb->dev); + + if (search_dev_ep (s, purb)) { + usb_dec_dev_use (purb->dev); + return -ENXIO; // urb already queued + + } + +#ifdef DEBUG_SLAB + purb_priv = kmem_cache_alloc(urb_priv_kmem, in_interrupt ()? SLAB_ATOMIC : SLAB_KERNEL); +#else + purb_priv = kmalloc (sizeof (urb_priv_t), in_interrupt ()? GFP_ATOMIC : GFP_KERNEL); +#endif + if (!purb_priv) { + usb_dec_dev_use (purb->dev); + return -ENOMEM; + } + + purb->hcpriv = purb_priv; + INIT_LIST_HEAD (&purb_priv->desc_list); + purb_priv->short_control_packet=0; + dbg("submit_urb: scheduling %p", purb); + + switch (usb_pipetype (purb->pipe)) { + case PIPE_ISOCHRONOUS: + ret = uhci_submit_iso_urb (purb); + break; + case PIPE_INTERRUPT: + ret = uhci_submit_int_urb (purb); + break; + case PIPE_CONTROL: + //dump_urb (purb); + ret = uhci_submit_control_urb (purb); + break; + case PIPE_BULK: + ret = uhci_submit_bulk_urb (purb); + break; + default: + ret = -EINVAL; + } + + dbg("submit_urb: scheduled with ret: %d", ret); + + if (ret != USB_ST_NOERROR) { + usb_dec_dev_use (purb->dev); +#ifdef DEBUG_SLAB + kmem_cache_free(urb_priv_kmem, purb_priv); +#else + kfree (purb_priv); +#endif + return ret; + } +/* + purb->status = USB_ST_URB_PENDING; + queue_urb (s, &purb->urb_list,1); + dbg("submit_urb: exit"); +*/ + return 0; +} +/*------------------------------------------------------------------- + Virtual Root Hub + -------------------------------------------------------------------*/ + +_static __u8 root_hub_dev_des[] = +{ + 0x12, /* __u8 bLength; */ + 0x01, /* __u8 bDescriptorType; Device */ + 0x00, /* __u16 bcdUSB; v1.0 */ + 0x01, + 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ + 0x00, /* __u8 bDeviceSubClass; */ + 0x00, /* __u8 bDeviceProtocol; */ + 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ + 0x00, /* __u16 idVendor; */ + 0x00, + 0x00, /* __u16 idProduct; */ + 0x00, + 0x00, /* __u16 bcdDevice; */ + 0x00, + 0x00, /* __u8 iManufacturer; */ + 0x00, /* __u8 iProduct; */ + 0x00, /* __u8 iSerialNumber; */ + 0x01 /* __u8 bNumConfigurations; */ +}; + + +/* Configuration descriptor */ +_static __u8 root_hub_config_des[] = +{ + 0x09, /* __u8 bLength; */ + 0x02, /* __u8 bDescriptorType; Configuration */ + 0x19, /* __u16 wTotalLength; */ + 0x00, + 0x01, /* __u8 bNumInterfaces; */ + 0x01, /* __u8 bConfigurationValue; */ + 0x00, /* __u8 iConfiguration; */ + 0x40, /* __u8 bmAttributes; + Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */ + 0x00, /* __u8 MaxPower; */ + + /* interface */ + 0x09, /* __u8 if_bLength; */ + 0x04, /* __u8 if_bDescriptorType; Interface */ + 0x00, /* __u8 if_bInterfaceNumber; */ + 0x00, /* __u8 if_bAlternateSetting; */ + 0x01, /* __u8 if_bNumEndpoints; */ + 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ + 0x00, /* __u8 if_bInterfaceSubClass; */ + 0x00, /* __u8 if_bInterfaceProtocol; */ + 0x00, /* __u8 if_iInterface; */ + + /* endpoint */ + 0x07, /* __u8 ep_bLength; */ + 0x05, /* __u8 ep_bDescriptorType; Endpoint */ + 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ + 0x03, /* __u8 ep_bmAttributes; Interrupt */ + 0x08, /* __u16 ep_wMaxPacketSize; 8 Bytes */ + 0x00, + 0xff /* __u8 ep_bInterval; 255 ms */ +}; + + +_static __u8 root_hub_hub_des[] = +{ + 0x09, /* __u8 bLength; */ + 0x29, /* __u8 bDescriptorType; Hub-descriptor */ + 0x02, /* __u8 bNbrPorts; */ + 0x00, /* __u16 wHubCharacteristics; */ + 0x00, + 0x01, /* __u8 bPwrOn2pwrGood; 2ms */ + 0x00, /* __u8 bHubContrCurrent; 0 mA */ + 0x00, /* __u8 DeviceRemovable; *** 7 Ports max *** */ + 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */ +}; + +/*-------------------------------------------------------------------------*/ +/* prepare Interrupt pipe transaction data; HUB INTERRUPT ENDPOINT */ +_static int rh_send_irq (purb_t purb) +{ + + int len = 1; + int i; + puhci_t uhci = purb->dev->bus->hcpriv; + unsigned int io_addr = uhci->io_addr; + __u16 data = 0; + + for (i = 0; i < uhci->rh.numports; i++) { + data |= ((inw (io_addr + USBPORTSC1 + i * 2) & 0xa) > 0 ? (1 << (i + 1)) : 0); + len = (i + 1) / 8 + 1; + } + + *(__u16 *) purb->transfer_buffer = cpu_to_le16 (data); + purb->actual_length = len; + purb->status = USB_ST_NOERROR; + + if ((data > 0) && (uhci->rh.send != 0)) { + dbg("Root-Hub INT complete: port1: %x port2: %x data: %x", + inw (io_addr + USBPORTSC1), inw (io_addr + USBPORTSC2), data); + purb->complete (purb); + + } + return USB_ST_NOERROR; +} + +/*-------------------------------------------------------------------------*/ +/* Virtual Root Hub INTs are polled by this timer every "intervall" ms */ +_static int rh_init_int_timer (purb_t purb); + +_static void rh_int_timer_do (unsigned long ptr) +{ + int len; + + purb_t purb = (purb_t) ptr; + puhci_t uhci = purb->dev->bus->hcpriv; + + if (uhci->rh.send) { + len = rh_send_irq (purb); + if (len > 0) { + purb->actual_length = len; + if (purb->complete) + purb->complete (purb); + } + } + rh_init_int_timer (purb); +} + +/*-------------------------------------------------------------------------*/ +/* Root Hub INTs are polled by this timer */ +_static int rh_init_int_timer (purb_t purb) +{ + puhci_t uhci = purb->dev->bus->hcpriv; + + uhci->rh.interval = purb->interval; + init_timer (&uhci->rh.rh_int_timer); + uhci->rh.rh_int_timer.function = rh_int_timer_do; + uhci->rh.rh_int_timer.data = (unsigned long) purb; + uhci->rh.rh_int_timer.expires = jiffies + (HZ * (purb->interval < 30 ? 30 : purb->interval)) / 1000; + add_timer (&uhci->rh.rh_int_timer); + + return 0; +} + +/*-------------------------------------------------------------------------*/ +#define OK(x) len = (x); break + +#define CLR_RH_PORTSTAT(x) \ + status = inw(io_addr+USBPORTSC1+2*(wIndex-1)); \ + status = (status & 0xfff5) & ~(x); \ + outw(status, io_addr+USBPORTSC1+2*(wIndex-1)) + +#define SET_RH_PORTSTAT(x) \ + status = inw(io_addr+USBPORTSC1+2*(wIndex-1)); \ + status = (status & 0xfff5) | (x); \ + outw(status, io_addr+USBPORTSC1+2*(wIndex-1)) + + +/*-------------------------------------------------------------------------*/ +/**** + ** Root Hub Control Pipe + *************************/ + + +_static int rh_submit_urb (purb_t purb) +{ + struct usb_device *usb_dev = purb->dev; + puhci_t uhci = usb_dev->bus->hcpriv; + unsigned int pipe = purb->pipe; + devrequest *cmd = (devrequest *) purb->setup_packet; + void *data = purb->transfer_buffer; + int leni = purb->transfer_buffer_length; + int len = 0; + int status = 0; + int stat = USB_ST_NOERROR; + int i; + unsigned int io_addr = uhci->io_addr; + __u16 cstatus; + + __u16 bmRType_bReq; + __u16 wValue; + __u16 wIndex; + __u16 wLength; + + if (usb_pipetype (pipe) == PIPE_INTERRUPT) { + dbg("Root-Hub submit IRQ: every %d ms", purb->interval); + uhci->rh.urb = purb; + uhci->rh.send = 1; + uhci->rh.interval = purb->interval; + rh_init_int_timer (purb); + + return USB_ST_NOERROR; + } + + + bmRType_bReq = cmd->requesttype | cmd->request << 8; + wValue = le16_to_cpu (cmd->value); + wIndex = le16_to_cpu (cmd->index); + wLength = le16_to_cpu (cmd->length); + + for (i = 0; i < 8; i++) + uhci->rh.c_p_r[i] = 0; + + dbg("Root-Hub: adr: %2x cmd(%1x): %04x %04x %04x %04x", + uhci->rh.devnum, 8, bmRType_bReq, wValue, wIndex, wLength); + + switch (bmRType_bReq) { + /* Request Destination: + without flags: Device, + RH_INTERFACE: interface, + RH_ENDPOINT: endpoint, + RH_CLASS means HUB here, + RH_OTHER | RH_CLASS almost ever means HUB_PORT here + */ + + case RH_GET_STATUS: + *(__u16 *) data = cpu_to_le16 (1); + OK (2); + case RH_GET_STATUS | RH_INTERFACE: + *(__u16 *) data = cpu_to_le16 (0); + OK (2); + case RH_GET_STATUS | RH_ENDPOINT: + *(__u16 *) data = cpu_to_le16 (0); + OK (2); + case RH_GET_STATUS | RH_CLASS: + *(__u32 *) data = cpu_to_le32 (0); + OK (4); /* hub power ** */ + case RH_GET_STATUS | RH_OTHER | RH_CLASS: + status = inw (io_addr + USBPORTSC1 + 2 * (wIndex - 1)); + cstatus = ((status & USBPORTSC_CSC) >> (1 - 0)) | + ((status & USBPORTSC_PEC) >> (3 - 1)) | + (uhci->rh.c_p_r[wIndex - 1] << (0 + 4)); + status = (status & USBPORTSC_CCS) | + ((status & USBPORTSC_PE) >> (2 - 1)) | + ((status & USBPORTSC_SUSP) >> (12 - 2)) | + ((status & USBPORTSC_PR) >> (9 - 4)) | + (1 << 8) | /* power on ** */ + ((status & USBPORTSC_LSDA) << (-8 + 9)); + + *(__u16 *) data = cpu_to_le16 (status); + *(__u16 *) (data + 2) = cpu_to_le16 (cstatus); + OK (4); + + case RH_CLEAR_FEATURE | RH_ENDPOINT: + switch (wValue) { + case (RH_ENDPOINT_STALL): + OK (0); + } + break; + + case RH_CLEAR_FEATURE | RH_CLASS: + switch (wValue) { + case (RH_C_HUB_OVER_CURRENT): + OK (0); /* hub power over current ** */ + } + break; + + case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: + switch (wValue) { + case (RH_PORT_ENABLE): + CLR_RH_PORTSTAT (USBPORTSC_PE); + OK (0); + case (RH_PORT_SUSPEND): + CLR_RH_PORTSTAT (USBPORTSC_SUSP); + OK (0); + case (RH_PORT_POWER): + OK (0); /* port power ** */ + case (RH_C_PORT_CONNECTION): + SET_RH_PORTSTAT (USBPORTSC_CSC); + OK (0); + case (RH_C_PORT_ENABLE): + SET_RH_PORTSTAT (USBPORTSC_PEC); + OK (0); + case (RH_C_PORT_SUSPEND): +/*** WR_RH_PORTSTAT(RH_PS_PSSC); */ + OK (0); + case (RH_C_PORT_OVER_CURRENT): + OK (0); /* port power over current ** */ + case (RH_C_PORT_RESET): + uhci->rh.c_p_r[wIndex - 1] = 0; + OK (0); + } + break; + + case RH_SET_FEATURE | RH_OTHER | RH_CLASS: + switch (wValue) { + case (RH_PORT_SUSPEND): + SET_RH_PORTSTAT (USBPORTSC_SUSP); + OK (0); + case (RH_PORT_RESET): + SET_RH_PORTSTAT (USBPORTSC_PR); + wait_ms (10); + uhci->rh.c_p_r[wIndex - 1] = 1; + CLR_RH_PORTSTAT (USBPORTSC_PR); + udelay (10); + SET_RH_PORTSTAT (USBPORTSC_PE); + wait_ms (10); + SET_RH_PORTSTAT (0xa); + OK (0); + case (RH_PORT_POWER): + OK (0); /* port power ** */ + case (RH_PORT_ENABLE): + SET_RH_PORTSTAT (USBPORTSC_PE); + OK (0); + } + break; + + case RH_SET_ADDRESS: + uhci->rh.devnum = wValue; + OK (0); + + case RH_GET_DESCRIPTOR: + switch ((wValue & 0xff00) >> 8) { + case (0x01): /* device descriptor */ + len = min (leni, min (sizeof (root_hub_dev_des), wLength)); + memcpy (data, root_hub_dev_des, len); + OK (len); + case (0x02): /* configuration descriptor */ + len = min (leni, min (sizeof (root_hub_config_des), wLength)); + memcpy (data, root_hub_config_des, len); + OK (len); + case (0x03): /*string descriptors */ + stat = -EPIPE; + } + break; + + case RH_GET_DESCRIPTOR | RH_CLASS: + root_hub_hub_des[2] = uhci->rh.numports; + len = min (leni, min (sizeof (root_hub_hub_des), wLength)); + memcpy (data, root_hub_hub_des, len); + OK (len); + + case RH_GET_CONFIGURATION: + *(__u8 *) data = 0x01; + OK (1); + + case RH_SET_CONFIGURATION: + OK (0); + default: + stat = -EPIPE; + } + + + dbg("Root-Hub stat port1: %x port2: %x", + inw (io_addr + USBPORTSC1), inw (io_addr + USBPORTSC2)); + + purb->actual_length = len; + purb->status = stat; + if (purb->complete) + purb->complete (purb); + return USB_ST_NOERROR; +} +/*-------------------------------------------------------------------------*/ + +_static int rh_unlink_urb (purb_t purb) +{ + puhci_t uhci = purb->dev->bus->hcpriv; + + dbg("Root-Hub unlink IRQ"); + uhci->rh.send = 0; + del_timer (&uhci->rh.rh_int_timer); + return 0; +} +/*-------------------------------------------------------------------*/ + +/* + * Map status to standard result codes + * + * is (td->status & 0xFE0000) [a.k.a. uhci_status_bits(td->status) + * is True for output TDs and False for input TDs. + */ +_static int uhci_map_status (int status, int dir_out) +{ + if (!status) + return USB_ST_NOERROR; + if (status & TD_CTRL_BITSTUFF) /* Bitstuff error */ + return -EPROTO; + if (status & TD_CTRL_CRCTIMEO) { /* CRC/Timeout */ + if (dir_out) + return -ETIMEDOUT; + else + return -EILSEQ; + } + if (status & TD_CTRL_NAK) /* NAK */ + return -ETIMEDOUT; + if (status & TD_CTRL_BABBLE) /* Babble */ + return -EPIPE; + if (status & TD_CTRL_DBUFERR) /* Buffer error */ + return -ENOSR; + if (status & TD_CTRL_STALLED) /* Stalled */ + return -EPIPE; + if (status & TD_CTRL_ACTIVE) /* Active */ + return USB_ST_NOERROR; + + return -EPROTO; +} + +/* + * Only the USB core should call uhci_alloc_dev and uhci_free_dev + */ +_static int uhci_alloc_dev (struct usb_device *usb_dev) +{ + return 0; +} + +_static int uhci_free_dev (struct usb_device *usb_dev) +{ + return 0; +} + +/* + * uhci_get_current_frame_number() + * + * returns the current frame number for a USB bus/controller. + */ +_static int uhci_get_current_frame_number (struct usb_device *usb_dev) +{ + return UHCI_GET_CURRENT_FRAME ((puhci_t) usb_dev->bus->hcpriv); +} + +struct usb_operations uhci_device_operations = +{ + uhci_alloc_dev, + uhci_free_dev, + uhci_get_current_frame_number, + uhci_submit_urb, + uhci_unlink_urb +}; + +/* + * For IN-control transfers, process_transfer gets a bit more complicated, + * since there are devices that return less data (eg. strings) than they + * have announced. This leads to a queue abort due to the short packet, + * the status stage is not executed. If this happens, the status stage + * is manually re-executed. + * FIXME: Stall-condition may override 'nearly' successful CTRL-IN-transfer + * when the transfered length fits exactly in maxsze-packets. A bit + * more intelligence is needed to detect this and finish without error. + */ +_static int process_transfer (puhci_t s, purb_t purb) +{ + int ret = USB_ST_NOERROR; + purb_priv_t purb_priv = purb->hcpriv; + struct list_head *qhl = purb_priv->desc_list.next; + puhci_desc_t qh = list_entry (qhl, uhci_desc_t, desc_list); + struct list_head *p = qh->vertical.next; + puhci_desc_t desc= list_entry (purb_priv->desc_list.prev, uhci_desc_t, desc_list); + puhci_desc_t last_desc = list_entry (desc->vertical.prev, uhci_desc_t, vertical); + int data_toggle = usb_gettoggle (purb->dev, usb_pipeendpoint (purb->pipe), usb_pipeout (purb->pipe)); // save initial data_toggle + + + // extracted and remapped info from TD + int maxlength; + int actual_length; + int status = USB_ST_NOERROR; + + dbg("process_transfer: urb contains bulk/control request"); + + + /* if the status phase has been retriggered and the + queue is empty or the last status-TD is inactive, the retriggered + status stage is completed + */ +#if 1 + if (purb_priv->short_control_packet && + ((qh->hw.qh.element == UHCI_PTR_TERM) ||(!(last_desc->hw.td.status & TD_CTRL_ACTIVE)))) + goto transfer_finished; +#endif + purb->actual_length=0; + + for (; p != &qh->vertical; p = p->next) { + desc = list_entry (p, uhci_desc_t, vertical); + + if (desc->hw.td.status & TD_CTRL_ACTIVE) // do not process active TDs + return ret; + + // extract transfer parameters from TD + actual_length = (desc->hw.td.status + 1) & 0x7ff; + maxlength = (((desc->hw.td.info >> 21) & 0x7ff) + 1) & 0x7ff; + status = uhci_map_status (uhci_status_bits (desc->hw.td.status), usb_pipeout (purb->pipe)); + + // see if EP is stalled + if (status == -EPIPE) { + // set up stalled condition + usb_endpoint_halt (purb->dev, usb_pipeendpoint (purb->pipe), usb_pipeout (purb->pipe)); + } + + // if any error occured stop processing of further TDs + if (status != USB_ST_NOERROR) { + // only set ret if status returned an error + uhci_show_td (desc); + ret = status; + purb->error_count++; + break; + } + else if ((desc->hw.td.info & 0xff) != USB_PID_SETUP) + purb->actual_length += actual_length; + +#if 0 + // if (i++==0) + uhci_show_td (desc); // show first TD of each transfer +#endif + + // got less data than requested + if ( (actual_length < maxlength)) { + if (purb->transfer_flags & USB_DISABLE_SPD) { + ret = USB_ST_SHORT_PACKET; // treat as real error + dbg("process_transfer: SPD!!"); + break; // exit after this TD because SP was detected + } + + // short read during control-IN: re-start status stage + if ((usb_pipetype (purb->pipe) == PIPE_CONTROL)) { + if (uhci_packetid(last_desc->hw.td.info) == USB_PID_OUT) { + + qh->hw.qh.element = virt_to_bus (last_desc); // re-trigger status stage + dbg("short packet during control transfer, retrigger status stage @ %p",last_desc); + uhci_show_td (desc); + uhci_show_td (last_desc); + purb_priv->short_control_packet=1; + return 0; + } + } + // all other cases: short read is OK + data_toggle = uhci_toggle (desc->hw.td.info); + break; + } + + data_toggle = uhci_toggle (desc->hw.td.info); + //dbg("process_transfer: len:%d status:%x mapped:%x toggle:%d", actual_length, desc->hw.td.status,status, data_toggle); + + } + usb_settoggle (purb->dev, usb_pipeendpoint (purb->pipe), usb_pipeout (purb->pipe), !data_toggle); + transfer_finished: + + /* APC BackUPS Pro kludge */ + /* It tries to send all of the descriptor instead of */ + /* the amount we requested */ + if (desc->hw.td.status & TD_CTRL_IOC && + status & TD_CTRL_ACTIVE && + status & TD_CTRL_NAK ) + { + dbg("APS WORKAROUND"); + ret=0; + status=0; + } + + unlink_qh (s, qh); + delete_qh (s, qh); + + purb->status = status; + + dbg("process_transfer: urb %p, wanted len %d, len %d status %x err %d", + purb,purb->transfer_buffer_length,purb->actual_length, purb->status, purb->error_count); + //dbg("process_transfer: exit"); +#if 0 + if (purb->actual_length){ + char *uu; + uu=purb->transfer_buffer; + dbg("%x %x %x %x %x %x %x %x", + *uu,*(uu+1),*(uu+2),*(uu+3),*(uu+4),*(uu+5),*(uu+6),*(uu+7)); + } +#endif + return ret; +} + +_static int process_interrupt (puhci_t s, purb_t purb) +{ + int i, ret = USB_ST_URB_PENDING; + purb_priv_t purb_priv = purb->hcpriv; + struct list_head *p = purb_priv->desc_list.next; + puhci_desc_t desc = list_entry (purb_priv->desc_list.prev, uhci_desc_t, desc_list); + + int actual_length; + int status = USB_ST_NOERROR; + + //dbg("urb contains interrupt request"); + + for (i = 0; p != &purb_priv->desc_list; p = p->next, i++) // Maybe we allow more than one TD later ;-) + { + desc = list_entry (p, uhci_desc_t, desc_list); + + if (desc->hw.td.status & TD_CTRL_ACTIVE) { + // do not process active TDs + //dbg("TD ACT Status @%p %08x",desc,desc->hw.td.status); + break; + } + + if (!desc->hw.td.status & TD_CTRL_IOC) { + // do not process one-shot TDs, no recycling + break; + } + // extract transfer parameters from TD + + actual_length = (desc->hw.td.status + 1) & 0x7ff; + status = uhci_map_status (uhci_status_bits (desc->hw.td.status), usb_pipeout (purb->pipe)); + + // see if EP is stalled + if (status == -EPIPE) { + // set up stalled condition + usb_endpoint_halt (purb->dev, usb_pipeendpoint (purb->pipe), usb_pipeout (purb->pipe)); + } + + // if any error occured: ignore this td, and continue + if (status != USB_ST_NOERROR) { + uhci_show_td (desc); + purb->error_count++; + goto recycle; + } + else + purb->actual_length = actual_length; + + // FIXME: SPD? + + recycle: + if (purb->complete) { + //dbg("process_interrupt: calling completion, status %i",status); + purb->status = status; + purb->complete ((struct urb *) purb); + purb->status = USB_ST_URB_PENDING; + } + + // Recycle INT-TD if interval!=0, else mark TD as one-shot + if (purb->interval) { + desc->hw.td.info &= ~(1 << TD_TOKEN_TOGGLE); + if (status==0) { + desc->hw.td.info |= (usb_gettoggle (purb->dev, usb_pipeendpoint (purb->pipe), + usb_pipeout (purb->pipe)) << TD_TOKEN_TOGGLE); + usb_dotoggle (purb->dev, usb_pipeendpoint (purb->pipe), usb_pipeout (purb->pipe)); + } else { + desc->hw.td.info |= (!usb_gettoggle (purb->dev, usb_pipeendpoint (purb->pipe), + usb_pipeout (purb->pipe)) << TD_TOKEN_TOGGLE); + } + desc->hw.td.status= (purb->pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC | + (purb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27); + wmb(); + } + else { + desc->hw.td.status &= ~TD_CTRL_IOC; // inactivate TD + } + } + + return ret; +} + + +_static int process_iso (puhci_t s, purb_t purb) +{ + int i; + int ret = USB_ST_NOERROR; + purb_priv_t purb_priv = purb->hcpriv; + struct list_head *p = purb_priv->desc_list.next; + puhci_desc_t desc = list_entry (purb_priv->desc_list.prev, uhci_desc_t, desc_list); + + dbg("urb contains iso request"); + if (desc->hw.td.status & TD_CTRL_ACTIVE) + return USB_ST_PARTIAL_ERROR; // last TD not finished + + purb->error_count = 0; + purb->actual_length = 0; + purb->status = USB_ST_NOERROR; + + for (i = 0; p != &purb_priv->desc_list; p = p->next, i++) { + desc = list_entry (p, uhci_desc_t, desc_list); + + //uhci_show_td(desc); + if (desc->hw.td.status & TD_CTRL_ACTIVE) { + // means we have completed the last TD, but not the TDs before + desc->hw.td.status &= ~TD_CTRL_ACTIVE; + dbg("TD still active (%x)- grrr. paranoia!", desc->hw.td.status); + ret = USB_ST_PARTIAL_ERROR; + purb->iso_frame_desc[i].status = ret; + unlink_td (s, desc); + // FIXME: immediate deletion may be dangerous + goto err; + } + + unlink_td (s, desc); + + if (purb->number_of_packets <= i) { + dbg("purb->number_of_packets (%d)<=(%d)", purb->number_of_packets, i); + ret = USB_ST_URB_INVALID_ERROR; + goto err; + } + + if (purb->iso_frame_desc[i].offset + purb->transfer_buffer != bus_to_virt (desc->hw.td.buffer)) { + // Hm, something really weird is going on + dbg("Pointer Paranoia: %p!=%p", purb->iso_frame_desc[i].offset + purb->transfer_buffer, bus_to_virt (desc->hw.td.buffer)); + ret = USB_ST_URB_INVALID_ERROR; + purb->iso_frame_desc[i].status = ret; + goto err; + } + purb->iso_frame_desc[i].actual_length = (desc->hw.td.status + 1) & 0x7ff; + purb->iso_frame_desc[i].status = uhci_map_status (uhci_status_bits (desc->hw.td.status), usb_pipeout (purb->pipe)); + purb->actual_length += purb->iso_frame_desc[i].actual_length; + + err: + + if (purb->iso_frame_desc[i].status != USB_ST_NOERROR) { + purb->error_count++; + purb->status = purb->iso_frame_desc[i].status; + } + dbg("process_iso: len:%d status:%x", + purb->iso_frame_desc[i].length, purb->iso_frame_desc[i].status); + + delete_desc (desc); + list_del (p); + } + dbg("process_iso: exit %i (%d)", i, ret); + return ret; +} + + +_static int process_urb (puhci_t s, struct list_head *p) +{ + int ret = USB_ST_NOERROR; + purb_t purb; + + spin_lock(&s->urb_list_lock); + purb=list_entry (p, urb_t, urb_list); + dbg("found queued urb: %p", purb); + + switch (usb_pipetype (purb->pipe)) { + case PIPE_CONTROL: + case PIPE_BULK: + ret = process_transfer (s, purb); + break; + case PIPE_ISOCHRONOUS: + ret = process_iso (s, purb); + break; + case PIPE_INTERRUPT: + ret = process_interrupt (s, purb); + break; + } + + spin_unlock(&s->urb_list_lock); + + if (purb->status != USB_ST_URB_PENDING) { + int proceed = 0; + dbg("dequeued urb: %p", purb); + dequeue_urb (s, p, 1); + +#ifdef DEBUG_SLAB + kmem_cache_free(urb_priv_kmem, purb->hcpriv); +#else + kfree (purb->hcpriv); +#endif + + if ((usb_pipetype (purb->pipe) != PIPE_INTERRUPT)) { + purb_t tmp = purb->next; // pointer to first urb + int is_ring = 0; + + if (purb->next) { + do { + if (tmp->status != USB_ST_URB_PENDING) { + proceed = 1; + break; + } + tmp = tmp->next; + } + while (tmp != NULL && tmp != purb->next); + if (tmp == purb->next) + is_ring = 1; + } + + // In case you need the current URB status for your completion handler + if (purb->complete && (!proceed || (purb->transfer_flags & USB_URB_EARLY_COMPLETE))) { + dbg("process_transfer: calling early completion"); + purb->complete ((struct urb *) purb); + if (!proceed && is_ring && (purb->status != USB_ST_URB_KILLED)) + uhci_submit_urb (purb); + } + + if (proceed && purb->next) { + // if there are linked urbs - handle submitting of them right now. + tmp = purb->next; // pointer to first urb + + do { + if ((tmp->status != USB_ST_URB_PENDING) && (tmp->status != USB_ST_URB_KILLED) && uhci_submit_urb (tmp) != USB_ST_NOERROR) + break; + tmp = tmp->next; + } + while (tmp != NULL && tmp != purb->next); // submit until we reach NULL or our own pointer or submit fails + + if (purb->complete && !(purb->transfer_flags & USB_URB_EARLY_COMPLETE)) { + dbg("process_transfer: calling completion"); + purb->complete ((struct urb *) purb); + } + } + usb_dec_dev_use (purb->dev); + } + } + + return ret; +} + +_static void uhci_interrupt (int irq, void *__uhci, struct pt_regs *regs) +{ + puhci_t s = __uhci; + unsigned int io_addr = s->io_addr; + unsigned short status; + struct list_head *p, *p2; + + /* + * Read the interrupt status, and write it back to clear the + * interrupt cause + */ + + status = inw (io_addr + USBSTS); + + if (!status) /* shared interrupt, not mine */ + return; + + dbg("interrupt"); + + if (status != 1) { + warn("interrupt, status %x", status); + + // remove host controller halted state + if ((status&0x20) && (s->running)) { + // more to be done - check TDs for invalid entries + // but TDs are only invalid if somewhere else is a (memory ?) problem + outw (USBCMD_RS | inw(io_addr + USBCMD), io_addr + USBCMD); + } + //uhci_show_status (s); + } + //beep(1000); + /* + * the following is very subtle and was blatantly wrong before + * traverse the list in *reverse* direction, because new entries + * may be added at the end. + * also, because process_urb may unlink the current urb, + * we need to advance the list before + * - Thomas Sailer + */ + + spin_lock(&s->unlink_urb_lock); + spin_lock (&s->urb_list_lock); + p = s->urb_list.prev; + spin_unlock (&s->urb_list_lock); + + while (p != &s->urb_list) { + p2 = p; + p = p->prev; + process_urb (s, p2); + } + + spin_unlock(&s->unlink_urb_lock); + + outw (status, io_addr + USBSTS); +#ifdef __alpha + mb (); // ? +#endif + dbg("done\n\n"); +} + +_static void reset_hc (puhci_t s) +{ + unsigned int io_addr = s->io_addr; + + s->apm_state = 0; + /* Global reset for 50ms */ + outw (USBCMD_GRESET, io_addr + USBCMD); + wait_ms (50); + outw (0, io_addr + USBCMD); + wait_ms (10); +} + +_static void start_hc (puhci_t s) +{ + unsigned int io_addr = s->io_addr; + int timeout = 1000; + + /* + * Reset the HC - this will force us to get a + * new notification of any already connected + * ports due to the virtual disconnect that it + * implies. + */ + outw (USBCMD_HCRESET, io_addr + USBCMD); + + while (inw (io_addr + USBCMD) & USBCMD_HCRESET) { + if (!--timeout) { + err("USBCMD_HCRESET timed out!"); + break; + } + } + + /* Turn on all interrupts */ + outw (USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP, io_addr + USBINTR); + + /* Start at frame 0 */ + outw (0, io_addr + USBFRNUM); + outl (virt_to_bus (s->framelist), io_addr + USBFLBASEADD); + + /* Run and mark it configured with a 64-byte max packet */ + outw (USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD); + s->apm_state = 1; + s->running = 1; +} + +_static void __exit uhci_cleanup_dev(puhci_t s) +{ + struct usb_device *root_hub = s->bus->root_hub; + if (root_hub) + usb_disconnect (&root_hub); + + usb_deregister_bus (s->bus); + s->running = 0; + reset_hc (s); + release_region (s->io_addr, s->io_size); + free_irq (s->irq, s); + usb_free_bus (s->bus); + cleanup_skel (s); + kfree (s); + +} + +_static int __init uhci_start_usb (puhci_t s) +{ /* start it up */ + /* connect the virtual root hub */ + struct usb_device *usb_dev; + + usb_dev = usb_alloc_dev (NULL, s->bus); + if (!usb_dev) + return -1; + + s->bus->root_hub = usb_dev; + usb_connect (usb_dev); + + if (usb_new_device (usb_dev) != 0) { + usb_free_dev (usb_dev); + return -1; + } + + return 0; +} + +_static int __init alloc_uhci (int irq, unsigned int io_addr, unsigned int io_size) +{ + puhci_t s; + struct usb_bus *bus; + + s = kmalloc (sizeof (uhci_t), GFP_KERNEL); + if (!s) + return -1; + + memset (s, 0, sizeof (uhci_t)); + INIT_LIST_HEAD (&s->urb_list); + spin_lock_init (&s->urb_list_lock); + spin_lock_init (&s->qh_lock); + spin_lock_init (&s->td_lock); + spin_lock_init (&s->unlink_urb_lock); + s->irq = -1; + s->io_addr = io_addr; + s->io_size = io_size; + s->next = devs; //chain new uhci device into global list + + bus = usb_alloc_bus (&uhci_device_operations); + if (!bus) { + kfree (s); + return -1; + } + + s->bus = bus; + bus->hcpriv = s; + + /* UHCI specs says devices must have 2 ports, but goes on to say */ + /* they may have more but give no way to determine how many they */ + /* have, so default to 2 */ + /* According to the UHCI spec, Bit 7 is always set to 1. So we try */ + /* to use this to our advantage */ + + for (s->maxports = 0; s->maxports < (io_size - 0x10) / 2; s->maxports++) { + unsigned int portstatus; + + portstatus = inw (io_addr + 0x10 + (s->maxports * 2)); + dbg("port %i, adr %x status %x", s->maxports, + io_addr + 0x10 + (s->maxports * 2), portstatus); + if (!(portstatus & 0x0080)) + break; + } + dbg("Detected %d ports", s->maxports); + + /* This is experimental so anything less than 2 or greater than 8 is */ + /* something weird and we'll ignore it */ + if (s->maxports < 2 || s->maxports > 8) { + dbg("Port count misdetected, forcing to 2 ports"); + s->maxports = 2; + } + + s->rh.numports = s->maxports; + + if (init_skel (s)) { + usb_free_bus (bus); + kfree(s); + return -1; + } + + request_region (s->io_addr, io_size, MODNAME); + reset_hc (s); + usb_register_bus (s->bus); + + start_hc (s); + + if (request_irq (irq, uhci_interrupt, SA_SHIRQ, MODNAME, s)) { + err("request_irq %d failed!",irq); + usb_free_bus (bus); + reset_hc (s); + release_region (s->io_addr, s->io_size); + cleanup_skel(s); + kfree(s); + return -1; + } + + s->irq = irq; + + if(uhci_start_usb (s) < 0) { + uhci_cleanup_dev(s); + return -1; + } + + //chain new uhci device into global list + devs = s; + + return 0; +} + +_static int __init start_uhci (struct pci_dev *dev) +{ + int i; + + /* Search for the IO base address.. */ + for (i = 0; i < 6; i++) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,8) + unsigned int io_addr = dev->resource[i].start; + unsigned int io_size = + dev->resource[i].end - dev->resource[i].start + 1; + if (!(dev->resource[i].flags & 1)) + continue; +#else + unsigned int io_addr = dev->base_address[i]; + unsigned int io_size = 0x14; + if (!(io_addr & 1)) + continue; + io_addr &= ~1; +#endif + + /* Is it already in use? */ + if (check_region (io_addr, io_size)) + break; + /* disable legacy emulation */ + pci_write_config_word (dev, USBLEGSUP, USBLEGSUP_DEFAULT); + + return alloc_uhci(dev->irq, io_addr, io_size); + } + return -1; +} + +#ifdef CONFIG_APM +_static int handle_apm_event (apm_event_t event) +{ + static int down = 0; + puhci_t s = devs; + dbg("handle_apm_event(%d)", event); + switch (event) { + case APM_SYS_SUSPEND: + case APM_USER_SUSPEND: + if (down) { + dbg("received extra suspend event"); + break; + } + while (s) { + reset_hc (s); + s = s->next; + } + down = 1; + break; + case APM_NORMAL_RESUME: + case APM_CRITICAL_RESUME: + if (!down) { + dbg("received bogus resume event"); + break; + } + down = 0; + while (s) { + start_hc (s); + s = s->next; + } + break; + } + return 0; +} +#endif + +int __init uhci_init (void) +{ + int retval = -ENODEV; + struct pci_dev *dev = NULL; + u8 type; + int i=0; + +#ifdef DEBUG_SLAB + char *slabname=kmalloc(16, GFP_KERNEL); + + if(!slabname) + return -ENOMEM; + + strcpy(slabname, "uhci_desc"); + uhci_desc_kmem = kmem_cache_create(slabname, sizeof(uhci_desc_t), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); + + if(!uhci_desc_kmem) { + err("kmem_cache_create for uhci_desc failed (out of memory)"); + return -ENOMEM; + } + + slabname=kmalloc(16, GFP_KERNEL); + + if(!slabname) + return -ENOMEM; + + strcpy(slabname, "urb_priv"); + urb_priv_kmem = kmem_cache_create(slabname, sizeof(urb_priv_t), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); + + if(!urb_priv_kmem) { + err("kmem_cache_create for urb_priv_t failed (out of memory)"); + return -ENOMEM; + } +#endif + info(VERSTR); + + for (;;) { + dev = pci_find_class (PCI_CLASS_SERIAL_USB << 8, dev); + if (!dev) + break; + + /* Is it UHCI */ + pci_read_config_byte (dev, PCI_CLASS_PROG, &type); + if (type != 0) + continue; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,8) + pci_enable_device (dev); +#endif + if(!dev->irq) + { + err("Found UHCI device with no IRQ assigned. Check BIOS settings!"); + continue; + } + + /* Ok set it up */ + retval = start_uhci (dev); + + if (!retval) + i++; + + } + +#ifdef CONFIG_APM + if(i) + apm_register_callback (&handle_apm_event); +#endif + return retval; +} + +void __exit uhci_cleanup (void) +{ + puhci_t s; + while ((s = devs)) { + devs = devs->next; + uhci_cleanup_dev(s); + } +#ifdef DEBUG_SLAB + kmem_cache_shrink(uhci_desc_kmem); + kmem_cache_shrink(urb_priv_kmem); +#endif +} + +#ifdef MODULE +int init_module (void) +{ + return uhci_init (); +} + +void cleanup_module (void) +{ +#ifdef CONFIG_APM + apm_unregister_callback (&handle_apm_event); +#endif + uhci_cleanup (); +} + +#endif //MODULE diff -ur --new-file old/linux/drivers/usb/usb-uhci.h new/linux/drivers/usb/usb-uhci.h --- old/linux/drivers/usb/usb-uhci.h Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/usb/usb-uhci.h Mon Jan 24 07:39:14 2000 @@ -0,0 +1,252 @@ +#ifndef __LINUX_UHCI_H +#define __LINUX_UHCI_H + +/* + $Id: usb-uhci.h,v 1.31 2000/01/15 22:02:30 acher Exp $ + */ +#define MODNAME "usb-uhci" +#define VERSTR "version v1.169 time " __TIME__ " " __DATE__ + +/* Command register */ +#define USBCMD 0 +#define USBCMD_RS 0x0001 /* Run/Stop */ +#define USBCMD_HCRESET 0x0002 /* Host reset */ +#define USBCMD_GRESET 0x0004 /* Global reset */ +#define USBCMD_EGSM 0x0008 /* Global Suspend Mode */ +#define USBCMD_FGR 0x0010 /* Force Global Resume */ +#define USBCMD_SWDBG 0x0020 /* SW Debug mode */ +#define USBCMD_CF 0x0040 /* Config Flag (sw only) */ +#define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */ + +/* Status register */ +#define USBSTS 2 +#define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */ +#define USBSTS_ERROR 0x0002 /* Interrupt due to error */ +#define USBSTS_RD 0x0004 /* Resume Detect */ +#define USBSTS_HSE 0x0008 /* Host System Error - basically PCI problems */ +#define USBSTS_HCPE 0x0010 /* Host Controller Process Error - the scripts were buggy */ +#define USBSTS_HCH 0x0020 /* HC Halted */ + +/* Interrupt enable register */ +#define USBINTR 4 +#define USBINTR_TIMEOUT 0x0001 /* Timeout/CRC error enable */ +#define USBINTR_RESUME 0x0002 /* Resume interrupt enable */ +#define USBINTR_IOC 0x0004 /* Interrupt On Complete enable */ +#define USBINTR_SP 0x0008 /* Short packet interrupt enable */ + +#define USBFRNUM 6 +#define USBFLBASEADD 8 +#define USBSOF 12 + +/* USB port status and control registers */ +#define USBPORTSC1 16 +#define USBPORTSC2 18 +#define USBPORTSC_CCS 0x0001 /* Current Connect Status ("device present") */ +#define USBPORTSC_CSC 0x0002 /* Connect Status Change */ +#define USBPORTSC_PE 0x0004 /* Port Enable */ +#define USBPORTSC_PEC 0x0008 /* Port Enable Change */ +#define USBPORTSC_LS 0x0030 /* Line Status */ +#define USBPORTSC_RD 0x0040 /* Resume Detect */ +#define USBPORTSC_LSDA 0x0100 /* Low Speed Device Attached */ +#define USBPORTSC_PR 0x0200 /* Port Reset */ +#define USBPORTSC_SUSP 0x1000 /* Suspend */ + +/* Legacy support register */ +#define USBLEGSUP 0xc0 +#define USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */ + +#define UHCI_NULL_DATA_SIZE 0x7ff /* for UHCI controller TD */ + +#define UHCI_PTR_BITS 0x000F +#define UHCI_PTR_TERM 0x0001 +#define UHCI_PTR_QH 0x0002 +#define UHCI_PTR_DEPTH 0x0004 + +#define UHCI_NUMFRAMES 1024 /* in the frame list [array] */ +#define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ +#define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */ + +/* + * for TD : + */ +#define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */ +#define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */ +#define TD_CTRL_LS (1 << 26) /* Low Speed Device */ +#define TD_CTRL_IOS (1 << 25) /* Isochronous Select */ +#define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */ +#define TD_CTRL_ACTIVE (1 << 23) /* TD Active */ +#define TD_CTRL_STALLED (1 << 22) /* TD Stalled */ +#define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */ +#define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */ +#define TD_CTRL_NAK (1 << 19) /* NAK Received */ +#define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */ +#define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */ +#define TD_CTRL_ACTLEN_MASK 0x7ff /* actual length, encoded as n - 1 */ + +#define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \ + TD_CTRL_BABBLE | TD_CTRL_CRCTIME | TD_CTRL_BITSTUFF) + +#define uhci_status_bits(ctrl_sts) (ctrl_sts & 0xFE0000) +#define uhci_actual_length(ctrl_sts) ((ctrl_sts + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */ +#define uhci_ptr_to_virt(x) bus_to_virt(x & ~UHCI_PTR_BITS) + +/* + * for TD : + */ +#define UHCI_TD_REMOVE 0x0001 /* Remove when done */ + +/* + * for TD : (a.k.a. Token) + */ +#define TD_TOKEN_TOGGLE 19 + +#define uhci_maxlen(token) ((token) >> 21) +#define uhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE) & 1) +#define uhci_endpoint(token) (((token) >> 15) & 0xf) +#define uhci_devaddr(token) (((token) >> 8) & 0x7f) +#define uhci_devep(token) (((token) >> 8) & 0x7ff) +#define uhci_packetid(token) ((token) & 0xff) +#define uhci_packetout(token) (uhci_packetid(token) != USB_PID_IN) +#define uhci_packetin(token) (uhci_packetid(token) == USB_PID_IN) + +/* ------------------------------------------------------------------------------------ + New TD/QH-structures + ------------------------------------------------------------------------------------ */ +typedef enum { + TD_TYPE, QH_TYPE +} uhci_desc_type_t; + +typedef struct { + __u32 link; + __u32 status; + __u32 info; + __u32 buffer; +} uhci_td_t, *puhci_td_t; + +typedef struct { + __u32 head; + __u32 element; /* Queue element pointer */ +} uhci_qh_t, *puhci_qh_t; + +typedef struct { + union { + uhci_td_t td; + uhci_qh_t qh; + } hw; + uhci_desc_type_t type; + struct list_head horizontal; + struct list_head vertical; + struct list_head desc_list; +} uhci_desc_t, *puhci_desc_t; + +typedef struct { + struct list_head desc_list; // list pointer to all corresponding TDs/QHs associated with this request + int short_control_packet; +} urb_priv_t, *purb_priv_t; + +struct virt_root_hub { + int devnum; /* Address of Root Hub endpoint */ + void *urb; + void *int_addr; + int send; + int interval; + int numports; + int c_p_r[8]; + struct timer_list rh_int_timer; +}; + +typedef struct uhci { + int irq; + unsigned int io_addr; + unsigned int io_size; + unsigned int maxports; + int running; + + int apm_state; + + struct uhci *next; // chain of uhci device contexts + + struct list_head urb_list; // list of all pending urbs + + spinlock_t urb_list_lock; // lock to keep consistency + + struct usb_bus *bus; // our bus + + spinlock_t unlink_urb_lock; // lock for unlink_urb + + __u32 *framelist; + uhci_desc_t **iso_td; + uhci_desc_t *int_chain[8]; + uhci_desc_t *control_chain; + uhci_desc_t *bulk_chain; + uhci_desc_t *chain_end; + spinlock_t qh_lock; + spinlock_t td_lock; + struct virt_root_hub rh; //private data of the virtual root hub +} uhci_t, *puhci_t; + + +#define MAKE_TD_ADDR(a) (virt_to_bus(a)&~UHCI_PTR_QH) +#define MAKE_QH_ADDR(a) (virt_to_bus(a)|UHCI_PTR_QH) +#define UHCI_GET_CURRENT_FRAME(uhci) (inw ((uhci)->io_addr + USBFRNUM)) + +/* ------------------------------------------------------------------------------------ + Virtual Root HUB + ------------------------------------------------------------------------------------ */ +/* destination of request */ +#define RH_INTERFACE 0x01 +#define RH_ENDPOINT 0x02 +#define RH_OTHER 0x03 + +#define RH_CLASS 0x20 +#define RH_VENDOR 0x40 + +/* Requests: bRequest << 8 | bmRequestType */ +#define RH_GET_STATUS 0x0080 +#define RH_CLEAR_FEATURE 0x0100 +#define RH_SET_FEATURE 0x0300 +#define RH_SET_ADDRESS 0x0500 +#define RH_GET_DESCRIPTOR 0x0680 +#define RH_SET_DESCRIPTOR 0x0700 +#define RH_GET_CONFIGURATION 0x0880 +#define RH_SET_CONFIGURATION 0x0900 +#define RH_GET_STATE 0x0280 +#define RH_GET_INTERFACE 0x0A80 +#define RH_SET_INTERFACE 0x0B00 +#define RH_SYNC_FRAME 0x0C80 +/* Our Vendor Specific Request */ +#define RH_SET_EP 0x2000 + + +/* Hub port features */ +#define RH_PORT_CONNECTION 0x00 +#define RH_PORT_ENABLE 0x01 +#define RH_PORT_SUSPEND 0x02 +#define RH_PORT_OVER_CURRENT 0x03 +#define RH_PORT_RESET 0x04 +#define RH_PORT_POWER 0x08 +#define RH_PORT_LOW_SPEED 0x09 +#define RH_C_PORT_CONNECTION 0x10 +#define RH_C_PORT_ENABLE 0x11 +#define RH_C_PORT_SUSPEND 0x12 +#define RH_C_PORT_OVER_CURRENT 0x13 +#define RH_C_PORT_RESET 0x14 + +/* Hub features */ +#define RH_C_HUB_LOCAL_POWER 0x00 +#define RH_C_HUB_OVER_CURRENT 0x01 + +#define RH_DEVICE_REMOTE_WAKEUP 0x00 +#define RH_ENDPOINT_STALL 0x01 + +/* Our Vendor Specific feature */ +#define RH_REMOVE_EP 0x00 + + +#define RH_ACK 0x01 +#define RH_REQ_ERR -1 +#define RH_NACK 0x00 + +#define min(a,b) (((a)<(b))?(a):(b)) + +#endif diff -ur --new-file old/linux/drivers/usb/usb.c new/linux/drivers/usb/usb.c --- old/linux/drivers/usb/usb.c Fri Jan 21 00:00:16 2000 +++ new/linux/drivers/usb/usb.c Fri Jan 28 01:40:53 2000 @@ -15,7 +15,7 @@ * It should be considered a slave, with no callbacks. Callbacks * are evil. * - * $Id: usb.c,v 1.39 1999/12/27 15:17:47 acher Exp $ + * $Id: usb.c,v 1.53 2000/01/14 16:19:09 acher Exp $ */ #include @@ -486,7 +486,8 @@ /*-------------------------------------------------------------------*/ void usb_free_urb(urb_t* urb) { - kfree(urb); + if(urb) + kfree(urb); } /*-------------------------------------------------------------------*/ int usb_submit_urb(urb_t *urb) @@ -515,7 +516,7 @@ static void usb_api_blocking_completion(urb_t *urb) { api_wrapper_data *awd = (api_wrapper_data *)urb->context; - + if (waitqueue_active(awd->wakeup)) wake_up(awd->wakeup); #if 0 @@ -541,7 +542,7 @@ *-------------------------------------------------------------------*/ // Starts urb and waits for completion or timeout -static int usb_start_wait_urb(urb_t *urb, int timeout, unsigned long* rval) +static int usb_start_wait_urb(urb_t *urb, int timeout, int* actual_length) { DECLARE_WAITQUEUE(wait, current); DECLARE_WAIT_QUEUE_HEAD(wqh); @@ -551,7 +552,7 @@ awd.wakeup=&wqh; awd.handler=0; init_waitqueue_head(&wqh); - current->state = TASK_UNINTERRUPTIBLE; + current->state = TASK_INTERRUPTIBLE; add_wait_queue(&wqh, &wait); urb->context=&awd; status=usb_submit_urb(urb); @@ -572,15 +573,15 @@ if (!status) { // timeout - dbg("usb_control/bulk_msg: timeout"); + printk("usb_control/bulk_msg: timeout\n"); usb_unlink_urb(urb); // remove urb safely status=-ETIMEDOUT; } else status=urb->status; - if (rval) - *rval=urb->actual_length; + if (actual_length) + *actual_length=urb->actual_length; usb_free_urb(urb); return status; @@ -593,7 +594,7 @@ { urb_t *urb; int retv; - unsigned long length; + int length; urb=usb_alloc_urb(0); if (!urb) @@ -601,7 +602,7 @@ FILL_CONTROL_URB(urb, usb_dev, pipe, (unsigned char*)cmd, data, len, /* build urb */ (usb_complete_t)usb_api_blocking_completion,0); - + retv=usb_start_wait_urb(urb,timeout, &length); if (retv < 0) return retv; @@ -613,15 +614,25 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout) { - devrequest dr; - - dr.requesttype = requesttype; - dr.request = request; - dr.value = cpu_to_le16p(&value); - dr.index = cpu_to_le16p(&index); - dr.length = cpu_to_le16p(&size); + devrequest *dr = kmalloc(sizeof(devrequest), GFP_KERNEL); + int ret; + + if(!dr) + return -ENOMEM; + + dr->requesttype = requesttype; + dr->request = request; + dr->value = cpu_to_le16p(&value); + dr->index = cpu_to_le16p(&index); + dr->length = cpu_to_le16p(&size); + //dbg("usb_control_msg"); - return usb_internal_control_msg(dev, pipe, &dr, data, size, timeout); + + ret=usb_internal_control_msg(dev, pipe, dr, data, size, timeout); + + kfree(dr); + + return ret; } /*-------------------------------------------------------------------*/ @@ -629,7 +640,7 @@ /* synchronous behavior */ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, - void *data, int len, unsigned long *rval, int timeout) + void *data, int len, int *actual_length, int timeout) { urb_t *urb; @@ -643,7 +654,7 @@ FILL_BULK_URB(urb,usb_dev,pipe,(unsigned char*)data,len, /* build urb */ (usb_complete_t)usb_api_blocking_completion,0); - return usb_start_wait_urb(urb,timeout,rval); + return usb_start_wait_urb(urb,timeout,actual_length); } /*-------------------------------------------------------------------*/ @@ -1087,7 +1098,7 @@ for (i = 0; i < config->bNumInterfaces; i++) { header = (struct usb_descriptor_header *)buffer; - if (header->bLength > size) { + if ((header->bLength > size) || (header->bLength <= 2)) { err("ran out of descriptors parsing"); return -1; } @@ -1222,7 +1233,8 @@ /* Free up all the children.. */ for (i = 0; i < USB_MAXCHILDREN; i++) { struct usb_device **child = dev->children + i; - usb_disconnect(child); + if (*child) + usb_disconnect(child); } /* remove /proc/bus/usb entry */ @@ -1246,6 +1258,9 @@ { int devnum; // FIXME needs locking for SMP!! + /* why? this is called only from the hub thread, + * which hopefully doesn't run on multiple CPU's simulatenously 8-) + */ dev->descriptor.bMaxPacketSize0 = 8; /* Start off at 8 bytes */ devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1); if (devnum < 128) { @@ -1272,6 +1287,8 @@ { int i = 5; int result; + + memset(buf,0,size); // Make sure we parse really received data while (i--) { if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), @@ -1283,12 +1300,12 @@ return result; } -int usb_get_class_descriptor(struct usb_device *dev, unsigned char type, - unsigned char id, unsigned char index, void *buf, int size) +int usb_get_class_descriptor(struct usb_device *dev, int ifnum, + unsigned char type, unsigned char id, void *buf, int size) { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, - (type << 8) + id, index, buf, size, HZ * GET_TIMEOUT); + (type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT); } int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size) @@ -1317,31 +1334,31 @@ USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2, HZ * GET_TIMEOUT); } -int usb_get_protocol(struct usb_device *dev) +int usb_get_protocol(struct usb_device *dev, int ifnum) { unsigned char type; int ret; if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_PROTOCOL, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, 1, &type, 1, HZ * GET_TIMEOUT)) < 0) + 0, ifnum, &type, 1, HZ * GET_TIMEOUT)) < 0) return ret; return type; } -int usb_set_protocol(struct usb_device *dev, int protocol) +int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol) { return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - protocol, 1, NULL, 0, HZ * SET_TIMEOUT); + protocol, ifnum, NULL, 0, HZ * SET_TIMEOUT); } -int usb_set_idle(struct usb_device *dev, int duration, int report_id) +int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id) { return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (duration << 8) | report_id, 1, NULL, 0, HZ * SET_TIMEOUT); + (duration << 8) | report_id, ifnum, NULL, 0, HZ * SET_TIMEOUT); } static void usb_set_maxpacket(struct usb_device *dev) @@ -1373,10 +1390,11 @@ * endp: endpoint number in bits 0-3; * direction flag in bit 7 (1 = IN, 0 = OUT) */ -int usb_clear_halt(struct usb_device *dev, int endp) +int usb_clear_halt(struct usb_device *dev, int pipe) { int result; __u16 status; + int endp=usb_pipeendpoint(pipe)|(usb_pipein(pipe)<<7); /* if (!usb_endpoint_halted(dev, endp & 0x0f, usb_endpoint_out(endp))) @@ -1399,11 +1417,11 @@ if (status & 1) return -EPIPE; /* still halted */ - usb_endpoint_running(dev, endp & 0x0f, usb_endpoint_out(endp)); + usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)); /* toggle is reset on clear */ - usb_settoggle(dev, endp & 0x0f, usb_endpoint_out(endp), 0); + usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0); return 0; } @@ -1462,18 +1480,18 @@ return 0; } -int usb_get_report(struct usb_device *dev, unsigned char type, unsigned char id, unsigned char index, void *buf, int size) +int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size) { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_REPORT, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, index, buf, size, HZ * GET_TIMEOUT); + (type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT); } -int usb_set_report(struct usb_device *dev, unsigned char type, unsigned char id, unsigned char index, void *buf, int size) +int usb_set_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size) { return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, index, buf, size, HZ); + (type << 8) + id, ifnum, buf, size, HZ); } int usb_get_configuration(struct usb_device *dev) @@ -1482,6 +1500,7 @@ unsigned int cfgno; unsigned char buffer[8]; unsigned char *bigbuffer; + unsigned int tmp; struct usb_config_descriptor *desc = (struct usb_config_descriptor *)buffer; @@ -1511,8 +1530,11 @@ /* We grab the first 8 bytes so we know how long the whole */ /* configuration is */ result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8); - if (result < 0) { - err("unable to get descriptor"); + if (result < 8) { + if (result < 0) + err("unable to get descriptor"); + else + err("config descriptor too short (expected %i, got %i)",8,result); goto err; } @@ -1525,13 +1547,19 @@ result=-ENOMEM; goto err; } - + tmp=desc->wTotalLength; /* Now that we know the length, get the whole thing */ result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, desc->wTotalLength); if (result < 0) { err("couldn't get all of config descriptors"); kfree(bigbuffer); goto err; + } + + if (result < tmp) { + err("config descriptor too short (expected %i, got %i)",tmp,result); + kfree(bigbuffer); + goto err; } result = usb_parse_configuration(dev, &dev->config[cfgno], bigbuffer); kfree(bigbuffer); @@ -1551,13 +1579,17 @@ return result; } +/* + * usb_string: + * returns string length (> 0) or error (< 0) + */ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) { unsigned char *tbuf; int err; unsigned int u, idx; - if (size <= 0 || !buf) + if (size <= 0 || !buf || !index) return -EINVAL; buf[0] = 0; tbuf = kmalloc(256, GFP_KERNEL); @@ -1574,15 +1606,15 @@ err = usb_get_string(dev, dev->string_langid, index, tbuf, tbuf[0]); if (err < 0) goto errout; - size--; - for (idx = 0, u = 2; u < tbuf[0]; u += 2) { + + size--; /* leave room for trailing NULL char in output buffer */ + for (idx = 0, u = 2; u < err; u += 2) { if (idx >= size) break; - if (tbuf[u+1]) { - buf[idx++] = '?'; /* non ASCII character */ - continue; - } - buf[idx++] = tbuf[u]; + if (tbuf[u+1]) /* high byte */ + buf[idx++] = '?'; /* non-ASCII character */ + else + buf[idx++] = tbuf[u]; } buf[idx] = 0; err = idx; @@ -1603,6 +1635,7 @@ { unsigned char *buf; int addr, err; + int tmp; info("USB new device connect, assigned device number %d", dev->devnum); @@ -1615,13 +1648,15 @@ dev->devnum = 0; err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8); - if (err < 0) { - err("USB device not responding, giving up (error=%d)", err); + if (err < 8) { + if (err < 0) + err("USB device not responding, giving up (error=%d)", err); + else + err("USB device descriptor short read (expected %i, got %i)",8,err); clear_bit(addr, &dev->bus->devmap.devicemap); dev->devnum = -1; return 1; } - dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0; dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0; switch (dev->descriptor.bMaxPacketSize0) { @@ -1644,9 +1679,15 @@ wait_ms(10); /* Let the SET_ADDRESS settle */ + tmp = sizeof(dev->descriptor); + err = usb_get_device_descriptor(dev); - if (err < 0) { - err("unable to get device descriptor (error=%d)",err); + if (err < tmp) { + if (err < 0) + err("unable to get device descriptor (error=%d)",err); + else + err("USB device descriptor short read (expected %i, got %i)",tmp,err); + clear_bit(dev->devnum, &dev->bus->devmap.devicemap); dev->devnum = -1; return 1; @@ -1684,9 +1725,12 @@ info("USB device number %d default language ID 0x%x", dev->devnum, dev->string_langid); } - usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer); - usb_show_string(dev, "Product", dev->descriptor.iProduct); - usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber); + if (dev->descriptor.iManufacturer) + usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer); + if (dev->descriptor.iProduct) + usb_show_string(dev, "Product", dev->descriptor.iProduct); + if (dev->descriptor.iSerialNumber) + usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber); /* now that the basic setup is over, add a /proc/bus/usb entry */ usbdevfs_add_device(dev); diff -ur --new-file old/linux/drivers/usb/usb.h new/linux/drivers/usb/usb.h --- old/linux/drivers/usb/usb.h Fri Jan 21 00:00:16 2000 +++ new/linux/drivers/usb/usb.h Tue Jan 25 20:41:20 2000 @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include /* for in_interrupt() */ /* USB constants */ @@ -116,7 +119,6 @@ #include #include -#include #define USB_MAJOR 180 @@ -159,8 +161,12 @@ static __inline__ void wait_ms(unsigned int ms) { - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout(1 + ms * HZ / 1000); + if(!in_interrupt()) { + current->state = TASK_UNINTERRUPTIBLE; + schedule_timeout(1 + ms * HZ / 1000); + } + else + mdelay(ms); } typedef struct { @@ -428,7 +434,7 @@ int usb_submit_urb(purb_t purb); int usb_unlink_urb(purb_t purb); int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest *cmd, void *data, int len, int timeout); -int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, unsigned long *rval, int timeout); +int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout); /*-------------------------------------------------------------------* * COMPATIBILITY STUFF * @@ -661,22 +667,22 @@ int usb_set_address(struct usb_device *dev); int usb_get_descriptor(struct usb_device *dev, unsigned char desctype, unsigned char descindex, void *buf, int size); -int usb_get_class_descriptor(struct usb_device *dev, unsigned char desctype, - unsigned char descindex, unsigned char ifnum, void *buf, int size); +int usb_get_class_descriptor(struct usb_device *dev, int ifnum, unsigned char desctype, + unsigned char descindex, void *buf, int size); int usb_get_device_descriptor(struct usb_device *dev); int __usb_get_extra_descriptor(char *buffer, unsigned size, unsigned char type, void **ptr); -int usb_get_status (struct usb_device *dev, int type, int target, void *data); -int usb_get_protocol(struct usb_device *dev); -int usb_set_protocol(struct usb_device *dev, int protocol); -int usb_set_interface(struct usb_device *dev, int interface, int alternate); -int usb_set_idle(struct usb_device *dev, int duration, int report_id); +int usb_get_status(struct usb_device *dev, int type, int target, void *data); +int usb_get_protocol(struct usb_device *dev, int ifnum); +int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol); +int usb_set_interface(struct usb_device *dev, int ifnum, int alternate); +int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id); int usb_set_configuration(struct usb_device *dev, int configuration); -int usb_get_report(struct usb_device *dev, unsigned char type, - unsigned char id, unsigned char index, void *buf, int size); -int usb_set_report(struct usb_device *dev, unsigned char type, - unsigned char id, unsigned char index, void *buf, int size); +int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, + unsigned char id, void *buf, int size); +int usb_set_report(struct usb_device *dev, int ifnum, unsigned char type, + unsigned char id, void *buf, int size); int usb_string(struct usb_device *dev, int index, char *buf, size_t size); -int usb_clear_halt(struct usb_device *dev, int endp); +int usb_clear_halt(struct usb_device *dev, int pipe); #define usb_get_extra_descriptor(ifpoint,type,ptr)\ __usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,type,(void**)ptr) diff -ur --new-file old/linux/drivers/usb/usb_scsi.c new/linux/drivers/usb/usb_scsi.c --- old/linux/drivers/usb/usb_scsi.c Tue Jan 18 01:24:48 2000 +++ new/linux/drivers/usb/usb_scsi.c Thu Jan 1 01:00:00 1970 @@ -1,1539 +0,0 @@ -/* Driver for USB Mass Storage compliant devices - * - * (c) 1999 Michael Gee (michael@linuxspecific.com) - * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) - * - * Further reference: - * This driver is based on the 'USB Mass Storage Class' document. This - * describes in detail the protocol used to communicate with such - * devices. Clearly, the designers had SCSI commands in mind when they - * created this document. The commands are all similar to commands - * in the SCSI-II specification. - * - * It is important to note that in a number of cases this class exhibits - * class-specific exemptions from the USB specification. Notably the - * usage of NAK, STALL and ACK differs from the norm, in that they are - * used to communicate wait, failed and OK on commands. - * Also, for certain devices, the interrupt endpoint is used to convey - * status of a command. - * - * Basically, this stuff is WEIRD!! - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "../scsi/scsi.h" -#include "../scsi/hosts.h" -#include "../scsi/sd.h" - -#include "usb.h" -#include "usb_scsi.h" - -/* direction table -- this indicates the direction of the data - * transfer for each command code -- a 1 indicates input - */ -unsigned char us_direction[256/8] = { - 0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77, - 0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* - * Per device data - */ - -static int my_host_number; - -int usb_stor_debug = 1; - -struct us_data { - struct us_data *next; /* next device */ - struct usb_device *pusb_dev; - unsigned int flags; /* from filter initially */ - __u8 ifnum; /* interface number */ - __u8 ep_in; /* in endpoint */ - __u8 ep_out; /* out ....... */ - __u8 ep_int; /* interrupt . */ - __u8 subclass; /* as in overview */ - __u8 protocol; /* .............. */ - __u8 attention_done; /* force attn on first cmd */ - int (*pop)(Scsi_Cmnd *); /* protocol specific do cmd */ - int (*pop_reset)(struct us_data *); /* ........... device reset */ - GUID(guid); /* unique dev id */ - struct Scsi_Host *host; /* our dummy host data */ - Scsi_Host_Template *htmplt; /* own host template */ - int host_number; /* to find us */ - int host_no; /* allocated by scsi */ - int fixedlength; /* expand commands */ - Scsi_Cmnd *srb; /* current srb */ - int action; /* what to do */ - wait_queue_head_t waitq; /* thread waits */ - wait_queue_head_t ip_waitq; /* for CBI interrupts */ - __u16 ip_data; /* interrupt data */ - int ip_wanted; /* needed */ - int pid; /* control thread */ - struct semaphore *notify; /* wait for thread to begin */ - void *irq_handle; /* for USB int requests */ - unsigned int irqpipe; /* pipe for release_irq */ - int mode_xlate; /* trans MODE_6 to _10? */ -}; - -/* - * kernel thread actions - */ - -#define US_ACT_COMMAND 1 -#define US_ACT_ABORT 2 -#define US_ACT_DEVICE_RESET 3 -#define US_ACT_BUS_RESET 4 -#define US_ACT_HOST_RESET 5 - -static struct us_data *us_list; - -static void * storage_probe(struct usb_device *dev, unsigned int ifnum); -static void storage_disconnect(struct usb_device *dev, void *ptr); -static struct usb_driver storage_driver = { - "usb-storage", - storage_probe, - storage_disconnect, - { NULL, NULL } -}; - -/*********************************************************************** - * Data transfer routines - ***********************************************************************/ - -/* transfer one buffer (breaking into packets if necessary) */ -static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length) -{ - int max_size = usb_maxpacket(us->pusb_dev, pipe, usb_pipeout(pipe)) * 16; - int this_xfer; - int result; - unsigned long partial; - int maxtry = 100; - - /* while we have data to transfer */ - while (length) { - - /* calculate how long this will be -- maximum or a remainder */ - this_xfer = length > max_size ? max_size : length; - length -= this_xfer; - - do { - /* transfer the data */ - US_DEBUGP("Bulk xfer %x(%d)\n", (unsigned int)buf, this_xfer); - result = usb_bulk_msg(us->pusb_dev, pipe, buf, - this_xfer, &partial, HZ*5); - US_DEBUGP("bulk_msg returned %d xferred %lu/%d\n", - result, partial, this_xfer); - - /* if we stall, we need to clear it before we go on */ - if (result == USB_ST_STALL) { - US_DEBUGP("clearing endpoint halt for pipe %x\n", pipe); - usb_clear_halt(us->pusb_dev, - usb_pipeendpoint(pipe) | (pipe & USB_DIR_IN)); - } - - /* we want to retry if the device reported NAK */ - if (result == USB_ST_TIMEOUT) { - - /* if our try counter reaches 0, bail out */ - if (!maxtry--) - break; - - /* otherwise, we did transmit some data, and we update pointers */ - this_xfer -= partial; - buf += partial; - - } else if (!result && partial != this_xfer) { - /* result is an error, not a NAK, and short data - assume end */ - result = USB_ST_DATAUNDERRUN; - break; - - } else if (result == USB_ST_STALL && us->protocol == US_PR_CB) { - /* for CB devices, a stall isn't fatal? */ - - /* if our try counter reaches 0, bail out */ - if (!maxtry--) - break; - - this_xfer -= partial; - buf += partial; - } - - /* continue until this transfer is done */ - } while ( this_xfer ); - - /* if we have some nonzero result, we return it here */ - if (result) - return result; - - /* otherwise, we advance the buf pointer - * note that the code above doesn't advance the pointer if all - * goes well - */ - buf += this_xfer; - } - - /* if we get here, we're done and successful */ - return 0; -} - -/* transfer one SCSI command, using scatter-gather if requested */ -static int us_transfer(Scsi_Cmnd *srb, int dir_in) -{ - struct us_data *us = (struct us_data *)srb->host_scribble; - int i; - int result = -1; - unsigned int pipe = dir_in ? usb_rcvbulkpipe(us->pusb_dev, us->ep_in) : - usb_sndbulkpipe(us->pusb_dev, us->ep_out); - - if (srb->use_sg) { - struct scatterlist *sg = (struct scatterlist *) srb->request_buffer; - - for (i = 0; i < srb->use_sg; i++) { - result = us_one_transfer(us, pipe, sg[i].address, sg[i].length); - if (result) - break; - } - } - else - result = us_one_transfer(us, pipe, - srb->request_buffer, srb->request_bufflen); - - if (result) - US_DEBUGP("us_transfer returning error %d\n", result); - return result; -} - -/* calculate the length of the data transfer (not the command) for any - * given SCSI command - */ -static unsigned int us_transfer_length(Scsi_Cmnd *srb) -{ - int i; - unsigned int total = 0; - - /* always zero for some commands */ - switch (srb->cmnd[0]) { - case SEEK_6: - case SEEK_10: - case REZERO_UNIT: - case ALLOW_MEDIUM_REMOVAL: - case START_STOP: - case TEST_UNIT_READY: - return 0; - - default: - break; - } - - if (srb->use_sg) { - struct scatterlist *sg = (struct scatterlist *) srb->request_buffer; - - for (i = 0; i < srb->use_sg; i++) { - total += sg[i].length; - } - return total; - } - else - return srb->request_bufflen; -} - -/*********************************************************************** - * Transport routines - ***********************************************************************/ - -static int CBI_irq(int state, void *buffer, int len, void *dev_id) -{ - struct us_data *us = (struct us_data *)dev_id; - - US_DEBUGP("CBI_irq() called!!\n"); - - if (state != USB_ST_REMOVED) { - us->ip_data = le16_to_cpup((__u16 *)buffer); - US_DEBUGP("Interrupt Status %x\n", us->ip_data); - } - - if (us->ip_wanted) { - us->ip_wanted = 0; - wake_up(&us->ip_waitq); - } - - /* this return code is truly meaningless */ - return 0; -} - -static int pop_CB_reset(struct us_data *us) -{ - unsigned char cmd[12]; - int result; - - US_DEBUGP("pop_CB_reset\n"); - - memset(cmd, -1, sizeof(cmd)); - cmd[0] = SEND_DIAGNOSTIC; - cmd[1] = 4; - result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), - US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, us->ifnum, cmd, sizeof(cmd), HZ*5); - - /* long wait for reset */ - - schedule_timeout(HZ*6); - - US_DEBUGP("pop_CB_reset: clearing endpoint halt\n"); - usb_clear_halt(us->pusb_dev, us->ep_in | USB_DIR_IN); - usb_clear_halt(us->pusb_dev, us->ep_out | USB_DIR_OUT); - - US_DEBUGP("pop_CB_reset done\n"); - return 0; -} - -static int pop_CB_command(Scsi_Cmnd *srb) -{ - struct us_data *us = (struct us_data *)srb->host_scribble; - unsigned char cmd[16]; - int result; - int retry = 5; - int done_start = 0; - - /* we'll try this up to 5 times? */ - while (retry--) { - if (us->flags & US_FL_FIXED_COMMAND) { - memset(cmd, 0, us->fixedlength); - - /* fix some commands */ - - switch (srb->cmnd[0]) { - case WRITE_6: - case READ_6: - cmd[0] = srb->cmnd[0] | 0x20; - cmd[1] = srb->cmnd[1] & 0xE0; - cmd[2] = 0; - cmd[3] = srb->cmnd[1] & 0x1F; - cmd[4] = srb->cmnd[2]; - cmd[5] = srb->cmnd[3]; - cmd[8] = srb->cmnd[4]; - break; - - case MODE_SENSE: - case MODE_SELECT: - us->mode_xlate = (srb->cmnd[0] == MODE_SENSE); - cmd[0] = srb->cmnd[0] | 0x40; - cmd[1] = srb->cmnd[1]; - cmd[2] = srb->cmnd[2]; - cmd[8] = srb->cmnd[4]; - break; - - default: - us->mode_xlate = 0; - memcpy(cmd, srb->cmnd, srb->cmd_len); - break; - } /* switch */ - - result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), - US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, us->ifnum, - cmd, us->fixedlength, HZ*5); - US_DEBUGP("First usb_control_msg returns %d\n", result); - - /* For UFI, if this is the first time we've sent this TEST_UNIT_READY - * command, we can try again - */ - if (!done_start && (us->subclass == US_SC_UFI) - && (cmd[0] == TEST_UNIT_READY) && (result < 0)) { - - /* as per spec try a start command, wait and retry */ - wait_ms(100); - - done_start++; - memset(cmd, 0, sizeof(cmd)); - cmd[0] = START_STOP; - cmd[4] = 1; /* start */ - - result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), - US_CBI_ADSC, - USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, us->ifnum, - cmd, us->fixedlength, HZ*5); - US_DEBUGP("Next usb_control_msg returns %d\n", result); - - /* allow another retry */ - retry++; - continue; - } - } else { /* !US_FL_FIXED_COMMAND */ - result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), - US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, us->ifnum, - srb->cmnd, srb->cmd_len, HZ*5); - } - - /* return an answer if we've got one */ - if (/*result != USB_ST_STALL &&*/ result != USB_ST_TIMEOUT) - return result; - } - - /* all done -- return our status */ - return result; -} - -/* - * Control/Bulk status handler - */ - -static int pop_CB_status(Scsi_Cmnd *srb) -{ - struct us_data *us = (struct us_data *)srb->host_scribble; - int result; - __u8 status[2]; - int retry = 5; - - US_DEBUGP("pop_CB_status, proto=%x\n", us->protocol); - switch (us->protocol) { - case US_PR_CB: - /* get from control */ - - while (retry--) { - result = usb_control_msg(us->pusb_dev, usb_rcvctrlpipe(us->pusb_dev,0), - USB_REQ_GET_STATUS, USB_DIR_IN | - USB_TYPE_STANDARD | USB_RECIP_DEVICE, - 0, us->ifnum, status, sizeof(status), HZ*5); - if (result != USB_ST_TIMEOUT) - break; - } - if (result) { - US_DEBUGP("Bad AP status request %d\n", result); - return DID_ABORT << 16; - } - US_DEBUGP("Got AP status %x %x\n", status[0], status[1]); - if (srb->cmnd[0] != REQUEST_SENSE && srb->cmnd[0] != INQUIRY && - ( (status[0] & ~3) || status[1])) - return (DID_OK << 16) | 2; - else - return DID_OK << 16; - break; - - case US_PR_CBI: - /* get from interrupt pipe */ - - /* add interrupt transfer, marked for removal */ - us->ip_wanted = 1; - - /* go to sleep until we get this interrup */ - sleep_on(&us->ip_waitq); - - /* NO! We don't release this IRQ. We just re-use the handler - usb_release_irq(us->pusb_dev, us->irq_handle, us->irqpipe); - us->irq_handle = NULL; - */ - - if (us->ip_wanted) { - US_DEBUGP("Did not get interrupt on CBI\n"); - us->ip_wanted = 0; - return DID_ABORT << 16; - } - - US_DEBUGP("Got interrupt data %x\n", us->ip_data); - - /* sort out what it means */ - - if (us->subclass == US_SC_UFI) { - /* gives us asc and ascq, as per request sense */ - - if (srb->cmnd[0] == REQUEST_SENSE || - srb->cmnd[0] == INQUIRY) - return DID_OK << 16; - else - return (DID_OK << 16) + ((us->ip_data & 0xff) ? 2 : 0); - } - if (us->ip_data & 0xff) { - US_DEBUGP("Bad CBI interrupt data %x\n", us->ip_data); - return DID_ABORT << 16; - } - return (DID_OK << 16) + ((us->ip_data & 0x300) ? 2 : 0); - } - return DID_ERROR << 16; -} - -/* Protocol command handlers */ - -static int pop_CBI(Scsi_Cmnd *srb) -{ - int result; - - US_DEBUGP("CBI gets a command:\n"); - US_DEBUG(us_show_command(srb)); - - /* run the command */ - if ((result = pop_CB_command(srb)) < 0) { - US_DEBUGP("Call to pop_CB_command returned %d\n", result); - if (result == USB_ST_STALL || result == USB_ST_TIMEOUT) { - return (DID_OK << 16) | 2; - } - return DID_ERROR << 16; - } - - /* transfer the data */ - if (us_transfer_length(srb)) { - result = us_transfer(srb, US_DIRECTION(srb->cmnd[0])); - if ((result < 0) && - (result != USB_ST_DATAUNDERRUN) && - (result != USB_ST_STALL)) { - US_DEBUGP("CBI attempted to transfer data, result is %x\n", result); - return DID_ERROR << 16; - } -#if 0 - else if (result == USB_ST_DATAUNDERRUN) { - return DID_OK << 16; - } - } else { - if (!result) { - return DID_OK << 16; - } -#endif - } - - /* get status */ - return pop_CB_status(srb); -} - -static int pop_Bulk_reset(struct us_data *us) -{ - int result; - - result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), - US_BULK_RESET, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - US_BULK_RESET_HARD, us->ifnum, - NULL, 0, HZ*5); - if (result) - US_DEBUGP("Bulk hard reset failed %d\n", result); - usb_clear_halt(us->pusb_dev, us->ep_in | USB_DIR_IN); - usb_clear_halt(us->pusb_dev, us->ep_out | USB_DIR_OUT); - - /* long wait for reset */ - - schedule_timeout(HZ*6); - - return result; -} - -/* - * The bulk only protocol handler. - * Uses the in and out endpoints to transfer commands and data (nasty) - */ -static int pop_Bulk(Scsi_Cmnd *srb) -{ - struct us_data *us = (struct us_data *)srb->host_scribble; - struct bulk_cb_wrap bcb; - struct bulk_cs_wrap bcs; - int result; - unsigned long partial; - int stall; - - /* set up the command wrapper */ - - bcb.Signature = US_BULK_CB_SIGN; - bcb.DataTransferLength = us_transfer_length(srb);; - bcb.Flags = US_DIRECTION(srb->cmnd[0]) << 7; - bcb.Tag = srb->serial_number; - bcb.Lun = 0; - memset(bcb.CDB, 0, sizeof(bcb.CDB)); - memcpy(bcb.CDB, srb->cmnd, srb->cmd_len); - if (us->flags & US_FL_FIXED_COMMAND) { - bcb.Length = us->fixedlength; - } else { - bcb.Length = srb->cmd_len; - } - - /* send it to out endpoint */ - - US_DEBUGP("Bulk command S %x T %x L %d F %d CL %d\n", - bcb.Signature, bcb.Tag, bcb.DataTransferLength, - bcb.Flags, bcb.Length); - result = usb_bulk_msg(us->pusb_dev, - usb_sndbulkpipe(us->pusb_dev, us->ep_out), &bcb, - US_BULK_CB_WRAP_LEN, &partial, HZ*5); - if (result) { - US_DEBUGP("Bulk command result %x\n", result); - return DID_ABORT << 16; - } - - //return DID_BAD_TARGET << 16; - /* send/receive data */ - - if (bcb.DataTransferLength) { - result = us_transfer(srb, bcb.Flags); - if (result && result != USB_ST_DATAUNDERRUN && result != USB_ST_STALL) { - US_DEBUGP("Bulk transfer result %x\n", result); - return DID_ABORT << 16; - } - } - - /* get status */ - - stall = 0; - do { - result = usb_bulk_msg(us->pusb_dev, - usb_rcvbulkpipe(us->pusb_dev, us->ep_in), &bcs, - US_BULK_CS_WRAP_LEN, &partial, HZ*5); - if (result == USB_ST_STALL || result == USB_ST_TIMEOUT) - stall++; - else - break; - } while ( stall < 3); - if (result && result != USB_ST_DATAUNDERRUN) { - US_DEBUGP("Bulk status result = %x\n", result); - return DID_ABORT << 16; - } - - /* check bulk status */ - - US_DEBUGP("Bulk status S %x T %x R %d V %x\n", - bcs.Signature, bcs.Tag, bcs.Residue, bcs.Status); - if (bcs.Signature != US_BULK_CS_SIGN || bcs.Tag != bcb.Tag || - bcs.Status > US_BULK_STAT_PHASE) { - US_DEBUGP("Bulk logical error\n"); - return DID_ABORT << 16; - } - - /* We need to fix some of this status handling. */ - switch (bcs.Status) { - case US_BULK_STAT_OK: - return DID_OK << 16; - - case US_BULK_STAT_FAIL: - /* check for underrun - dont report */ - if (bcs.Residue) - return DID_OK << 16; - //pop_Bulk_reset(us); - break; - - case US_BULK_STAT_PHASE: - return DID_ERROR << 16; - } - - return (DID_OK << 16) | 2; /* check sense required */ -} - -/* Host functions */ - -/* detect adapter (always true ) */ -static int us_detect(struct SHT *sht) -{ - /* FIXME - not nice at all, but how else ? */ - struct us_data *us = (struct us_data *)sht->proc_dir; - char name[32]; - - /* set up our name */ - sprintf(name, "usbscsi%d", us->host_number); - sht->name = sht->proc_name = kmalloc(strlen(name)+1, GFP_KERNEL); - if (!sht->proc_name) - return 0; - strcpy(sht->proc_name, name); - - /* we start with no /proc directory entry */ - sht->proc_dir = NULL; - - /* register the host */ - us->host = scsi_register(sht, sizeof(us)); - if (us->host) { - us->host->hostdata[0] = (unsigned long)us; - us->host_no = us->host->host_no; - return 1; - } - - /* odd... didn't register properly. Abort and free pointers */ - kfree(sht->proc_name); - sht->proc_name = NULL; - sht->name = NULL; - return 0; -} - -/* release - must be here to stop scsi - * from trying to release IRQ etc. - * Kill off our data - */ -static int us_release(struct Scsi_Host *psh) -{ - struct us_data *us = (struct us_data *)psh->hostdata[0]; - struct us_data *prev = (struct us_data *)&us_list; - - if (us->irq_handle) { - usb_release_irq(us->pusb_dev, us->irq_handle, us->irqpipe); - us->irq_handle = NULL; - } - if (us->pusb_dev) - usb_deregister(&storage_driver); - - /* FIXME - leaves hanging host template copy */ - /* (because scsi layer uses it after removal !!!) */ - while (prev->next != us) - prev = prev->next; - prev->next = us->next; - return 0; -} - -/* run command */ -static int us_command( Scsi_Cmnd *srb ) -{ - US_DEBUGP("Bad use of us_command\n"); - - return DID_BAD_TARGET << 16; -} - -/* run command */ -static int us_queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *)) -{ - struct us_data *us = (struct us_data *)srb->host->hostdata[0]; - - US_DEBUGP("Command wakeup\n"); - if (us->srb) { - /* busy */ - } - srb->host_scribble = (unsigned char *)us; - us->srb = srb; - srb->scsi_done = done; - us->action = US_ACT_COMMAND; - - /* wake up the process task */ - - wake_up_interruptible(&us->waitq); - - return 0; -} - -static int us_abort( Scsi_Cmnd *srb ) -{ - return 0; -} - -static int us_bus_reset( Scsi_Cmnd *srb ) -{ - struct us_data *us = (struct us_data *)srb->host->hostdata[0]; - - US_DEBUGP("Bus reset requested\n"); - us->pop_reset(us); - return SUCCESS; -} - -static int us_host_reset( Scsi_Cmnd *srb ) -{ - return 0; -} - -/*********************************************************************** - * /proc/scsi/ functions - ***********************************************************************/ - -/* we use this macro to help us write into the buffer */ -#undef SPRINTF -#define SPRINTF(args...) do { if (pos < (buffer + length)) pos += sprintf (pos, ## args); } while (0) - -int usb_stor_proc_info (char *buffer, char **start, off_t offset, - int length, int hostno, int inout) -{ - struct us_data *us = us_list; - char *pos = buffer; - char *tmp_ptr; - - /* find our data from hostno */ - while (us) { - if (us->host_no == hostno) - break; - us = us->next; - } - - /* if we couldn't find it, we return an error */ - if (!us) - return -ESRCH; - - /* if someone is sending us data, just throw it away */ - if (inout) - return length; - - /* print the controler name */ - SPRINTF ("Host scsi%d: usb-scsi\n", hostno); - - /* print product and vendor strings */ - tmp_ptr = kmalloc(256, GFP_KERNEL); - if (!us->pusb_dev || !tmp_ptr) { - SPRINTF("Vendor: Unknown Vendor\n"); - SPRINTF("Product: Unknown Product\n"); - } else { - SPRINTF("Vendor: "); - if (usb_string(us->pusb_dev, us->pusb_dev->descriptor.iManufacturer, tmp_ptr, 256) > 0) - SPRINTF("%s\n", tmp_ptr); - else - SPRINTF("Unknown Vendor\n"); - - SPRINTF("Product: "); - if (usb_string(us->pusb_dev, us->pusb_dev->descriptor.iProduct, tmp_ptr, 256) > 0) - SPRINTF("%s\n", tmp_ptr); - else - SPRINTF("Unknown Vendor\n"); - } - kfree(tmp_ptr); - - SPRINTF("Protocol: "); - switch (us->protocol) { - case US_PR_CB: - SPRINTF("Control/Bulk\n"); - break; - - case US_PR_CBI: - SPRINTF("Control/Bulk/Interrupt\n"); - break; - - case US_PR_BULK: - SPRINTF("Bulk only\n"); - break; - - default: - SPRINTF("Unknown Protocol\n"); - break; - } - - /* show the GUID of the device */ - SPRINTF("GUID: " GUID_FORMAT "\n", GUID_ARGS(us->guid)); - - /* - * Calculate start of next buffer, and return value. - */ - *start = buffer + offset; - - if ((pos - buffer) < offset) - return (0); - else if ((pos - buffer - offset) < length) - return (pos - buffer - offset); - else - return (length); -} - -/* - * this defines our 'host' - */ - -static Scsi_Host_Template my_host_template = { - NULL, /* next */ - NULL, /* module */ - NULL, /* proc_dir */ - usb_stor_proc_info, - NULL, /* name - points to unique */ - us_detect, - us_release, - NULL, /* info */ - NULL, /* ioctl */ - us_command, - us_queuecommand, - NULL, /* eh_strategy */ - us_abort, - us_bus_reset, - us_bus_reset, - us_host_reset, - NULL, /* abort */ - NULL, /* reset */ - NULL, /* slave_attach */ - NULL, /* bios_param */ - 1, /* can_queue */ - -1, /* this_id */ - SG_ALL, /* sg_tablesize */ - 1, /* cmd_per_lun */ - 0, /* present */ - FALSE, /* unchecked_isa_dma */ - FALSE, /* use_clustering */ - TRUE, /* use_new_eh_code */ - TRUE /* emulated */ -}; - -static unsigned char sense_notready[] = { - 0x70, /* current error */ - 0x00, - 0x02, /* not ready */ - 0x00, - 0x00, - 10, /* additional length */ - 0x00, - 0x00, - 0x00, - 0x00, - 0x04, /* not ready */ - 0x03, /* manual intervention */ - 0x00, - 0x00, - 0x00, - 0x00 -}; - -static int usb_stor_control_thread(void * __us) -{ - struct us_data *us = (struct us_data *)__us; - int action; - - lock_kernel(); - - /* - * This thread doesn't need any user-level access, - * so get rid of all our resources.. - */ - daemonize(); - - sprintf(current->comm, "usbscsi%d", us->host_number); - - unlock_kernel(); - - up(us->notify); - - for(;;) { - siginfo_t info; - int unsigned long signr; - - interruptible_sleep_on(&us->waitq); - - action = us->action; - us->action = 0; - - switch (action) { - case US_ACT_COMMAND: - if (us->srb->target || us->srb->lun) { - /* bad device */ - US_DEBUGP( "Bad device number (%d/%d) or dev %x\n", - us->srb->target, us->srb->lun, (unsigned int)us->pusb_dev); - us->srb->result = DID_BAD_TARGET << 16; - } else if (!us->pusb_dev) { - - /* our device has gone - pretend not ready */ - - if (us->srb->cmnd[0] == REQUEST_SENSE) { - memcpy(us->srb->request_buffer, sense_notready, sizeof(sense_notready)); - us->srb->result = DID_OK << 16; - } else { - us->srb->result = (DID_OK << 16) | 2; - } - } else { - US_DEBUG(us_show_command(us->srb)); - - if (us->srb->cmnd[0] == START_STOP && - us->pusb_dev->descriptor.idProduct == 0x0001 && - us->pusb_dev->descriptor.idVendor == 0x04e6) - us->srb->result = DID_OK << 16; - else { - unsigned int savelen = us->srb->request_bufflen; - unsigned int saveallocation = 0; - - /* check for variable length - do properly if so */ - switch (us->srb->cmnd[0]) { - case REQUEST_SENSE: - if (us->srb->request_bufflen > 18) - us->srb->request_bufflen = 18; - else - break; - saveallocation = us->srb->cmnd[4]; - us->srb->cmnd[4] = 18; - break; - - case INQUIRY: - if (us->srb->request_bufflen > 36) - us->srb->request_bufflen = 36; - else - break; - saveallocation = us->srb->cmnd[4]; - us->srb->cmnd[4] = 36; - break; - - case MODE_SENSE: - if (us->srb->request_bufflen > 4) - us->srb->request_bufflen = 4; - else - break; - saveallocation = us->srb->cmnd[4]; - us->srb->cmnd[4] = 4; - break; - - case LOG_SENSE: - case MODE_SENSE_10: - if (us->srb->request_bufflen > 8) - us->srb->request_bufflen = 8; - else - break; - saveallocation = (us->srb->cmnd[7] << 8) | us->srb->cmnd[8]; - us->srb->cmnd[7] = 0; - us->srb->cmnd[8] = 8; - break; - - default: - break; - } /* end switch on cmnd[0] */ - -#if 0 - /* translate READ_6 to READ_10 */ - if (us->srb->cmnd[0] == 0x08) { - - /* get the control */ - us->srb->cmnd[9] = us->srb->cmnd[5]; - - /* get the length */ - us->srb->cmnd[8] = us->srb->cmnd[6]; - us->srb->cmnd[7] = 0; - - /* set the reserved area to 0 */ - us->srb->cmnd[6] = 0; - - /* get LBA */ - us->srb->cmnd[5] = us->srb->cmnd[3]; - us->srb->cmnd[4] = us->srb->cmnd[2]; - us->srb->cmnd[3] = 0; - us->srb->cmnd[2] = 0; - - /* LUN and other info in cmnd[1] can stay */ - - /* fix command code */ - us->srb->cmnd[0] = 0x28; - - US_DEBUGP("Changing READ_6 to READ_10\n"); - US_DEBUG(us_show_command(us->srb)); - } - - /* translate WRITE_6 to WRITE_10 */ - if (us->srb->cmnd[0] == 0x0A) { - - /* get the control */ - us->srb->cmnd[9] = us->srb->cmnd[5]; - - /* get the length */ - us->srb->cmnd[8] = us->srb->cmnd[4]; - us->srb->cmnd[7] = 0; - - /* set the reserved area to 0 */ - us->srb->cmnd[6] = 0; - - /* get LBA */ - us->srb->cmnd[5] = us->srb->cmnd[3]; - us->srb->cmnd[4] = us->srb->cmnd[2]; - us->srb->cmnd[3] = 0; - us->srb->cmnd[2] = 0; - - /* LUN and other info in cmnd[1] can stay */ - - /* fix command code */ - us->srb->cmnd[0] = 0x2A; - - US_DEBUGP("Changing WRITE_6 to WRITE_10\n"); - US_DEBUG(us_show_command(us->srb)); - } -#endif - - /* let's do the command */ - us->srb->result = us->pop(us->srb); - - if (savelen != us->srb->request_bufflen && - us->srb->result == (DID_OK << 16)) { - unsigned char *p = (unsigned char *)us->srb->request_buffer; - unsigned int length = 0; - - /* set correct length and retry */ - switch (us->srb->cmnd[0]) { - case REQUEST_SENSE: - /* simply return 18 bytes */ - p[7] = 10; - length = us->srb->request_bufflen; - break; - - case INQUIRY: - length = p[4] + 5 > savelen ? savelen : p[4] + 5; - us->srb->cmnd[4] = length; - break; - - case MODE_SENSE: - US_DEBUGP("MODE_SENSE Mode data length is %d\n", p[0]); - length = p[0] + 1 > savelen ? savelen : p[0] + 1; - us->srb->cmnd[4] = length; - break; - - case LOG_SENSE: - length = ((p[2] << 8) + p[3]) + 4 > savelen ? savelen : ((p[2] << 8) + p[3]) + 4; - us->srb->cmnd[7] = length >> 8; - us->srb->cmnd[8] = length; - break; - - case MODE_SENSE_10: - US_DEBUGP("MODE_SENSE_10 Mode data length is %d\n", - (p[0] << 8) + p[1]); - length = ((p[0] << 8) + p[1]) + 6 > savelen ? savelen : ((p[0] << 8) + p[1]) + 6; - us->srb->cmnd[7] = length >> 8; - us->srb->cmnd[8] = length; - break; - } /* end switch on cmnd[0] */ - - US_DEBUGP("Old/New length = %d/%d\n", - savelen, length); - - if (us->srb->request_bufflen != length) { - US_DEBUGP("redoing cmd with len=%d\n", length); - us->srb->request_bufflen = length; - us->srb->result = us->pop(us->srb); - } - /* reset back to original values */ - - us->srb->request_bufflen = savelen; - switch (us->srb->cmnd[0]) { - case INQUIRY: - if ((((unsigned char*)us->srb->request_buffer)[2] & 0x7) == 0) { - US_DEBUGP("Fixing INQUIRY data, setting SCSI rev to 2\n"); - ((unsigned char*)us->srb->request_buffer)[2] |= 2; - } - /* FALL THROUGH */ - case REQUEST_SENSE: - case MODE_SENSE: - if (us->srb->use_sg == 0 && length > 0) { - int i; - printk(KERN_DEBUG "Data is"); - for (i = 0; i < 32 && i < length; ++i) - printk(" %.2x", ((unsigned char *)us->srb->request_buffer)[i]); - if (i < length) - printk(" ..."); - printk("\n"); - } - us->srb->cmnd[4] = saveallocation; - if (us->mode_xlate) { - /* convert MODE_SENSE_10 return data - * format to MODE_SENSE_6 format */ - unsigned char *dta = (unsigned char *)us->srb->request_buffer; - dta[0] = dta[1]; /* data len */ - dta[1] = dta[2]; /* med type */ - dta[2] = dta[3]; /* dev-spec prm */ - dta[3] = dta[7]; /* block desc len */ - printk (KERN_DEBUG USB_SCSI "new MODE_SENSE_6 data = %.2X %.2X %.2X %.2X\n", - dta[0], dta[1], dta[2], dta[3]); - } - break; - - case LOG_SENSE: - case MODE_SENSE_10: - us->srb->cmnd[7] = saveallocation >> 8; - us->srb->cmnd[8] = saveallocation; - break; - } /* end switch on cmnd[0] */ - } - /* force attention on first command */ - if (!us->attention_done) { - US_DEBUGP("forcing unit attention\n"); - if (us->srb->cmnd[0] == REQUEST_SENSE) { - if (us->srb->result == (DID_OK << 16)) { - unsigned char *p = (unsigned char *)us->srb->request_buffer; - - us->attention_done = 1; - if ((p[2] & 0x0f) != UNIT_ATTENTION) { - p[2] = UNIT_ATTENTION; - p[12] = 0x29; /* power on, reset or bus-reset */ - p[13] = 0; - } - } - } else if (us->srb->cmnd[0] != INQUIRY && - us->srb->result == (DID_OK << 16)) { - us->srb->result |= 2; /* force check condition */ - } - } - } - } - US_DEBUGP("scsi cmd done, result=%x\n", us->srb->result); - us->srb->scsi_done(us->srb); - us->srb = NULL; - break; - - case US_ACT_ABORT: - break; - - case US_ACT_DEVICE_RESET: - break; - - case US_ACT_BUS_RESET: - break; - - case US_ACT_HOST_RESET: - break; - - } /* end switch on action */ - - if (signal_pending(current)) { - /* sending SIGUSR1 makes us print out some info */ - spin_lock_irq(¤t->sigmask_lock); - signr = dequeue_signal(¤t->blocked, &info); - spin_unlock_irq(¤t->sigmask_lock); - - if (signr == SIGUSR2) { - usb_stor_debug = !usb_stor_debug; - printk(USB_SCSI "debug toggle = %d\n", usb_stor_debug); - } else { - break; /* exit the loop on any other signal */ - } - } - } - - // MOD_DEC_USE_COUNT; - - printk("usb_stor_control_thread exiting\n"); - - return 0; -} - -/* Probe to see if a new device is actually a SCSI device */ -static void * storage_probe(struct usb_device *dev, unsigned int ifnum) -{ - struct usb_interface_descriptor *interface; - int i; - char mf[32]; /* manufacturer */ - char prod[32]; /* product */ - char serial[32]; /* serial number */ - struct us_data *ss = NULL; - unsigned int flags = 0; - GUID(guid); /* Global Unique Identifier */ - struct us_data *prev; - Scsi_Host_Template *htmplt; - int protocol = 0; - int subclass = 0; - struct usb_interface_descriptor *altsetting = - &(dev->actconfig->interface[ifnum].altsetting[0]); - - /* clear the GUID and fetch the strings */ - GUID_CLEAR(guid); - usb_string(dev, dev->descriptor.iManufacturer, mf, sizeof(mf)); - usb_string(dev, dev->descriptor.iProduct, prod, sizeof(prod)); - usb_string(dev, dev->descriptor.iSerialNumber, serial, sizeof(serial)); - - /* let's examine the device now */ - - /* We make an exception for the shuttle E-USB */ - if (dev->descriptor.idVendor == 0x04e6 && - dev->descriptor.idProduct == 0x0001) { - protocol = US_PR_CB; - subclass = US_SC_8070; /* an assumption */ - } else if (dev->descriptor.bDeviceClass != 0 || - altsetting->bInterfaceClass != USB_CLASS_MASS_STORAGE || - altsetting->bInterfaceSubClass < US_SC_MIN || - altsetting->bInterfaceSubClass > US_SC_MAX) { - /* if it's not a mass storage, we go no further */ - return NULL; - } - - /* At this point, we know we've got a live one */ - US_DEBUGP("USB Mass Storage device detected\n"); - - /* Create a GUID for this device */ - if (dev->descriptor.iSerialNumber && serial[0]) { - /* If we have a serial number, and it's a non-NULL string */ - make_guid(guid, dev->descriptor.idVendor, - dev->descriptor.idProduct, - serial); - } else { - /* We don't have a serial number, so we use 0 */ - make_guid(guid, dev->descriptor.idVendor, - dev->descriptor.idProduct, "0"); - } - - /* Now check if we have seen this GUID before, and restore - * the flags if we find it - */ - for (ss = us_list; ss != NULL; ss = ss->next) { - if (!ss->pusb_dev && GUID_EQUAL(guid, ss->guid)) { - US_DEBUGP("Found existing GUID " GUID_FORMAT "\n", - GUID_ARGS(guid)); - flags = ss->flags; - break; - } - } - - /* If ss == NULL, then this is a new device. Allocate memory for it */ - if (!ss) { - if ((ss = (struct us_data *)kmalloc(sizeof(*ss), - GFP_KERNEL)) == NULL) { - printk(KERN_WARNING USB_SCSI "Out of memory\n"); - return NULL; - } - memset(ss, 0, sizeof(struct us_data)); - } - - /* Initialize the us_data structure with some useful info */ - interface = altsetting; - ss->flags = flags; - ss->ifnum = ifnum; - ss->pusb_dev = dev; - ss->attention_done = 0; - - /* If the device has subclass and protocol, then use that. Otherwise, - * take data from the specific interface. - */ - if (subclass) { - ss->subclass = subclass; - ss->protocol = protocol; - } else { - ss->subclass = interface->bInterfaceSubClass; - ss->protocol = interface->bInterfaceProtocol; - } - - /* set the handler pointers based on the protocol */ - US_DEBUGP("Protocol: "); - switch (ss->protocol) { - case US_PR_CB: - US_DEBUGPX("Control/Bulk\n"); - ss->pop = pop_CBI; - ss->pop_reset = pop_CB_reset; - break; - - case US_PR_CBI: - US_DEBUGPX("Control/Bulk/Interrupt\n"); - ss->pop = pop_CBI; - ss->pop_reset = pop_CB_reset; - break; - - case US_PR_BULK: - US_DEBUGPX("Bulk\n"); - ss->pop = pop_Bulk; - ss->pop_reset = pop_Bulk_reset; - break; - - default: - US_DEBUGPX("Unknown\n"); - kfree(ss); - return NULL; - break; - } - - /* - * We are expecting a minimum of 2 endpoints - in and out (bulk). - * An optional interrupt is OK (necessary for CBI protocol). - * We will ignore any others. - */ - for (i = 0; i < interface->bNumEndpoints; i++) { - /* is it an BULK endpoint? */ - if ((interface->endpoint[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_BULK) { - if (interface->endpoint[i].bEndpointAddress & USB_DIR_IN) - ss->ep_in = interface->endpoint[i].bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - else - ss->ep_out = interface->endpoint[i].bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - } - - /* is it an interrupt endpoint? */ - if ((interface->endpoint[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_INT) { - ss->ep_int = interface->endpoint[i].bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - } - } - US_DEBUGP("Endpoints In %d Out %d Int %d\n", - ss->ep_in, ss->ep_out, ss->ep_int); - - /* Do some basic sanity checks, and bail if we find a problem */ - if (usb_set_interface(dev, interface->bInterfaceNumber, 0) || - !ss->ep_in || !ss->ep_out || - (ss->protocol == US_PR_CBI && ss->ep_int == 0)) { - US_DEBUGP("Problems with device\n"); - if (ss->host) { - scsi_unregister_module(MODULE_SCSI_HA, ss->htmplt); - kfree(ss->htmplt->name); - kfree(ss->htmplt); - } - - kfree(ss); - return NULL; - } - - /* If this is a new device (i.e. we haven't seen it before), we need to - * generate a scsi host definition, and register with scsi above us - */ - if (!ss->host) { - /* copy the GUID we created before */ - US_DEBUGP("New GUID " GUID_FORMAT "\n", GUID_ARGS(guid)); - memcpy(ss->guid, guid, sizeof(guid)); - - /* set class specific stuff */ - US_DEBUGP("SubClass: "); - switch (ss->subclass) { - case US_SC_RBC: - US_DEBUGPX("Reduced Block Commands\n"); - break; - - case US_SC_8020: - US_DEBUGPX("8020\n"); - break; - - case US_SC_QIC: - US_DEBUGPX("QIC157\n"); - break; - - case US_SC_8070: - US_DEBUGPX("8070\n"); - ss->flags |= US_FL_FIXED_COMMAND; - ss->fixedlength = 12; - break; - - case US_SC_SCSI: - US_DEBUGPX("Transparent SCSI\n"); - break; - - case US_SC_UFI: - US_DEBUGPX("UFI\n"); - ss->flags |= US_FL_FIXED_COMMAND; - ss->fixedlength = 12; - break; - - default: - US_DEBUGPX("Unknown\n"); - break; - } - - /* Allocate memory for the SCSI Host Template */ - if ((htmplt = (Scsi_Host_Template *) - kmalloc(sizeof(*ss->htmplt), GFP_KERNEL)) == NULL ) { - - printk(KERN_WARNING USB_SCSI "Out of memory\n"); - - kfree(ss); - return NULL; - } - - /* Initialize the host template based on the default one */ - memcpy(htmplt, &my_host_template, sizeof(my_host_template)); - - /* Grab the next host number */ - ss->host_number = my_host_number++; - - /* MDD: FIXME: this is bad. We abuse this pointer so we - * can pass the ss pointer to the host controler thread - * in us_detect - */ - (struct us_data *)htmplt->proc_dir = ss; - - /* shuttle E-USB */ - if (dev->descriptor.idVendor == 0x04e6 && - dev->descriptor.idProduct == 0x0001) { - __u8 qstat[2]; - int result; - - result = usb_control_msg(ss->pusb_dev, usb_rcvctrlpipe(dev,0), - 1, 0xC0, - 0, ss->ifnum, - qstat, 2, HZ*5); - US_DEBUGP("C0 status %x %x\n", qstat[0], qstat[1]); - init_waitqueue_head(&ss->ip_waitq); - ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int); - result = usb_request_irq(ss->pusb_dev, ss->irqpipe, CBI_irq, - 255, (void *)ss, &ss->irq_handle); - if (result) - return NULL; - - interruptible_sleep_on_timeout(&ss->ip_waitq, HZ*6); - } else if (ss->protocol == US_PR_CBI) - { - int result; - - init_waitqueue_head(&ss->ip_waitq); - - /* set up the IRQ pipe and handler */ - /* FIXME: This needs to get the period from the device */ - ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int); - result = usb_request_irq(ss->pusb_dev, ss->irqpipe, CBI_irq, - 255, (void *)ss, &ss->irq_handle); - if (result) { - US_DEBUGP("usb_request_irq failed (0x%x), No interrupt for CBI\n", - result); - } - } - - - /* start up our thread */ - { - DECLARE_MUTEX_LOCKED(sem); - - init_waitqueue_head(&ss->waitq); - - ss->notify = &sem; - ss->pid = kernel_thread(usb_stor_control_thread, ss, - CLONE_FS | CLONE_FILES | CLONE_SIGHAND); - if (ss->pid < 0) { - printk(KERN_WARNING USB_SCSI "Unable to start control thread\n"); - kfree(htmplt); - - kfree(ss); - return NULL; - } - - /* wait for it to start */ - down(&sem); - } - - /* now register - our detect function will be called */ - - scsi_register_module(MODULE_SCSI_HA, htmplt); - - /* put us in the list */ - - prev = (struct us_data *)&us_list; - while (prev->next) - prev = prev->next; - prev->next = ss; - } - - printk(KERN_WARNING "WARNING: USB SCSI data integrity not assured\n"); - printk(KERN_INFO "USB SCSI device found at address %d\n", dev->devnum); - - return ss; -} - -/* Handle a disconnect event from the USB core */ -static void storage_disconnect(struct usb_device *dev, void *ptr) -{ - struct us_data *ss = ptr; - - if (!ss) - return; - - ss->pusb_dev = NULL; - // MOD_DEC_USE_COUNT; -} - - -/*********************************************************************** - * Initialization and registration - ***********************************************************************/ - -int usb_stor_init(void) -{ - // MOD_INC_USE_COUNT; - - if (usb_register(&storage_driver) < 0) - return -1; - - printk(KERN_INFO "USB SCSI support registered.\n"); - return 0; -} - -#ifdef MODULE -int init_module(void) -{ - /* MDD: Perhaps we should register the host here */ - return usb_stor_init(); -} - -void cleanup_module(void) -{ - usb_deregister(&storage_driver); -} -#endif diff -ur --new-file old/linux/drivers/usb/usb_scsi.h new/linux/drivers/usb/usb_scsi.h --- old/linux/drivers/usb/usb_scsi.h Sat Jan 8 01:07:14 2000 +++ new/linux/drivers/usb/usb_scsi.h Thu Jan 1 01:00:00 1970 @@ -1,146 +0,0 @@ -/* Driver for USB SCSI - include file - * - * (C) Michael Gee (michael@linuxspecific.com) 1999 - * - * This driver is schizoid - it makes a USB scanner appear as both a SCSI device - * and a character device. The latter is only available if the device has an - * interrupt endpoint, and is used specifically to receive interrupt events. - * - * In order to support various 'strange' scanners, this module supports plug-in - * device-specific filter modules, which can do their own thing when required. - * - */ - -#include - -#define USB_SCSI "usbscsi: " - -extern int usb_stor_debug; - -#ifdef CONFIG_USB_SCSI_DEBUG -void us_show_command(Scsi_Cmnd *srb); -#define US_DEBUGP(x...) { if(usb_stor_debug) printk( KERN_DEBUG USB_SCSI ## x ); } -#define US_DEBUGPX(x...) { if(usb_stor_debug) printk( ## x ); } -#define US_DEBUG(x) { if(usb_stor_debug) x; } -#else -#define US_DEBUGP(x...) -#define US_DEBUGPX(x...) -#define US_DEBUG(x) -#endif - -/* bit set if input */ -extern unsigned char us_direction[256/8]; -#define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1) - -/* Sub Classes */ - -#define US_SC_RBC 1 /* Typically, flash devices */ -#define US_SC_8020 2 /* CD-ROM */ -#define US_SC_QIC 3 /* QIC-157 Tapes */ -#define US_SC_UFI 4 /* Floppy */ -#define US_SC_8070 5 /* Removable media */ -#define US_SC_SCSI 6 /* Transparent */ -#define US_SC_MIN US_SC_RBC -#define US_SC_MAX US_SC_SCSI - -/* Protocols */ - -#define US_PR_CB 1 /* Control/Bulk w/o interrupt */ -#define US_PR_CBI 0 /* Control/Bulk/Interrupt */ -#define US_PR_BULK 0x50 /* bulk only */ - -/* - * Bulk only data structures (Zip 100, for example) - */ - -struct bulk_cb_wrap { - __u32 Signature; /* contains 'USBC' */ - __u32 Tag; /* unique per command id */ - __u32 DataTransferLength; /* size of data */ - __u8 Flags; /* direction in bit 0 */ - __u8 Lun; /* LUN normally 0 */ - __u8 Length; /* of of the CDB */ - __u8 CDB[16]; /* max command */ -}; - -#define US_BULK_CB_WRAP_LEN 31 -#define US_BULK_CB_SIGN 0x43425355 -#define US_BULK_FLAG_IN 1 -#define US_BULK_FLAG_OUT 0 - -struct bulk_cs_wrap { - __u32 Signature; /* should = 'USBS' */ - __u32 Tag; /* same as original command */ - __u32 Residue; /* amount not transferred */ - __u8 Status; /* see below */ - __u8 Filler[18]; -}; - -#define US_BULK_CS_WRAP_LEN 31 -#define US_BULK_CS_SIGN 0x53425355 -#define US_BULK_STAT_OK 0 -#define US_BULK_STAT_FAIL 1 -#define US_BULK_STAT_PHASE 2 - -#define US_BULK_RESET 0xff -#define US_BULK_RESET_SOFT 1 -#define US_BULK_RESET_HARD 0 - -/* - * CBI style - */ - -#define US_CBI_ADSC 0 - -/* - * Filter device definitions - */ -struct usb_scsi_filter { - - struct usb_scsi_filter * next; /* usb_scsi driver only */ - char *name; /* not really required */ - - unsigned int flags; /* Filter flags */ - void * (* probe) (struct usb_device *, char *, char *, char *); /* probe device */ - void (* release)(void *); /* device gone */ - int (* command)(void *, Scsi_Cmnd *); /* all commands */ -}; - -#define GUID(x) __u32 x[3] -#define GUID_EQUAL(x, y) (x[0] == y[0] && x[1] == y[1] && x[2] == y[2]) -#define GUID_CLEAR(x) x[0] = x[1] = x[2] = 0; -#define GUID_NONE(x) (!x[0] && !x[1] && !x[2]) -#define GUID_FORMAT "%08x%08x%08x" -#define GUID_ARGS(x) x[0], x[1], x[2] - -static inline void make_guid( __u32 *pg, __u16 vendor, __u16 product, char *serial) -{ - pg[0] = (vendor << 16) | product; - pg[1] = pg[2] = 0; - while (*serial) { - pg[1] <<= 4; - pg[1] |= pg[2] >> 28; - pg[2] <<= 4; - if (*serial >= 'a') - *serial -= 'a' - 'A'; - pg[2] |= (*serial <= '9' && *serial >= '0') ? *serial - '0' - : *serial - 'A' + 10; - serial++; - } -} - -/* Flag definitions */ -#define US_FL_IP_STATUS 0x00000001 /* status uses interrupt */ -#define US_FL_FIXED_COMMAND 0x00000002 /* expand commands to fixed size */ - -/* - * Called by filters to register/unregister the mini driver - * - * WARNING - the supplied probe function may be called before exiting this fn - */ -int usb_scsi_register(struct usb_scsi_filter *); -void usb_scsi_deregister(struct usb_scsi_filter *); - -#ifdef CONFIG_USB_HP4100 -int hp4100_init(void); -#endif diff -ur --new-file old/linux/drivers/usb/usb_scsi_debug.c new/linux/drivers/usb/usb_scsi_debug.c --- old/linux/drivers/usb/usb_scsi_debug.c Sat Oct 9 00:47:08 1999 +++ new/linux/drivers/usb/usb_scsi_debug.c Thu Jan 1 01:00:00 1970 @@ -1,102 +0,0 @@ - -/* Driver for USB scsi like devices - * - * (C) Michael Gee (michael@linuxspecific.com) 1999 - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "../scsi/scsi.h" -#include "../scsi/hosts.h" -#include "../scsi/sd.h" - -#include "usb.h" -#include "usb_scsi.h" - -void us_show_command(Scsi_Cmnd *srb) -{ - char *what = NULL; - - switch (srb->cmnd[0]) { - case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break; - case REZERO_UNIT: what = "REZERO_UNIT"; break; - case REQUEST_SENSE: what = "REQUEST_SENSE"; break; - case FORMAT_UNIT: what = "FORMAT_UNIT"; break; - case READ_BLOCK_LIMITS: what = "READ_BLOCK_LIMITS"; break; - case REASSIGN_BLOCKS: what = "REASSIGN_BLOCKS"; break; - case READ_6: what = "READ_6"; break; - case WRITE_6: what = "WRITE_6"; break; - case SEEK_6: what = "SEEK_6"; break; - case READ_REVERSE: what = "READ_REVERSE"; break; - case WRITE_FILEMARKS: what = "WRITE_FILEMARKS"; break; - case SPACE: what = "SPACE"; break; - case INQUIRY: what = "INQUIRY"; break; - case RECOVER_BUFFERED_DATA: what = "RECOVER_BUFFERED_DATA"; break; - case MODE_SELECT: what = "MODE_SELECT"; break; - case RESERVE: what = "RESERVE"; break; - case RELEASE: what = "RELEASE"; break; - case COPY: what = "COPY"; break; - case ERASE: what = "ERASE"; break; - case MODE_SENSE: what = "MODE_SENSE"; break; - case START_STOP: what = "START_STOP"; break; - case RECEIVE_DIAGNOSTIC: what = "RECEIVE_DIAGNOSTIC"; break; - case SEND_DIAGNOSTIC: what = "SEND_DIAGNOSTIC"; break; - case ALLOW_MEDIUM_REMOVAL: what = "ALLOW_MEDIUM_REMOVAL"; break; - case SET_WINDOW: what = "SET_WINDOW"; break; - case READ_CAPACITY: what = "READ_CAPACITY"; break; - case READ_10: what = "READ_10"; break; - case WRITE_10: what = "WRITE_10"; break; - case SEEK_10: what = "SEEK_10"; break; - case WRITE_VERIFY: what = "WRITE_VERIFY"; break; - case VERIFY: what = "VERIFY"; break; - case SEARCH_HIGH: what = "SEARCH_HIGH"; break; - case SEARCH_EQUAL: what = "SEARCH_EQUAL"; break; - case SEARCH_LOW: what = "SEARCH_LOW"; break; - case SET_LIMITS: what = "SET_LIMITS"; break; - case READ_POSITION: what = "READ_POSITION"; break; - case SYNCHRONIZE_CACHE: what = "SYNCHRONIZE_CACHE"; break; - case LOCK_UNLOCK_CACHE: what = "LOCK_UNLOCK_CACHE"; break; - case READ_DEFECT_DATA: what = "READ_DEFECT_DATA"; break; - case MEDIUM_SCAN: what = "MEDIUM_SCAN"; break; - case COMPARE: what = "COMPARE"; break; - case COPY_VERIFY: what = "COPY_VERIFY"; break; - case WRITE_BUFFER: what = "WRITE_BUFFER"; break; - case READ_BUFFER: what = "READ_BUFFER"; break; - case UPDATE_BLOCK: what = "UPDATE_BLOCK"; break; - case READ_LONG: what = "READ_LONG"; break; - case WRITE_LONG: what = "WRITE_LONG"; break; - case CHANGE_DEFINITION: what = "CHANGE_DEFINITION"; break; - case WRITE_SAME: what = "WRITE_SAME"; break; - case READ_TOC: what = "READ_TOC"; break; - case LOG_SELECT: what = "LOG_SELECT"; break; - case LOG_SENSE: what = "LOG_SENSE"; break; - case MODE_SELECT_10: what = "MODE_SELECT_10"; break; - case MODE_SENSE_10: what = "MODE_SENSE_10"; break; - case MOVE_MEDIUM: what = "MOVE_MEDIUM"; break; - case READ_12: what = "READ_12"; break; - case WRITE_12: what = "WRITE_12"; break; - case WRITE_VERIFY_12: what = "WRITE_VERIFY_12"; break; - case SEARCH_HIGH_12: what = "SEARCH_HIGH_12"; break; - case SEARCH_EQUAL_12: what = "SEARCH_EQUAL_12"; break; - case SEARCH_LOW_12: what = "SEARCH_LOW_12"; break; - case READ_ELEMENT_STATUS: what = "READ_ELEMENT_STATUS"; break; - case SEND_VOLUME_TAG: what = "SEND_VOLUME_TAG"; break; - case WRITE_LONG_2: what = "WRITE_LONG_2"; break; - default: break; - } - printk(KERN_DEBUG USB_SCSI "Command %s (%d bytes)\n", what, srb->cmd_len); - printk(KERN_DEBUG USB_SCSI " %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - srb->cmnd[0], srb->cmnd[1], srb->cmnd[2], srb->cmnd[3], srb->cmnd[4], srb->cmnd[5], - srb->cmnd[6], srb->cmnd[7], srb->cmnd[8], srb->cmnd[9]); -} diff -ur --new-file old/linux/drivers/usb/usb_storage.c new/linux/drivers/usb/usb_storage.c --- old/linux/drivers/usb/usb_storage.c Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/usb/usb_storage.c Fri Jan 28 01:40:53 2000 @@ -0,0 +1,1837 @@ +/* Driver for USB Mass Storage compliant devices + * + * (c) 1999 Michael Gee (michael@linuxspecific.com) + * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) + * + * Further reference: + * This driver is based on the 'USB Mass Storage Class' document. This + * describes in detail the protocol used to communicate with such + * devices. Clearly, the designers had SCSI commands in mind when they + * created this document. The commands are all similar to commands + * in the SCSI-II specification. + * + * It is important to note that in a number of cases this class exhibits + * class-specific exemptions from the USB specification. Notably the + * usage of NAK, STALL and ACK differs from the norm, in that they are + * used to communicate wait, failed and OK on commands. + * Also, for certain devices, the interrupt endpoint is used to convey + * status of a command. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "../scsi/scsi.h" +#include "../scsi/hosts.h" +#include "../scsi/sd.h" + +#include "usb.h" +#include "usb_storage.h" + +/* direction table -- this indicates the direction of the data + * transfer for each command code -- a 1 indicates input + */ +unsigned char us_direction[256/8] = { + 0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77, + 0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* + * Per device data + */ + +static int my_host_number; + +int usb_stor_debug = 1; + +struct us_data; + +typedef int (*trans_cmnd)(Scsi_Cmnd*, struct us_data*); +typedef int (*trans_reset)(struct us_data*); +typedef void (*proto_cmnd)(Scsi_Cmnd*, struct us_data*); + +struct us_data { + struct us_data *next; /* next device */ + struct usb_device *pusb_dev; /* this usb_device */ + unsigned int flags; /* from filter initially */ + __u8 ifnum; /* interface number */ + __u8 ep_in; /* in endpoint */ + __u8 ep_out; /* out ....... */ + __u8 ep_int; /* interrupt . */ + __u8 subclass; /* as in overview */ + __u8 protocol; /* .............. */ + __u8 attention_done; /* force attn on first cmd */ + trans_cmnd transport; /* protocol specific do cmd */ + trans_reset transport_reset; /* .......... device reset */ + proto_cmnd proto_handler; /* protocol handler */ + GUID(guid); /* unique dev id */ + struct Scsi_Host *host; /* our dummy host data */ + Scsi_Host_Template *htmplt; /* own host template */ + int host_number; /* to find us */ + int host_no; /* allocated by scsi */ + Scsi_Cmnd *srb; /* current srb */ + int action; /* what to do */ + wait_queue_head_t waitq; /* thread waits */ + wait_queue_head_t ip_waitq; /* for CBI interrupts */ + __u16 ip_data; /* interrupt data */ + int ip_wanted; /* needed */ + int pid; /* control thread */ + struct semaphore *notify; /* wait for thread to begin */ + void *irq_handle; /* for USB int requests */ + unsigned int irqpipe; /* pipe for release_irq */ +}; + +/* + * kernel thread actions + */ + +#define US_ACT_COMMAND 1 +#define US_ACT_ABORT 2 +#define US_ACT_DEVICE_RESET 3 +#define US_ACT_BUS_RESET 4 +#define US_ACT_HOST_RESET 5 + +static struct us_data *us_list; + +static void * storage_probe(struct usb_device *dev, unsigned int ifnum); +static void storage_disconnect(struct usb_device *dev, void *ptr); +static struct usb_driver storage_driver = { + "usb-storage", + storage_probe, + storage_disconnect, + { NULL, NULL } +}; + +/*********************************************************************** + * Data transfer routines + ***********************************************************************/ + +/* Transfer one buffer (breaking into packets if necessary) + * Note that this function is necessary because if the device NAKs, we + * need to know that information directly + * + * FIXME: is the above true? Or will the URB status show ETIMEDOUT after + * retrying several times allready? Perhaps this is the way we should + * be going anyway? + */ +static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length) +{ + int max_size; + int this_xfer; + int result; + int partial; + int maxtry; + + /* determine the maximum packet size for these transfers */ + max_size = usb_maxpacket(us->pusb_dev, + pipe, usb_pipeout(pipe)) * 16; + + /* while we have data left to transfer */ + while (length) { + + /* calculate how long this will be -- maximum or a remainder */ + this_xfer = length > max_size ? max_size : length; + length -= this_xfer; + + /* FIXME: this number is totally outrageous. We need to pick + * a better (smaller) number). + */ + + /* setup the retry counter */ + maxtry = 100; + + /* set up the transfer loop */ + do { + /* transfer the data */ + US_DEBUGP("Bulk xfer 0x%x(%d) try #%d\n", + (unsigned int)buf, this_xfer, 101 - maxtry); + result = usb_bulk_msg(us->pusb_dev, pipe, buf, + this_xfer, &partial, HZ*5); + US_DEBUGP("bulk_msg returned %d xferred %d/%d\n", + result, partial, this_xfer); + + /* if we stall, we need to clear it before we go on */ + if (result == -EPIPE) { + US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe); + usb_clear_halt(us->pusb_dev, pipe); + } + + /* update to show what data was transferred */ + this_xfer -= partial; + buf += partial; + + /* NAK - we retry a few times */ + if (result == -ETIMEDOUT) { + + US_DEBUGP("us_one_transfer: device NAKed\n"); + + /* if our try counter reaches 0, bail out */ + if (!maxtry--) + return -ETIMEDOUT; + + /* just continue the while loop */ + continue; + } + + /* other errors (besides NAK) -- we just bail out*/ + if (result != 0) { + US_DEBUGP("us_one_transfer: device returned error %d\n", result); + return result; + } + + /* continue until this transfer is done */ + } while ( this_xfer ); + } + + /* if we get here, we're done and successful */ + return 0; +} + +static unsigned int us_transfer_length(Scsi_Cmnd *srb); + +/* transfer one SCSI command, using scatter-gather if requested */ +/* FIXME: what do the return codes here mean? */ +static int us_transfer(Scsi_Cmnd *srb, int dir_in) +{ + struct us_data *us = (struct us_data *)srb->host_scribble; + int i; + int result = -1; + unsigned int pipe = dir_in ? usb_rcvbulkpipe(us->pusb_dev, us->ep_in) : + usb_sndbulkpipe(us->pusb_dev, us->ep_out); + + /* FIXME: stop transferring data at us_transfer_length(), not + * bufflen */ + if (srb->use_sg) { + struct scatterlist *sg = (struct scatterlist *) srb->request_buffer; + + for (i = 0; i < srb->use_sg; i++) { + result = us_one_transfer(us, pipe, sg[i].address, sg[i].length); + if (result) + break; + } + } + else + result = us_one_transfer(us, pipe, srb->request_buffer, + us_transfer_length(srb)); + + if (result < 0) + US_DEBUGP("us_transfer returning error %d\n", result); + return result; +} + +/* calculate the length of the data transfer (not the command) for any + * given SCSI command + */ +static unsigned int us_transfer_length(Scsi_Cmnd *srb) +{ + int i; + unsigned int total = 0; + + /* always zero for some commands */ + switch (srb->cmnd[0]) { + case SEEK_6: + case SEEK_10: + case REZERO_UNIT: + case ALLOW_MEDIUM_REMOVAL: + case START_STOP: + case TEST_UNIT_READY: + return 0; + + case REQUEST_SENSE: + case INQUIRY: + case MODE_SENSE: + return srb->cmnd[4]; + + case LOG_SENSE: + case MODE_SENSE_10: + return (srb->cmnd[7] << 8) + srb->cmnd[8]; + + default: + break; + } + + if (srb->use_sg) { + struct scatterlist *sg = (struct scatterlist *) srb->request_buffer; + + for (i = 0; i < srb->use_sg; i++) { + total += sg[i].length; + } + return total; + } + else + return srb->request_bufflen; +} + +/*********************************************************************** + * Protocol routines + ***********************************************************************/ + +static int CB_transport(Scsi_Cmnd *srb, struct us_data *us); +static int Bulk_transport(Scsi_Cmnd *srb, struct us_data *us); + +static void ufi_command(Scsi_Cmnd *srb, struct us_data *us) +{ + int old_cmnd = 0; + + /* fix some commands -- this is a form of mode translation + * UFI devices only accept 12 byte long commands + * + * NOTE: This only works because a Scsi_Cmnd struct field contains + * a unsigned char cmnd[12], so we know we have storage available + */ + + /* set command length to 12 bytes (this affects the transport layer) */ + srb->cmd_len = 12; + + /* determine the correct (or minimum) data length for these commands */ + switch (us->srb->cmnd[0]) { + + /* for INQUIRY, UFI devices only ever return 36 bytes */ + case INQUIRY: + us->srb->cmnd[4] = 36; + break; + + /* change MODE_SENSE/MODE_SELECT from 6 to 10 byte commands */ + case MODE_SENSE: + case MODE_SELECT: + /* save the command so we can tell what it was */ + old_cmnd = srb->cmnd[0]; + + srb->cmnd[11] = 0; + srb->cmnd[10] = 0; + srb->cmnd[9] = 0; + + /* if we're sending data, we send all. If getting data, + * get the minimum */ + if (srb->cmnd[0] == MODE_SELECT) + srb->cmnd[8] = srb->cmnd[4]; + else + srb->cmnd[8] = 8; + + srb->cmnd[7] = 0; + srb->cmnd[6] = 0; + srb->cmnd[5] = 0; + srb->cmnd[4] = 0; + srb->cmnd[3] = 0; + srb->cmnd[2] = srb->cmnd[2]; + srb->cmnd[1] = srb->cmnd[1]; + srb->cmnd[0] = srb->cmnd[0] | 0x40; + break; + + /* again, for MODE_SENSE_10, we get the minimum (8) */ + case MODE_SENSE_10: + us->srb->cmnd[7] = 0; + us->srb->cmnd[8] = 8; + break; + + /* for REQUEST_SENSE, UFI devices only ever return 18 bytes */ + case REQUEST_SENSE: + us->srb->cmnd[4] = 18; + break; + + /* change READ_6/WRITE_6 to READ_10/WRITE_10, which + * are UFI commands */ + case WRITE_6: + case READ_6: + srb->cmnd[11] = 0; + srb->cmnd[10] = 0; + srb->cmnd[9] = 0; + srb->cmnd[8] = srb->cmnd[4]; + srb->cmnd[7] = 0; + srb->cmnd[6] = 0; + srb->cmnd[5] = srb->cmnd[3]; + srb->cmnd[4] = srb->cmnd[2]; + srb->cmnd[3] = srb->cmnd[1] & 0x1F; + srb->cmnd[2] = 0; + srb->cmnd[1] = srb->cmnd[1] & 0xE0; + srb->cmnd[0] = srb->cmnd[0] | 0x20; + break; + } /* end switch on cmnd[0] */ + + /* send the command to the transport layer */ + us->srb->result = us->transport(srb, us); + + /* if we have an error, we're going to do a + * REQUEST_SENSE automatically */ + + /* FIXME: we should only do this for device + * errors, not system errors */ + if (us->srb->result) { + int temp_result; + int count; + void* old_request_buffer; + + US_DEBUGP("Command FAILED: Issuing auto-REQUEST_SENSE\n"); + + /* set the result so the higher layers expect this data */ + us->srb->result = CHECK_CONDITION; + + us->srb->cmnd[0] = REQUEST_SENSE; + us->srb->cmnd[1] = 0; + us->srb->cmnd[2] = 0; + us->srb->cmnd[3] = 0; + us->srb->cmnd[4] = 18; + us->srb->cmnd[5] = 0; + + /* set the buffer length for transfer */ + old_request_buffer = us->srb->request_buffer; + us->srb->request_bufflen = 18; + us->srb->request_buffer = kmalloc(18, GFP_KERNEL); + + /* FIXME: what if this command fails? */ + temp_result = us->transport(us->srb, us); + US_DEBUGP("-- Result from auto-sense is %d\n", temp_result); + + /* copy the data from the request buffer to the sense buffer */ + for(count = 0; count < 18; count++) + us->srb->sense_buffer[count] = + ((unsigned char *)(us->srb->request_buffer))[count]; + + US_DEBUGP("-- sense key: 0x%x, ASC: 0x%x, ASCQ: 0x%x\n", + us->srb->sense_buffer[2] & 0xf, + us->srb->sense_buffer[12], us->srb->sense_buffer[13]); + + /* we're done here */ + kfree(us->srb->request_buffer); + us->srb->request_buffer = old_request_buffer; + return; + } + + /* FIXME: if we need to send more data, or recieve data, we should + * do it here. Then, we can do status handling here also. + * + * This includes MODE_SENSE from above + */ + if (old_cmnd == MODE_SENSE) { + unsigned char *dta = (unsigned char *)us->srb->request_buffer; + + /* calculate the new length */ + int length = (dta[0] << 8) + dta[1] + 2; + + /* copy the available data length into the structure */ + us->srb->cmnd[7] = length >> 8; + us->srb->cmnd[8] = length & 0xFF; + + /* send the command to the transport layer */ + us->srb->result = us->transport(srb, us); + + /* FIXME: this assumes that the 2nd attempt is always + * successful convert MODE_SENSE_10 return data format + * to MODE_SENSE_6 format */ + dta[0] = dta[1]; /* data len */ + dta[1] = dta[2]; /* med type */ + dta[2] = dta[3]; /* dev-spec prm */ + dta[3] = dta[7]; /* block desc len */ + printk (KERN_DEBUG USB_STORAGE + "new MODE_SENSE_6 data = %.2X %.2X %.2X %.2X\n", + dta[0], dta[1], dta[2], dta[3]); + } + + /* FIXME: if this was a TEST_UNIT_READY, and we get a NOT READY/ + * LOGICAL DRIVE NOT READY then we do a START_STOP, and retry + */ + + /* FIXME: here is where we need to fix-up the return data from + * an INQUIRY command to show ANSI SCSI rev 2 + */ + + /* FIXME: The rest of this is bogus. usb_control_msg() will only + * return an error if we've really honked things up. If it just + * needs a START_STOP, then we'll get some data back via + * REQUEST_SENSE -- either way, this belongs at a higher level + */ + +#if 0 + /* For UFI, if this is the first time we've sent this TEST_UNIT_READY + * command, we can try again + */ + if (!done_start && (us->subclass == US_SC_UFI) + && (cmd[0] == TEST_UNIT_READY) && (result < 0)) { + + /* as per spec try a start command, wait and retry */ + wait_ms(100); + + done_start++; + memset(cmd, 0, sizeof(cmd)); + cmd[0] = START_STOP; + cmd[4] = 1; /* start */ + + result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), + US_CBI_ADSC, + USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0, us->ifnum, + cmd, 12, HZ*5); + US_DEBUGP("Next usb_control_msg returns %d\n", result); + + /* allow another retry */ + retry++; + continue; + } +#endif +} + +static void transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us) +{ + unsigned int savelen = us->srb->request_bufflen; + unsigned int saveallocation = 0; + +#if 0 + /* force attention on first command */ + if (!us->attention_done) { + if (us->srb->cmnd[0] == REQUEST_SENSE) { + US_DEBUGP("forcing unit attention\n"); + us->attention_done = 1; + + if (us->srb->result == USB_STOR_TRANSPORT_GOOD) { + unsigned char *p = (unsigned char *)us->srb->request_buffer; + + if ((p[2] & 0x0f) != UNIT_ATTENTION) { + p[2] = UNIT_ATTENTION; + p[12] = 0x29; /* power on, reset or bus-reset */ + p[13] = 0; + } /* if ((p[2] & 0x0f) != UNIT_ATTENTION) */ + } /* if (us->srb->result == USB_STORE_TRANSPORT_GOOD) */ + } + } /* if (!us->attention_done) */ +#endif + + /* If the command has a variable-length payload, then we do them + * in two steps -- first we do the minimum, then we recalculate + * then length, and re-issue the command + * + * we use savelen to remember how much buffer we really have + * we use savealloction to remember how much was really requested + */ + + /* FIXME: remove savelen based on mods to us_transfer_length() */ + switch (us->srb->cmnd[0]) { + case REQUEST_SENSE: + if (us->srb->request_bufflen > 18) + us->srb->request_bufflen = 18; + else + break; + saveallocation = us->srb->cmnd[4]; + us->srb->cmnd[4] = 18; + break; + + case INQUIRY: + if (us->srb->request_bufflen > 36) + us->srb->request_bufflen = 36; + else + break; + saveallocation = us->srb->cmnd[4]; + us->srb->cmnd[4] = 36; + break; + + case MODE_SENSE: + if (us->srb->request_bufflen > 4) + us->srb->request_bufflen = 4; + else + break; + saveallocation = us->srb->cmnd[4]; + us->srb->cmnd[4] = 4; + break; + + case LOG_SENSE: + case MODE_SENSE_10: + if (us->srb->request_bufflen > 8) + us->srb->request_bufflen = 8; + else + break; + saveallocation = (us->srb->cmnd[7] << 8) | us->srb->cmnd[8]; + us->srb->cmnd[7] = 0; + us->srb->cmnd[8] = 8; + break; + + default: + break; + } /* end switch on cmnd[0] */ + + /* This code supports devices which do not support {READ|WRITE}_6 + * Apparently, neither Windows or MacOS will use these commands, + * so some devices do not support them + */ + if (us->flags & US_FL_MODE_XLATE) { + + /* translate READ_6 to READ_10 */ + if (us->srb->cmnd[0] == 0x08) { + + /* get the control */ + us->srb->cmnd[9] = us->srb->cmnd[5]; + + /* get the length */ + us->srb->cmnd[8] = us->srb->cmnd[6]; + us->srb->cmnd[7] = 0; + + /* set the reserved area to 0 */ + us->srb->cmnd[6] = 0; + + /* get LBA */ + us->srb->cmnd[5] = us->srb->cmnd[3]; + us->srb->cmnd[4] = us->srb->cmnd[2]; + us->srb->cmnd[3] = 0; + us->srb->cmnd[2] = 0; + + /* LUN and other info in cmnd[1] can stay */ + + /* fix command code */ + us->srb->cmnd[0] = 0x28; + + US_DEBUGP("Changing READ_6 to READ_10\n"); + US_DEBUG(us_show_command(us->srb)); + } + + /* translate WRITE_6 to WRITE_10 */ + if (us->srb->cmnd[0] == 0x0A) { + + /* get the control */ + us->srb->cmnd[9] = us->srb->cmnd[5]; + + /* get the length */ + us->srb->cmnd[8] = us->srb->cmnd[4]; + us->srb->cmnd[7] = 0; + + /* set the reserved area to 0 */ + us->srb->cmnd[6] = 0; + + /* get LBA */ + us->srb->cmnd[5] = us->srb->cmnd[3]; + us->srb->cmnd[4] = us->srb->cmnd[2]; + us->srb->cmnd[3] = 0; + us->srb->cmnd[2] = 0; + + /* LUN and other info in cmnd[1] can stay */ + + /* fix command code */ + us->srb->cmnd[0] = 0x2A; + + US_DEBUGP("Changing WRITE_6 to WRITE_10\n"); + US_DEBUG(us_show_command(us->srb)); + } + } /* end if (us->flags & US_FL_MODE_XLATE) */ + + /* send the command to the transport layer */ + us->srb->result = us->transport(us->srb, us); + + /* if we have an error, we're going to do a REQUEST_SENSE + * automatically */ + /* FIXME: we should only do this for device errors, not + * system errors */ + if (us->srb->result) { + int temp_result; + int count; + void* old_request_buffer; + + US_DEBUGP("Command FAILED: Issuing auto-REQUEST_SENSE\n"); + + /* set the result so the higher layers expect this data */ + us->srb->result = CHECK_CONDITION; + + us->srb->cmnd[0] = REQUEST_SENSE; + us->srb->cmnd[1] = 0; + us->srb->cmnd[2] = 0; + us->srb->cmnd[3] = 0; + us->srb->cmnd[4] = 18; + us->srb->cmnd[5] = 0; + + /* set the buffer length for transfer */ + old_request_buffer = us->srb->request_buffer; + us->srb->request_bufflen = 18; + us->srb->request_buffer = kmalloc(18, GFP_KERNEL); + + /* FIXME: what if this command fails? */ + temp_result = us->transport(us->srb, us); + US_DEBUGP("-- Result from auto-sense is %d\n", temp_result); + + /* copy the data from the request buffer to the sense buffer */ + for(count = 0; count < 18; count++) + us->srb->sense_buffer[count] = + ((unsigned char *)(us->srb->request_buffer))[count]; + + US_DEBUGP("-- sense key: 0x%x, ASC: 0x%x, ASCQ: 0x%x\n", + us->srb->sense_buffer[2] & 0xf, + us->srb->sense_buffer[12], us->srb->sense_buffer[13]); + + /* we're done here */ + kfree(us->srb->request_buffer); + us->srb->request_buffer = old_request_buffer; + return; + } + + if (savelen != us->srb->request_bufflen) { + unsigned char *p = (unsigned char *)us->srb->request_buffer; + unsigned int length = 0; + + /* set correct length and retry */ + switch (us->srb->cmnd[0]) { + + /* FIXME: we should try to get all the sense data */ + case REQUEST_SENSE: + /* simply return 18 bytes */ + p[7] = 10; + length = us->srb->request_bufflen; + break; + + case INQUIRY: + length = p[4] + 5 > savelen ? savelen : p[4] + 5; + us->srb->cmnd[4] = length; + break; + + case MODE_SENSE: + US_DEBUGP("MODE_SENSE Mode data length is %d\n", p[0]); + length = p[0] + 1 > savelen ? savelen : p[0] + 1; + us->srb->cmnd[4] = length; + break; + + case LOG_SENSE: + length = ((p[2] << 8) + p[3]) + 4 > savelen ? savelen : ((p[2] << 8) + p[3]) + 4; + us->srb->cmnd[7] = length >> 8; + us->srb->cmnd[8] = length; + break; + + case MODE_SENSE_10: + US_DEBUGP("MODE_SENSE_10 Mode data length is %d\n", + (p[0] << 8) + p[1]); + length = ((p[0] << 8) + p[1]) + 6 > savelen ? savelen : ((p[0] << 8) + p[1]) + 6; + us->srb->cmnd[7] = length >> 8; + us->srb->cmnd[8] = length; + break; + } /* end switch on cmnd[0] */ + + US_DEBUGP("Old/New length = %d/%d\n", + savelen, length); + + /* issue the new command */ + /* FIXME: this assumes that the second attempt is + * always successful */ + if (us->srb->request_bufflen != length) { + US_DEBUGP("redoing cmd with len=%d\n", length); + us->srb->request_bufflen = length; + us->srb->result = us->transport(us->srb, us); + } + + /* reset back to original values */ + us->srb->request_bufflen = savelen; + + /* fix data as necessary */ + switch (us->srb->cmnd[0]) { + case INQUIRY: + if ((((unsigned char*)us->srb->request_buffer)[2] & 0x7) == 0) { + US_DEBUGP("Fixing INQUIRY data, setting SCSI rev to 2\n"); + ((unsigned char*)us->srb->request_buffer)[2] |= 2; + } + /* FALL THROUGH */ + case REQUEST_SENSE: + case MODE_SENSE: + if (us->srb->use_sg == 0 && length > 0) { + int i; + printk(KERN_DEBUG "Data is"); + for (i = 0; i < 32 && i < length; ++i) + printk(" %.2x", ((unsigned char *)us->srb->request_buffer)[i]); + if (i < length) + printk(" ..."); + printk("\n"); + } + + /* FIXME: is this really necessary? */ + us->srb->cmnd[4] = saveallocation; + break; + + case LOG_SENSE: + case MODE_SENSE_10: + /* FIXME: is this really necessary? */ + us->srb->cmnd[7] = saveallocation >> 8; + us->srb->cmnd[8] = saveallocation; + break; + } /* end switch on cmnd[0] */ + } /* if good command */ +} + +/*********************************************************************** + * Transport routines + ***********************************************************************/ + +static int CBI_irq(int state, void *buffer, int len, void *dev_id) +{ + struct us_data *us = (struct us_data *)dev_id; + + US_DEBUGP("USB IRQ recieved for device on host %d\n", us->host_no); + + /* save the data for interpretation later */ + if (state != USB_ST_REMOVED) { + us->ip_data = le16_to_cpup((__u16 *)buffer); + US_DEBUGP("Interrupt Status 0x%x\n", us->ip_data); + } + + /* was this a wanted interrupt? */ + if (us->ip_wanted) { + us->ip_wanted = 0; + wake_up(&us->ip_waitq); + } else { + US_DEBUGP("ERROR: Unwanted interrupt received!\n"); + } + + /* This return code is truly meaningless -- and I mean truly. It gets + * ignored by other layers. It used to indicate if we wanted to get + * another interrupt or disable the interrupt callback + */ + return 0; +} + +/* FIXME: this reset function doesn't really reset the port, and it + * should. Actually it should probably do what it's doing here, and + * reset the port physically + */ +static int CB_reset(struct us_data *us) +{ + unsigned char cmd[12]; + int result; + + US_DEBUGP("CB_reset\n"); + + memset(cmd, 0xFF, sizeof(cmd)); + cmd[0] = SEND_DIAGNOSTIC; + cmd[1] = 4; + result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), + US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0, us->ifnum, cmd, sizeof(cmd), HZ*5); + + /* long wait for reset */ + schedule_timeout(HZ*6); + + US_DEBUGP("CB_reset: clearing endpoint halt\n"); + usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_in)); + usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_out)); + + US_DEBUGP("CB_reset done\n"); + return 0; +} + +static int pop_CB_status(Scsi_Cmnd *srb); + +/* FIXME: we also need a CBI_command which sets up the completion + * interrupt, and waits for it + */ +static int CB_transport(Scsi_Cmnd *srb, struct us_data *us) +{ + int result; + + US_DEBUGP("CBI gets a command:\n"); + US_DEBUG(us_show_command(srb)); + + /* FIXME: we aren't setting the ip_wanted indicator early enough, which + * causes some commands to never complete. This hangs the driver. + */ + + /* let's send the command via the control pipe */ + result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), + US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0, us->ifnum, + srb->cmnd, srb->cmd_len, HZ*5); + + /* check the return code for the command */ + if (result < 0) { + US_DEBUGP("Call to usb_control_msg() returned %d\n", result); + + /* a stall is a fatal condition from the device */ + if (result == -EPIPE) { + US_DEBUGP("-- Stall on control pipe detected. Clearing\n"); + + US_DEBUGP("-- Return from usb_clear_halt() is %d\n", + usb_clear_halt(us->pusb_dev, + usb_sndctrlpipe(us->pusb_dev, 0))); + return USB_STOR_TRANSPORT_ERROR; + } + + /* FIXME: we need to handle NAKs here */ + return USB_STOR_TRANSPORT_ERROR; + } + + /* transfer the data payload for this command, if one exists*/ + if (us_transfer_length(srb)) { + result = us_transfer(srb, US_DIRECTION(srb->cmnd[0])); + US_DEBUGP("CBI attempted to transfer data, result is 0x%x\n", result); + + /* FIXME: what do the return codes from us_transfer mean? */ + if ((result < 0) && + (result != USB_ST_DATAUNDERRUN) && + (result != USB_ST_STALL)) { + return DID_ERROR << 16; + } + } /* if (us_transfer_length(srb)) */ + + /* get status and return it */ + return pop_CB_status(srb); +} + +/* + * Control/Bulk status handler + */ + +static int pop_CB_status(Scsi_Cmnd *srb) +{ + struct us_data *us = (struct us_data *)srb->host_scribble; + int result; + __u8 status[2]; + int retry = 5; + + US_DEBUGP("pop_CB_status, proto=0x%x\n", us->protocol); + switch (us->protocol) { + case US_PR_CB: + /* get from control */ + + while (retry--) { + result = usb_control_msg(us->pusb_dev, usb_rcvctrlpipe(us->pusb_dev,0), + USB_REQ_GET_STATUS, USB_DIR_IN | + USB_TYPE_STANDARD | USB_RECIP_DEVICE, + 0, us->ifnum, status, sizeof(status), HZ*5); + if (result != USB_ST_TIMEOUT) + break; + } + if (result) { + US_DEBUGP("Bad AP status request %d\n", result); + return DID_ABORT << 16; + } + US_DEBUGP("Got AP status 0x%x 0x%x\n", status[0], status[1]); + if (srb->cmnd[0] != REQUEST_SENSE && srb->cmnd[0] != INQUIRY && + ( (status[0] & ~3) || status[1])) + return (DID_OK << 16) | 2; + else + return USB_STOR_TRANSPORT_GOOD; + break; + + /* FIXME: this should be in a separate function */ + case US_PR_CBI: + /* get from interrupt pipe */ + + /* add interrupt transfer, marked for removal */ + us->ip_wanted = 1; + + /* go to sleep until we get this interrup */ + /* FIXME: this should be changed to use a timeout */ + sleep_on(&us->ip_waitq); + + if (us->ip_wanted) { + US_DEBUGP("Did not get interrupt on CBI\n"); + us->ip_wanted = 0; + return USB_STOR_TRANSPORT_ERROR; + } + + US_DEBUGP("Got interrupt data 0x%x\n", us->ip_data); + + /* UFI gives us ASC and ASCQ, like a request sense */ + /* FIXME: is this right? do REQUEST_SENSE and INQUIRY need special + * case handling? + */ + if (us->subclass == US_SC_UFI) { + if (srb->cmnd[0] == REQUEST_SENSE || + srb->cmnd[0] == INQUIRY) + return USB_STOR_TRANSPORT_GOOD; + else + if (us->ip_data) + return USB_STOR_TRANSPORT_FAILED; + else + return USB_STOR_TRANSPORT_GOOD; + } + + /* otherwise, we interpret the data normally */ + switch (us->ip_data) { + case 0x0001: + return USB_STOR_TRANSPORT_GOOD; + case 0x0002: + return USB_STOR_TRANSPORT_FAILED; + default: + return USB_STOR_TRANSPORT_ERROR; + } + } + US_DEBUGP("pop_CB_status, reached end of function\n"); + return USB_STOR_TRANSPORT_ERROR; +} + +static int Bulk_reset(struct us_data *us) +{ + int result; + + result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), + US_BULK_RESET, USB_TYPE_CLASS | USB_RECIP_INTERFACE, + US_BULK_RESET_HARD, us->ifnum, + NULL, 0, HZ*5); + if (result) + US_DEBUGP("Bulk hard reset failed %d\n", result); + usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_in)); + usb_clear_halt(us->pusb_dev, usb_sndbulkpipe(us->pusb_dev, us->ep_out)); + + /* long wait for reset */ + schedule_timeout(HZ*6); + + return result; +} + +/* + * The bulk only protocol handler. + * Uses the in and out endpoints to transfer commands and data + */ +static int Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) +{ + struct bulk_cb_wrap bcb; + struct bulk_cs_wrap bcs; + int result; + int pipe; + int partial; + + /* set up the command wrapper */ + bcb.Signature = US_BULK_CB_SIGN; + bcb.DataTransferLength = us_transfer_length(srb); + bcb.Flags = US_DIRECTION(srb->cmnd[0]) << 7; + bcb.Tag = srb->serial_number; + bcb.Lun = 0; + bcb.Length = srb->cmd_len; + + /* construct the pipe handle */ + pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out); + + /* copy the command payload */ + memset(bcb.CDB, 0, sizeof(bcb.CDB)); + memcpy(bcb.CDB, srb->cmnd, bcb.Length); + + /* send it to out endpoint */ + US_DEBUGP("Bulk command S 0x%x T 0x%x L %d F %d CL %d\n", + bcb.Signature, bcb.Tag, bcb.DataTransferLength, + bcb.Flags, bcb.Length); + result = usb_bulk_msg(us->pusb_dev, pipe, &bcb, + US_BULK_CB_WRAP_LEN, &partial, HZ*5); + US_DEBUGP("Bulk command transfer result 0x%x\n", result); + + /* if we stall, we need to clear it before we go on */ + if (result == -EPIPE) { + US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe); + usb_clear_halt(us->pusb_dev, pipe); + } + + /* if the command transfered well, then we go to the data stage */ + /* FIXME: Regardless of the status of the data stage, we go on to the + * status stage. Note that this implies that if a command is + * partially successful, we rely on the device reporting an error + * the CSW. The spec says that the device may just decide to short us. + */ + if (result == 0) { + /* send/receive data payload, if there is any */ + if (bcb.DataTransferLength) { + result = us_transfer(srb, bcb.Flags); + US_DEBUGP("Bulk data transfer result 0x%x\n", result); +#if 0 + if ((result < 0) && (result != USB_ST_DATAUNDERRUN) + && (result != USB_ST_STALL)) { + US_DEBUGP("Bulk data transfer result 0x%x\n", result); + return DID_ABORT << 16; + } +#endif + } + } + + /* See flow chart on pg 15 of the Bulk Only Transport spec for + * an explanation of how this code works. + */ + + /* construct the pipe handle */ + pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in); + + /* get CSW for device status */ + result = usb_bulk_msg(us->pusb_dev, pipe, &bcs, + US_BULK_CS_WRAP_LEN, &partial, HZ*5); + + /* did the attempt to read the CSW fail? */ + if (result == -EPIPE) { + US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe); + usb_clear_halt(us->pusb_dev, pipe); + + /* get the status again */ + result = usb_bulk_msg(us->pusb_dev, pipe, &bcs, + US_BULK_CS_WRAP_LEN, &partial, HZ*5); + + /* if it fails again, we need a reset and return an error*/ + if (result == -EPIPE) { + Bulk_reset(us); + return (DID_ABORT << 16); + } + } + + /* if we still have a failure at this point, we're in trouble */ + if (result) { + US_DEBUGP("Bulk status result = 0x%x\n", result); + return DID_ABORT << 16; + } + + /* check bulk status */ + US_DEBUGP("Bulk status S 0x%x T 0x%x R %d V 0x%x\n", + bcs.Signature, bcs.Tag, bcs.Residue, bcs.Status); + if (bcs.Signature != US_BULK_CS_SIGN || bcs.Tag != bcb.Tag || + bcs.Status > US_BULK_STAT_PHASE || partial != 13) { + US_DEBUGP("Bulk logical error\n"); + return DID_ABORT << 16; + } + + /* based on the status code, we report good or bad */ + switch (bcs.Status) { + case US_BULK_STAT_OK: + /* if there is residue, we really didn't finish the command */ + if (bcs.Residue) + return DID_ERROR << 16; + else + return DID_OK << 16; + + case US_BULK_STAT_FAIL: + return DID_ERROR << 16; + + case US_BULK_STAT_PHASE: + Bulk_reset(us); + return DID_ERROR << 16; + } + + return DID_OK << 16; /* check sense required */ +} + +/*********************************************************************** + * Host functions + ***********************************************************************/ + +/* detect adapter (always true ) */ +static int us_detect(struct SHT *sht) +{ + /* FIXME - not nice at all, but how else ? */ + struct us_data *us = (struct us_data *)sht->proc_dir; + char name[32]; + + /* set up our name */ + sprintf(name, "usbscsi%d", us->host_number); + sht->name = sht->proc_name = kmalloc(strlen(name)+1, GFP_KERNEL); + if (!sht->proc_name) + return 0; + strcpy(sht->proc_name, name); + + /* we start with no /proc directory entry */ + sht->proc_dir = NULL; + + /* register the host */ + us->host = scsi_register(sht, sizeof(us)); + if (us->host) { + us->host->hostdata[0] = (unsigned long)us; + us->host_no = us->host->host_no; + return 1; + } + + /* odd... didn't register properly. Abort and free pointers */ + kfree(sht->proc_name); + sht->proc_name = NULL; + sht->name = NULL; + return 0; +} + +/* release - must be here to stop scsi + * from trying to release IRQ etc. + * Kill off our data + */ +static int us_release(struct Scsi_Host *psh) +{ + struct us_data *us = (struct us_data *)psh->hostdata[0]; + struct us_data *prev = (struct us_data *)&us_list; + + if (us->irq_handle) { + usb_release_irq(us->pusb_dev, us->irq_handle, us->irqpipe); + us->irq_handle = NULL; + } + if (us->pusb_dev) + usb_deregister(&storage_driver); + + /* FIXME - leaves hanging host template copy */ + /* (because scsi layer uses it after removal !!!) */ + while (prev->next != us) + prev = prev->next; + prev->next = us->next; + return 0; +} + +/* run command */ +static int us_command( Scsi_Cmnd *srb ) +{ + US_DEBUGP("Bad use of us_command\n"); + + return DID_BAD_TARGET << 16; +} + +/* run command */ +static int us_queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *)) +{ + struct us_data *us = (struct us_data *)srb->host->hostdata[0]; + + US_DEBUGP("Command wakeup\n"); + if (us->srb) { + /* busy */ + } + srb->host_scribble = (unsigned char *)us; + us->srb = srb; + srb->scsi_done = done; + us->action = US_ACT_COMMAND; + + /* wake up the process task */ + + wake_up_interruptible(&us->waitq); + + return 0; +} + +/* FIXME: This doesn't actually abort anything */ +static int us_abort( Scsi_Cmnd *srb ) +{ + return 0; +} + +static int us_bus_reset( Scsi_Cmnd *srb ) +{ + // struct us_data *us = (struct us_data *)srb->host->hostdata[0]; + + US_DEBUGP("Bus reset requested\n"); + // us->transport_reset(us); + return SUCCESS; +} + +/* FIXME: This doesn't actually reset anything */ +static int us_host_reset( Scsi_Cmnd *srb ) +{ + return 0; +} + +/*********************************************************************** + * /proc/scsi/ functions + ***********************************************************************/ + +/* we use this macro to help us write into the buffer */ +#undef SPRINTF +#define SPRINTF(args...) do { if (pos < (buffer + length)) pos += sprintf (pos, ## args); } while (0) + +int usb_stor_proc_info (char *buffer, char **start, off_t offset, + int length, int hostno, int inout) +{ + struct us_data *us = us_list; + char *pos = buffer; + char *tmp_ptr; + + /* find our data from hostno */ + while (us) { + if (us->host_no == hostno) + break; + us = us->next; + } + + /* if we couldn't find it, we return an error */ + if (!us) + return -ESRCH; + + /* if someone is sending us data, just throw it away */ + if (inout) + return length; + + /* print the controler name */ + SPRINTF ("Host scsi%d: usb-storage\n", hostno); + + /* print product and vendor strings */ + tmp_ptr = kmalloc(256, GFP_KERNEL); + if (!us->pusb_dev || !tmp_ptr) { + SPRINTF(" Vendor: Unknown Vendor\n"); + SPRINTF(" Product: Unknown Product\n"); + } else { + SPRINTF(" Vendor: "); + if (usb_string(us->pusb_dev, us->pusb_dev->descriptor.iManufacturer, tmp_ptr, 256) > 0) + SPRINTF("%s\n", tmp_ptr); + else + SPRINTF("Unknown Vendor\n"); + + SPRINTF(" Product: "); + if (usb_string(us->pusb_dev, us->pusb_dev->descriptor.iProduct, tmp_ptr, 256) > 0) + SPRINTF("%s\n", tmp_ptr); + else + SPRINTF("Unknown Product\n"); + kfree(tmp_ptr); + } + + SPRINTF(" Protocol: "); + switch (us->protocol) { + case US_PR_CB: + SPRINTF("Control/Bulk\n"); + break; + + case US_PR_CBI: + SPRINTF("Control/Bulk/Interrupt\n"); + break; + + case US_PR_BULK: + SPRINTF("Bulk only\n"); + break; + + default: + SPRINTF("Unknown Protocol\n"); + break; + } + + /* show the GUID of the device */ + SPRINTF(" GUID: " GUID_FORMAT "\n", GUID_ARGS(us->guid)); + + /* + * Calculate start of next buffer, and return value. + */ + *start = buffer + offset; + + if ((pos - buffer) < offset) + return (0); + else if ((pos - buffer - offset) < length) + return (pos - buffer - offset); + else + return (length); +} + +/* + * this defines our 'host' + */ + +static Scsi_Host_Template my_host_template = { + NULL, /* next */ + NULL, /* module */ + NULL, /* proc_dir */ + usb_stor_proc_info, + NULL, /* name - points to unique */ + us_detect, + us_release, + NULL, /* info */ + NULL, /* ioctl */ + us_command, + us_queuecommand, + NULL, /* eh_strategy */ + us_abort, + us_bus_reset, + us_bus_reset, + us_host_reset, + NULL, /* abort */ + NULL, /* reset */ + NULL, /* slave_attach */ + NULL, /* bios_param */ + 1, /* can_queue */ + -1, /* this_id */ + SG_ALL, /* sg_tablesize */ + 1, /* cmd_per_lun */ + 0, /* present */ + FALSE, /* unchecked_isa_dma */ + FALSE, /* use_clustering */ + TRUE, /* use_new_eh_code */ + TRUE /* emulated */ +}; + +static unsigned char sense_notready[] = { + 0x70, /* current error */ + 0x00, + 0x02, /* not ready */ + 0x00, + 0x00, + 0x0a, /* additional length */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x04, /* not ready */ + 0x03, /* manual intervention */ + 0x00, + 0x00, + 0x00, + 0x00 +}; + +static int usb_stor_control_thread(void * __us) +{ + struct us_data *us = (struct us_data *)__us; + int action; + + lock_kernel(); + + /* + * This thread doesn't need any user-level access, + * so get rid of all our resources.. + */ + daemonize(); + + sprintf(current->comm, "usbscsi%d", us->host_number); + + unlock_kernel(); + + up(us->notify); + + for(;;) { + siginfo_t info; + int unsigned long signr; + + interruptible_sleep_on(&us->waitq); + + action = us->action; + us->action = 0; + + /* FIXME: we need to examine placment of break; and + * scsi_done() calls */ + + switch (action) { + case US_ACT_COMMAND: + /* bad device */ + if (us->srb->target || us->srb->lun) { + US_DEBUGP( "Bad device number (%d/%d) or dev 0x%x\n", + us->srb->target, us->srb->lun, (unsigned int)us->pusb_dev); + us->srb->result = DID_BAD_TARGET << 16; + + us->srb->scsi_done(us->srb); + us->srb = NULL; + break; + } + + /* our device has gone - pretend not ready */ + /* FIXME: we also need to handle INQUIRY here, + * probably */ + if (!us->pusb_dev) { + if (us->srb->cmnd[0] == REQUEST_SENSE) { + memcpy(us->srb->request_buffer, sense_notready, + sizeof(sense_notready)); + us->srb->result = DID_OK << 16; + } else { + us->srb->result = (DID_OK << 16) | 2; + } + + us->srb->scsi_done(us->srb); + us->srb = NULL; + break; + } + + /* we've got a command, let's do it! */ + US_DEBUG(us_show_command(us->srb)); + + /* FIXME: this is to support Shuttle E-USB bridges, it + * appears */ + if (us->srb->cmnd[0] == START_STOP && + us->pusb_dev->descriptor.idProduct == 0x0001 && + us->pusb_dev->descriptor.idVendor == 0x04e6) + us->srb->result = DID_OK << 16; + else { + us->proto_handler(us->srb, us); + } + + US_DEBUGP("scsi cmd done, result=0x%x\n", us->srb->result); + us->srb->scsi_done(us->srb); + us->srb = NULL; + break; + + case US_ACT_ABORT: + break; + + case US_ACT_DEVICE_RESET: + break; + + case US_ACT_BUS_RESET: + break; + + case US_ACT_HOST_RESET: + break; + + } /* end switch on action */ + + if (signal_pending(current)) { + /* sending SIGUSR1 makes us print out some info */ + spin_lock_irq(¤t->sigmask_lock); + signr = dequeue_signal(¤t->blocked, &info); + spin_unlock_irq(¤t->sigmask_lock); + + if (signr == SIGUSR2) { + usb_stor_debug = !usb_stor_debug; + printk(USB_STORAGE "debug toggle = %d\n", usb_stor_debug); + } else { + break; /* exit the loop on any other signal */ + } + } + } + + // MOD_DEC_USE_COUNT; + + printk("usb_stor_control_thread exiting\n"); + + /* FIXME: this is a hack to allow for debugging */ + // scsi_unregister_module(MODULE_SCSI_HA, us->htmplt); + + return 0; +} + +/* Probe to see if a new device is actually a SCSI device */ +static void * storage_probe(struct usb_device *dev, unsigned int ifnum) +{ + struct usb_interface_descriptor *interface; + int i; + char mf[32]; /* manufacturer */ + char prod[32]; /* product */ + char serial[32]; /* serial number */ + struct us_data *ss = NULL; + unsigned int flags = 0; + GUID(guid); /* Global Unique Identifier */ + struct us_data *prev; + Scsi_Host_Template *htmplt; + int protocol = 0; + int subclass = 0; + struct usb_interface_descriptor *altsetting = + &(dev->actconfig->interface[ifnum].altsetting[0]); + + /* clear the GUID and fetch the strings */ + GUID_CLEAR(guid); + memset(mf, 0, sizeof(mf)); + memset(prod, 0, sizeof(prod)); + memset(serial, 0, sizeof(serial)); + if (dev->descriptor.iManufacturer) + usb_string(dev, dev->descriptor.iManufacturer, mf, sizeof(mf)); + if (dev->descriptor.iProduct) + usb_string(dev, dev->descriptor.iProduct, prod, sizeof(prod)); + if (dev->descriptor.iSerialNumber) + usb_string(dev, dev->descriptor.iSerialNumber, serial, sizeof(serial)); + + /* let's examine the device now */ + + /* We make an exception for the shuttle E-USB */ + if (dev->descriptor.idVendor == 0x04e6 && + dev->descriptor.idProduct == 0x0001) { + protocol = US_PR_CB; + subclass = US_SC_8070; /* an assumption */ + } else if (dev->descriptor.bDeviceClass != 0 || + altsetting->bInterfaceClass != USB_CLASS_MASS_STORAGE || + altsetting->bInterfaceSubClass < US_SC_MIN || + altsetting->bInterfaceSubClass > US_SC_MAX) { + /* if it's not a mass storage, we go no further */ + return NULL; + } + + /* At this point, we know we've got a live one */ + US_DEBUGP("USB Mass Storage device detected\n"); + + /* Create a GUID for this device */ + if (dev->descriptor.iSerialNumber && serial[0]) { + /* If we have a serial number, and it's a non-NULL string */ + make_guid(guid, dev->descriptor.idVendor, + dev->descriptor.idProduct, serial); + } else { + /* We don't have a serial number, so we use 0 */ + make_guid(guid, dev->descriptor.idVendor, + dev->descriptor.idProduct, "0"); + } + + /* Now check if we have seen this GUID before, and restore + * the flags if we find it + */ + for (ss = us_list; ss != NULL; ss = ss->next) { + if (!ss->pusb_dev && GUID_EQUAL(guid, ss->guid)) { + US_DEBUGP("Found existing GUID " GUID_FORMAT "\n", + GUID_ARGS(guid)); + flags = ss->flags; + break; + } + } + + /* If ss == NULL, then this is a new device. Allocate memory for it */ + if (!ss) { + if ((ss = (struct us_data *)kmalloc(sizeof(*ss), + GFP_KERNEL)) == NULL) { + printk(KERN_WARNING USB_STORAGE "Out of memory\n"); + return NULL; + } + memset(ss, 0, sizeof(struct us_data)); + } + + /* Initialize the us_data structure with some useful info */ + interface = altsetting; + ss->flags = flags; + ss->ifnum = ifnum; + ss->pusb_dev = dev; + ss->attention_done = 0; + + /* If the device has subclass and protocol, then use that. Otherwise, + * take data from the specific interface. + */ + if (subclass) { + ss->subclass = subclass; + ss->protocol = protocol; + } else { + ss->subclass = interface->bInterfaceSubClass; + ss->protocol = interface->bInterfaceProtocol; + } + + /* set the handler pointers based on the protocol */ + US_DEBUGP("Transport: "); + switch (ss->protocol) { + case US_PR_CB: + US_DEBUGPX("Control/Bulk\n"); + ss->transport = CB_transport; + ss->transport_reset = CB_reset; + break; + + case US_PR_CBI: + US_DEBUGPX("Control/Bulk/Interrupt\n"); + ss->transport = CB_transport; + ss->transport_reset = CB_reset; + break; + + case US_PR_BULK: + US_DEBUGPX("Bulk\n"); + ss->transport = Bulk_transport; + ss->transport_reset = Bulk_reset; + break; + + default: + US_DEBUGPX("Unknown\n"); + kfree(ss); + return NULL; + break; + } + + /* + * We are expecting a minimum of 2 endpoints - in and out (bulk). + * An optional interrupt is OK (necessary for CBI protocol). + * We will ignore any others. + */ + for (i = 0; i < interface->bNumEndpoints; i++) { + /* is it an BULK endpoint? */ + if ((interface->endpoint[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_BULK) { + if (interface->endpoint[i].bEndpointAddress & USB_DIR_IN) + ss->ep_in = interface->endpoint[i].bEndpointAddress & + USB_ENDPOINT_NUMBER_MASK; + else + ss->ep_out = interface->endpoint[i].bEndpointAddress & + USB_ENDPOINT_NUMBER_MASK; + } + + /* is it an interrupt endpoint? */ + if ((interface->endpoint[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT) { + ss->ep_int = interface->endpoint[i].bEndpointAddress & + USB_ENDPOINT_NUMBER_MASK; + } + } + US_DEBUGP("Endpoints In %d Out %d Int %d\n", + ss->ep_in, ss->ep_out, ss->ep_int); + + /* Do some basic sanity checks, and bail if we find a problem */ + if (usb_set_interface(dev, interface->bInterfaceNumber, 0) || + !ss->ep_in || !ss->ep_out || + (ss->protocol == US_PR_CBI && ss->ep_int == 0)) { + US_DEBUGP("Problems with device\n"); + if (ss->host) { + scsi_unregister_module(MODULE_SCSI_HA, ss->htmplt); + kfree(ss->htmplt->name); + kfree(ss->htmplt); + } + + kfree(ss); + return NULL; + } + + /* If this is a new device (i.e. we haven't seen it before), we need to + * generate a scsi host definition, and register with scsi above us + */ + if (!ss->host) { + /* copy the GUID we created before */ + US_DEBUGP("New GUID " GUID_FORMAT "\n", GUID_ARGS(guid)); + memcpy(ss->guid, guid, sizeof(guid)); + + /* set class specific stuff */ + US_DEBUGP("Protocol: "); + switch (ss->subclass) { + case US_SC_RBC: + US_DEBUGPX("Reduced Block Commands\n"); + break; + + case US_SC_8020: + US_DEBUGPX("8020\n"); + break; + + case US_SC_QIC: + US_DEBUGPX("QIC157\n"); + break; + + case US_SC_8070: + US_DEBUGPX("8070\n"); + break; + + case US_SC_SCSI: + US_DEBUGPX("Transparent SCSI\n"); + ss->proto_handler = transparent_scsi_command; + break; + + case US_SC_UFI: + US_DEBUGPX("UFI\n"); + ss->proto_handler = ufi_command; + break; + + default: + US_DEBUGPX("Unknown\n"); + break; + } + + /* We only handle certain protocols. Currently, these are + *the only ones that devices use. + */ + if ((ss->subclass != US_SC_SCSI) && (ss->subclass != US_SC_UFI)) { + US_DEBUGP("Sorry, we do not support that protocol yet.\n"); + US_DEBUGP("If you have a device which uses one of the unsupported\n"); + US_DEBUGP("protocols, please contact mdharm-usb@one-eyed-alien.net\n"); + + kfree(ss); + return NULL; + } + + /* Allocate memory for the SCSI Host Template */ + if ((htmplt = (Scsi_Host_Template *) + kmalloc(sizeof(*ss->htmplt), GFP_KERNEL)) == NULL ) { + + printk(KERN_WARNING USB_STORAGE "Out of memory\n"); + + kfree(ss); + return NULL; + } + + /* Initialize the host template based on the default one */ + memcpy(htmplt, &my_host_template, sizeof(my_host_template)); + + /* Grab the next host number */ + ss->host_number = my_host_number++; + + /* MDD: FIXME: this is bad. We abuse this pointer so we + * can pass the ss pointer to the host controler thread + * in us_detect + */ + (struct us_data *)htmplt->proc_dir = ss; + + /* shuttle E-USB */ + if (dev->descriptor.idVendor == 0x04e6 && + dev->descriptor.idProduct == 0x0001) { + __u8 qstat[2]; + int result; + + result = usb_control_msg(ss->pusb_dev, usb_rcvctrlpipe(dev,0), + 1, 0xC0, + 0, ss->ifnum, + qstat, 2, HZ*5); + US_DEBUGP("C0 status 0x%x 0x%x\n", qstat[0], qstat[1]); + init_waitqueue_head(&ss->ip_waitq); + ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int); + result = usb_request_irq(ss->pusb_dev, ss->irqpipe, CBI_irq, + 255, (void *)ss, &ss->irq_handle); + if (result) + return NULL; + + interruptible_sleep_on_timeout(&ss->ip_waitq, HZ*6); + } else if (ss->protocol == US_PR_CBI) + { + int result; + + init_waitqueue_head(&ss->ip_waitq); + + /* set up the IRQ pipe and handler */ + /* FIXME: This needs to get the period from the device */ + ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int); + result = usb_request_irq(ss->pusb_dev, ss->irqpipe, CBI_irq, + 255, (void *)ss, &ss->irq_handle); + if (result) { + US_DEBUGP("usb_request_irq failed (0x%x), No interrupt for CBI\n", + result); + } + } + + + /* start up our thread */ + { + DECLARE_MUTEX_LOCKED(sem); + + init_waitqueue_head(&ss->waitq); + + ss->notify = &sem; + ss->pid = kernel_thread(usb_stor_control_thread, ss, + CLONE_FS | CLONE_FILES | CLONE_SIGHAND); + if (ss->pid < 0) { + printk(KERN_WARNING USB_STORAGE "Unable to start control thread\n"); + kfree(htmplt); + + kfree(ss); + return NULL; + } + + /* wait for it to start */ + down(&sem); + } + + /* now register - our detect function will be called */ + scsi_register_module(MODULE_SCSI_HA, htmplt); + + /* put us in the list */ + prev = (struct us_data *)&us_list; + while (prev->next) + prev = prev->next; + prev->next = ss; + } + + printk(KERN_INFO "WARNING: USB Mass Storage data integrity not assured\n"); + printk(KERN_INFO "USB Mass Storage device found at %d\n", dev->devnum); + + return ss; +} + +/* Handle a disconnect event from the USB core */ +static void storage_disconnect(struct usb_device *dev, void *ptr) +{ + struct us_data *ss = ptr; + + if (!ss) + return; + + ss->pusb_dev = NULL; + // MOD_DEC_USE_COUNT; +} + + +/*********************************************************************** + * Initialization and registration + ***********************************************************************/ + +int usb_stor_init(void) +{ + // MOD_INC_USE_COUNT; + + /* register the driver, return -1 if error */ + if (usb_register(&storage_driver) < 0) + return -1; + + printk(KERN_INFO "USB Mass Storage support registered.\n"); + return 0; +} + +#ifdef MODULE +int init_module(void) +{ + /* MDD: Perhaps we should register the host here */ + return usb_stor_init(); +} + +void cleanup_module(void) +{ + usb_deregister(&storage_driver); +} +#endif diff -ur --new-file old/linux/drivers/usb/usb_storage.h new/linux/drivers/usb/usb_storage.h --- old/linux/drivers/usb/usb_storage.h Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/usb/usb_storage.h Thu Jan 27 16:40:16 2000 @@ -0,0 +1,130 @@ +/* Driver for USB mass storage - include file + * + * (c) 1999 Michael Gee (michael@linuxspecific.com) + * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) + * + */ + +#include + +#define USB_STORAGE "usb-storage: " + +extern int usb_stor_debug; + +#ifdef CONFIG_USB_STORAGE_DEBUG +void us_show_command(Scsi_Cmnd *srb); +#define US_DEBUGP(x...) { if(usb_stor_debug) printk( KERN_DEBUG USB_STORAGE ## x ); } +#define US_DEBUGPX(x...) { if(usb_stor_debug) printk( ## x ); } +#define US_DEBUG(x) { if(usb_stor_debug) x; } +#else +#define US_DEBUGP(x...) +#define US_DEBUGPX(x...) +#define US_DEBUG(x) +#endif + +/* bit set if input */ +extern unsigned char us_direction[256/8]; +#define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1) + +/* Sub Classes */ + +#define US_SC_RBC 1 /* Typically, flash devices */ +#define US_SC_8020 2 /* CD-ROM */ +#define US_SC_QIC 3 /* QIC-157 Tapes */ +#define US_SC_UFI 4 /* Floppy */ +#define US_SC_8070 5 /* Removable media */ +#define US_SC_SCSI 6 /* Transparent */ +#define US_SC_MIN US_SC_RBC +#define US_SC_MAX US_SC_SCSI + +/* Protocols */ + +#define US_PR_CB 1 /* Control/Bulk w/o interrupt */ +#define US_PR_CBI 0 /* Control/Bulk/Interrupt */ +#define US_PR_BULK 0x50 /* bulk only */ + +/* + * Bulk only data structures (Zip 100, for example) + */ + +/* command block wrapper */ +struct bulk_cb_wrap { + __u32 Signature; /* contains 'USBC' */ + __u32 Tag; /* unique per command id */ + __u32 DataTransferLength; /* size of data */ + __u8 Flags; /* direction in bit 0 */ + __u8 Lun; /* LUN normally 0 */ + __u8 Length; /* of of the CDB */ + __u8 CDB[16]; /* max command */ +}; + +#define US_BULK_CB_WRAP_LEN 31 +#define US_BULK_CB_SIGN 0x43425355 +#define US_BULK_FLAG_IN 1 +#define US_BULK_FLAG_OUT 0 + +/* command status wrapper */ +struct bulk_cs_wrap { + __u32 Signature; /* should = 'USBS' */ + __u32 Tag; /* same as original command */ + __u32 Residue; /* amount not transferred */ + __u8 Status; /* see below */ + __u8 Filler[18]; +}; + +#define US_BULK_CS_WRAP_LEN 31 +#define US_BULK_CS_SIGN 0x53425355 +#define US_BULK_STAT_OK 0 +#define US_BULK_STAT_FAIL 1 +#define US_BULK_STAT_PHASE 2 + +#define US_BULK_RESET 0xff +#define US_BULK_RESET_SOFT 1 +#define US_BULK_RESET_HARD 0 + +/* + * Transport return codes + */ + +#define USB_STOR_TRANSPORT_GOOD 0 /* Transport good, command good */ +#define USB_STOR_TRANSPORT_FAILED 1 /* Transport good, command failed */ +#define USB_STOR_TRANSPORT_ERROR 2 /* Transport bad (i.e. device dead */ + +/* + * CBI style + */ + +#define US_CBI_ADSC 0 + +/* + * GUID definitions + */ + +#define GUID(x) __u32 x[3] +#define GUID_EQUAL(x, y) (x[0] == y[0] && x[1] == y[1] && x[2] == y[2]) +#define GUID_CLEAR(x) x[0] = x[1] = x[2] = 0; +#define GUID_NONE(x) (!x[0] && !x[1] && !x[2]) +#define GUID_FORMAT "%08x%08x%08x" +#define GUID_ARGS(x) x[0], x[1], x[2] + +static inline void make_guid( __u32 *pg, __u16 vendor, __u16 product, char *serial) +{ + pg[0] = (vendor << 16) | product; + pg[1] = pg[2] = 0; + while (*serial) { + pg[1] <<= 4; + pg[1] |= pg[2] >> 28; + pg[2] <<= 4; + if (*serial >= 'a') + *serial -= 'a' - 'A'; + pg[2] |= (*serial <= '9' && *serial >= '0') ? *serial - '0' + : *serial - 'A' + 10; + serial++; + } +} + +/* Flag definitions */ +#define US_FL_IP_STATUS 0x00000001 /* status uses interrupt */ +#define US_FL_FIXED_COMMAND 0x00000002 /* expand commands to fixed size */ +#define US_FL_MODE_XLATE 0x00000004 /* translate _6 to _10 comands for + Win/MacOS compatibility */ diff -ur --new-file old/linux/drivers/usb/usb_storage_debug.c new/linux/drivers/usb/usb_storage_debug.c --- old/linux/drivers/usb/usb_storage_debug.c Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/usb/usb_storage_debug.c Thu Jan 27 16:40:16 2000 @@ -0,0 +1,104 @@ + +/* Driver for USB mass storage (scsi-like) devices + * + * (C) Michael Gee (michael@linuxspecific.com) 1999 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "../scsi/scsi.h" +#include "../scsi/hosts.h" +#include "../scsi/sd.h" + +#include "usb.h" +#include "usb_storage.h" + +void us_show_command(Scsi_Cmnd *srb) +{ + char *what = NULL; + + switch (srb->cmnd[0]) { + case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break; + case REZERO_UNIT: what = "REZERO_UNIT"; break; + case REQUEST_SENSE: what = "REQUEST_SENSE"; break; + case FORMAT_UNIT: what = "FORMAT_UNIT"; break; + case READ_BLOCK_LIMITS: what = "READ_BLOCK_LIMITS"; break; + case REASSIGN_BLOCKS: what = "REASSIGN_BLOCKS"; break; + case READ_6: what = "READ_6"; break; + case WRITE_6: what = "WRITE_6"; break; + case SEEK_6: what = "SEEK_6"; break; + case READ_REVERSE: what = "READ_REVERSE"; break; + case WRITE_FILEMARKS: what = "WRITE_FILEMARKS"; break; + case SPACE: what = "SPACE"; break; + case INQUIRY: what = "INQUIRY"; break; + case RECOVER_BUFFERED_DATA: what = "RECOVER_BUFFERED_DATA"; break; + case MODE_SELECT: what = "MODE_SELECT"; break; + case RESERVE: what = "RESERVE"; break; + case RELEASE: what = "RELEASE"; break; + case COPY: what = "COPY"; break; + case ERASE: what = "ERASE"; break; + case MODE_SENSE: what = "MODE_SENSE"; break; + case START_STOP: what = "START_STOP"; break; + case RECEIVE_DIAGNOSTIC: what = "RECEIVE_DIAGNOSTIC"; break; + case SEND_DIAGNOSTIC: what = "SEND_DIAGNOSTIC"; break; + case ALLOW_MEDIUM_REMOVAL: what = "ALLOW_MEDIUM_REMOVAL"; break; + case SET_WINDOW: what = "SET_WINDOW"; break; + case READ_CAPACITY: what = "READ_CAPACITY"; break; + case READ_10: what = "READ_10"; break; + case WRITE_10: what = "WRITE_10"; break; + case SEEK_10: what = "SEEK_10"; break; + case WRITE_VERIFY: what = "WRITE_VERIFY"; break; + case VERIFY: what = "VERIFY"; break; + case SEARCH_HIGH: what = "SEARCH_HIGH"; break; + case SEARCH_EQUAL: what = "SEARCH_EQUAL"; break; + case SEARCH_LOW: what = "SEARCH_LOW"; break; + case SET_LIMITS: what = "SET_LIMITS"; break; + case READ_POSITION: what = "READ_POSITION"; break; + case SYNCHRONIZE_CACHE: what = "SYNCHRONIZE_CACHE"; break; + case LOCK_UNLOCK_CACHE: what = "LOCK_UNLOCK_CACHE"; break; + case READ_DEFECT_DATA: what = "READ_DEFECT_DATA"; break; + case MEDIUM_SCAN: what = "MEDIUM_SCAN"; break; + case COMPARE: what = "COMPARE"; break; + case COPY_VERIFY: what = "COPY_VERIFY"; break; + case WRITE_BUFFER: what = "WRITE_BUFFER"; break; + case READ_BUFFER: what = "READ_BUFFER"; break; + case UPDATE_BLOCK: what = "UPDATE_BLOCK"; break; + case READ_LONG: what = "READ_LONG"; break; + case WRITE_LONG: what = "WRITE_LONG"; break; + case CHANGE_DEFINITION: what = "CHANGE_DEFINITION"; break; + case WRITE_SAME: what = "WRITE_SAME"; break; + case READ_TOC: what = "READ_TOC"; break; + case LOG_SELECT: what = "LOG_SELECT"; break; + case LOG_SENSE: what = "LOG_SENSE"; break; + case MODE_SELECT_10: what = "MODE_SELECT_10"; break; + case MODE_SENSE_10: what = "MODE_SENSE_10"; break; + case MOVE_MEDIUM: what = "MOVE_MEDIUM"; break; + case READ_12: what = "READ_12"; break; + case WRITE_12: what = "WRITE_12"; break; + case WRITE_VERIFY_12: what = "WRITE_VERIFY_12"; break; + case SEARCH_HIGH_12: what = "SEARCH_HIGH_12"; break; + case SEARCH_EQUAL_12: what = "SEARCH_EQUAL_12"; break; + case SEARCH_LOW_12: what = "SEARCH_LOW_12"; break; + case READ_ELEMENT_STATUS: what = "READ_ELEMENT_STATUS"; break; + case SEND_VOLUME_TAG: what = "SEND_VOLUME_TAG"; break; + case WRITE_LONG_2: what = "WRITE_LONG_2"; break; + default: break; + } + printk(KERN_DEBUG USB_STORAGE + "Command %s (%d bytes)\n", what, srb->cmd_len); + printk(KERN_DEBUG USB_STORAGE + " %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + srb->cmnd[0], srb->cmnd[1], srb->cmnd[2], srb->cmnd[3], srb->cmnd[4], srb->cmnd[5], + srb->cmnd[6], srb->cmnd[7], srb->cmnd[8], srb->cmnd[9]); +} diff -ur --new-file old/linux/drivers/usb/usbdevice_fs.h new/linux/drivers/usb/usbdevice_fs.h --- old/linux/drivers/usb/usbdevice_fs.h Fri Jan 21 00:00:16 2000 +++ new/linux/drivers/usb/usbdevice_fs.h Tue Jan 25 20:41:20 2000 @@ -111,7 +111,6 @@ #ifdef __KERNEL__ -#include #include #include diff -ur --new-file old/linux/drivers/usb/usbkbd.c new/linux/drivers/usb/usbkbd.c --- old/linux/drivers/usb/usbkbd.c Thu Jan 20 18:48:48 2000 +++ new/linux/drivers/usb/usbkbd.c Mon Jan 24 07:39:14 2000 @@ -142,7 +142,8 @@ if (!(endpoint->bEndpointAddress & 0x80)) return NULL; if ((endpoint->bmAttributes & 3) != 3) return NULL; - usb_set_protocol(dev, 0); + usb_set_protocol(dev, interface->bInterfaceNumber, 0); + usb_set_idle(dev, interface->bInterfaceNumber, 0, 0); if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL; memset(kbd, 0, sizeof(struct usb_kbd)); diff -ur --new-file old/linux/drivers/usb/usbmouse.c new/linux/drivers/usb/usbmouse.c --- old/linux/drivers/usb/usbmouse.c Sun Jan 2 21:12:59 2000 +++ new/linux/drivers/usb/usbmouse.c Mon Jan 24 07:39:14 2000 @@ -83,8 +83,9 @@ if ((endpoint->bmAttributes & 3) != 3) return NULL; #ifndef USBMOUSE_EXTRA - usb_set_protocol(dev, 0); + usb_set_protocol(dev, interface->bInterfaceNumber, 0); #endif + usb_set_idle(dev, interface->bInterfaceNumber, 0, 0); if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) return NULL; memset(mouse, 0, sizeof(struct usb_mouse)); diff -ur --new-file old/linux/drivers/usb/uss720.c new/linux/drivers/usb/uss720.c --- old/linux/drivers/usb/uss720.c Thu Dec 23 02:36:47 1999 +++ new/linux/drivers/usb/uss720.c Tue Jan 25 20:37:21 2000 @@ -177,7 +177,7 @@ /* * Access functions. */ - +#if 0 static int uss720_irq(int usbstatus, void *buffer, int len, void *dev_id) { struct parport *pp = (struct parport *)dev_id; @@ -191,6 +191,7 @@ parport_generic_irq(0, pp, NULL); return 1; } +#endif static void parport_uss720_write_data(struct parport *pp, unsigned char d) { @@ -356,7 +357,7 @@ #else struct parport_uss720_private *priv = pp->private_data; struct usb_device *usbdev = priv->usbdev; - unsigned long rlen; + int rlen; int i; if (!usbdev) @@ -365,7 +366,7 @@ return 0; i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buf, length, &rlen, HZ*20); if (i) - printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %lu\n", buf, length, rlen); + printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %u\n", buf, length, rlen); change_mode(pp, ECR_PS2); return rlen; #endif @@ -417,7 +418,7 @@ { struct parport_uss720_private *priv = pp->private_data; struct usb_device *usbdev = priv->usbdev; - unsigned long rlen; + int rlen; int i; if (!usbdev) @@ -426,7 +427,7 @@ return 0; i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buffer, len, &rlen, HZ*20); if (i) - printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %lu\n", buffer, len, rlen); + printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %u\n", buffer, len, rlen); change_mode(pp, ECR_PS2); return rlen; } @@ -435,7 +436,7 @@ { struct parport_uss720_private *priv = pp->private_data; struct usb_device *usbdev = priv->usbdev; - unsigned long rlen; + int rlen; int i; if (!usbdev) @@ -444,7 +445,7 @@ return 0; i = usb_bulk_msg(usbdev, usb_rcvbulkpipe(usbdev, 2), buffer, len, &rlen, HZ*20); if (i) - printk(KERN_ERR "uss720: recvbulk ep 2 buf %p len %u rlen %lu\n", buffer, len, rlen); + printk(KERN_ERR "uss720: recvbulk ep 2 buf %p len %u rlen %u\n", buffer, len, rlen); change_mode(pp, ECR_PS2); return rlen; } @@ -468,7 +469,7 @@ { struct parport_uss720_private *priv = pp->private_data; struct usb_device *usbdev = priv->usbdev; - unsigned long rlen; + int rlen; int i; if (!usbdev) @@ -477,7 +478,7 @@ return 0; i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buffer, len, &rlen, HZ*20); if (i) - printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %lu\n", buffer, len, rlen); + printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %u\n", buffer, len, rlen); change_mode(pp, ECR_PS2); return rlen; } @@ -606,8 +607,10 @@ MOD_INC_USE_COUNT; return pp; +#if 0 probe_abort_port: parport_unregister_port(pp); +#endif probe_abort: kfree(priv); return NULL; diff -ur --new-file old/linux/drivers/usb/wmforce.c new/linux/drivers/usb/wmforce.c --- old/linux/drivers/usb/wmforce.c Thu Jan 20 18:48:48 2000 +++ new/linux/drivers/usb/wmforce.c Fri Jan 21 22:03:02 2000 @@ -1,9 +1,9 @@ /* * wmforce.c Version 0.1 * - * Copyright (c) 1999 Vojtech Pavlik + * Copyright (c) 2000 Vojtech Pavlik * - * USB Logitech WingMan Force tablet support + * USB Logitech WingMan Force joystick support * * Sponsored by SuSE */ diff -ur --new-file old/linux/drivers/video/Config.in new/linux/drivers/video/Config.in --- old/linux/drivers/video/Config.in Fri Dec 3 05:02:32 1999 +++ new/linux/drivers/video/Config.in Mon Jan 24 20:04:36 2000 @@ -240,7 +240,7 @@ "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ - "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "m" -o \ + "$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_SGIVW" = "m" -o \ "$CONFIG_FB_CYBER2000" = "m" ]; then define_tristate CONFIG_FBCON_CFB16 m fi @@ -314,13 +314,6 @@ else if [ "$CONFIG_FB_VGA16" = "m" ]; then define_tristate CONFIG_FBCON_VGA_PLANES m - fi - fi - if [ "$CONFIG_FB_MDA" = "y" -o "$CONFIG_FB_VGA" = "y" ]; then - define_tristate CONFIG_FBCON_VGA y - else - if [ "$CONFIG_FB_MDA" = "m" -o "$CONFIG_FB_VGA" = "m" ]; then - define_tristate CONFIG_FBCON_VGA m fi fi fi diff -ur --new-file old/linux/drivers/video/amifb.c new/linux/drivers/video/amifb.c --- old/linux/drivers/video/amifb.c Mon Oct 11 19:26:52 1999 +++ new/linux/drivers/video/amifb.c Wed Jan 26 21:45:20 2000 @@ -1939,7 +1939,7 @@ u_long ptr; size += PAGE_SIZE-1; - if (!(ptr = (u_long)amiga_chip_alloc(size))) + if (!(ptr = (u_long)amiga_chip_alloc(size, "amifb"))) panic("No Chip RAM for frame buffer"); memset((void *)ptr, 0, size); ptr = PAGE_ALIGN(ptr); diff -ur --new-file old/linux/drivers/video/bwtwofb.c new/linux/drivers/video/bwtwofb.c --- old/linux/drivers/video/bwtwofb.c Tue Dec 21 07:06:42 1999 +++ new/linux/drivers/video/bwtwofb.c Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: bwtwofb.c,v 1.11 1999/11/19 09:56:54 davem Exp $ +/* $Id: bwtwofb.c,v 1.12 2000/01/21 03:57:05 anton Exp $ * bwtwofb.c: BWtwo frame buffer driver * * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) @@ -172,7 +172,7 @@ #ifdef CONFIG_SUN4 res.start = phys; res.end = res.start + BWTWO_REGISTER_OFFSET + sizeof(struct bw2_regs) - 1; - res.flags = IORESOURE_IO | (fb->iospace & 0xff); + res.flags = IORESOURCE_IO | (fb->iospace & 0xff); resp = &res; #else resp = &fb->sbdp->resource[0]; diff -ur --new-file old/linux/drivers/video/clgenfb.c new/linux/drivers/video/clgenfb.c --- old/linux/drivers/video/clgenfb.c Thu Jan 6 19:30:52 2000 +++ new/linux/drivers/video/clgenfb.c Wed Jan 26 21:45:20 2000 @@ -316,7 +316,7 @@ #ifdef CONFIG_ZORRO static const struct { clgen_board_t btype; - int key, key2; + zorro_id id, id2; } clgen_zorro_probe_list[] __initdata = { { BT_SD64, ZORRO_PROD_HELFRICH_SD64_RAM, @@ -414,8 +414,6 @@ } fbcon_cmap; #ifdef CONFIG_ZORRO - int keyRAM; /* RAM, REG zorro board keys */ - int keyREG; unsigned long board_addr, board_size; #endif @@ -2714,22 +2712,26 @@ #ifdef CONFIG_ZORRO -static int __init clgen_zorro_find (int *key_o, int *key2_o, clgen_board_t *btype) +static int __init clgen_zorro_find (struct zorro_dev **z_o, + struct zorro_dev **z2_o, + clgen_board_t *btype) { - int i, key = 0; - - assert (key_o != NULL); + struct zorro_dev *z = NULL; + int i; + + assert (z_o != NULL); assert (btype != NULL); - for (i = 0; i < arraysize(clgen_zorro_probe_list) && !key; i++) - key = zorro_find (clgen_zorro_probe_list[i].key, 0, 0); + for (i = 0; i < arraysize(clgen_zorro_probe_list); i++) + if ((z = zorro_find_device(clgen_zorro_probe_list[i].id, NULL))) + break; - if (key) { - *key_o = key; - if (clgen_zorro_probe_list[i].key2) - *key2_o = zorro_find (clgen_zorro_probe_list[i].key2, 0, 0); + if (z) { + *z_o = z; + if (clgen_zorro_probe_list[i].id2) + *z2_o = zorro_find_device(clgen_zorro_probe_list[i].id2, NULL); else - *key2_o = 0; + *z2_o = NULL; *btype = clgen_zorro_probe_list[i - 1].btype; printk (KERN_INFO "clgen: %s board detected; ", @@ -2766,26 +2768,21 @@ static int __init clgen_zorro_setup (struct clgenfb_info *info, clgen_board_t *btype) { - int key = 0, key2 = 0; - const struct ConfigDev *cd = NULL; - const struct ConfigDev *cd2 = NULL; + struct zorro_dev *z = NULL, *z2 = NULL; unsigned long board_addr, board_size; assert (info != NULL); assert (btype != NULL); - if (clgen_zorro_find (&key, &key2, btype)) + if (clgen_zorro_find (&z, &z2, btype)) return -1; - assert (key > 0); - assert (key2 >= 0); + assert (z > 0); + assert (z2 >= 0); assert (*btype != BT_NONE); - info->keyRAM = key; - info->keyREG = key2; - cd = zorro_get_board (key); - info->board_addr = board_addr = (unsigned long) cd->cd_BoardAddr; - info->board_size = board_size = (unsigned long) cd->cd_BoardSize; + info->board_addr = board_addr = z->resource.start; + info->board_size = board_size = z->resource.end-z->resource.start+1; if (!request_mem_region(board_addr, board_size, "clgenfb")) { printk(KERN_ERR "clgen: cannot reserve region 0x%lu, abort\n", @@ -2810,8 +2807,7 @@ info->fbmem_phys = board_addr + 16777216; info->fbmem = ioremap (info->fbmem_phys, 16777216); } else { - cd2 = zorro_get_board (key2); - printk (" REG at $%lx\n", (unsigned long) cd2->cd_BoardAddr); + printk (" REG at $%lx\n", (unsigned long) z2->resource.start); info->fbmem_phys = board_addr; if (board_addr > 0x01000000) @@ -2820,17 +2816,12 @@ info->fbmem = (caddr_t) ZTWO_VADDR (board_addr); /* set address for REG area of board */ - info->regs = (caddr_t) ZTWO_VADDR (cd2->cd_BoardAddr); - info->fbregs_phys = (unsigned long) cd2->cd_BoardAddr; + info->regs = (caddr_t) ZTWO_VADDR (z2->resource.start); + info->fbregs_phys = z2->resource.start; DPRINTK ("clgen: Virtual address for board set to: $%p\n", info->regs); } - /* mark this board as "autoconfigured" */ - zorro_config_board (key, 0); - if (*btype != BT_PICASSO4) - zorro_config_board (key2, 0); - printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n"); return 0; @@ -2968,10 +2959,6 @@ switch_monitor (info, 0); clgen_zorro_unmap (info); - - zorro_unconfig_board (info->keyRAM, 0); - if (info->btype != BT_PICASSO4) - zorro_unconfig_board (info->keyREG, 0); #else clgen_pci_unmap (info); #endif /* CONFIG_ZORRO */ diff -ur --new-file old/linux/drivers/video/cvisionppc.h new/linux/drivers/video/cvisionppc.h --- old/linux/drivers/video/cvisionppc.h Thu Feb 25 19:02:12 1999 +++ new/linux/drivers/video/cvisionppc.h Tue Jan 25 23:13:46 2000 @@ -7,7 +7,7 @@ * $Id: cvisionppc.h,v 1.8 1999/01/28 13:18:07 illo Exp $ * -------------------------------------------------------------------------- * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive + * License. See the file COPYING in the main directory of this archive * for more details. */ diff -ur --new-file old/linux/drivers/video/cyberfb.c new/linux/drivers/video/cyberfb.c --- old/linux/drivers/video/cyberfb.c Thu Aug 19 20:01:00 1999 +++ new/linux/drivers/video/cyberfb.c Wed Jan 26 21:45:20 2000 @@ -1104,76 +1104,75 @@ int __init cyberfb_init(void) { + unsigned long board_addr, board_size; struct cyberfb_par par; - unsigned long board_addr; - unsigned long board_size; - const struct ConfigDev *cd; - unsigned int CyberKey = 0; + struct zorro_dev *z = NULL; DPRINTK("ENTER\n"); - if (!(CyberKey = zorro_find(ZORRO_PROD_PHASE5_CYBERVISION64, 0, 0))) { - DPRINTK("EXIT - zorro_find failed\n"); - return -ENXIO; - } - - cd = zorro_get_board (CyberKey); - zorro_config_board (CyberKey, 0); - board_addr = (unsigned long)cd->cd_BoardAddr; - board_size = (unsigned long)cd->cd_BoardSize; - DPRINTK("board_addr=%08lx\n", board_addr); - DPRINTK("board_size=%08lx\n", board_size); - - CyberBase = ioremap(board_addr, board_size); - CyberRegs = CyberBase + 0x02000000; - CyberMem = CyberBase + 0x01400000; - DPRINTK("CyberBase=%08lx CyberRegs=%08lx CyberMem=%08lx\n", - CyberBase, (long unsigned int)CyberRegs, CyberMem); - - CyberMem_phys = board_addr + 0x01400000; - CyberRegs_phys = CyberMem_phys + 0x00c00000; - DPRINTK("CyberMem=%08lx CyberRegs=%08lx\n", CyberMem, - (long unsigned int)CyberRegs); + while ((z = zorro_find_device(ZORRO_PROD_PHASE5_CYBERVISION64, z))) { + board_addr = z->resource.start; + board_size = z->resource.end-z->resource.start+1; + CyberMem_phys = board_addr + 0x01400000; + CyberRegs_phys = CyberMem_phys + 0x00c00000; + if (!request_mem_region(CyberRegs_phys, 0x10000, "S3 Trio64")) + continue; + if (!request_mem_region(CyberMem_phys, 0x4000000, "RAM")) { + release_mem_region(CyberRegs_phys, 0x10000); + continue; + } + strcpy(z->name, "CyberVision64 Graphics Board"); + DPRINTK("board_addr=%08lx\n", board_addr); + DPRINTK("board_size=%08lx\n", board_size); + + CyberBase = ioremap(board_addr, board_size); + CyberRegs = CyberBase + 0x02000000; + CyberMem = CyberBase + 0x01400000; + DPRINTK("CyberBase=%08lx CyberRegs=%08lx CyberMem=%08lx\n", + CyberBase, (long unsigned int)CyberRegs, CyberMem); #ifdef CYBERFBDEBUG - DPRINTK("Register state just after mapping memory\n"); - cv64_dump(); + DPRINTK("Register state just after mapping memory\n"); + cv64_dump(); #endif - strcpy(fb_info.modename, cyberfb_name); - fb_info.changevar = NULL; - fb_info.node = -1; - fb_info.fbops = &cyberfb_ops; - fb_info.disp = &disp; - fb_info.switch_con = &Cyberfb_switch; - fb_info.updatevar = &Cyberfb_updatevar; - fb_info.blank = &Cyberfb_blank; - - Cyber_init(); - /* ++Andre: set cyberfb default mode */ - if (!cyberfb_usermode) { - cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var; - DPRINTK("Use default cyber8 mode\n"); - } - Cyber_decode_var(&cyberfb_default, &par); - Cyber_encode_var(&cyberfb_default, &par); - - do_fb_set_var(&cyberfb_default, 1); - cyberfb_get_var(&fb_display[0].var, -1, &fb_info); - cyberfb_set_disp(-1, &fb_info); - do_install_cmap(0, &fb_info); - - if (register_framebuffer(&fb_info) < 0) { - DPRINTK("EXIT - register_framebuffer failed\n"); - return -EINVAL; + strcpy(fb_info.modename, cyberfb_name); + fb_info.changevar = NULL; + fb_info.node = -1; + fb_info.fbops = &cyberfb_ops; + fb_info.disp = &disp; + fb_info.switch_con = &Cyberfb_switch; + fb_info.updatevar = &Cyberfb_updatevar; + fb_info.blank = &Cyberfb_blank; + + Cyber_init(); + /* ++Andre: set cyberfb default mode */ + if (!cyberfb_usermode) { + cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var; + DPRINTK("Use default cyber8 mode\n"); + } + Cyber_decode_var(&cyberfb_default, &par); + Cyber_encode_var(&cyberfb_default, &par); + + do_fb_set_var(&cyberfb_default, 1); + cyberfb_get_var(&fb_display[0].var, -1, &fb_info); + cyberfb_set_disp(-1, &fb_info); + do_install_cmap(0, &fb_info); + + if (register_framebuffer(&fb_info) < 0) { + DPRINTK("EXIT - register_framebuffer failed\n"); + release_mem_region(board_addr, board_size); + return -EINVAL; + } + + printk("fb%d: %s frame buffer device, using %ldK of video memory\n", + GET_FB_IDX(fb_info.node), fb_info.modename, CyberSize>>10); + + /* TODO: This driver cannot be unloaded yet */ + MOD_INC_USE_COUNT; + DPRINTK("EXIT\n"); + return 0; } - - printk("fb%d: %s frame buffer device, using %ldK of video memory\n", - GET_FB_IDX(fb_info.node), fb_info.modename, CyberSize>>10); - - /* TODO: This driver cannot be unloaded yet */ - MOD_INC_USE_COUNT; - DPRINTK("EXIT\n"); - return 0; + return -ENXIO; } diff -ur --new-file old/linux/drivers/video/fbcon.c new/linux/drivers/video/fbcon.c --- old/linux/drivers/video/fbcon.c Fri Jan 7 21:59:42 2000 +++ new/linux/drivers/video/fbcon.c Mon Jan 24 20:04:36 2000 @@ -237,7 +237,7 @@ fbcon_vbl_handler(0, NULL, NULL); cursor_timer.expires = jiffies+HZ/50; cursor_timer.data = 0; - cursor_timer.next = cursor_timer.next = NULL; + cursor_timer.next = cursor_timer.prev = NULL; add_timer(&cursor_timer); } diff -ur --new-file old/linux/drivers/video/fbgen.c new/linux/drivers/video/fbgen.c --- old/linux/drivers/video/fbgen.c Thu Dec 9 22:05:08 1999 +++ new/linux/drivers/video/fbgen.c Tue Jan 25 23:13:46 2000 @@ -4,7 +4,7 @@ * Created 3 Jan 1998 by Geert Uytterhoeven * * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive + * License. See the file COPYING in the main directory of this archive * for more details. */ diff -ur --new-file old/linux/drivers/video/fbmem.c new/linux/drivers/video/fbmem.c --- old/linux/drivers/video/fbmem.c Fri Jan 7 21:59:42 2000 +++ new/linux/drivers/video/fbmem.c Thu Jan 27 18:01:58 2000 @@ -432,8 +432,7 @@ /* frame buffer memory */ start = fix.smem_start; - len = (start & ~PAGE_MASK)+fix.smem_len; - len = (len+~PAGE_MASK) & PAGE_MASK; /* someone's on crack. */ + len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.smem_len); if (off >= len) { /* memory mapped io */ off -= len; @@ -441,8 +440,7 @@ if (var.accel_flags) return -EINVAL; start = fix.mmio_start; - len = (start & ~PAGE_MASK)+fix.mmio_len; - len = (len+~PAGE_MASK) & PAGE_MASK; + len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.mmio_len); } start &= PAGE_MASK; if ((vma->vm_end - vma->vm_start + off) > len) diff -ur --new-file old/linux/drivers/video/fm2fb.c new/linux/drivers/video/fm2fb.c --- old/linux/drivers/video/fm2fb.c Thu Aug 19 20:01:00 1999 +++ new/linux/drivers/video/fm2fb.c Wed Jan 26 21:45:20 2000 @@ -376,95 +376,99 @@ int __init fm2fb_init(void) { - int key, is_fm; - const struct ConfigDev *cd = NULL; - unsigned long board, *ptr; + int is_fm; + struct zorro_dev *z = NULL; + unsigned long *ptr; int x, y; - if (!(key = is_fm = zorro_find(ZORRO_PROD_BSC_FRAMEMASTER_II, 0, 0)) && - !(key = zorro_find(ZORRO_PROD_HELFRICH_RAINBOW_II, 0, 0))) - return -ENXIO; - cd = zorro_get_board(key); - if (!(board = (u_long)cd->cd_BoardAddr)) - return -ENXIO; - zorro_config_board(key, 0); - - /* assigning memory to kernel space */ - fm2fb_mem_phys = board; - fm2fb_mem = ioremap(board, FRAMEMASTER_SIZE); - fm2fb_reg_phys = fm2fb_mem_phys+FRAMEMASTER_REG; - fm2fb_reg = (unsigned char *)(fm2fb_mem+FRAMEMASTER_REG); - - /* make EBU color bars on display */ - ptr = (unsigned long *)fm2fb_mem; - for (y = 0; y < 576; y++) { - for (x = 0; x < 96; x++) *ptr++ = 0xffffff; /* white */ - for (x = 0; x < 96; x++) *ptr++ = 0xffff00; /* yellow */ - for (x = 0; x < 96; x++) *ptr++ = 0x00ffff; /* cyan */ - for (x = 0; x < 96; x++) *ptr++ = 0x00ff00; /* green */ - for (x = 0; x < 96; x++) *ptr++ = 0xff00ff; /* magenta */ - for (x = 0; x < 96; x++) *ptr++ = 0xff0000; /* red */ - for (x = 0; x < 96; x++) *ptr++ = 0x0000ff; /* blue */ - for (x = 0; x < 96; x++) *ptr++ = 0x000000; /* black */ + while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { + if (z->id == ZORRO_PROD_BSC_FRAMEMASTER_II) + is_fm = 1; + else if (z->id == ZORRO_PROD_HELFRICH_RAINBOW_II) + is_fm = 0; + else + continue; + if (!request_mem_region(z->resource.start, FRAMEMASTER_SIZE, "fm2fb")) + continue; + + /* assigning memory to kernel space */ + fm2fb_mem_phys = z->resource.start; + fm2fb_mem = ioremap(fm2fb_mem_phys, FRAMEMASTER_SIZE); + fm2fb_reg_phys = fm2fb_mem_phys+FRAMEMASTER_REG; + fm2fb_reg = (unsigned char *)(fm2fb_mem+FRAMEMASTER_REG); + + /* make EBU color bars on display */ + ptr = (unsigned long *)fm2fb_mem; + for (y = 0; y < 576; y++) { + for (x = 0; x < 96; x++) *ptr++ = 0xffffff; /* white */ + for (x = 0; x < 96; x++) *ptr++ = 0xffff00; /* yellow */ + for (x = 0; x < 96; x++) *ptr++ = 0x00ffff; /* cyan */ + for (x = 0; x < 96; x++) *ptr++ = 0x00ff00; /* green */ + for (x = 0; x < 96; x++) *ptr++ = 0xff00ff; /* magenta */ + for (x = 0; x < 96; x++) *ptr++ = 0xff0000; /* red */ + for (x = 0; x < 96; x++) *ptr++ = 0x0000ff; /* blue */ + for (x = 0; x < 96; x++) *ptr++ = 0x000000; /* black */ + } + fm2fbcon_blank(0, NULL); + + if (fm2fb_mode == -1) + fm2fb_mode = FM2FB_MODE_PAL; + + fb_var = fb_var_modes[fm2fb_mode]; + + strcpy(fb_fix.id, is_fm ? "FrameMaster II" : "Rainbow II"); + fb_fix.smem_start = fm2fb_mem_phys; + fb_fix.smem_len = FRAMEMASTER_REG; + fb_fix.type = FB_TYPE_PACKED_PIXELS; + fb_fix.type_aux = 0; + fb_fix.visual = FB_VISUAL_TRUECOLOR; + fb_fix.line_length = 768<<2; + fb_fix.mmio_start = fm2fb_reg_phys; + fb_fix.mmio_len = 8; + fb_fix.accel = FB_ACCEL_NONE; + + disp.var = fb_var; + disp.cmap.start = 0; + disp.cmap.len = 0; + disp.cmap.red = disp.cmap.green = disp.cmap.blue = disp.cmap.transp = NULL; + disp.screen_base = (char *)fm2fb_mem; + disp.visual = fb_fix.visual; + disp.type = fb_fix.type; + disp.type_aux = fb_fix.type_aux; + disp.ypanstep = 0; + disp.ywrapstep = 0; + disp.line_length = fb_fix.line_length; + disp.can_soft_blank = 1; + disp.inverse = 0; + #ifdef FBCON_HAS_CFB32 + disp.dispsw = &fbcon_cfb32; + disp.dispsw_data = &fbcon_cfb32_cmap; + #else + disp.dispsw = &fbcon_dummy; + #endif + disp.scrollmode = SCROLL_YREDRAW; + + strcpy(fb_info.modename, fb_fix.id); + fb_info.node = -1; + fb_info.fbops = &fm2fb_ops; + fb_info.disp = &disp; + fb_info.fontname[0] = '\0'; + fb_info.changevar = NULL; + fb_info.switch_con = &fm2fbcon_switch; + fb_info.updatevar = &fm2fbcon_updatevar; + fb_info.blank = &fm2fbcon_blank; + fb_info.flags = FBINFO_FLAG_DEFAULT; + + fm2fb_set_var(&fb_var, -1, &fb_info); + + if (register_framebuffer(&fb_info) < 0) + return -EINVAL; + + printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.node), + fb_fix.id); + return 0; } - fm2fbcon_blank(0, NULL); - - if (fm2fb_mode == -1) - fm2fb_mode = FM2FB_MODE_PAL; - - fb_var = fb_var_modes[fm2fb_mode]; - - strcpy(fb_fix.id, is_fm ? "FrameMaster II" : "Rainbow II"); - fb_fix.smem_start = fm2fb_mem_phys; - fb_fix.smem_len = FRAMEMASTER_REG; - fb_fix.type = FB_TYPE_PACKED_PIXELS; - fb_fix.type_aux = 0; - fb_fix.visual = FB_VISUAL_TRUECOLOR; - fb_fix.line_length = 768<<2; - fb_fix.mmio_start = fm2fb_reg_phys; - fb_fix.mmio_len = 8; - fb_fix.accel = FB_ACCEL_NONE; - - disp.var = fb_var; - disp.cmap.start = 0; - disp.cmap.len = 0; - disp.cmap.red = disp.cmap.green = disp.cmap.blue = disp.cmap.transp = NULL; - disp.screen_base = (char *)fm2fb_mem; - disp.visual = fb_fix.visual; - disp.type = fb_fix.type; - disp.type_aux = fb_fix.type_aux; - disp.ypanstep = 0; - disp.ywrapstep = 0; - disp.line_length = fb_fix.line_length; - disp.can_soft_blank = 1; - disp.inverse = 0; -#ifdef FBCON_HAS_CFB32 - disp.dispsw = &fbcon_cfb32; - disp.dispsw_data = &fbcon_cfb32_cmap; -#else - disp.dispsw = &fbcon_dummy; -#endif - disp.scrollmode = SCROLL_YREDRAW; - - strcpy(fb_info.modename, fb_fix.id); - fb_info.node = -1; - fb_info.fbops = &fm2fb_ops; - fb_info.disp = &disp; - fb_info.fontname[0] = '\0'; - fb_info.changevar = NULL; - fb_info.switch_con = &fm2fbcon_switch; - fb_info.updatevar = &fm2fbcon_updatevar; - fb_info.blank = &fm2fbcon_blank; - fb_info.flags = FBINFO_FLAG_DEFAULT; - - fm2fb_set_var(&fb_var, -1, &fb_info); - - if (register_framebuffer(&fb_info) < 0) - return -EINVAL; - - printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.node), - fb_fix.id); - return 0; + return -ENXIO; } int __init fm2fb_setup(char *options) diff -ur --new-file old/linux/drivers/video/igafb.c new/linux/drivers/video/igafb.c --- old/linux/drivers/video/igafb.c Tue Dec 21 07:06:42 1999 +++ new/linux/drivers/video/igafb.c Tue Jan 25 19:26:04 2000 @@ -623,7 +623,6 @@ return 1; } - int __init igafb_init(void) { struct pci_dev *pdev; @@ -643,10 +642,10 @@ * XXX We tried to use cyber2000fb.c for IGS 2000. * But it does not initialize the chip in JavaStation-E, alas. */ - pdev = pci_find_device(PCI_VENDOR_ID_INTERG, - 0x2000, 0); - if(pdev == NULL) + pdev = pci_find_device(PCI_VENDOR_ID_INTERG, 0x2000, 0); + if(pdev == NULL) { return -ENXIO; + } iga2000 = 1; } @@ -657,15 +656,18 @@ } memset(info, 0, sizeof(struct fb_info_iga)); - info->frame_buffer = ioremap(pdev->resource[0].start, 1024*1024*2); - if (!info->frame_buffer) { + if ((addr = pdev->resource[0].start) == 0) { + printk("igafb_init: no memory start\n", addr); kfree(info); return -ENXIO; } - addr = pdev->resource[0].start; - if (!addr) + if ((info->frame_buffer = ioremap(addr, 1024*1024*2)) == 0) { + printk("igafb_init: can't remap %lx[2M]\n", addr); + kfree(info); return -ENXIO; + } + info->frame_buffer_phys = addr & PCI_BASE_ADDRESS_MEM_MASK; #ifdef __sparc__ @@ -693,8 +695,9 @@ } else { info->io_base_phys = 0x30000000; /* XXX */ } - info->io_base = (int) ioremap(info->io_base_phys, 0x1000); - if (!info->io_base) { + if ((info->io_base = (int) ioremap(info->io_base_phys, 0x1000)) == 0) { + printk("igafb_init: can't remap %lx[4K]\n", info->io_base_phys); + iounmap(info->frame_buffer); kfree(info); return -ENXIO; } @@ -709,8 +712,9 @@ info->mmap_map = kmalloc(4 * sizeof(*info->mmap_map), GFP_ATOMIC); if (!info->mmap_map) { - printk("igafb_init: can't alloc mmap_map\n"); - /* XXX Here we left I/O allocated */ + printk("igafb_init: can't alloc mmap_map\n"); + iounmap(info->io_base); + iounmap(info->frame_buffer); kfree(info); return -ENOMEM; } @@ -763,7 +767,9 @@ #endif - if (!iga_init(info)) { + if (!iga_init(info)) { + iounmap(info->io_base); + iounmap(info->frame_buffer); if (info->mmap_map) kfree(info->mmap_map); kfree(info); diff -ur --new-file old/linux/drivers/video/offb.c new/linux/drivers/video/offb.c --- old/linux/drivers/video/offb.c Thu Jan 6 19:31:38 2000 +++ new/linux/drivers/video/offb.c Thu Jan 27 19:52:14 2000 @@ -470,8 +470,7 @@ } #endif /* CONFIG_FB_PLATINUM */ #ifdef CONFIG_FB_CLGEN - if ((!strncmp(dp->name, "MacPicasso",10) || - (!strncmp(dp->name, "54m30",5)) { + if (!strncmp(dp->name, "MacPicasso",10) || !strncmp(dp->name, "54m30",5)) { clgen_of_init(dp); return 1; } diff -ur --new-file old/linux/drivers/video/platinumfb.h new/linux/drivers/video/platinumfb.h --- old/linux/drivers/video/platinumfb.h Wed Sep 30 19:19:11 1998 +++ new/linux/drivers/video/platinumfb.h Tue Jan 25 23:13:46 2000 @@ -15,7 +15,7 @@ * Created 28 Dec 1997 by Geert Uytterhoeven * * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive + * License. See the file COPYING in the main directory of this archive * for more details. */ diff -ur --new-file old/linux/drivers/video/pm2fb.c new/linux/drivers/video/pm2fb.c --- old/linux/drivers/video/pm2fb.c Thu Jan 6 19:30:52 2000 +++ new/linux/drivers/video/pm2fb.c Tue Jan 25 23:13:46 2000 @@ -9,7 +9,7 @@ * TODO multiple boards support * -------------------------------------------------------------------------- * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive + * License. See the file COPYING in the main directory of this archive * for more details. */ diff -ur --new-file old/linux/drivers/video/pm2fb.h new/linux/drivers/video/pm2fb.h --- old/linux/drivers/video/pm2fb.h Tue Dec 21 07:06:42 1999 +++ new/linux/drivers/video/pm2fb.h Tue Jan 25 23:13:46 2000 @@ -5,7 +5,7 @@ * $Id: pm2fb.h,v 1.21 1999/01/28 13:18:07 illo Exp $ * -------------------------------------------------------------------------- * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive + * License. See the file COPYING in the main directory of this archive * for more details. */ diff -ur --new-file old/linux/drivers/video/retz3fb.c new/linux/drivers/video/retz3fb.c --- old/linux/drivers/video/retz3fb.c Thu Aug 19 20:01:00 1999 +++ new/linux/drivers/video/retz3fb.c Wed Jan 26 21:45:21 2000 @@ -1423,85 +1423,93 @@ int __init retz3fb_init(void) { unsigned long board_addr, board_size; - unsigned int key; - const struct ConfigDev *cd; + struct zorro_dev *z = NULL; volatile unsigned char *regs; struct retz3fb_par par; struct retz3_fb_info *zinfo; struct fb_info *fb_info; short i; + int res = -ENXIO; - if (!(key = zorro_find(ZORRO_PROD_MACROSYSTEMS_RETINA_Z3, 0, 0))) - return -ENXIO; - - if (!(zinfo = kmalloc(sizeof(struct retz3_fb_info), GFP_KERNEL))) - return -ENOMEM; - memset(zinfo, 0, sizeof(struct retz3_fb_info)); - - cd = zorro_get_board (key); - zorro_config_board (key, 0); - board_addr = (unsigned long)cd->cd_BoardAddr; - board_size = (unsigned long)cd->cd_BoardSize; - - zinfo->base = ioremap(board_addr, board_size); - zinfo->regs = zinfo->base; - zinfo->fbmem = zinfo->base + VIDEO_MEM_OFFSET; - /* Get memory size - for now we asume its a 4MB board */ - zinfo->fbsize = 0x00400000; /* 4 MB */ - zinfo->physregs = board_addr; - zinfo->physfbmem = board_addr + VIDEO_MEM_OFFSET; + while ((z = zorro_find_device(ZORRO_PROD_MACROSYSTEMS_RETINA_Z3, z))) { + board_addr = z->resource.start; + board_size = z->resource.end-z->resource.start+1; + if (!request_mem_region(board_addr, 0x0c00000, + "ncr77c32blt")) { + continue; + if (!request_mem_region(board_addr+VIDEO_MEM_OFFSET, + 0x00400000, "RAM")) + release_mem_region(board_addr, 0x00c00000); + continue; + } + strcpy(z->name, "Retina Z3 Graphics "); + if (!(zinfo = kmalloc(sizeof(struct retz3_fb_info), + GFP_KERNEL))) + return -ENOMEM; + memset(zinfo, 0, sizeof(struct retz3_fb_info)); + + zinfo->base = ioremap(board_addr, board_size); + zinfo->regs = zinfo->base; + zinfo->fbmem = zinfo->base + VIDEO_MEM_OFFSET; + /* Get memory size - for now we asume its a 4MB board */ + zinfo->fbsize = 0x00400000; /* 4 MB */ + zinfo->physregs = board_addr; + zinfo->physfbmem = board_addr + VIDEO_MEM_OFFSET; - fb_info = fbinfo(zinfo); + fb_info = fbinfo(zinfo); - for (i = 0; i < 256; i++){ for (i = 0; i < 256; i++){ - zinfo->color_table[i][0] = i; - zinfo->color_table[i][1] = i; - zinfo->color_table[i][2] = i; + for (i = 0; i < 256; i++){ + zinfo->color_table[i][0] = i; + zinfo->color_table[i][1] = i; + zinfo->color_table[i][2] = i; + } } - } - regs = zinfo->regs; - /* Disable hardware cursor */ - seq_w(regs, SEQ_CURSOR_Y_INDEX, 0x00); + regs = zinfo->regs; + /* Disable hardware cursor */ + seq_w(regs, SEQ_CURSOR_Y_INDEX, 0x00); - retz3_setcolreg (255, 56<<8, 100<<8, 160<<8, 0, fb_info); - retz3_setcolreg (254, 0, 0, 0, 0, fb_info); + retz3_setcolreg (255, 56<<8, 100<<8, 160<<8, 0, fb_info); + retz3_setcolreg (254, 0, 0, 0, 0, fb_info); - strcpy(fb_info->modename, retz3fb_name); - fb_info->changevar = NULL; - fb_info->node = -1; - fb_info->fbops = &retz3fb_ops; - fb_info->disp = &zinfo->disp; - fb_info->switch_con = &z3fb_switch; - fb_info->updatevar = &z3fb_updatevar; - fb_info->blank = &z3fb_blank; - fb_info->flags = FBINFO_FLAG_DEFAULT; - strncpy(fb_info->fontname, fontname, 40); + strcpy(fb_info->modename, retz3fb_name); + fb_info->changevar = NULL; + fb_info->node = -1; + fb_info->fbops = &retz3fb_ops; + fb_info->disp = &zinfo->disp; + fb_info->switch_con = &z3fb_switch; + fb_info->updatevar = &z3fb_updatevar; + fb_info->blank = &z3fb_blank; + fb_info->flags = FBINFO_FLAG_DEFAULT; + strncpy(fb_info->fontname, fontname, 40); - if (z3fb_mode == -1) - retz3fb_default = retz3fb_predefined[0].var; + if (z3fb_mode == -1) + retz3fb_default = retz3fb_predefined[0].var; - retz3_decode_var(&retz3fb_default, &par); - retz3_encode_var(&retz3fb_default, &par); + retz3_decode_var(&retz3fb_default, &par); + retz3_encode_var(&retz3fb_default, &par); - do_fb_set_var(fb_info, &retz3fb_default, 0); - retz3fb_get_var(&zinfo->disp.var, -1, fb_info); + do_fb_set_var(fb_info, &retz3fb_default, 0); + retz3fb_get_var(&zinfo->disp.var, -1, fb_info); - retz3fb_set_disp(-1, fb_info); + retz3fb_set_disp(-1, fb_info); - do_install_cmap(0, fb_info); + do_install_cmap(0, fb_info); - if (register_framebuffer(fb_info) < 0) - return -EINVAL; + if (register_framebuffer(fb_info) < 0) + return -EINVAL; - printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of video memory\n", - GET_FB_IDX(fb_info->node), fb_info->modename,zinfo->fbsize>>10); + printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of " + "video memory\n", GET_FB_IDX(fb_info->node), + fb_info->modename, zinfo->fbsize>>10); - /* TODO: This driver cannot be unloaded yet */ - MOD_INC_USE_COUNT; + /* TODO: This driver cannot be unloaded yet */ + MOD_INC_USE_COUNT; - return 0; + res = 0; + } + return res; } diff -ur --new-file old/linux/drivers/video/rivafb.c new/linux/drivers/video/rivafb.c --- old/linux/drivers/video/rivafb.c Thu Jan 6 19:30:52 2000 +++ new/linux/drivers/video/rivafb.c Tue Jan 25 23:13:46 2000 @@ -13,7 +13,7 @@ * KGI code provided the basis for state storage, init, and mode switching. * * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive + * License. See the file COPYING in the main directory of this archive * for more details. */ diff -ur --new-file old/linux/drivers/video/skeletonfb.c new/linux/drivers/video/skeletonfb.c --- old/linux/drivers/video/skeletonfb.c Thu Aug 12 19:22:33 1999 +++ new/linux/drivers/video/skeletonfb.c Tue Jan 25 23:13:46 2000 @@ -4,7 +4,7 @@ * Created 28 Dec 1997 by Geert Uytterhoeven * * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive + * License. See the file COPYING in the main directory of this archive * for more details. */ @@ -287,7 +287,8 @@ struct fbgen_hwswitch xxx_switch = { xxx_detect, xxx_encode_fix, xxx_decode_var, xxx_encode_var, xxx_get_par, - xxx_set_par, xxx_getcolreg, xxx_setcolreg, xxx_blank, xxx_dispsw + xxx_set_par, xxx_getcolreg, xxx_setcolreg, xxx_pan_display, xxx_blank, + xxx_set_disp }; diff -ur --new-file old/linux/drivers/video/virgefb.c new/linux/drivers/video/virgefb.c --- old/linux/drivers/video/virgefb.c Mon Oct 11 19:26:52 1999 +++ new/linux/drivers/video/virgefb.c Wed Jan 26 21:45:21 2000 @@ -167,7 +167,6 @@ #define VIRGE16_PIXCLOCK 25000 /* ++Geert: Just a guess */ -static unsigned int CyberKey = 0; static unsigned char Cyber_colour_table [256][3]; static unsigned long CyberMem; static unsigned long CyberSize; @@ -1166,28 +1165,39 @@ int __init virgefb_init(void) { struct virgefb_par par; - unsigned long board_addr; - const struct ConfigDev *cd; + unsigned long board_addr, ramsize; + struct zorro_dev *z = NULL; - if (!(CyberKey = zorro_find(ZORRO_PROD_PHASE5_CYBERVISION64_3D, 0, 0))) - return -ENXIO; - - cd = zorro_get_board (CyberKey); - zorro_config_board (CyberKey, 0); - board_addr = (unsigned long)cd->cd_BoardAddr; + while ((z = zorro_find_device(ZORRO_PROD_PHASE5_CYBERVISION64_3D, z))) { + board_addr = z->resource.start; + if (board_addr < 0x01000000) { + /* + * Ok we got the board running in Z2 space. + */ + CyberRegs_phys = (unsigned long)(board_addr + 0x003e0000); + CyberMem_phys = board_addr; + ramsize = 0x00380000; + } else { + CyberRegs_phys = board_addr + 0x05000000; + CyberMem_phys = board_addr + 0x04000000; /* was 0x04800000 */ + ramsize = 0x00400000; + } + if (!request_mem_region(CyberRegs_phys, 0x10000, "S3 ViRGE")) + continue; + if (!request_mem_region(CyberMem_phys, ramsize, "RAM")) { + release_mem_region(CyberRegs_phys, 0x10000); + continue; + } + strcpy(z->name, "CyberVision64-3D Graphics Board"); - /* This includes the video memory as well as the S3 register set */ - if ((unsigned long)cd->cd_BoardAddr < 0x01000000) - { + if (board_addr < 0x01000000) { /* * Ok we got the board running in Z2 space. */ - CyberMem_phys = board_addr; CyberMem = ZTWO_VADDR(CyberMem_phys); CyberVGARegs = (unsigned long) \ ZTWO_VADDR(board_addr + 0x003c0000); - CyberRegs_phys = (unsigned long)(board_addr + 0x003e0000); CyberRegs = (unsigned char *)ZTWO_VADDR(CyberRegs_phys); Cyber_register_base = (unsigned long) \ ZTWO_VADDR(board_addr + 0x003c8000); @@ -1195,50 +1205,49 @@ ZTWO_VADDR(board_addr + 0x003a0000); cv3d_on_zorro2 = 1; printk(KERN_INFO "CV3D detected running in Z2 mode.\n"); - } - else - { - CyberVGARegs = (unsigned long)ioremap(board_addr +0x0c000000, 0x00010000); - CyberRegs_phys = board_addr + 0x05000000; - CyberMem_phys = board_addr + 0x04000000; /* was 0x04800000 */ + } else { + CyberVGARegs = (unsigned long)ioremap(board_addr+0x0c000000, 0x00010000); CyberRegs = ioremap(CyberRegs_phys, 0x00010000); CyberMem = (unsigned long)ioremap(CyberMem_phys, 0x01000000); /* was 0x00400000 */ cv3d_on_zorro2 = 0; printk(KERN_INFO "CV3D detected running in Z3 mode.\n"); - } + } - fbhw = &Cyber_switch; + fbhw = &Cyber_switch; - strcpy(fb_info.modename, virgefb_name); - fb_info.changevar = NULL; - fb_info.node = -1; - fb_info.fbops = &virgefb_ops; - fb_info.disp = &disp; - fb_info.switch_con = &Cyberfb_switch; - fb_info.updatevar = &Cyberfb_updatevar; - fb_info.blank = &Cyberfb_blank; - fb_info.flags = FBINFO_FLAG_DEFAULT; - - fbhw->init(); - fbhw->decode_var(&virgefb_default, &par); - fbhw->encode_var(&virgefb_default, &par); - - do_fb_set_var(&virgefb_default, 1); - virgefb_get_var(&fb_display[0].var, -1, &fb_info); - virgefb_set_disp(-1, &fb_info); - do_install_cmap(0, &fb_info); + strcpy(fb_info.modename, virgefb_name); + fb_info.changevar = NULL; + fb_info.node = -1; + fb_info.fbops = &virgefb_ops; + fb_info.disp = &disp; + fb_info.switch_con = &Cyberfb_switch; + fb_info.updatevar = &Cyberfb_updatevar; + fb_info.blank = &Cyberfb_blank; + fb_info.flags = FBINFO_FLAG_DEFAULT; + + fbhw->init(); + fbhw->decode_var(&virgefb_default, &par); + fbhw->encode_var(&virgefb_default, &par); + + do_fb_set_var(&virgefb_default, 1); + virgefb_get_var(&fb_display[0].var, -1, &fb_info); + virgefb_set_disp(-1, &fb_info); + do_install_cmap(0, &fb_info); - if (register_framebuffer(&fb_info) < 0) { + if (register_framebuffer(&fb_info) < 0) { printk(KERN_ERR "virgefb.c: register_framebuffer failed\n"); return -EINVAL; - } + } - printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of video memory\n", - GET_FB_IDX(fb_info.node), fb_info.modename, CyberSize>>10); + printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of " + "video memory\n", GET_FB_IDX(fb_info.node), + fb_info.modename, CyberSize>>10); - /* TODO: This driver cannot be unloaded yet */ - MOD_INC_USE_COUNT; - return 0; + /* TODO: This driver cannot be unloaded yet */ + MOD_INC_USE_COUNT; + return 0; + } + return -ENODEV; } diff -ur --new-file old/linux/drivers/zorro/Makefile new/linux/drivers/zorro/Makefile --- old/linux/drivers/zorro/Makefile Thu Jul 30 20:10:22 1998 +++ new/linux/drivers/zorro/Makefile Wed Jan 26 21:45:21 2000 @@ -19,10 +19,10 @@ ifeq ($(CONFIG_MODULES),y) O_TARGET = zorro_syms.o OX_OBJS = zorrosyms.o -O_OBJS = zorro.o +O_OBJS = zorro.o names.o L_OBJS := zorro_syms.o else -L_OBJS := zorro.o +L_OBJS := zorro.o names.o endif ifdef CONFIG_PROC_FS diff -ur --new-file old/linux/drivers/zorro/names.c new/linux/drivers/zorro/names.c --- old/linux/drivers/zorro/names.c Thu Jan 1 01:00:00 1970 +++ new/linux/drivers/zorro/names.c Wed Jan 26 21:45:21 2000 @@ -0,0 +1,83 @@ +/* + * $Id: zorro.c,v 1.1.2.1 1998/06/07 23:21:02 geert Exp $ + * + * Zorro Expansion Device Names + * + * Copyright (C) 1999-2000 Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include + + + /* + * Just for reference, these are the boards we have a driver for in the + * kernel: + * + * ZORRO_PROD_AMERISTAR_A2065 + * ZORRO_PROD_BSC_FRAMEMASTER_II + * ZORRO_PROD_BSC_MULTIFACE_III + * ZORRO_PROD_BSC_OKTAGON_2008 + * ZORRO_PROD_CBM_A2065_1 + * ZORRO_PROD_CBM_A2065_2 + * ZORRO_PROD_CBM_A4091_1 + * ZORRO_PROD_CBM_A4091_2 + * ZORRO_PROD_CBM_A590_A2091_1 + * ZORRO_PROD_CBM_A590_A2091_2 + * ZORRO_PROD_GVP_A1291 + * ZORRO_PROD_GVP_A530_SCSI + * ZORRO_PROD_GVP_COMBO_030_R3_SCSI + * ZORRO_PROD_GVP_COMBO_030_R4_SCSI + * ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM + * ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG + * ZORRO_PROD_GVP_GFORCE_030_SCSI + * ZORRO_PROD_GVP_GFORCE_040_060 + * ZORRO_PROD_GVP_GFORCE_040_1 + * ZORRO_PROD_GVP_GFORCE_040_SCSI_1 + * ZORRO_PROD_GVP_IO_EXTENDER + * ZORRO_PROD_GVP_SERIES_II + * ZORRO_PROD_HELFRICH_PICCOLO_RAM + * ZORRO_PROD_HELFRICH_PICCOLO_REG + * ZORRO_PROD_HELFRICH_RAINBOW_II + * ZORRO_PROD_HELFRICH_SD64_RAM + * ZORRO_PROD_HELFRICH_SD64_REG + * ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET + * ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA + * ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL + * ZORRO_PROD_MACROSYSTEMS_RETINA_Z3 + * ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx + * ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM + * ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060 + * ZORRO_PROD_PHASE5_BLIZZARD_1230_IV_1260 + * ZORRO_PROD_PHASE5_BLIZZARD_2060 + * ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS + * ZORRO_PROD_PHASE5_CYBERSTORM_MK_II + * ZORRO_PROD_PHASE5_CYBERVISION64 + * ZORRO_PROD_PHASE5_CYBERVISION64_3D + * ZORRO_PROD_VILLAGE_TRONIC_ARIADNE + * ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2 + * ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM + * ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG + * ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3 + * + * And I guess these are automagically supported as well :-) + * + * ZORRO_PROD_CBM_A560_RAM + * ZORRO_PROD_CBM_A590_A2052_A2058_A2091 + */ + +void __init zorro_namedevice(struct zorro_dev *dev) +{ + /* + * Nah, we're not that stupid to put name databases in the kernel ;-) + * That's why we have zorroutils... + */ + sprintf(dev->name, "Zorro device %08x", dev->id); +} + diff -ur --new-file old/linux/drivers/zorro/proc.c new/linux/drivers/zorro/proc.c --- old/linux/drivers/zorro/proc.c Sun Dec 5 17:42:03 1999 +++ new/linux/drivers/zorro/proc.c Wed Jan 26 21:45:21 2000 @@ -3,7 +3,7 @@ * * Procfs interface for the Zorro bus. * - * Copyright (C) 1998 Geert Uytterhoeven + * Copyright (C) 1998-2000 Geert Uytterhoeven * * Heavily based on the procfs interface for the PCI bus, which is * @@ -46,7 +46,8 @@ { struct inode *ino = file->f_dentry->d_inode; struct proc_dir_entry *dp = ino->u.generic_ip; - struct ConfigDev *cd = dp->data; + struct zorro_dev *dev = dp->data; + struct ConfigDev cd; int pos = *ppos; if (pos >= sizeof(struct ConfigDev)) @@ -55,7 +56,16 @@ nbytes = sizeof(struct ConfigDev); if (pos + nbytes > sizeof(struct ConfigDev)) nbytes = sizeof(struct ConfigDev) - pos; - if (copy_to_user(buf, cd, nbytes)) + + /* Construct a ConfigDev */ + memset(&cd, 0, sizeof(cd)); + cd.cd_Rom = dev->rom; + cd.cd_SlotAddr = dev->slotaddr; + cd.cd_SlotSize = dev->slotsize; + cd.cd_BoardAddr = (void *)dev->resource.start; + cd.cd_BoardSize = dev->resource.end-dev->resource.start+1; + + if (copy_to_user(buf, &cd, nbytes)) return -EFAULT; *ppos += nbytes; @@ -88,20 +98,11 @@ int len, cnt; for (slot = cnt = 0; slot < zorro_num_autocon && count > cnt; slot++) { - struct ConfigDev *cd = &zorro_autocon[slot]; - u16 manuf = cd->cd_Rom.er_Manufacturer; - u8 prod = cd->cd_Rom.er_Product; - u8 epc; - if (manuf == ZORRO_MANUF(ZORRO_PROD_GVP_EPC_BASE) && - prod == ZORRO_PROD(ZORRO_PROD_GVP_EPC_BASE)) { - /* GVP quirk */ - u32 addr = (u32)cd->cd_BoardAddr; - epc = (*(u16 *)ZTWO_VADDR(addr+0x8000)) & GVP_PRODMASK; - } else - epc = 0; - len = sprintf(buf, "%02x\t%04x%02x%02x\t%08x\t%08x\t%02x\n", - slot, manuf, prod, epc, (u32)cd->cd_BoardAddr, - cd->cd_BoardSize, cd->cd_Rom.er_Type); + struct zorro_dev *dev = &zorro_autocon[slot]; + len = sprintf(buf, "%02x\t%08x\t%08lx\t%08lx\t%02x\n", slot, + dev->id, dev->resource.start, + dev->resource.end-dev->resource.start+1, + dev->rom.er_Type); at += len; if (at >= pos) { if (!*start) { @@ -128,7 +129,7 @@ return -ENOMEM; entry->ops = &proc_bus_zorro_inode_operations; entry->data = &zorro_autocon[slot]; - entry->size = sizeof(struct ConfigDev); + entry->size = sizeof(struct zorro_dev); return 0; } diff -ur --new-file old/linux/drivers/zorro/zorro.c new/linux/drivers/zorro/zorro.c --- old/linux/drivers/zorro/zorro.c Thu Aug 26 21:42:33 1999 +++ new/linux/drivers/zorro/zorro.c Wed Jan 26 21:45:21 2000 @@ -3,7 +3,7 @@ * * Zorro Bus Services * - * Copyright (C) 1995-1998 Geert Uytterhoeven + * Copyright (C) 1995-2000 Geert Uytterhoeven * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive @@ -20,120 +20,47 @@ #include - /* - * Expansion Devices - */ - -u_int zorro_num_autocon = 0; -struct ConfigDev zorro_autocon[ZORRO_NUM_AUTO]; -static u32 zorro_autocon_parts[ZORRO_NUM_AUTO] = { 0, }; +extern void zorro_namedevice(struct zorro_dev *dev); - /* - * Find the key for the next unconfigured expansion device of a specific - * type. - * - * Part is a device specific number (0 <= part <= 31) to allow for the - * independent configuration of independent parts of an expansion board. - * Thanks to Jes Soerensen for this idea! - * - * Index is used to specify the first board in the autocon list - * to be tested. It was inserted in order to solve the problem - * with the GVP boards that use the same product code, but - * it should help if there are other companies which use the same - * method as GVP. Drivers for boards which are not using this - * method do not need to think of this - just set index = 0. - * - * Example: - * - * while ((key = zorro_find(ZORRO_PROD_MY_BOARD, MY_PART, 0))) { - * cd = zorro_get_board(key); - * initialise_this_board; - * zorro_config_board(key, MY_PART); - * } + * Zorro Expansion Devices */ -u_int zorro_find(zorro_id id, u_int part, u_int index) -{ - u16 manuf = ZORRO_MANUF(id); - u8 prod = ZORRO_PROD(id); - u8 epc = ZORRO_EPC(id); - u_int key; - const struct ConfigDev *cd; - u32 addr; - - if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO)) - return 0; - - if (part > 31) { - printk("zorro_find: bad part %d\n", part); - return 0; - } - - for (key = index+1; key <= zorro_num_autocon; key++) { - cd = &zorro_autocon[key-1]; - addr = (u32)cd->cd_BoardAddr; - if ((cd->cd_Rom.er_Manufacturer == manuf) && - (cd->cd_Rom.er_Product == prod) && - !(zorro_autocon_parts[key-1] & (1< zorro_num_autocon)) { - printk("zorro_get_board: bad key %d\n", key); - return NULL; - } - return &zorro_autocon[key-1]; -} - +static struct resource zorro_res[4] = { + { "Zorro II exp", 0x00e80000, 0x00efffff }, + { "Zorro II mem", 0x00200000, 0x009fffff }, + { "Zorro III exp", 0xff000000, 0xffffffff }, + { "Zorro III cfg", 0x40000000, 0x7fffffff } +}; +#endif + /* - * Mark a part of a board as configured + * Find Zorro Devices */ -void zorro_config_board(u_int key, u_int part) +struct zorro_dev *zorro_find_device(zorro_id id, struct zorro_dev *from) { - if ((key < 1) || (key > zorro_num_autocon)) - printk("zorro_config_board: bad key %d\n", key); - else if (part > 31) - printk("zorro_config_board: bad part %d\n", part); - else if (zorro_autocon_parts[key-1] & (1< zorro_num_autocon)) - printk("zorro_unconfig_board: bad key %d\n", key); - else if (part > 31) - printk("zorro_unconfig_board: bad part %d\n", part); - else if (!(zorro_autocon_parts[key-1] & (1<id) + return dev; + return NULL; } @@ -153,17 +80,16 @@ u32 zorro_unused_z2ram[4] = { 0, 0, 0, 0 }; -static void __init mark_region(u32 addr, u_int size, int flag) +static void __init mark_region(unsigned long start, unsigned long end, + int flag) { - u32 start, end; + if (flag) + start += Z2RAM_CHUNKMASK; + else + end += Z2RAM_CHUNKMASK; + start &= ~Z2RAM_CHUNKMASK; + end &= ~Z2RAM_CHUNKMASK; - if (flag) { - start = (addr+Z2RAM_CHUNKMASK) & ~Z2RAM_CHUNKMASK; - end = (addr+size) & ~Z2RAM_CHUNKMASK; - } else { - start = addr & ~Z2RAM_CHUNKMASK; - end = (addr+size+Z2RAM_CHUNKMASK) & ~Z2RAM_CHUNKMASK; - } if (end <= Z2RAM_START || start >= Z2RAM_END) return; start = start < Z2RAM_START ? 0x00000000 : start-Z2RAM_START; @@ -185,27 +111,46 @@ void __init zorro_init(void) { + struct zorro_dev *dev; u_int i; - if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO)) { - printk("Zorro: No Zorro bus detected\n"); + if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO)) return; - } printk("Zorro: Probing AutoConfig expansion devices: %d device%s\n", zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); + /* Request the resources */ +#if 0 + for (i = 0; i < (AMIGAHW_PRESENT(ZORRO3) ? 4 : 2); i++) + request_resource(&iomem_resource, &zorro_res[i]); +#endif + for (i = 0; i < zorro_num_autocon; i++) { + dev = &zorro_autocon[i]; + dev->id = (dev->rom.er_Manufacturer<<16) | (dev->rom.er_Product<<8); + if (dev->id == ZORRO_PROD_GVP_EPC_BASE) { + /* GVP quirk */ + unsigned long magic = dev->resource.start+0x8000; + dev->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK; + } + dev->resource.name = dev->name; + zorro_namedevice(dev); + if (request_resource(&iomem_resource, &dev->resource)) + printk("zorro_init: cannot request resource for board %d\n", i); + } + /* Mark all available Zorro II memory */ for (i = 0; i < zorro_num_autocon; i++) { - const struct ConfigDev *cd = &zorro_autocon[i]; - if (cd->cd_Rom.er_Type & ERTF_MEMLIST) - mark_region((u32)cd->cd_BoardAddr, cd->cd_BoardSize, 1); + dev = &zorro_autocon[i]; + if (dev->rom.er_Type & ERTF_MEMLIST) + mark_region(dev->resource.start, dev->resource.end+1, 1); } /* Unmark all used Zorro II memory */ for (i = 0; i < m68k_num_memory; i++) if (m68k_memory[i].addr < 16*1024*1024) - mark_region(m68k_memory[i].addr, m68k_memory[i].size, 0); + mark_region(m68k_memory[i].addr, + m68k_memory[i].addr+m68k_memory[i].size, 0); #ifdef CONFIG_PROC_FS zorro_proc_init(); diff -ur --new-file old/linux/drivers/zorro/zorrosyms.c new/linux/drivers/zorro/zorrosyms.c --- old/linux/drivers/zorro/zorrosyms.c Thu Jul 30 20:10:22 1998 +++ new/linux/drivers/zorro/zorrosyms.c Wed Jan 26 21:45:21 2000 @@ -3,7 +3,7 @@ * * Zorro Bus Services -- Exported Symbols * - * Copyright (C) 1998 Geert Uytterhoeven + * Copyright (C) 1998-2000 Geert Uytterhoeven */ #include @@ -12,10 +12,7 @@ /* Board configuration */ -EXPORT_SYMBOL(zorro_find); -EXPORT_SYMBOL(zorro_get_board); -EXPORT_SYMBOL(zorro_config_board); -EXPORT_SYMBOL(zorro_unconfig_board); +EXPORT_SYMBOL(zorro_find_device); /* Z2 memory */ diff -ur --new-file old/linux/fs/Config.in new/linux/fs/Config.in --- old/linux/fs/Config.in Mon Jan 10 23:19:46 2000 +++ new/linux/fs/Config.in Tue Jan 25 20:45:02 2000 @@ -6,30 +6,27 @@ bool 'Quota support' CONFIG_QUOTA tristate 'Kernel automounter support' CONFIG_AUTOFS_FS +tristate 'Kernel automounter version 4 support (also supports v3)' CONFIG_AUTOFS4_FS -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'ADFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_ADFS_FS -fi +dep_tristate 'ADFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL + tristate 'Amiga FFS filesystem support' CONFIG_AFFS_FS -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Apple Macintosh filesystem support (EXPERIMENTAL)' CONFIG_HFS_FS - tristate 'BFS filesystem (read only) support (EXPERIMENTAL)' CONFIG_BFS_FS - if [ "$CONFIG_BFS_FS" != "n" ]; then - bool ' BFS filesystem write support (DANGEROUS)' CONFIG_BFS_FS_WRITE - fi -fi + +dep_tristate 'Apple Macintosh filesystem support (EXPERIMENTAL)' CONFIG_HFS_FS $CONFIG_EXPERIMENTAL + +dep_tristate 'BFS filesystem (read only) support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL +dep_bool ' BFS filesystem write support (DANGEROUS)' CONFIG_BFS_FS_WRITE $CONFIG_BFS_FS + # msdos filesystems tristate 'DOS FAT fs support' CONFIG_FAT_FS dep_tristate ' MSDOS fs support' CONFIG_MSDOS_FS $CONFIG_FAT_FS dep_tristate ' UMSDOS: Unix-like filesystem on top of standard MSDOS fs' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS dep_tristate ' VFAT (Windows-95) fs support' CONFIG_VFAT_FS $CONFIG_FAT_FS - -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'EFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_EFS_FS -fi +dep_tristate 'EFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_EFS_FS $CONFIG_EXPERIMENTAL tristate 'Compressed ROM filessytem support' CONFIG_CRAMFS + tristate 'ISO 9660 CDROM filesystem support' CONFIG_ISO9660_FS if [ "$CONFIG_ISO9660_FS" != "n" ]; then bool ' Microsoft Joliet CDROM extensions' CONFIG_JOLIET @@ -39,39 +36,35 @@ fi tristate 'Minix fs support' CONFIG_MINIX_FS + tristate 'NTFS filesystem support (read only)' CONFIG_NTFS_FS -if [ "$CONFIG_NTFS_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' NTFS write support (DANGEROUS)' CONFIG_NTFS_RW -fi +dep_bool ' NTFS write support (DANGEROUS)' CONFIG_NTFS_RW $CONFIG_NTFS_FS $CONFIG_EXPERIMENTAL + tristate 'OS/2 HPFS filesystem support' CONFIG_HPFS_FS + bool '/proc filesystem support' CONFIG_PROC_FS -if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then - # It compiles as a module for testing only. It should not be used - # as a module in general. If we make this "tristate", a bunch of people - # who don't know what they are doing turn it on and complain when it - # breaks. - bool '/dev/pts filesystem for Unix98 PTYs' CONFIG_DEVPTS_FS -fi -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'QNX4 filesystem support (read only) (EXPERIMENTAL)' CONFIG_QNX4FS_FS - if [ "$CONFIG_QNX4FS_FS" != "n" ]; then - bool ' QNX4FS write support (DANGEROUS)' CONFIG_QNX4FS_RW - fi -fi + +# It compiles as a module for testing only. It should not be used +# as a module in general. If we make this "tristate", a bunch of people +# who don't know what they are doing turn it on and complain when it +# breaks. +dep_bool '/dev/pts filesystem for Unix98 PTYs' CONFIG_DEVPTS_FS $CONFIG_UNIX98_PTYS + +dep_tristate 'QNX4 filesystem support (read only) (EXPERIMENTAL)' CONFIG_QNX4FS_FS $CONFIG_EXPERIMENTAL +dep_bool ' QNX4FS write support (DANGEROUS)' CONFIG_QNX4FS_RW $CONFIG_QNX4FS_FS + tristate 'ROM filesystem support' CONFIG_ROMFS_FS + tristate 'Second extended fs support' CONFIG_EXT2_FS + tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS -if [ "$CONFIG_SYSV_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' SYSV filesystem write support (DANGEROUS)' CONFIG_SYSV_FS_WRITE -fi +dep_bool ' SYSV filesystem write support (DANGEROUS)' CONFIG_SYSV_FS_WRITE $CONFIG_SYSV_FS $CONFIG_EXPERIMENTAL + tristate 'UDF filesystem support (read only)' CONFIG_UDF_FS -if [ "$CONFIG_UDF_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' UDF write support (DANGEROUS)' CONFIG_UDF_RW -fi +dep_bool ' UDF write support (DANGEROUS)' CONFIG_UDF_RW $CONFIG_UDF_FS $CONFIG_EXPERIMENTAL + tristate 'UFS filesystem support (read only)' CONFIG_UFS_FS -if [ "$CONFIG_UFS_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' UFS filesystem write support (DANGEROUS)' CONFIG_UFS_FS_WRITE -fi +dep_bool ' UFS filesystem write support (DANGEROUS)' CONFIG_UFS_FS_WRITE $CONFIG_UFS_FS $CONFIG_EXPERIMENTAL if [ "$CONFIG_NET" = "y" ]; then @@ -81,16 +74,12 @@ if [ "$CONFIG_INET" = "y" ]; then tristate 'Coda filesystem support (advanced network fs)' CONFIG_CODA_FS + tristate 'NFS filesystem support' CONFIG_NFS_FS - if [ "$CONFIG_NFS_FS" = "y" -a "$CONFIG_IP_PNP" = "y" ]; then - bool ' Root file system on NFS' CONFIG_ROOT_NFS - fi + dep_bool ' Root file system on NFS' CONFIG_ROOT_NFS $CONFIG_NFS_FS $CONFIG_IP_PNP + tristate 'NFS server support' CONFIG_NFSD - if [ "$CONFIG_NFSD" != "n" ]; then - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' Provide NFSv3 server support (EXPERIMENTAL)' CONFIG_NFSD_V3 - fi - fi + dep_bool ' Provide NFSv3 server support (EXPERIMENTAL)' CONFIG_NFSD_V3 $CONFIG_NFSD $CONFIG_EXPERIMENTAL if [ "$CONFIG_NFS_FS" = "y" -o "$CONFIG_NFSD" = "y" ]; then define_tristate CONFIG_SUNRPC y diff -ur --new-file old/linux/fs/Makefile new/linux/fs/Makefile --- old/linux/fs/Makefile Tue Dec 28 02:30:02 1999 +++ new/linux/fs/Makefile Tue Jan 25 20:45:02 2000 @@ -18,7 +18,8 @@ MOD_LIST_NAME := FS_MODULES ALL_SUB_DIRS = coda minix ext2 fat msdos vfat proc isofs nfs umsdos ntfs \ hpfs sysv smbfs ncpfs ufs efs affs romfs autofs hfs lockd \ - nfsd nls devpts adfs partitions qnx4 udf bfs cramfs openpromfs + nfsd nls devpts adfs partitions qnx4 udf bfs cramfs openpromfs \ + autofs4 SUB_DIRS := partitions @@ -250,6 +251,14 @@ else ifeq ($(CONFIG_AUTOFS_FS),m) MOD_SUB_DIRS += autofs + endif +endif + +ifeq ($(CONFIG_AUTOFS4_FS),y) +SUB_DIRS += autofs4 +else + ifeq ($(CONFIG_AUTOFS4_FS),m) + MOD_SUB_DIRS += autofs4 endif endif diff -ur --new-file old/linux/fs/autofs/init.c new/linux/fs/autofs/init.c --- old/linux/fs/autofs/init.c Thu Aug 26 23:18:06 1999 +++ new/linux/fs/autofs/init.c Tue Jan 25 23:18:13 2000 @@ -21,25 +21,18 @@ NULL }; -#ifdef MODULE -int init_module(void) +static int __init init_autofs_fs(void) { return register_filesystem(&autofs_fs_type); } -void cleanup_module(void) +static void __exit exit_autofs_fs(void) { unregister_filesystem(&autofs_fs_type); } -#else /* MODULE */ - -int __init init_autofs_fs(void) -{ - return register_filesystem(&autofs_fs_type); -} - -#endif /* !MODULE */ +module_init(init_autofs_fs) +module_exit(exit_autofs_fs) #ifdef DEBUG void autofs_say(const char *name, int len) diff -ur --new-file old/linux/fs/autofs4/Makefile new/linux/fs/autofs4/Makefile --- old/linux/fs/autofs4/Makefile Thu Jan 1 01:00:00 1970 +++ new/linux/fs/autofs4/Makefile Tue Jan 25 20:45:02 2000 @@ -0,0 +1,35 @@ +# +# Makefile for the linux autofs-filesystem routines. +# +# We can build this either out of the kernel tree or the autofs tools tree. +# + +O_TARGET := autofs4.o +O_OBJS := inohash.o init.o inode.o root.o symlink.o waitq.o expire.o + +M_OBJS := $(O_TARGET) + +ifdef TOPDIR +# +# Part of the kernel code +# +include $(TOPDIR)/Rules.make +else +# +# Standalone (handy for development) +# +include ../Makefile.rules + +CFLAGS += -D__KERNEL__ -DMODULE $(KFLAGS) -I../include -I$(KINCLUDE) $(MODFLAGS) + +all: $(O_TARGET) + +$(O_TARGET): $(O_OBJS) + $(LD) -r -o $(O_TARGET) $(O_OBJS) + +install: $(O_TARGET) + install -c $(O_TARGET) /lib/modules/`uname -r`/fs + +clean: + rm -f *.o *.s +endif diff -ur --new-file old/linux/fs/autofs4/autofs_i.h new/linux/fs/autofs4/autofs_i.h --- old/linux/fs/autofs4/autofs_i.h Thu Jan 1 01:00:00 1970 +++ new/linux/fs/autofs4/autofs_i.h Fri Jan 28 17:01:56 2000 @@ -0,0 +1,175 @@ +/* -*- linux-c -*- ------------------------------------------------------- * + * + * linux/fs/autofs/autofs_i.h + * + * Copyright 1997-1998 Transmeta Corporation - All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* Internal header file for autofs */ + +#include +#include + +/* This is the range of ioctl() numbers we claim as ours */ +#define AUTOFS_IOC_FIRST AUTOFS_IOC_READY +#define AUTOFS_IOC_COUNT 32 + +#include +#include +#include +#include +#include +#include + +/* #define DEBUG */ + +#ifdef DEBUG +#define DPRINTK(D) do{ printk("pid %d: ", current->pid); printk D; } while(0) +#else +#define DPRINTK(D) do {} while(0) +#endif + +#define AUTOFS_SUPER_MAGIC 0x0187 + +/* + * If the daemon returns a negative response (AUTOFS_IOC_FAIL) then the + * kernel will keep the negative response cached for up to the time given + * here, although the time can be shorter if the kernel throws the dcache + * entry away. This probably should be settable from user space. + */ +#define AUTOFS_NEGATIVE_TIMEOUT (60*HZ) /* 1 minute */ + +/* Unified info structure. This is pointed to by both the dentry and + inode structures. Each file in the filesystem has an instance of this + structure. It holds a reference to the dentry, so dentries are never + flushed while the file exists. All name lookups are dealt with at the + dentry level, although the filesystem can interfere in the validation + process. Readdir is implemented by traversing the dentry lists. */ +struct autofs_info { + struct dentry *dentry; + struct inode *inode; + + int flags; + + struct autofs_sb_info *sbi; + struct list_head ino_hash; + unsigned long last_used; + + ino_t ino; + mode_t mode; + size_t size; + + void (*free)(struct autofs_info *); + union { + const char *symlink; + } u; +}; + +#define AUTOFS_INF_EXPIRING (1<<0) /* dentry is in the process of expiring */ + +struct autofs_inohash { + struct list_head head; +}; + +struct autofs_wait_queue { + wait_queue_head_t queue; + struct autofs_wait_queue *next; + autofs_wqt_t wait_queue_token; + /* We use the following to see what we are waiting for */ + int hash; + int len; + char *name; + /* This is for status reporting upon return */ + int status; + int wait_ctr; +}; + +#define AUTOFS_ROOT_INO 1 +#define AUTOFS_FIRST_INO 2 + +#define AUTOFS_SBI_MAGIC 0x6d4a556d + +struct autofs_sb_info { + u32 magic; + struct file *pipe; + pid_t oz_pgrp; + int catatonic; + int version; + unsigned long exp_timeout; + ino_t next_ino; + struct super_block *sb; + struct autofs_wait_queue *queues; /* Wait queue pointer */ + struct autofs_inohash ihash; +}; + +static inline struct autofs_sb_info *autofs4_sbi(struct super_block *sb) +{ + return (struct autofs_sb_info *)(sb->u.generic_sbp); +} + +static inline struct autofs_info *autofs4_dentry_ino(struct dentry *dentry) +{ + return (struct autofs_info *)(dentry->d_fsdata); +} + +/* autofs4_oz_mode(): do we see the man behind the curtain? (The + processes which do manipulations for us in user space sees the raw + filesystem without "magic".) */ + +static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) { + return sbi->catatonic || current->pgrp == sbi->oz_pgrp; +} + +/* Does a dentry have some pending activity? */ +static inline int autofs4_ispending(struct dentry *dentry) +{ + struct autofs_info *inf = autofs4_dentry_ino(dentry); + + return (dentry->d_flags & DCACHE_AUTOFS_PENDING) || + (inf != NULL && inf->flags & AUTOFS_INF_EXPIRING); +} + +/* Inode hash operations */ +void autofs4_init_ihash(struct autofs_inohash *); +void autofs4_ihash_insert(struct autofs_inohash *ih, struct autofs_info *ino); +void autofs4_ihash_delete(struct autofs_info *ino); +void autofs4_ihash_nuke(struct autofs_inohash *ih); +struct autofs_info *autofs4_ihash_find(struct autofs_inohash *ih, ino_t ino); + +struct autofs_info *autofs4_init_inf(struct autofs_sb_info *, mode_t mode); +void autofs4_free_ino(struct autofs_info *); + +/* Expiration */ +int is_autofs4_dentry(struct dentry *); +int autofs4_expire_run(struct super_block *, struct autofs_sb_info *, + struct autofs_packet_expire *); +int autofs4_expire_multi(struct super_block *, struct autofs_sb_info *, int *); + +/* Operations structures */ + +extern struct inode_operations autofs4_symlink_inode_operations; +extern struct inode_operations autofs4_dir_inode_operations; +extern struct inode_operations autofs4_root_inode_operations; + +/* Initializing function */ + +struct super_block *autofs4_read_super(struct super_block *, void *,int); +struct autofs_info *autofs4_init_ino(struct autofs_info *, struct autofs_sb_info *sbi, mode_t mode); + +/* Queue management functions */ + +enum autofs_notify +{ + NFY_NONE, + NFY_MOUNT, + NFY_EXPIRE +}; + +int autofs4_wait(struct autofs_sb_info *,struct qstr *, enum autofs_notify); +int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int); +void autofs4_catatonic_mode(struct autofs_sb_info *); diff -ur --new-file old/linux/fs/autofs4/expire.c new/linux/fs/autofs4/expire.c --- old/linux/fs/autofs4/expire.c Thu Jan 1 01:00:00 1970 +++ new/linux/fs/autofs4/expire.c Tue Jan 25 20:45:02 2000 @@ -0,0 +1,234 @@ +/* -*- linux-c -*- --------------------------------------------------------- * + * + * linux/fs/autofs/expire.c + * + * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved + * Copyright 1999 Jeremy Fitzhardinge + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * ------------------------------------------------------------------------- */ + +#include "autofs_i.h" + +/* + * Determine if a dentry tree is in use. This is much the + * same as the standard is_root_busy() function, except + * that :- + * - the extra dentry reference in autofs dentries is not + * considered to be busy + * - mountpoints within the tree are not busy + * - it traverses across mountpoints + * XXX doesn't consider children of covered dentries at mountpoints + */ +static int is_tree_busy(struct dentry *root) +{ + struct dentry *this_parent; + struct list_head *next; + int count; + + root = root->d_mounts; + + count = root->d_count; + this_parent = root; + + DPRINTK(("is_tree_busy: starting at %.*s/%.*s, d_count=%d\n", + root->d_covers->d_parent->d_name.len, + root->d_covers->d_parent->d_name.name, + root->d_name.len, root->d_name.name, + root->d_count)); + + /* Ignore autofs's extra reference */ + if (is_autofs4_dentry(root)) { + DPRINTK(("is_tree_busy: autofs\n")); + count--; + } + + /* Mountpoints don't count */ + if (root->d_mounts != root || + root->d_covers != root) { + DPRINTK(("is_tree_busy: mountpoint\n")); + count--; + } + +repeat: + next = this_parent->d_mounts->d_subdirs.next; +resume: + while (next != &this_parent->d_mounts->d_subdirs) { + int adj = 0; + struct list_head *tmp = next; + struct dentry *dentry = list_entry(tmp, struct dentry, + d_child); + + next = tmp->next; + + dentry = dentry->d_mounts; + + DPRINTK(("is_tree_busy: considering %.*s/%.*s, d_count=%d, count=%d\n", + this_parent->d_name.len, + this_parent->d_name.name, + dentry->d_covers->d_name.len, + dentry->d_covers->d_name.name, + dentry->d_count, count)); + + /* Decrement count for unused children */ + count += (dentry->d_count - 1); + + /* Mountpoints don't count */ + if (dentry->d_mounts != dentry || + dentry->d_covers != dentry) { + DPRINTK(("is_tree_busy: mountpoint\n")); + adj++; + } + + /* Ignore autofs's extra reference */ + if (is_autofs4_dentry(dentry)) { + DPRINTK(("is_tree_busy: autofs\n")); + adj++; + } + + count -= adj; + + if (!list_empty(&dentry->d_mounts->d_subdirs)) { + this_parent = dentry->d_mounts; + goto repeat; + } + + /* root is busy if any leaf is busy */ + if (dentry->d_count != adj) { + DPRINTK(("is_tree_busy: busy leaf (d_count=%d adj=%d)\n", + dentry->d_count, adj)); + return 1; + } + } + /* + * All done at this level ... ascend and resume the search. + */ + if (this_parent != root) { + next = this_parent->d_covers->d_child.next; + this_parent = this_parent->d_covers->d_parent; + goto resume; + } + + DPRINTK(("is_tree_busy: count=%d\n", count)); + return count != 0; /* remaining users? */ +} + +/* + * Find an eligible tree to time-out + * A tree is eligible if :- + * - it is unused by any user process + * - it has been unused for exp_timeout time + */ +static struct dentry *autofs4_expire(struct super_block *sb, + struct autofs_sb_info *sbi, + int do_now) +{ + unsigned long now = jiffies; /* snapshot of now */ + unsigned long timeout; + struct dentry *root = sb->s_root; + struct list_head *tmp; + + if (!sbi->exp_timeout || !root) + return NULL; + + timeout = sbi->exp_timeout; + + for(tmp = root->d_subdirs.next; + tmp != &root->d_subdirs; + tmp = tmp->next) { + struct autofs_info *ino; + struct dentry *dentry = list_entry(tmp, struct dentry, d_child); + + if (dentry->d_inode == NULL) + continue; + + ino = autofs4_dentry_ino(dentry); + + if (ino == NULL) { + /* dentry in the process of being deleted */ + continue; + } + + /* No point expiring a pending mount */ + if (dentry->d_flags & DCACHE_AUTOFS_PENDING) + continue; + + if (!do_now) { + /* Too young to die */ + if (time_after(ino->last_used+timeout, now)) + continue; + + /* update last_used here :- + - obviously makes sense if it is in use now + - less obviously, prevents rapid-fire expire + attempts if expire fails the first time */ + ino->last_used = now; + } + + if (!is_tree_busy(dentry)) { + DPRINTK(("autofs_expire: returning %p %.*s\n", + dentry, dentry->d_name.len, dentry->d_name.name)); + /* Start from here next time */ + list_del(&root->d_subdirs); + list_add(&root->d_subdirs, &dentry->d_child); + return dentry; + } + } + + return NULL; +} + +/* Perform an expiry operation */ +int autofs4_expire_run(struct super_block *sb, + struct autofs_sb_info *sbi, + struct autofs_packet_expire *pkt_p) +{ + struct autofs_packet_expire pkt; + struct dentry *dentry; + + memset(&pkt,0,sizeof pkt); + + pkt.hdr.proto_version = sbi->version; + pkt.hdr.type = autofs_ptype_expire; + + if ((dentry = autofs4_expire(sb, sbi, 0)) == NULL) + return -EAGAIN; + + pkt.len = dentry->d_name.len; + memcpy(pkt.name, dentry->d_name.name, pkt.len); + pkt.name[pkt.len] = '\0'; + + if ( copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire)) ) + return -EFAULT; + + return 0; +} + +/* Call repeatedly until it returns -EAGAIN, meaning there's nothing + more to be done */ +int autofs4_expire_multi(struct super_block *sb, + struct autofs_sb_info *sbi, int *arg) +{ + struct dentry *dentry; + int ret = -EAGAIN; + int do_now = 0; + + if (arg && get_user(do_now, arg)) + return -EFAULT; + + if ((dentry = autofs4_expire(sb, sbi, do_now)) != NULL) { + struct autofs_info *de_info = autofs4_dentry_ino(dentry); + + /* This is synchronous because it makes the daemon a + little easier */ + de_info->flags |= AUTOFS_INF_EXPIRING; + ret = autofs4_wait(sbi, &dentry->d_name, NFY_EXPIRE); + de_info->flags &= ~AUTOFS_INF_EXPIRING; + } + + return ret; +} + diff -ur --new-file old/linux/fs/autofs4/init.c new/linux/fs/autofs4/init.c --- old/linux/fs/autofs4/init.c Thu Jan 1 01:00:00 1970 +++ new/linux/fs/autofs4/init.c Tue Jan 25 23:16:36 2000 @@ -0,0 +1,35 @@ +/* -*- linux-c -*- --------------------------------------------------------- * + * + * linux/fs/autofs/init.c + * + * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * ------------------------------------------------------------------------- */ + +#include +#include +#include "autofs_i.h" + +static struct file_system_type autofs_fs_type = { + "autofs", + 0, + autofs4_read_super, + NULL +}; + +static int __init init_autofs4_fs(void) +{ + return register_filesystem(&autofs_fs_type); +} + +static void __exit exit_autofs4_fs(void) +{ + unregister_filesystem(&autofs_fs_type); +} + +module_init(init_autofs4_fs) +module_exit(exit_autofs4_fs) diff -ur --new-file old/linux/fs/autofs4/inode.c new/linux/fs/autofs4/inode.c --- old/linux/fs/autofs4/inode.c Thu Jan 1 01:00:00 1970 +++ new/linux/fs/autofs4/inode.c Tue Jan 25 20:45:02 2000 @@ -0,0 +1,423 @@ +/* -*- linux-c -*- --------------------------------------------------------- * + * + * linux/fs/autofs/inode.c + * + * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * ------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include +#include "autofs_i.h" +#define __NO_VERSION__ +#include + +static void ino_lnkfree(struct autofs_info *ino) +{ + if (ino->u.symlink) { + kfree(ino->u.symlink); + ino->u.symlink = NULL; + } +} + +struct autofs_info *autofs4_init_ino(struct autofs_info *ino, + struct autofs_sb_info *sbi, mode_t mode) +{ + int reinit = 1; + + if (ino == NULL) { + reinit = 0; + ino = kmalloc(sizeof(*ino), GFP_KERNEL); + } + + if (ino == NULL) + return NULL; + + ino->flags = 0; + ino->ino = sbi->next_ino++; + ino->mode = mode; + ino->inode = NULL; + ino->dentry = NULL; + ino->size = 0; + + ino->last_used = jiffies; + + ino->sbi = sbi; + INIT_LIST_HEAD(&ino->ino_hash); + + if (reinit && ino->free) + (ino->free)(ino); + + memset(&ino->u, 0, sizeof(ino->u)); + + ino->free = NULL; + + if (S_ISLNK(mode)) + ino->free = ino_lnkfree; + + return ino; +} + +void autofs4_free_ino(struct autofs_info *ino) +{ + autofs4_ihash_delete(ino); + if (ino->dentry) { + ino->dentry->d_fsdata = NULL; + if (ino->dentry->d_inode) + dput(ino->dentry); + ino->dentry = NULL; + } + if (ino->free) + (ino->free)(ino); + kfree(ino); +} + +/* + * Dummy functions - do we ever actually want to do + * something here? + */ +static void autofs4_put_inode(struct inode *inode) +{ +} + +static void autofs4_clear_inode(struct inode *inode) +{ +} + +static void autofs4_put_super(struct super_block *sb) +{ + struct autofs_sb_info *sbi = autofs4_sbi(sb); + + sb->u.generic_sbp = NULL; + + if ( !sbi->catatonic ) + autofs4_catatonic_mode(sbi); /* Free wait queues, close pipe */ + + kfree(sbi); + + DPRINTK(("autofs: shutting down\n")); + +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif +} + +static void autofs4_umount_begin(struct super_block *sb) +{ + struct autofs_sb_info *sbi = autofs4_sbi(sb); + + if (!sbi->catatonic) + autofs4_catatonic_mode(sbi); +} + +static int autofs4_statfs(struct super_block *sb, struct statfs *buf, int bufsiz); +static void autofs4_read_inode(struct inode *inode); +static void autofs4_write_inode(struct inode *inode); + +static struct super_operations autofs4_sops = { + read_inode: autofs4_read_inode, + write_inode: autofs4_write_inode, + put_inode: autofs4_put_inode, + clear_inode: autofs4_clear_inode, + put_super: autofs4_put_super, + statfs: autofs4_statfs, + umount_begin: autofs4_umount_begin, +}; + +static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, + pid_t *pgrp, int *minproto, int *maxproto) +{ + char *this_char, *value; + + *uid = current->uid; + *gid = current->gid; + *pgrp = current->pgrp; + + *minproto = *maxproto = AUTOFS_PROTO_VERSION; + + *pipefd = -1; + + if ( !options ) return 1; + for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) { + if ((value = strchr(this_char,'=')) != NULL) + *value++ = 0; + if (!strcmp(this_char,"fd")) { + if (!value || !*value) + return 1; + *pipefd = simple_strtoul(value,&value,0); + if (*value) + return 1; + } + else if (!strcmp(this_char,"uid")) { + if (!value || !*value) + return 1; + *uid = simple_strtoul(value,&value,0); + if (*value) + return 1; + } + else if (!strcmp(this_char,"gid")) { + if (!value || !*value) + return 1; + *gid = simple_strtoul(value,&value,0); + if (*value) + return 1; + } + else if (!strcmp(this_char,"pgrp")) { + if (!value || !*value) + return 1; + *pgrp = simple_strtoul(value,&value,0); + if (*value) + return 1; + } + else if (!strcmp(this_char,"minproto")) { + if (!value || !*value) + return 1; + *minproto = simple_strtoul(value,&value,0); + if (*value) + return 1; + } + else if (!strcmp(this_char,"maxproto")) { + if (!value || !*value) + return 1; + *maxproto = simple_strtoul(value,&value,0); + if (*value) + return 1; + } + else break; + } + return (*pipefd < 0); +} + +static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi) +{ + struct autofs_info *ino; + + ino = autofs4_init_ino(NULL, sbi, S_IFDIR | 0755); + if (!ino) + return NULL; + + ino->ino = AUTOFS_ROOT_INO; + + return ino; +} + +struct super_block *autofs4_read_super(struct super_block *s, void *data, + int silent) +{ + struct inode * root_inode; + struct dentry * root; + struct file * pipe; + int pipefd; + struct autofs_sb_info *sbi; + int minproto, maxproto; + + MOD_INC_USE_COUNT; + + lock_super(s); + /* Super block already completed? */ + if (s->s_root) + goto out_unlock; + + sbi = (struct autofs_sb_info *) kmalloc(sizeof(*sbi), GFP_KERNEL); + if ( !sbi ) + goto fail_unlock; + DPRINTK(("autofs: starting up, sbi = %p\n",sbi)); + + memset(sbi, 0, sizeof(*sbi)); + + s->u.generic_sbp = sbi; + sbi->magic = AUTOFS_SBI_MAGIC; + sbi->catatonic = 0; + sbi->exp_timeout = 0; + sbi->oz_pgrp = current->pgrp; + sbi->sb = s; + sbi->version = 0; + autofs4_init_ihash(&sbi->ihash); + sbi->queues = NULL; + sbi->next_ino = AUTOFS_FIRST_INO; + s->s_blocksize = 1024; + s->s_blocksize_bits = 10; + s->s_magic = AUTOFS_SUPER_MAGIC; + s->s_op = &autofs4_sops; + s->s_root = NULL; + unlock_super(s); /* shouldn't we keep it locked a while longer? */ + + /* + * Get the root inode and dentry, but defer checking for errors. + */ + autofs4_ihash_insert(&sbi->ihash, autofs4_mkroot(sbi)); + + root_inode = iget(s, AUTOFS_ROOT_INO); + root = d_alloc_root(root_inode); + pipe = NULL; + + /* + * Check whether somebody else completed the super block. + */ + if (s->s_root) + goto out_dput; + + if (!root) + goto fail_iput; + + /* Can this call block? */ + if (parse_options(data, &pipefd, + &root_inode->i_uid, &root_inode->i_gid, + &sbi->oz_pgrp, + &minproto, &maxproto)) { + printk("autofs: called with bogus options\n"); + goto fail_dput; + } + + /* Couldn't this be tested earlier? */ + if (maxproto < AUTOFS_MIN_PROTO_VERSION || + minproto > AUTOFS_PROTO_VERSION) { + printk("autofs: kernel does not match daemon version " + "daemon (%d, %d) kernel (%d, %d)\n", + minproto, maxproto, + AUTOFS_MIN_PROTO_VERSION, AUTOFS_PROTO_VERSION); + goto fail_dput; + } + + sbi->version = maxproto > AUTOFS_PROTO_VERSION ? AUTOFS_PROTO_VERSION : maxproto; + + DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, sbi->oz_pgrp)); + pipe = fget(pipefd); + /* + * Check whether somebody else completed the super block. + */ + if (s->s_root) + goto out_fput; + + if ( !pipe ) { + printk("autofs: could not open pipe file descriptor\n"); + goto fail_dput; + } + if ( !pipe->f_op || !pipe->f_op->write ) + goto fail_fput; + sbi->pipe = pipe; + + /* + * Success! Install the root dentry now to indicate completion. + */ + s->s_root = root; + return s; + + /* + * Success ... somebody else completed the super block for us. + */ +out_unlock: + unlock_super(s); + goto out_dec; +out_fput: + if (pipe) + fput(pipe); +out_dput: + if (root) + dput(root); + else + iput(root_inode); +out_dec: + MOD_DEC_USE_COUNT; + return s; + + /* + * Failure ... clear the s_dev slot and clean up. + */ +fail_fput: + printk("autofs: pipe file descriptor does not contain proper ops\n"); + /* + * fput() can block, so we clear the super block first. + */ + s->s_dev = 0; + fput(pipe); + /* fall through */ +fail_dput: + /* + * dput() can block, so we clear the super block first. + */ + s->s_dev = 0; + dput(root); + goto fail_free; +fail_iput: + printk("autofs: get root dentry failed\n"); + /* + * iput() can block, so we clear the super block first. + */ + s->s_dev = 0; + iput(root_inode); +fail_free: + kfree(sbi); + goto fail_dec; +fail_unlock: + unlock_super(s); +fail_dec: + s->s_dev = 0; + MOD_DEC_USE_COUNT; + return NULL; +} + +static int autofs4_statfs(struct super_block *sb, struct statfs *buf, int bufsiz) +{ + struct statfs tmp; + + tmp.f_type = AUTOFS_SUPER_MAGIC; + tmp.f_bsize = 1024; + tmp.f_blocks = 0; + tmp.f_bfree = 0; + tmp.f_bavail = 0; + tmp.f_files = 0; + tmp.f_ffree = 0; + tmp.f_namelen = NAME_MAX; + return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0; +} + +static void autofs4_read_inode(struct inode *inode) +{ + struct autofs_sb_info *sbi = autofs4_sbi(inode->i_sb); + struct autofs_info *inf; + + inf = autofs4_ihash_find(&sbi->ihash, inode->i_ino); + + if (inf == NULL || inf->inode != NULL) + return; + + inode->i_mode = inf->mode; + inode->i_mtime = inode->i_ctime = inode->i_atime = CURRENT_TIME; + inode->i_size = inf->size; + + inode->i_blocks = 0; + inode->i_blksize = 0; + inode->i_nlink = 1; + + if (inode->i_sb->s_root) { + inode->i_uid = inode->i_sb->s_root->d_inode->i_uid; + inode->i_gid = inode->i_sb->s_root->d_inode->i_gid; + } else { + inode->i_uid = 0; + inode->i_gid = 0; + } + + inf->inode = inode; + + if (S_ISDIR(inf->mode)) { + inode->i_nlink = 2; + if (inode->i_ino == AUTOFS_ROOT_INO) + inode->i_op = &autofs4_root_inode_operations; + else + inode->i_op = &autofs4_dir_inode_operations; + } else if (S_ISLNK(inf->mode)) { + inode->i_op = &autofs4_symlink_inode_operations; + } +} + +static void autofs4_write_inode(struct inode *inode) +{ +} diff -ur --new-file old/linux/fs/autofs4/inohash.c new/linux/fs/autofs4/inohash.c --- old/linux/fs/autofs4/inohash.c Thu Jan 1 01:00:00 1970 +++ new/linux/fs/autofs4/inohash.c Tue Jan 25 20:45:02 2000 @@ -0,0 +1,68 @@ +/* + * "inohash" is a misnomer. Inodes are just stored in a single list, + * since this code is only ever asked for the most recently inserted + * inode. + * + * Copyright 1999 Jeremy Fitzhardinge + */ + +#include "autofs_i.h" + +void autofs4_init_ihash(struct autofs_inohash *ih) +{ + INIT_LIST_HEAD(&ih->head); +} + +void autofs4_ihash_insert(struct autofs_inohash *ih, + struct autofs_info *ino) +{ + DPRINTK(("autofs_ihash_insert: adding ino %ld\n", ino->ino)); + + list_add(&ino->ino_hash, &ih->head); +} + +void autofs4_ihash_delete(struct autofs_info *inf) +{ + DPRINTK(("autofs_ihash_delete: deleting ino %ld\n", inf->ino)); + + if (!list_empty(&inf->ino_hash)) + list_del(&inf->ino_hash); +} + +struct autofs_info *autofs4_ihash_find(struct autofs_inohash *ih, + ino_t inum) +{ + struct list_head *tmp; + + for(tmp = ih->head.next; + tmp != &ih->head; + tmp = tmp->next) { + struct autofs_info *ino = list_entry(tmp, struct autofs_info, ino_hash); + if (ino->ino == inum) { + DPRINTK(("autofs_ihash_find: found %ld -> %p\n", + inum, ino)); + return ino; + } + } + DPRINTK(("autofs_ihash_find: didn't find %ld\n", inum)); + return NULL; +} + +void autofs4_ihash_nuke(struct autofs_inohash *ih) +{ + struct list_head *tmp = ih->head.next; + struct list_head *next; + + for(; tmp != &ih->head; tmp = next) { + struct autofs_info *ino; + + next = tmp->next; + + ino = list_entry(tmp, struct autofs_info, ino_hash); + + DPRINTK(("autofs_ihash_nuke: nuking %ld\n", ino->ino)); + autofs4_free_ino(ino); + } + INIT_LIST_HEAD(&ih->head); +} + diff -ur --new-file old/linux/fs/autofs4/root.c new/linux/fs/autofs4/root.c --- old/linux/fs/autofs4/root.c Thu Jan 1 01:00:00 1970 +++ new/linux/fs/autofs4/root.c Tue Jan 25 20:45:02 2000 @@ -0,0 +1,624 @@ +/* -*- linux-c -*- --------------------------------------------------------- * + * + * linux/fs/autofs/root.c + * + * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved + * Copyright 1999 Jeremy Fitzhardinge + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * ------------------------------------------------------------------------- */ + +#include +#include +#include +#include "autofs_i.h" + +static int autofs4_dir_readdir(struct file *,void *,filldir_t); +static struct dentry *autofs4_dir_lookup(struct inode *,struct dentry *); +static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *); +static int autofs4_dir_unlink(struct inode *,struct dentry *); +static int autofs4_dir_rmdir(struct inode *,struct dentry *); +static int autofs4_dir_mkdir(struct inode *,struct dentry *,int); +static int autofs4_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long); +static struct dentry *autofs4_root_lookup(struct inode *,struct dentry *); + +static struct file_operations autofs4_root_operations = { + readdir: autofs4_dir_readdir, /* readdir */ + ioctl: autofs4_root_ioctl, /* ioctl */ +}; + +struct inode_operations autofs4_root_inode_operations = { + &autofs4_root_operations, /* file operations */ + + lookup: autofs4_root_lookup, /* lookup */ + unlink: autofs4_dir_unlink, /* unlink */ + symlink: autofs4_dir_symlink, /* symlink */ + mkdir: autofs4_dir_mkdir, /* mkdir */ + rmdir: autofs4_dir_rmdir, /* rmdir */ +}; + +static struct file_operations autofs4_dir_operations = { + readdir: autofs4_dir_readdir, /* readdir */ +}; + +struct inode_operations autofs4_dir_inode_operations = { + &autofs4_dir_operations, /* file operations */ + + lookup: autofs4_dir_lookup, /* lookup */ + unlink: autofs4_dir_unlink, /* unlink */ + symlink: autofs4_dir_symlink, /* symlink */ + mkdir: autofs4_dir_mkdir, /* mkdir */ + rmdir: autofs4_dir_rmdir, /* rmdir */ +}; + +static inline struct dentry *nth_child(struct dentry *dir, int nr) +{ + struct list_head *tmp = dir->d_subdirs.next; + + while(tmp != &dir->d_subdirs) { + if (nr-- == 0) + return list_entry(tmp, struct dentry, d_child); + tmp = tmp->next; + } + return NULL; +} + +static int autofs4_dir_readdir(struct file *filp, void *dirent, + filldir_t filldir) +{ + struct autofs_sb_info *sbi; + struct autofs_info *ino; + struct dentry *dentry = filp->f_dentry; + struct dentry *dent_ptr; + struct inode *dir = dentry->d_inode; + struct list_head *cursor; + off_t nr; + + sbi = autofs4_sbi(dir->i_sb); + ino = autofs4_dentry_ino(dentry); + nr = filp->f_pos; + + switch(nr) + { + case 0: + if (filldir(dirent, ".", 1, nr, dir->i_ino) < 0) + return 0; + filp->f_pos = ++nr; + /* fall through */ + case 1: + if (filldir(dirent, "..", 2, nr, dentry->d_covers->d_parent->d_inode->i_ino) < 0) + return 0; + filp->f_pos = ++nr; + /* fall through */ + default: + dent_ptr = nth_child(dentry, nr-2); + if (dent_ptr == NULL) + break; + + cursor = &dent_ptr->d_child; + + while(cursor != &dentry->d_subdirs) { + dent_ptr = list_entry(cursor, struct dentry, d_child); + if (dent_ptr->d_inode && + filldir(dirent, dent_ptr->d_name.name, dent_ptr->d_name.len, nr, + dent_ptr->d_inode->i_ino) < 0) + return 0; + filp->f_pos = ++nr; + cursor = cursor->next; + } + break; + } + + return 0; +} + +/* Update usage from here to top of tree, so that scan of + top-level directories will give a useful result */ +static void autofs4_update_usage(struct dentry *dentry) +{ + struct dentry *top = dentry->d_sb->s_root; + + for(; dentry != top; dentry = dentry->d_parent) { + struct autofs_info *ino = autofs4_dentry_ino(dentry->d_covers); + + if (ino) { + update_atime(dentry->d_inode); + ino->last_used = jiffies; + } + } +} + +static int try_to_fill_dentry(struct dentry *dentry, + struct super_block *sb, + struct autofs_sb_info *sbi) +{ + struct autofs_info *de_info = autofs4_dentry_ino(dentry); + int status = 0; + + /* Block on any pending expiry here; invalidate the dentry + when expiration is done to trigger mount request with a new + dentry */ + if (de_info && (de_info->flags & AUTOFS_INF_EXPIRING)) { + DPRINTK(("try_to_fill_entry: waiting for expire %p name=%.*s, flags&PENDING=%s de_info=%p de_info->flags=%x\n", + dentry, dentry->d_name.len, dentry->d_name.name, + dentry->d_flags & DCACHE_AUTOFS_PENDING?"t":"f", + de_info, de_info?de_info->flags:0)); + status = autofs4_wait(sbi, &dentry->d_name, NFY_NONE); + + DPRINTK(("try_to_fill_entry: expire done status=%d\n", status)); + + return 0; + } + + DPRINTK(("try_to_fill_entry: dentry=%p %.*s ino=%p\n", + dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode)); + + /* Wait for a pending mount, triggering one if there isn't one already */ + while(dentry->d_inode == NULL) { + DPRINTK(("try_to_fill_entry: waiting for mount name=%.*s, de_info=%p de_info->flags=%x\n", + dentry->d_name.len, dentry->d_name.name, + de_info, de_info?de_info->flags:0)); + status = autofs4_wait(sbi, &dentry->d_name, NFY_MOUNT); + + DPRINTK(("try_to_fill_entry: mount done status=%d\n", status)); + + if (status && dentry->d_inode) + return 0; /* Try to get the kernel to invalidate this dentry */ + + /* Turn this into a real negative dentry? */ + if (status == -ENOENT) { + dentry->d_time = jiffies + AUTOFS_NEGATIVE_TIMEOUT; + dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; + return 1; + } else if (status) { + /* Return a negative dentry, but leave it "pending" */ + return 1; + } + status = autofs4_wait(sbi, &dentry->d_name, NFY_MOUNT); + } + + /* If this is an unused directory that isn't a mount point, + bitch at the daemon and fix it in user space */ + if (S_ISDIR(dentry->d_inode->i_mode) && + dentry->d_mounts == dentry && + list_empty(&dentry->d_subdirs)) { + DPRINTK(("try_to_fill_entry: mounting existing dir\n")); + return autofs4_wait(sbi, &dentry->d_name, NFY_MOUNT) == 0; + } + + /* We don't update the usages for the autofs daemon itself, this + is necessary for recursive autofs mounts */ + if (!autofs4_oz_mode(sbi)) + autofs4_update_usage(dentry); + + dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; + return 1; +} + + +/* + * Revalidate is called on every cache lookup. Some of those + * cache lookups may actually happen while the dentry is not + * yet completely filled in, and revalidate has to delay such + * lookups.. + */ +static int autofs4_root_revalidate(struct dentry * dentry, int flags) +{ + struct inode * dir = dentry->d_parent->d_inode; + struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); + struct autofs_info *ino; + int oz_mode = autofs4_oz_mode(sbi); + + /* Pending dentry */ + if (autofs4_ispending(dentry)) { + if (autofs4_oz_mode(sbi)) + return 1; + else + return try_to_fill_dentry(dentry, dir->i_sb, sbi); + } + + /* Negative dentry.. invalidate if "old" */ + if (dentry->d_inode == NULL) + return (dentry->d_time - jiffies <= AUTOFS_NEGATIVE_TIMEOUT); + + ino = autofs4_dentry_ino(dentry); + + /* Check for a non-mountpoint directory with no contents */ + if (S_ISDIR(dentry->d_inode->i_mode) && + dentry->d_mounts == dentry && + list_empty(&dentry->d_subdirs)) { + DPRINTK(("autofs_root_revalidate: dentry=%p %.*s, emptydir\n", + dentry, dentry->d_name.len, dentry->d_name.name)); + if (autofs4_oz_mode(sbi)) + return 1; + else + return try_to_fill_dentry(dentry, dir->i_sb, sbi); + } + + /* Update the usage list */ + if (!oz_mode) + autofs4_update_usage(dentry); + + return 1; +} + +static int autofs4_revalidate(struct dentry *dentry, int flags) +{ + struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); + + if (!autofs4_oz_mode(sbi)) + autofs4_update_usage(dentry); + + return 1; +} + +static void autofs4_dentry_release(struct dentry *de) +{ + struct autofs_info *inf = autofs4_dentry_ino(de); + + DPRINTK(("autofs4_dentry_release: releasing %p\n", de)); + + de->d_fsdata = NULL; + if (inf) { + inf->dentry = NULL; + inf->inode = NULL; + + autofs4_free_ino(inf); + } +} + +/* For dentries of directories in the root dir */ +static struct dentry_operations autofs4_root_dentry_operations = { + d_revalidate: autofs4_root_revalidate, /* d_revalidate */ + d_release: autofs4_dentry_release, +}; + +/* For other dentries */ +static struct dentry_operations autofs4_dentry_operations = { + d_revalidate: autofs4_revalidate, /* d_revalidate */ + d_release: autofs4_dentry_release, +}; + +/* Lookups in non-root dirs never find anything - if it's there, it's + already in the dcache */ +static struct dentry *autofs4_dir_lookup(struct inode *dir, struct dentry *dentry) +{ +#if 0 + DPRINTK(("autofs_dir_lookup: ignoring lookup of %.*s/%.*s\n", + dentry->d_parent->d_name.len, dentry->d_parent->d_name.name, + dentry->d_name.len, dentry->d_name.name)); +#endif + + dentry->d_fsdata = NULL; + d_add(dentry, NULL); + return NULL; +} + +/* Lookups in the root directory */ +static struct dentry *autofs4_root_lookup(struct inode *dir, struct dentry *dentry) +{ + struct autofs_sb_info *sbi; + int oz_mode; + + DPRINTK(("autofs_root_lookup: name = %.*s\n", + dentry->d_name.len, dentry->d_name.name)); + + if (dentry->d_name.len > NAME_MAX) + return ERR_PTR(-ENOENT);/* File name too long to exist */ + + sbi = autofs4_sbi(dir->i_sb); + + oz_mode = autofs4_oz_mode(sbi); + DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n", + current->pid, current->pgrp, sbi->catatonic, oz_mode)); + + /* + * Mark the dentry incomplete, but add it. This is needed so + * that the VFS layer knows about the dentry, and we can count + * on catching any lookups through the revalidate. + * + * Let all the hard work be done by the revalidate function that + * needs to be able to do this anyway.. + * + * We need to do this before we release the directory semaphore. + */ + if (dir->i_ino == AUTOFS_ROOT_INO) + dentry->d_op = &autofs4_root_dentry_operations; + else + dentry->d_op = &autofs4_dentry_operations; + + dentry->d_flags |= DCACHE_AUTOFS_PENDING; + dentry->d_fsdata = NULL; + d_add(dentry, NULL); + + if (dentry->d_op && dentry->d_op->d_revalidate) { + up(&dir->i_sem); + (dentry->d_op->d_revalidate)(dentry, 0); + down(&dir->i_sem); + } + + /* + * If we are still pending, check if we had to handle + * a signal. If so we can force a restart.. + */ + if (dentry->d_flags & DCACHE_AUTOFS_PENDING) { + if (signal_pending(current)) + return ERR_PTR(-ERESTARTNOINTR); + } + + /* + * If this dentry is unhashed, then we shouldn't honour this + * lookup even if the dentry is positive. Returning ENOENT here + * doesn't do the right thing for all system calls, but it should + * be OK for the operations we permit from an autofs. + */ + if ( dentry->d_inode && list_empty(&dentry->d_hash) ) + return ERR_PTR(-ENOENT); + + return NULL; +} + +static int autofs4_dir_symlink(struct inode *dir, + struct dentry *dentry, + const char *symname) +{ + struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); + struct autofs_info *ino = autofs4_dentry_ino(dentry); + struct inode *inode; + char *cp; + + DPRINTK(("autofs_dir_symlink: %s <- %.*s\n", symname, + dentry->d_name.len, dentry->d_name.name)); + + if (!S_ISDIR(dir->i_mode)) + return -ENOTDIR; + + if (!autofs4_oz_mode(sbi)) + return -EACCES; + + if (dentry->d_name.len > NAME_MAX) + return -ENAMETOOLONG; + + if (dentry->d_inode != NULL) + return -EEXIST; + + ino = autofs4_init_ino(ino, sbi, S_IFLNK | 0555); + if (ino == NULL) + return -ENOSPC; + + ino->size = strlen(symname); + ino->u.symlink = cp = kmalloc(ino->size + 1, GFP_KERNEL); + + if (cp == NULL) { + kfree(ino); + return -ENOSPC; + } + + strcpy(cp, symname); + + autofs4_ihash_insert(&sbi->ihash, ino); + inode = iget(dir->i_sb,ino->ino); + d_instantiate(dentry, inode); + + if (dir->i_ino == AUTOFS_ROOT_INO) + dentry->d_op = &autofs4_root_dentry_operations; + else + dentry->d_op = &autofs4_dentry_operations; + + dentry->d_fsdata = ino; + ino->dentry = dget(dentry); + ino->inode = inode; + + dir->i_mtime = CURRENT_TIME; + + return 0; +} + +/* + * NOTE! + * + * Normal filesystems would do a "d_delete()" to tell the VFS dcache + * that the file no longer exists. However, doing that means that the + * VFS layer can turn the dentry into a negative dentry. We don't want + * this, because since the unlink is probably the result of an expire. + * We simply d_drop it, which allows the dentry lookup to remount it + * if necessary. + * + * If a process is blocked on the dentry waiting for the expire to finish, + * it will invalidate the dentry and try to mount with a new one. + * + * Also see autofs_dir_rmdir().. + */ +static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry) +{ + struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); + struct autofs_info *ino = autofs4_dentry_ino(dentry); + + if (!S_ISDIR(dir->i_mode)) + return -ENOTDIR; + + if (dentry->d_inode == NULL) + return -ENOENT; + + /* This allows root to remove symlinks */ + if ( !autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) ) + return -EACCES; + + dput(ino->dentry); + + dentry->d_inode->i_size = 0; + dentry->d_inode->i_nlink = 0; + + dir->i_mtime = CURRENT_TIME; + + DPRINTK(("autofs_dir_unlink: unlinking %p %.*s, count=%d\n", + dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count)); + + d_drop(dentry); + + return 0; +} + +static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry) +{ + struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); + struct autofs_info *ino = autofs4_dentry_ino(dentry); + + if (!S_ISDIR(dir->i_mode)) + return -ENOTDIR; + + if (dentry->d_inode == NULL) + return -ENOENT; + + if (!autofs4_oz_mode(sbi)) + return -EACCES; + + if (!list_empty(&dentry->d_subdirs)) + return -ENOTEMPTY; + + dput(ino->dentry); + + dentry->d_inode->i_size = 0; + dentry->d_inode->i_nlink = 0; + + if (dir->i_nlink) + dir->i_nlink--; + + DPRINTK(("autofs_dir_rmdir: rmdir %p %.*s, count=%d\n", + dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count)); + + d_drop(dentry); + + return 0; +} + + + +static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode) +{ + struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); + struct autofs_info *ino = autofs4_dentry_ino(dentry); + struct inode *inode; + + if (!S_ISDIR(dir->i_mode)) + return -ENOTDIR; + + if ( !autofs4_oz_mode(sbi) ) + return -EACCES; + + if ( dentry->d_inode != NULL ) + return -EEXIST; + + if ( dentry->d_name.len > NAME_MAX ) + return -ENAMETOOLONG; + + DPRINTK(("autofs_dir_mkdir: dentry %p, creating %.*s\n", + dentry, dentry->d_name.len, dentry->d_name.name)); + + ino = autofs4_init_ino(ino, sbi, S_IFDIR | 0555); + if (ino == NULL) + return -ENOSPC; + + autofs4_ihash_insert(&sbi->ihash, ino); + + inode = iget(dir->i_sb, ino->ino); + d_instantiate(dentry, inode); + + if (dir->i_ino == AUTOFS_ROOT_INO) + dentry->d_op = &autofs4_root_dentry_operations; + else + dentry->d_op = &autofs4_dentry_operations; + + dentry->d_fsdata = ino; + ino->dentry = dget(dentry); + ino->inode = inode; + dir->i_nlink++; + dir->i_mtime = CURRENT_TIME; + + return 0; +} + +/* Get/set timeout ioctl() operation */ +static inline int autofs4_get_set_timeout(struct autofs_sb_info *sbi, + unsigned long *p) +{ + int rv; + unsigned long ntimeout; + + if ( (rv = get_user(ntimeout, p)) || + (rv = put_user(sbi->exp_timeout/HZ, p)) ) + return rv; + + if ( ntimeout > ULONG_MAX/HZ ) + sbi->exp_timeout = 0; + else + sbi->exp_timeout = ntimeout * HZ; + + return 0; +} + +/* Return protocol version */ +static inline int autofs4_get_protover(struct autofs_sb_info *sbi, int *p) +{ + return put_user(sbi->version, p); +} + +/* Identify autofs_dentries - this is so we can tell if there's + an extra dentry refcount or not. We only hold a refcount on the + dentry if its non-negative (ie, d_inode != NULL) +*/ +int is_autofs4_dentry(struct dentry *dentry) +{ + return dentry && dentry->d_inode && + (dentry->d_op == &autofs4_root_dentry_operations || + dentry->d_op == &autofs4_dentry_operations) && + dentry->d_fsdata != NULL; +} + +/* + * ioctl()'s on the root directory is the chief method for the daemon to + * generate kernel reactions + */ +static int autofs4_root_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct autofs_sb_info *sbi = autofs4_sbi(inode->i_sb); + + DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n", + cmd,arg,sbi,current->pgrp)); + + if ( _IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) || + _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT ) + return -ENOTTY; + + if ( !autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) ) + return -EPERM; + + switch(cmd) { + case AUTOFS_IOC_READY: /* Wait queue: go ahead and retry */ + return autofs4_wait_release(sbi,(autofs_wqt_t)arg,0); + case AUTOFS_IOC_FAIL: /* Wait queue: fail with ENOENT */ + return autofs4_wait_release(sbi,(autofs_wqt_t)arg,-ENOENT); + case AUTOFS_IOC_CATATONIC: /* Enter catatonic mode (daemon shutdown) */ + autofs4_catatonic_mode(sbi); + return 0; + case AUTOFS_IOC_PROTOVER: /* Get protocol version */ + return autofs4_get_protover(sbi, (int *)arg); + case AUTOFS_IOC_SETTIMEOUT: + return autofs4_get_set_timeout(sbi,(unsigned long *)arg); + + /* return a single thing to expire */ + case AUTOFS_IOC_EXPIRE: + return autofs4_expire_run(inode->i_sb,sbi, + (struct autofs_packet_expire *)arg); + /* same as above, but can send multiple expires through pipe */ + case AUTOFS_IOC_EXPIRE_MULTI: + return autofs4_expire_multi(inode->i_sb, sbi, (int *)arg); + + default: + return -ENOSYS; + } +} diff -ur --new-file old/linux/fs/autofs4/symlink.c new/linux/fs/autofs4/symlink.c --- old/linux/fs/autofs4/symlink.c Thu Jan 1 01:00:00 1970 +++ new/linux/fs/autofs4/symlink.c Tue Jan 25 20:45:02 2000 @@ -0,0 +1,34 @@ +/* -*- linux-c -*- --------------------------------------------------------- * + * + * linux/fs/autofs/symlink.c + * + * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * ------------------------------------------------------------------------- */ + +#include "autofs_i.h" + +static int autofs4_readlink(struct dentry *dentry, char *buffer, int buflen) +{ + struct autofs_info *ino = autofs4_dentry_ino(dentry); + + return vfs_readlink(dentry, buffer, buflen, ino->u.symlink); +} + +static struct dentry * autofs4_follow_link(struct dentry *dentry, + struct dentry *base, + unsigned int flags) +{ + struct autofs_info *ino = autofs4_dentry_ino(dentry); + + return vfs_follow_link(dentry, base, flags, ino->u.symlink); +} + +struct inode_operations autofs4_symlink_inode_operations = { + readlink: autofs4_readlink, + follow_link: autofs4_follow_link +}; diff -ur --new-file old/linux/fs/autofs4/waitq.c new/linux/fs/autofs4/waitq.c --- old/linux/fs/autofs4/waitq.c Thu Jan 1 01:00:00 1970 +++ new/linux/fs/autofs4/waitq.c Tue Jan 25 20:45:02 2000 @@ -0,0 +1,251 @@ +/* -*- linux-c -*- --------------------------------------------------------- * + * + * linux/fs/autofs/waitq.c + * + * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * ------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "autofs_i.h" + +/* We make this a static variable rather than a part of the superblock; it + is better if we don't reassign numbers easily even across filesystems */ +static autofs_wqt_t autofs4_next_wait_queue = 1; + +/* These are the signals we allow interrupting a pending mount */ +#define SHUTDOWN_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGQUIT)) + +void autofs4_catatonic_mode(struct autofs_sb_info *sbi) +{ + struct autofs_wait_queue *wq, *nwq; + + DPRINTK(("autofs: entering catatonic mode\n")); + + sbi->catatonic = 1; + wq = sbi->queues; + sbi->queues = NULL; /* Erase all wait queues */ + while ( wq ) { + nwq = wq->next; + wq->status = -ENOENT; /* Magic is gone - report failure */ + kfree(wq->name); + wq->name = NULL; + wake_up(&wq->queue); + wq = nwq; + } + if (sbi->pipe) { + fput(sbi->pipe); /* Close the pipe */ + sbi->pipe = NULL; + } + + autofs4_ihash_nuke(&sbi->ihash); + shrink_dcache_sb(sbi->sb); +} + +static int autofs4_write(struct file *file, const void *addr, int bytes) +{ + unsigned long sigpipe, flags; + mm_segment_t fs; + const char *data = (const char *)addr; + ssize_t wr = 0; + + /** WARNING: this is not safe for writing more than PIPE_BUF bytes! **/ + + sigpipe = sigismember(¤t->signal, SIGPIPE); + + /* Save pointer to user space and point back to kernel space */ + fs = get_fs(); + set_fs(KERNEL_DS); + + while (bytes && + (wr = file->f_op->write(file,data,bytes,&file->f_pos)) > 0) { + data += wr; + bytes -= wr; + } + + set_fs(fs); + + /* Keep the currently executing process from receiving a + SIGPIPE unless it was already supposed to get one */ + if (wr == -EPIPE && !sigpipe) { + spin_lock_irqsave(¤t->sigmask_lock, flags); + sigdelset(¤t->signal, SIGPIPE); + recalc_sigpending(current); + spin_unlock_irqrestore(¤t->sigmask_lock, flags); + } + + return (bytes > 0); +} + +static void autofs4_notify_daemon(struct autofs_sb_info *sbi, + struct autofs_wait_queue *wq, + enum autofs_packet_type type) +{ + union autofs_packet_union pkt; + size_t pktsz; + + DPRINTK(("autofs_notify: wait id = 0x%08lx, name = %.*s, type=%d\n", + wq->wait_queue_token, wq->len, wq->name, type)); + + memset(&pkt,0,sizeof pkt); /* For security reasons */ + + pkt.hdr.proto_version = sbi->version; + pkt.hdr.type = type; + if (type == autofs_ptype_missing) { + struct autofs_packet_missing *mp = &pkt.missing; + + pktsz = sizeof(*mp); + + mp->wait_queue_token = wq->wait_queue_token; + mp->len = wq->len; + memcpy(mp->name, wq->name, wq->len); + mp->name[wq->len] = '\0'; + } else if (type == autofs_ptype_expire_multi) { + struct autofs_packet_expire_multi *ep = &pkt.expire_multi; + + pktsz = sizeof(*ep); + + ep->wait_queue_token = wq->wait_queue_token; + ep->len = wq->len; + memcpy(ep->name, wq->name, wq->len); + ep->name[wq->len] = '\0'; + } else { + printk("autofs_notify_daemon: bad type %d!\n", type); + return; + } + + if (autofs4_write(sbi->pipe, &pkt, pktsz)) + autofs4_catatonic_mode(sbi); +} + +int autofs4_wait(struct autofs_sb_info *sbi, struct qstr *name, + enum autofs_notify notify) +{ + struct autofs_wait_queue *wq; + int status; + + /* In catatonic mode, we don't wait for nobody */ + if ( sbi->catatonic ) + return -ENOENT; + + /* We shouldn't be able to get here, but just in case */ + if ( name->len > NAME_MAX ) + return -ENOENT; + + for ( wq = sbi->queues ; wq ; wq = wq->next ) { + if ( wq->hash == name->hash && + wq->len == name->len && + wq->name && !memcmp(wq->name,name->name,name->len) ) + break; + } + + if ( !wq ) { + /* Create a new wait queue */ + wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL); + if ( !wq ) + return -ENOMEM; + + wq->name = kmalloc(name->len,GFP_KERNEL); + if ( !wq->name ) { + kfree(wq); + return -ENOMEM; + } + wq->wait_queue_token = autofs4_next_wait_queue; + if (++autofs4_next_wait_queue == 0) + autofs4_next_wait_queue = 1; + init_waitqueue_head(&wq->queue); + wq->hash = name->hash; + wq->len = name->len; + wq->status = -EINTR; /* Status return if interrupted */ + memcpy(wq->name, name->name, name->len); + wq->next = sbi->queues; + sbi->queues = wq; + + DPRINTK(("autofs_wait: new wait id = 0x%08lx, name = %.*s, nfy=%d\n", + wq->wait_queue_token, wq->len, wq->name, notify)); + /* autofs4_notify_daemon() may block */ + wq->wait_ctr = 2; + if (notify != NFY_NONE) { + autofs4_notify_daemon(sbi,wq, + notify == NFY_MOUNT ? autofs_ptype_missing : + autofs_ptype_expire_multi); + } + } else { + wq->wait_ctr++; + DPRINTK(("autofs_wait: existing wait id = 0x%08lx, name = %.*s, nfy=%d\n", + wq->wait_queue_token, wq->len, wq->name, notify)); + } + + /* wq->name is NULL if and only if the lock is already released */ + + if ( sbi->catatonic ) { + /* We might have slept, so check again for catatonic mode */ + wq->status = -ENOENT; + if ( wq->name ) { + kfree(wq->name); + wq->name = NULL; + } + } + + if ( wq->name ) { + /* Block all but "shutdown" signals while waiting */ + sigset_t oldset; + unsigned long irqflags; + + spin_lock_irqsave(¤t->sigmask_lock, irqflags); + oldset = current->blocked; + siginitsetinv(¤t->blocked, SHUTDOWN_SIGS & ~oldset.sig[0]); + recalc_sigpending(current); + spin_unlock_irqrestore(¤t->sigmask_lock, irqflags); + + interruptible_sleep_on(&wq->queue); + + spin_lock_irqsave(¤t->sigmask_lock, irqflags); + current->blocked = oldset; + recalc_sigpending(current); + spin_unlock_irqrestore(¤t->sigmask_lock, irqflags); + } else { + DPRINTK(("autofs_wait: skipped sleeping\n")); + } + + status = wq->status; + + if (--wq->wait_ctr == 0) /* Are we the last process to need status? */ + kfree(wq); + + return status; +} + + +int autofs4_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_token, int status) +{ + struct autofs_wait_queue *wq, **wql; + + for ( wql = &sbi->queues ; (wq = *wql) ; wql = &wq->next ) { + if ( wq->wait_queue_token == wait_queue_token ) + break; + } + if ( !wq ) + return -EINVAL; + + *wql = wq->next; /* Unlink from chain */ + kfree(wq->name); + wq->name = NULL; /* Do not wait on this queue */ + + wq->status = status; + + if (--wq->wait_ctr == 0) /* Is anyone still waiting for this guy? */ + kfree(wq); + else + wake_up(&wq->queue); + + return 0; +} + diff -ur --new-file old/linux/fs/block_dev.c new/linux/fs/block_dev.c --- old/linux/fs/block_dev.c Mon Jan 10 01:51:37 2000 +++ new/linux/fs/block_dev.c Mon Jan 24 20:04:37 2000 @@ -652,7 +652,7 @@ &def_blk_fops, /* default file operations */ }; -char * bdevname(kdev_t dev) +const char * bdevname(kdev_t dev) { static char buffer[32]; const char * name = blkdevs[MAJOR(dev)].name; diff -ur --new-file old/linux/fs/dcache.c new/linux/fs/dcache.c --- old/linux/fs/dcache.c Fri Jan 7 01:21:23 2000 +++ new/linux/fs/dcache.c Wed Jan 26 22:17:52 2000 @@ -412,20 +412,18 @@ */ int shrink_dcache_memory(int priority, unsigned int gfp_mask, zone_t * zone) { - if (gfp_mask & __GFP_IO) { - int count = 0; - lock_kernel(); - if (priority) - count = dentry_stat.nr_unused / priority; - prune_dcache(count); - unlock_kernel(); - /* FIXME: kmem_cache_shrink here should tell us - the number of pages freed, and it should - work in a __GFP_DMA/__GFP_HIGHMEM behaviour - to free only the interesting pages in - function of the needs of the current allocation. */ - kmem_cache_shrink(dentry_cache); - } + int count = 0; + lock_kernel(); + if (priority) + count = dentry_stat.nr_unused / priority; + prune_dcache(count); + unlock_kernel(); + /* FIXME: kmem_cache_shrink here should tell us + the number of pages freed, and it should + work in a __GFP_DMA/__GFP_HIGHMEM behaviour + to free only the interesting pages in + function of the needs of the current allocation. */ + kmem_cache_shrink(dentry_cache); return 0; } diff -ur --new-file old/linux/fs/devices.c new/linux/fs/devices.c --- old/linux/fs/devices.c Thu Jan 6 19:14:36 2000 +++ new/linux/fs/devices.c Mon Jan 24 20:04:37 2000 @@ -168,14 +168,14 @@ * Print device name (in decimal, hexadecimal or symbolic) * Note: returns pointer to static data! */ -char * kdevname(kdev_t dev) +const char * kdevname(kdev_t dev) { static char buffer[32]; sprintf(buffer, "%02x:%02x", MAJOR(dev), MINOR(dev)); return buffer; } -char * cdevname(kdev_t dev) +const char * cdevname(kdev_t dev) { static char buffer[32]; const char * name = chrdevs[MAJOR(dev)].name; diff -ur --new-file old/linux/fs/dquot.c new/linux/fs/dquot.c --- old/linux/fs/dquot.c Tue Dec 7 02:09:28 1999 +++ new/linux/fs/dquot.c Wed Jan 26 21:32:01 2000 @@ -797,17 +797,22 @@ return 0; } -static void print_warning(struct dquot *dquot, int flag, char *fmtstr, ...) +static void print_warning(struct dquot *dquot, int flag, const char *fmtstr) { - va_list args; + struct dentry *root; + char *path, *buffer; if (!need_print_warning(dquot, flag)) return; - va_start(args, fmtstr); - vsprintf(quotamessage, fmtstr, args); - va_end(args); + root = dquot->dq_mnt->mnt_sb->s_root; + dget(root); + buffer = (char *) __get_free_page(GFP_KERNEL); + path = buffer ? d_path(root, buffer, PAGE_SIZE) : "?"; + sprintf(quotamessage, fmtstr, path, quotatypes[dquot->dq_type]); + free_page((unsigned long) buffer); tty_write_message(current->tty, quotamessage); dquot->dq_flags |= flag; + dput(root); } static inline char ignore_hardlimit(struct dquot *dquot) @@ -817,16 +822,13 @@ static int check_idq(struct dquot *dquot, u_long inodes) { - short type = dquot->dq_type; - if (inodes <= 0 || dquot->dq_flags & DQ_FAKE) return QUOTA_OK; if (dquot->dq_ihardlimit && (dquot->dq_curinodes + inodes) > dquot->dq_ihardlimit && !ignore_hardlimit(dquot)) { - print_warning(dquot, DQ_INODES, "%s: write failed, %s file limit reached\n", - dquot->dq_mnt->mnt_dirname, quotatypes[type]); + print_warning(dquot, DQ_INODES, "%s: write failed, %s file limit reached\n"); return NO_QUOTA; } @@ -834,17 +836,15 @@ (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit && dquot->dq_itime && CURRENT_TIME >= dquot->dq_itime && !ignore_hardlimit(dquot)) { - print_warning(dquot, DQ_INODES, "%s: warning, %s file quota exceeded too long.\n", - dquot->dq_mnt->mnt_dirname, quotatypes[type]); + print_warning(dquot, DQ_INODES, "%s: warning, %s file quota exceeded too long.\n"); return NO_QUOTA; } if (dquot->dq_isoftlimit && (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit && dquot->dq_itime == 0) { - print_warning(dquot, 0, "%s: warning, %s file quota exceeded\n", - dquot->dq_mnt->mnt_dirname, quotatypes[type]); - dquot->dq_itime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.inode_expire[type]; + print_warning(dquot, 0, "%s: warning, %s file quota exceeded\n"); + dquot->dq_itime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.inode_expire[dquot->dq_type]; } return QUOTA_OK; @@ -852,8 +852,6 @@ static int check_bdq(struct dquot *dquot, u_long blocks, char prealloc) { - short type = dquot->dq_type; - if (blocks <= 0 || dquot->dq_flags & DQ_FAKE) return QUOTA_OK; @@ -861,8 +859,7 @@ (dquot->dq_curblocks + blocks) > dquot->dq_bhardlimit && !ignore_hardlimit(dquot)) { if (!prealloc) - print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk limit reached.\n", - dquot->dq_mnt->mnt_dirname, quotatypes[type]); + print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk limit reached.\n"); return NO_QUOTA; } @@ -871,8 +868,7 @@ dquot->dq_btime && CURRENT_TIME >= dquot->dq_btime && !ignore_hardlimit(dquot)) { if (!prealloc) - print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk quota exceeded too long.\n", - dquot->dq_mnt->mnt_dirname, quotatypes[type]); + print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk quota exceeded too long.\n"); return NO_QUOTA; } @@ -880,9 +876,8 @@ (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit && dquot->dq_btime == 0) { if (!prealloc) { - print_warning(dquot, 0, "%s: warning, %s disk quota exceeded\n", - dquot->dq_mnt->mnt_dirname, quotatypes[type]); - dquot->dq_btime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.block_expire[type]; + print_warning(dquot, 0, "%s: warning, %s disk quota exceeded\n"); + dquot->dq_btime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.block_expire[dquot->dq_type]; } else /* diff -ur --new-file old/linux/fs/ext2/namei.c new/linux/fs/ext2/namei.c --- old/linux/fs/ext2/namei.c Thu Jan 20 19:48:35 2000 +++ new/linux/fs/ext2/namei.c Sat Jan 22 20:16:29 2000 @@ -345,18 +345,20 @@ umode_t mode) { if (!EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE)) return; - if (S_ISCHR(mode)) + if (S_ISREG(mode)) + de->file_type = EXT2_FT_REG_FILE; + else if (S_ISDIR(mode)) + de->file_type = EXT2_FT_DIR; + else if (S_ISLNK(mode)) + de->file_type = EXT2_FT_SYMLINK; + else if (S_ISSOCK(mode)) + de->file_type = EXT2_FT_SOCK; + else if (S_ISFIFO(mode)) + de->file_type = EXT2_FT_FIFO; + else if (S_ISCHR(mode)) de->file_type = EXT2_FT_CHRDEV; else if (S_ISBLK(mode)) de->file_type = EXT2_FT_BLKDEV; - else if (S_ISFIFO(mode)) - de->file_type = EXT2_FT_FIFO; - else if (S_ISLNK(mode)) - de->file_type = EXT2_FT_SYMLINK; - else if (S_ISREG(mode)) - de->file_type = EXT2_FT_REG_FILE; - else if (S_ISDIR(mode)) - de->file_type = EXT2_FT_DIR; } /* diff -ur --new-file old/linux/fs/fat/misc.c new/linux/fs/fat/misc.c --- old/linux/fs/fat/misc.c Mon Aug 30 19:23:14 1999 +++ new/linux/fs/fat/misc.c Tue Jan 25 20:37:21 2000 @@ -338,7 +338,6 @@ month < 2 ? 1 : 0)+3653); /* days since 1.1.70 plus 80's leap day */ secs += sys_tz.tz_minuteswest*60; - if (sys_tz.tz_dsttime) secs -= 3600; return secs; } diff -ur --new-file old/linux/fs/filesystems.c new/linux/fs/filesystems.c --- old/linux/fs/filesystems.c Mon Jan 3 21:01:31 2000 +++ new/linux/fs/filesystems.c Tue Jan 25 23:18:52 2000 @@ -138,10 +138,6 @@ init_efs_fs(); #endif -#ifdef CONFIG_AUTOFS_FS - init_autofs_fs(); -#endif - #ifdef CONFIG_ADFS_FS init_adfs_fs(); #endif diff -ur --new-file old/linux/fs/hpfs/hpfs_fn.h new/linux/fs/hpfs/hpfs_fn.h --- old/linux/fs/hpfs/hpfs_fn.h Mon Dec 13 16:59:51 1999 +++ new/linux/fs/hpfs/hpfs_fn.h Tue Jan 25 20:37:21 2000 @@ -64,13 +64,13 @@ extern inline time_t local_to_gmt(struct super_block *s, time_t t) { extern struct timezone sys_tz; - return t + sys_tz.tz_minuteswest * 60 - (sys_tz.tz_dsttime ? 3600 : 0) +s->s_hpfs_timeshift; + return t + sys_tz.tz_minuteswest * 60 + s->s_hpfs_timeshift; } extern inline time_t gmt_to_local(struct super_block *s, time_t t) { extern struct timezone sys_tz; - return t - sys_tz.tz_minuteswest * 60 + (sys_tz.tz_dsttime ? 3600 : 0) -s->s_hpfs_timeshift; + return t - sys_tz.tz_minuteswest * 60 - s->s_hpfs_timeshift; } /* diff -ur --new-file old/linux/fs/inode.c new/linux/fs/inode.c --- old/linux/fs/inode.c Tue Jan 11 03:15:58 2000 +++ new/linux/fs/inode.c Wed Jan 26 22:17:52 2000 @@ -398,20 +398,17 @@ int shrink_icache_memory(int priority, int gfp_mask, zone_t *zone) { - if (gfp_mask & __GFP_IO) - { - int count = 0; + int count = 0; - if (priority) - count = inodes_stat.nr_unused / priority; - prune_icache(count); - /* FIXME: kmem_cache_shrink here should tell us - the number of pages freed, and it should - work in a __GFP_DMA/__GFP_HIGHMEM behaviour - to free only the interesting pages in - function of the needs of the current allocation. */ - kmem_cache_shrink(inode_cachep); - } + if (priority) + count = inodes_stat.nr_unused / priority; + prune_icache(count); + /* FIXME: kmem_cache_shrink here should tell us + the number of pages freed, and it should + work in a __GFP_DMA/__GFP_HIGHMEM behaviour + to free only the interesting pages in + function of the needs of the current allocation. */ + kmem_cache_shrink(inode_cachep); return 0; } diff -ur --new-file old/linux/fs/isofs/util.c new/linux/fs/isofs/util.c --- old/linux/fs/isofs/util.c Wed Jun 24 23:30:10 1998 +++ new/linux/fs/isofs/util.c Thu Jan 27 21:51:43 2000 @@ -114,7 +114,6 @@ crtime = 0; } else { int monlen[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; - extern struct timezone sys_tz; days = year * 365; if (year > 2) @@ -126,8 +125,6 @@ days += day - 1; crtime = ((((days * 24) + hour) * 60 + minute) * 60) + second; - if (sys_tz.tz_dsttime) - crtime -= 3600; /* sign extend */ if (tz & 0x80) @@ -149,7 +146,7 @@ * NOTE: mkisofs in versions prior to mkisofs-1.10 had * the sign wrong on the timezone offset. This has now * been corrected there too, but if you are getting screwy - * results this may be the explaination. If enough people + * results this may be the explanation. If enough people * complain, a user configuration option could be added * to add the timezone offset in with the wrong sign * for 'compatibility' with older discs, but I cannot see how diff -ur --new-file old/linux/fs/namei.c new/linux/fs/namei.c --- old/linux/fs/namei.c Wed Jan 12 20:51:49 2000 +++ new/linux/fs/namei.c Fri Jan 28 17:00:05 2000 @@ -1341,7 +1341,7 @@ return error; } -int vfs_readlink(struct dentry *dentry, char *buffer, int buflen, char *link) +int vfs_readlink(struct dentry *dentry, char *buffer, int buflen, const char *link) { u32 len; @@ -1359,7 +1359,7 @@ static inline struct dentry * __vfs_follow_link(struct dentry *dentry, struct dentry *base, - unsigned follow, char *link) + unsigned follow, const char *link) { struct dentry *result; UPDATE_ATIME(dentry->d_inode); @@ -1377,7 +1377,7 @@ struct dentry * vfs_follow_link(struct dentry *dentry, struct dentry *base, -unsigned int follow, char *link) +unsigned int follow, const char *link) { return __vfs_follow_link(dentry,base,follow,link); } diff -ur --new-file old/linux/fs/ncpfs/dir.c new/linux/fs/ncpfs/dir.c --- old/linux/fs/ncpfs/dir.c Tue Dec 7 19:21:10 1999 +++ new/linux/fs/ncpfs/dir.c Tue Jan 25 23:09:28 2000 @@ -868,6 +868,7 @@ struct ncp_server *server = NCP_SERVER(dir); struct ncp_entry_info finfo; int error, result, len = dentry->d_name.len + 1; + int opmode; __u8 __name[len]; PPRINTK("ncp_create_new: creating %s/%s, mode=%x\n", @@ -886,15 +887,22 @@ result = ncp_open_create_file_or_subdir(server, dir, __name, OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE, attributes, AR_READ | AR_WRITE, &finfo); - if (!result) { - finfo.access = O_RDWR; - error = ncp_instantiate(dir, dentry, &finfo); - } else { - if (result == 0x87) error = -ENAMETOOLONG; - DPRINTK("ncp_create: %s/%s failed\n", - dentry->d_parent->d_name.name, dentry->d_name.name); + opmode = O_RDWR; + if (result) { + result = ncp_open_create_file_or_subdir(server, dir, __name, + OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE, + attributes, AR_WRITE, &finfo); + if (result) { + if (result == 0x87) + error = -ENAMETOOLONG; + DPRINTK("ncp_create: %s/%s failed\n", + dentry->d_parent->d_name.name, dentry->d_name.name); + goto out; + } + opmode = O_WRONLY; } - + finfo.access = opmode; + error = ncp_instantiate(dir, dentry, &finfo); out: return error; } diff -ur --new-file old/linux/fs/ncpfs/file.c new/linux/fs/ncpfs/file.c --- old/linux/fs/ncpfs/file.c Sun Dec 5 17:42:03 1999 +++ new/linux/fs/ncpfs/file.c Tue Jan 25 23:09:28 2000 @@ -36,9 +36,8 @@ */ int ncp_make_open(struct inode *inode, int right) { - int error, result; + int error; int access; - struct ncp_entry_info finfo; error = -EINVAL; if (!inode) { @@ -53,6 +52,9 @@ error = -EACCES; lock_super(inode->i_sb); if (!NCP_FINFO(inode)->opened) { + struct ncp_entry_info finfo; + int result; + finfo.i.dirEntNum = NCP_FINFO(inode)->dirEntNum; finfo.i.volNumber = NCP_FINFO(inode)->volNumber; /* tries max. rights */ @@ -62,10 +64,21 @@ 0, AR_READ | AR_WRITE, &finfo); if (!result) goto update; - finfo.access = O_RDONLY; - result = ncp_open_create_file_or_subdir(NCP_SERVER(inode), + /* RDWR did not succeeded, try readonly or writeonly as requested */ + switch (right) { + case O_RDONLY: + finfo.access = O_RDONLY; + result = ncp_open_create_file_or_subdir(NCP_SERVER(inode), NULL, NULL, OC_MODE_OPEN, 0, AR_READ, &finfo); + break; + case O_WRONLY: + finfo.access = O_WRONLY; + result = ncp_open_create_file_or_subdir(NCP_SERVER(inode), + NULL, NULL, OC_MODE_OPEN, + 0, AR_WRITE, &finfo); + break; + } if (result) { PPRINTK("ncp_make_open: failed, result=%d\n", result); goto out_unlock; @@ -130,7 +143,7 @@ error = ncp_make_open(inode, O_RDONLY); if (error) { - printk(KERN_ERR "ncp_file_read: open failed, error=%d\n", error); + DPRINTK(KERN_ERR "ncp_file_read: open failed, error=%d\n", error); goto out; } @@ -208,9 +221,9 @@ errno = 0; if (!count) goto out; - errno = ncp_make_open(inode, O_RDWR); + errno = ncp_make_open(inode, O_WRONLY); if (errno) { - printk(KERN_ERR "ncp_file_write: open failed, error=%d\n", errno); + DPRINTK(KERN_ERR "ncp_file_write: open failed, error=%d\n", errno); return errno; } pos = *ppos; diff -ur --new-file old/linux/fs/ncpfs/inode.c new/linux/fs/ncpfs/inode.c --- old/linux/fs/ncpfs/inode.c Sun Jan 16 19:47:19 2000 +++ new/linux/fs/ncpfs/inode.c Tue Jan 25 23:09:28 2000 @@ -683,7 +683,7 @@ DPRINTK("ncpfs: trying to change size to %ld\n", attr->ia_size); - if ((result = ncp_make_open(inode, O_RDWR)) < 0) { + if ((result = ncp_make_open(inode, O_WRONLY)) < 0) { return -EACCES; } ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, diff -ur --new-file old/linux/fs/ncpfs/ioctl.c new/linux/fs/ncpfs/ioctl.c --- old/linux/fs/ncpfs/ioctl.c Sun Jan 16 19:52:45 2000 +++ new/linux/fs/ncpfs/ioctl.c Tue Jan 25 23:09:29 2000 @@ -330,6 +330,7 @@ default: return -EINVAL; } + /* locking needs both read and write access */ if ((result = ncp_make_open(inode, O_RDWR)) != 0) { return result; diff -ur --new-file old/linux/fs/ncpfs/mmap.c new/linux/fs/ncpfs/mmap.c --- old/linux/fs/ncpfs/mmap.c Sat Nov 20 19:09:05 1999 +++ new/linux/fs/ncpfs/mmap.c Mon Jan 24 20:04:37 2000 @@ -92,17 +92,9 @@ return page; } -struct vm_operations_struct ncp_file_mmap = +static struct vm_operations_struct ncp_file_mmap = { - NULL, /* open */ - NULL, /* close */ - NULL, /* unmap */ - NULL, /* protect */ - NULL, /* sync */ - NULL, /* advise */ - ncp_file_mmap_nopage, /* nopage */ - NULL, /* wppage */ - NULL /* swapout */ + nopage: ncp_file_mmap_nopage, }; diff -ur --new-file old/linux/fs/nfs/write.c new/linux/fs/nfs/write.c --- old/linux/fs/nfs/write.c Sun Nov 28 00:51:32 1999 +++ new/linux/fs/nfs/write.c Mon Jan 24 04:48:47 2000 @@ -416,7 +416,9 @@ int nfs_writepage(struct dentry * dentry, struct page *page) { - return nfs_writepage_sync(dentry, dentry->d_inode, page, 0, PAGE_SIZE); + int result = nfs_writepage_sync(dentry, dentry->d_inode, page, 0, PAGE_SIZE); + if ( result == PAGE_SIZE) return 0; + return result; } /* diff -ur --new-file old/linux/fs/nfsd/nfsfh.c new/linux/fs/nfsd/nfsfh.c --- old/linux/fs/nfsd/nfsfh.c Tue Jan 11 23:19:17 2000 +++ new/linux/fs/nfsd/nfsfh.c Wed Jan 26 22:25:58 2000 @@ -494,7 +494,7 @@ error = nfserr_perm; if (!rqstp->rq_secure && EX_SECURE(exp)) { printk(KERN_WARNING - "nfsd: request from insecure port (%08lx:%d)!\n", + "nfsd: request from insecure port (%08x:%d)!\n", ntohl(rqstp->rq_addr.sin_addr.s_addr), ntohs(rqstp->rq_addr.sin_port)); goto out; diff -ur --new-file old/linux/fs/open.c new/linux/fs/open.c --- old/linux/fs/open.c Fri Jan 7 01:17:19 2000 +++ new/linux/fs/open.c Fri Jan 28 17:05:02 2000 @@ -306,11 +306,12 @@ struct dentry * dentry; int old_fsuid, old_fsgid; kernel_cap_t old_cap; - int res = -EINVAL; + int res; + + if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ + return -EINVAL; lock_kernel(); - if (mode != (mode & S_IRWXO)) /* where's F_OK, X_OK, W_OK, R_OK? */ - goto out; old_fsuid = current->fsuid; old_fsgid = current->fsgid; old_cap = current->cap_effective; @@ -337,7 +338,7 @@ current->fsuid = old_fsuid; current->fsgid = old_fsgid; current->cap_effective = old_cap; -out: + unlock_kernel(); return res; } diff -ur --new-file old/linux/fs/partitions/Config.in new/linux/fs/partitions/Config.in --- old/linux/fs/partitions/Config.in Wed Dec 15 05:43:57 1999 +++ new/linux/fs/partitions/Config.in Mon Jan 24 20:21:47 2000 @@ -21,6 +21,8 @@ bool ' Solaris (x86) partition table support' CONFIG_SOLARIS_X86_PARTITION bool ' Unixware slices support' CONFIG_UNIXWARE_DISKLABEL fi + bool 'SGI partition support' CONFIG_SGI_PARTITION + bool 'Sun partition tables support' CONFIG_SUN_PARTITION else if [ "$ARCH" = "alpha" ]; then define_bool CONFIG_OSF_PARTITION y @@ -46,14 +48,10 @@ if [ "$CONFIG_ATARI" = "y" ]; then define_bool CONFIG_ATARI_PARTITION y fi -fi -if [ "$CONFIG_SGI" != "y" ]; then - bool 'SGI partition support' CONFIG_SGI_PARTITION -else - define_bool CONFIG_SGI_PARTITION y -fi -if [ "$ARCH" != "sparc" -a "$ARCH" != "sparc64" ]; then - bool 'Sun partition tables support' CONFIG_SUN_PARTITION -else - define_bool CONFIG_SUN_PARTITION y + if [ "$CONFIG_SGI" = "y" ]; then + define_bool CONFIG_SGI_PARTITION y + fi + if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then + define_bool CONFIG_SUN_PARTITION y + fi fi diff -ur --new-file old/linux/fs/partitions/check.c new/linux/fs/partitions/check.c --- old/linux/fs/partitions/check.c Wed Jan 19 03:54:21 2000 +++ new/linux/fs/partitions/check.c Mon Jan 24 20:04:36 2000 @@ -276,7 +276,6 @@ void register_disk(struct gendisk *gdev, kdev_t dev, unsigned minors, struct block_device_operations *ops, long size) { - unsigned first = (unsigned)dev; if (!gdev) return; grok_partitions(gdev, MINOR(dev)>>gdev->minor_shift, minors, size); diff -ur --new-file old/linux/fs/partitions/sgi.c new/linux/fs/partitions/sgi.c --- old/linux/fs/partitions/sgi.c Thu Aug 12 21:26:06 1999 +++ new/linux/fs/partitions/sgi.c Sat Jan 22 21:31:10 2000 @@ -44,15 +44,15 @@ struct sgi_partition *p; if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) { - printk("Dev %s: unable to read partition table\n", kdevname(dev)); + printk(KERN_WARNING "Dev %s: unable to read partition table\n", kdevname(dev)); return -1; } label = (struct sgi_disklabel *) bh->b_data; p = &label->partitions[0]; magic = label->magic_mushroom; if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) { - printk("Dev %s SGI disklabel: bad magic %08x\n", - kdevname(dev), magic); + /*printk("Dev %s SGI disklabel: bad magic %08x\n", + kdevname(dev), magic);*/ brelse(bh); return 0; } @@ -62,7 +62,7 @@ csum += be32_to_cpu(cs); } if(csum) { - printk("Dev %s SGI disklabel: csum bad, label corrupted\n", + printk(KERN_WARNING "Dev %s SGI disklabel: csum bad, label corrupted\n", kdevname(dev)); brelse(bh); return 0; diff -ur --new-file old/linux/fs/partitions/sun.c new/linux/fs/partitions/sun.c --- old/linux/fs/partitions/sun.c Thu Aug 12 21:26:06 1999 +++ new/linux/fs/partitions/sun.c Sat Jan 22 21:31:10 2000 @@ -48,15 +48,15 @@ unsigned long spc; if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) { - printk("Dev %s: unable to read partition table\n", + printk(KERN_WARNING "Dev %s: unable to read partition table\n", kdevname(dev)); return -1; } label = (struct sun_disklabel *) bh->b_data; p = label->partitions; if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) { - printk("Dev %s Sun disklabel: bad magic %04x\n", - kdevname(dev), be16_to_cpu(label->magic)); +/* printk(KERN_INFO "Dev %s Sun disklabel: bad magic %04x\n", + kdevname(dev), be16_to_cpu(label->magic)); */ brelse(bh); return 0; } diff -ur --new-file old/linux/fs/select.c new/linux/fs/select.c --- old/linux/fs/select.c Tue Aug 31 20:30:48 1999 +++ new/linux/fs/select.c Mon Jan 24 20:44:31 2000 @@ -8,6 +8,10 @@ * COFF/ELF binary emulation. If the process has the STICKY_TIMEOUTS * flag set in its personality we do *not* modify the given timeout * parameter to reflect time remaining. + * + * 24 January 2000 + * Changed sys_poll()/do_poll() to use PAGE_SIZE chunk-based allocation + * of fds to overcome nfds < 16390 descriptors limit (Tigran Aivazian). */ #include @@ -328,39 +332,48 @@ return ret; } -static int do_poll(unsigned int nfds, struct pollfd *fds, poll_table *wait, - long timeout) +#define POLLFD_PER_PAGE ((PAGE_SIZE) / sizeof(struct pollfd)) + +static void do_pollfd(struct pollfd * fdp, poll_table * wait, int *count) +{ + int fd; + unsigned int mask; + + mask = 0; + fd = fdp->fd; + if (fd >= 0) { + struct file * file = fget(fd); + mask = POLLNVAL; + if (file != NULL) { + mask = DEFAULT_POLLMASK; + if (file->f_op && file->f_op->poll) + mask = file->f_op->poll(file, wait); + mask &= fdp->events | POLLERR | POLLHUP; + fput(file); + } + if (mask) { + wait = NULL; + (*count)++; + } + } + fdp->revents = mask; +} + +static int do_poll(unsigned int nfds, unsigned int nchunks, unsigned int nleft, + struct pollfd *fds[], poll_table *wait, long timeout) { int count = 0; for (;;) { - unsigned int j; - struct pollfd * fdpnt; + unsigned int i, j; set_current_state(TASK_INTERRUPTIBLE); - for (fdpnt = fds, j = 0; j < nfds; j++, fdpnt++) { - int fd; - unsigned int mask; - - mask = 0; - fd = fdpnt->fd; - if (fd >= 0) { - struct file * file = fget(fd); - mask = POLLNVAL; - if (file != NULL) { - mask = DEFAULT_POLLMASK; - if (file->f_op && file->f_op->poll) - mask = file->f_op->poll(file, wait); - mask &= fdpnt->events | POLLERR | POLLHUP; - fput(file); - } - if (mask) { - wait = NULL; - count++; - } - } - fdpnt->revents = mask; - } + for (i=0; i < nchunks; i++) + for (j = 0; j < POLLFD_PER_PAGE; j++) + do_pollfd(fds[i] + j, wait, &count); + if (nleft) + for (j = 0; j < nleft; j++) + do_pollfd(fds[nchunks] + j, wait, &count); wait = NULL; if (count || !timeout || signal_pending(current)) @@ -373,18 +386,17 @@ asmlinkage long sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout) { - int i, fdcount, err, size; - struct pollfd * fds, *fds1; + int i, j, fdcount, err; + struct pollfd **fds; poll_table *wait_table = NULL, *wait = NULL; + int nchunks, nleft; - lock_kernel(); /* Do a sanity check on nfds ... */ - err = -EINVAL; if (nfds > current->files->max_fds) - goto out; + return -EINVAL; if (timeout) { - /* Carefula about overflow in the intermediate values */ + /* Careful about overflow in the intermediate values */ if ((unsigned long) timeout < MAX_SCHEDULE_TIMEOUT / HZ) timeout = (unsigned long)(timeout*HZ+999)/1000+1; else /* Negative or overflow */ @@ -402,32 +414,62 @@ wait = wait_table; } - size = nfds * sizeof(struct pollfd); - fds = (struct pollfd *) kmalloc(size, GFP_KERNEL); - if (!fds) + fds = (struct pollfd **)kmalloc( + (1 + (nfds - 1) / POLLFD_PER_PAGE) * sizeof(struct pollfd *), + GFP_KERNEL); + if (fds == NULL) goto out; + nchunks = 0; + nleft = nfds; + while (nleft > POLLFD_PER_PAGE) { /* allocate complete PAGE_SIZE chunks */ + fds[nchunks] = (struct pollfd *)__get_free_page(GFP_KERNEL); + if (fds[nchunks] == NULL) + goto out_fds; + nchunks++; + nleft -= POLLFD_PER_PAGE; + } + if (nleft) { /* allocate last PAGE_SIZE chunk, only nleft elements used */ + fds[nchunks] = (struct pollfd *)__get_free_page(GFP_KERNEL); + if (fds[nchunks] == NULL) + goto out_fds; + } + err = -EFAULT; - if (copy_from_user(fds, ufds, size)) - goto out_fds; + for (i=0; i < nchunks; i++) + if (copy_from_user(fds[i], ufds + i*POLLFD_PER_PAGE, PAGE_SIZE)) + goto out_fds1; + if (nleft) { + if (copy_from_user(fds[nchunks], ufds + nchunks*POLLFD_PER_PAGE, + nleft * sizeof(struct pollfd))) + goto out_fds1; + } - fdcount = do_poll(nfds, fds, wait, timeout); + lock_kernel(); + fdcount = do_poll(nfds, nchunks, nleft, fds, wait, timeout); + unlock_kernel(); /* OK, now copy the revents fields back to user space. */ - fds1 = fds; - for(i=0; i < (int)nfds; i++, ufds++, fds1++) { - __put_user(fds1->revents, &ufds->revents); - } + for(i=0; i < nchunks; i++) + for (j=0; j < POLLFD_PER_PAGE; j++, ufds++) + __put_user((fds[i] + j)->revents, &ufds->revents); + if (nleft) + for (j=0; j < nleft; j++, ufds++) + __put_user((fds[nchunks] + j)->revents, &ufds->revents); err = fdcount; if (!fdcount && signal_pending(current)) err = -EINTR; +out_fds1: + if (nleft) + free_page((unsigned long)(fds[nchunks])); out_fds: + for (i=0; i < nchunks; i++) + free_page((unsigned long)(fds[i])); kfree(fds); out: if (wait) free_wait(wait_table); - unlock_kernel(); return err; } diff -ur --new-file old/linux/fs/super.c new/linux/fs/super.c --- old/linux/fs/super.c Sun Jan 16 19:47:19 2000 +++ new/linux/fs/super.c Wed Jan 26 21:34:22 2000 @@ -302,16 +302,22 @@ int get_filesystem_info( char *buf ) { - struct vfsmount *tmp = vfsmntlist; + struct vfsmount *tmp; struct proc_fs_info *fs_infop; struct proc_nfs_info *nfs_infop; struct nfs_server *nfss; int len = 0; + char *path,*buffer = (char *) __get_free_page(GFP_KERNEL); - while ( tmp && len < PAGE_SIZE - 160) - { + if (!buffer) return 0; + for (tmp = vfsmntlist; tmp && len < PAGE_SIZE - 160; + tmp = tmp->mnt_next) { + path = d_path(tmp->mnt_sb->s_root, buffer, PAGE_SIZE); + if (!path) + continue; len += sprintf( buf + len, "%s %s %s %s", - tmp->mnt_devname, tmp->mnt_dirname, tmp->mnt_sb->s_type->name, + tmp->mnt_devname, path, + tmp->mnt_sb->s_type->name, tmp->mnt_flags & MS_RDONLY ? "ro" : "rw" ); for (fs_infop = fs_info; fs_infop->flag; fs_infop++) { if (tmp->mnt_flags & fs_infop->flag) { @@ -365,9 +371,9 @@ nfss->hostname); } len += sprintf( buf + len, " 0 0\n" ); - tmp = tmp->mnt_next; } + free_page((unsigned long) buffer); return len; } @@ -681,7 +687,7 @@ shrink_dcache_sb(sb); fsync_dev(dev); - if (dev==ROOT_DEV && !unmount_root) { + if (sb == current->fs->root->d_sb && !unmount_root) { /* * Special case for "unmounting" root ... * we just try to remount it readonly. @@ -1214,6 +1220,113 @@ } +static void chroot_fs_refs(struct dentry *old_root, + struct dentry *new_root) +{ + struct task_struct *p; + + read_lock(&tasklist_lock); + for_each_task(p) { + if (!p->fs) continue; + if (p->fs->root == old_root) { + dput(old_root); + p->fs->root = dget(new_root); + printk(KERN_DEBUG "chroot_fs_refs: changed root of " + "process %d\n",p->pid); + } + if (p->fs->pwd == old_root) { + dput(old_root); + p->fs->pwd = dget(new_root); + printk(KERN_DEBUG "chroot_fs_refs: changed cwd of " + "process %d\n",p->pid); + } + } + read_unlock(&tasklist_lock); +} + + +/* + * Moves the current root to put_root, and sets root/cwd of all processes + * which had them on the old root to new_root. + * + * Note: + * - we don't move root/cwd if they are not at the root (reason: if something + * cared enough to change them, it's probably wrong to force them elsewhere) + * - it's okay to pick a root that isn't the root of a file system, e.g. + * /nfs/my_root where /nfs is the mount point. Better avoid creating + * unreachable mount points this way, though. + */ + +asmlinkage long sys_pivot_root(const char *new_root, const char *put_old) +{ + struct dentry *root = current->fs->root; + struct dentry *d_new_root, *d_put_old, *covered; + struct dentry *root_dev_root, *new_root_dev_root; + struct dentry *walk, *next; + int error; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + lock_kernel(); + d_new_root = namei(new_root); + if (IS_ERR(d_new_root)) { + error = PTR_ERR(d_new_root); + goto out0; + } + d_put_old = namei(put_old); + if (IS_ERR(d_put_old)) { + error = PTR_ERR(d_put_old); + goto out1; + } + down(&mount_sem); + if (!d_new_root->d_inode || !d_put_old->d_inode) { + error = -ENOENT; + goto out2; + } + if (!S_ISDIR(d_new_root->d_inode->i_mode) || + !S_ISDIR(d_put_old->d_inode->i_mode)) { + error = -ENOTDIR; + goto out2; + } + error = -EBUSY; + if (d_new_root->d_sb == root->d_sb || d_put_old->d_sb == root->d_sb) + goto out2; /* loop */ + if (d_put_old != d_put_old->d_covers) + goto out2; /* mount point is busy */ + error = -EINVAL; + walk = d_put_old; /* make sure we can reach put_old from new_root */ + for (;;) { + next = walk->d_covers->d_parent; + if (next == walk) + goto out2; + if (next == d_new_root) + break; + walk = next; + } + + new_root_dev_root = d_new_root->d_sb->s_root; + covered = new_root_dev_root->d_covers; + new_root_dev_root->d_covers = new_root_dev_root; + dput(covered); + covered->d_mounts = covered; + + root_dev_root = root->d_sb->s_root; + root_dev_root->d_covers = dget(d_put_old); + d_put_old->d_mounts = root_dev_root; + chroot_fs_refs(root,d_new_root); + error = 0; +out2: + up(&mount_sem); + dput(d_put_old); +out1: + dput(d_new_root); +out0: + unlock_kernel(); + return error; +} + + #ifdef CONFIG_BLK_DEV_INITRD int __init change_root(kdev_t new_root_dev,const char *put_old) @@ -1272,7 +1385,7 @@ } return 0; } - printk(KERN_ERR "error %d\n",PTR_ERR(bdev)); + printk(KERN_ERR "error %ld\n",PTR_ERR(bdev)); return error; } remove_vfsmnt(old_root_dev); diff -ur --new-file old/linux/fs/udf/dir.c new/linux/fs/udf/dir.c --- old/linux/fs/udf/dir.c Fri Jan 7 20:43:09 2000 +++ new/linux/fs/udf/dir.c Tue Jan 25 20:19:04 2000 @@ -67,13 +67,13 @@ struct inode_operations udf_dir_inode_operations = { &udf_dir_operations, -#ifdef CONFIG_UDF_RW +#if CONFIG_UDF_RW == 1 udf_create, /* create */ #else NULL, /* create */ #endif udf_lookup, /* lookup */ -#ifdef CONFIG_UDF_RW +#if CONFIG_UDF_RW == 1 udf_link, /* link */ udf_unlink, /* unlink */ udf_symlink, /* symlink */ @@ -139,7 +139,7 @@ if ( filp->f_pos == 0 ) { - if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino) < 0) + if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino)) return 0; } @@ -161,7 +161,7 @@ char *nameptr; Uint16 liu; Uint8 lfi; - loff_t size = (UDF_I_EXT0OFFS(dir) + dir->i_size) >> 2; + loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; struct buffer_head * bh = NULL; lb_addr bloc, eloc; Uint32 extoffset, elen, offset; @@ -170,7 +170,7 @@ return 1; if (nf_pos == 0) - nf_pos = (UDF_I_EXT0OFFS(dir) >> 2); + nf_pos = (udf_ext0_offset(dir) >> 2); fibh.soffset = fibh.eoffset = (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2), @@ -251,7 +251,7 @@ if (!lfi) /* parent directory */ { - if (filldir(dirent, "..", 2, filp->f_pos, filp->f_dentry->d_parent->d_inode->i_ino) < 0) + if (filldir(dirent, "..", 2, filp->f_pos, filp->f_dentry->d_parent->d_inode->i_ino)) { if (fibh.sbh != fibh.ebh) udf_release_data(fibh.ebh); @@ -264,7 +264,7 @@ { if ((flen = udf_get_filename(nameptr, fname, lfi))) { - if (filldir(dirent, fname, flen, filp->f_pos, iblock) < 0) + if (filldir(dirent, fname, flen, filp->f_pos, iblock)) { if (fibh.sbh != fibh.ebh) udf_release_data(fibh.ebh); diff -ur --new-file old/linux/fs/udf/directory.c new/linux/fs/udf/directory.c --- old/linux/fs/udf/directory.c Sun Nov 21 01:16:57 1999 +++ new/linux/fs/udf/directory.c Tue Jan 25 20:19:04 2000 @@ -213,8 +213,8 @@ #ifdef __KERNEL__ udf_debug("0x%x != TID_FILE_IDENT_DESC\n", le16_to_cpu(fi->descTag.tagIdent)); - udf_debug("offset: %u sizeof: %u bufsize: %u\n", - *offset, sizeof(struct FileIdentDesc), bufsize); + udf_debug("offset: %u sizeof: %lu bufsize: %u\n", + *offset, (unsigned long)sizeof(struct FileIdentDesc), bufsize); #endif return NULL; } diff -ur --new-file old/linux/fs/udf/file.c new/linux/fs/udf/file.c --- old/linux/fs/udf/file.c Fri Jan 7 20:43:09 2000 +++ new/linux/fs/udf/file.c Tue Jan 25 20:19:04 2000 @@ -43,94 +43,6 @@ #include "udf_i.h" #include "udf_sb.h" -static loff_t udf_file_llseek(struct file *, loff_t, int); -static ssize_t udf_file_read_adinicb (struct file *, char *, size_t, loff_t *); -static ssize_t udf_file_write (struct file *, const char *, size_t, loff_t *); -static int udf_open_file(struct inode *, struct file *); -static int udf_release_file(struct inode *, struct file *); - -static struct file_operations udf_file_operations = { - udf_file_llseek, /* llseek */ - generic_file_read, /* read */ - udf_file_write, /* write */ - NULL, /* readdir */ - NULL, /* poll */ - udf_ioctl, /* ioctl */ - generic_file_mmap, /* mmap */ - udf_open_file, /* open */ - NULL, /* flush */ - udf_release_file, /* release */ - udf_sync_file, /* fsync */ - NULL, /* fasync */ - NULL /* lock */ -}; - -struct inode_operations udf_file_inode_operations = { - &udf_file_operations, - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - udf_get_block, /* get_block */ - block_read_full_page, /* readpage */ - block_write_full_page, /* writepage */ -#ifdef CONFIG_UDF_RW - udf_truncate, /* truncate */ -#else - NULL, /* truncate */ -#endif - NULL, /* permission */ - NULL /* revalidate */ -}; - -static struct file_operations udf_file_operations_adinicb = { - udf_file_llseek, /* llseek */ - udf_file_read_adinicb,/* read */ - udf_file_write, /* write */ - NULL, /* readdir */ - NULL, /* poll */ - udf_ioctl, /* ioctl */ - NULL, /* mmap */ - NULL, /* open */ - NULL, /* flush */ - udf_release_file, /* release */ - udf_sync_file, /* fsync */ - NULL, /* fasync */ - NULL /* lock */ -}; - -struct inode_operations udf_file_inode_operations_adinicb = { - &udf_file_operations_adinicb, - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - udf_get_block, /* get_block */ - block_read_full_page, /* readpage */ - block_write_full_page, /* writepage */ -#ifdef CONFIG_UDF_RW - udf_truncate, /* truncate */ -#else - NULL, /* truncate */ -#endif - NULL, /* permission */ - NULL /* revalidate */ -}; - /* * Make sure the offset never goes beyond the 32-bit mark.. */ @@ -181,104 +93,93 @@ { ssize_t retval; struct inode *inode = file->f_dentry->d_inode; - remove_suid(inode); - - if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB) - { - int i, err; - struct buffer_head *bh; - - if ((bh = udf_expand_adinicb(inode, &i, 0, &err))) - udf_release_data(bh); - else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB) - return err; - } retval = generic_file_write(file, buf, count, ppos, block_write_partial_page); if (retval > 0) { + remove_suid(inode); inode->i_ctime = inode->i_mtime = CURRENT_TIME; UDF_I_UCTIME(inode) = UDF_I_UMTIME(inode) = CURRENT_UTIME; + mark_inode_dirty(inode); } - mark_inode_dirty(inode); return retval; } -/* - * udf_file_read - * - * PURPOSE - * Read from an open file. - * - * DESCRIPTION - * Optional - sys_read() will return -EINVAL if this routine is not - * available. - * - * Refer to sys_read() in fs/read_write.c - * sys_read() -> . - * - * Note that you can use generic_file_read() instead, which requires that - * udf_readpage() be available, but you can use generic_readpage(), which - * requires that udf_block_map() be available. Reading will then be done by - * memory-mapping the file a page at a time. This is not suitable for - * devices that don't handle read-ahead [example: CD-R/RW that may have - * blank sectors that shouldn't be read]. - * - * Refer to generic_file_read() in mm/filemap.c and to generic_readpage() - * in fs/buffer.c - * - * Block devices can use block_read() instead. Refer to fs/block_dev.c - * - * PRE-CONDITIONS - * inode Pointer to inode to read from (never NULL). - * filp Pointer to file to read from (never NULL). - * buf Point to read buffer (validated). - * bufsize Size of read buffer. - * - * POST-CONDITIONS - * Bytes read (>=0) or an error code (<0) that - * sys_read() will return. - * - * HISTORY - * July 1, 1997 - Andrew E. Mileski - * Written, tested, and released. - */ -static ssize_t udf_file_read_adinicb(struct file * filp, char * buf, - size_t bufsize, loff_t * loff) +int udf_write_partial_page_adinicb(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf) { - struct inode *inode = filp->f_dentry->d_inode; - loff_t size, left, pos; - Uint32 block; - struct buffer_head *bh = NULL; + struct inode *inode = file->f_dentry->d_inode; + int err = 0, block; + struct buffer_head *bh; + unsigned long kaddr = 0; + + if (!PageLocked(page)) + BUG(); + if (offset < 0 || offset >= (inode->i_sb->s_blocksize - udf_file_entry_alloc_offset(inode))) + BUG(); + if (bytes+offset < 0 || bytes+offset > (inode->i_sb->s_blocksize - udf_file_entry_alloc_offset(inode))) + BUG(); + + kaddr = kmap(page); + block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); + bh = getblk (inode->i_dev, block, inode->i_sb->s_blocksize); + if (!buffer_uptodate(bh)) + { + ll_rw_block (READ, 1, &bh); + wait_on_buffer(bh); + } + err = copy_from_user((char *)kaddr + offset, buf, bytes); + memcpy(bh->b_data + udf_file_entry_alloc_offset(inode) + offset, + (char *)kaddr + offset, bytes); + mark_buffer_dirty(bh, 0); + brelse(bh); + kunmap(page); + SetPageUptodate(page); + return bytes; +} - size = inode->i_size; - if (*loff > size) - left = 0; +static ssize_t udf_file_write_adinicb(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + ssize_t retval; + struct inode *inode = file->f_dentry->d_inode; + int err, pos; + + if (file->f_flags & O_APPEND) + pos = inode->i_size; else - left = size - *loff; - if (left > bufsize) - left = bufsize; - - if (left <= 0) - return 0; - - pos = *loff + UDF_I_EXT0OFFS(inode); - block = udf_block_map(inode, 0); - if (!(bh = udf_tread(inode->i_sb, - udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0), - inode->i_sb->s_blocksize))) + pos = *ppos; + + if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) + + pos + count)) { - return 0; + udf_expand_file_adinicb(file, pos + count, &err); + if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB) + { + udf_debug("udf_expand_adinicb: err=%d\n", err); + return err; + } + else + return udf_file_write(file, buf, count, ppos); } - if (!copy_to_user(buf, bh->b_data + pos, left)) - *loff += left; else - left = -EFAULT; + { + if (pos + count > inode->i_size) + UDF_I_LENALLOC(inode) = pos + count; + else + UDF_I_LENALLOC(inode) = inode->i_size; + } - udf_release_data(bh); + retval = generic_file_write(file, buf, count, ppos, udf_write_partial_page_adinicb); - return left; + if (retval > 0) + { + remove_suid(inode); + inode->i_ctime = inode->i_mtime = CURRENT_TIME; + UDF_I_UCTIME(inode) = UDF_I_UMTIME(inode) = CURRENT_UTIME; + mark_inode_dirty(inode); + } + return retval; } /* @@ -435,3 +336,85 @@ return -EFBIG; return 0; } + +static struct file_operations udf_file_operations = { + udf_file_llseek, /* llseek */ + generic_file_read, /* read */ + udf_file_write, /* write */ + NULL, /* readdir */ + NULL, /* poll */ + udf_ioctl, /* ioctl */ + generic_file_mmap, /* mmap */ + udf_open_file, /* open */ + NULL, /* flush */ + udf_release_file, /* release */ + udf_sync_file, /* fsync */ + NULL, /* fasync */ + NULL /* lock */ +}; + +struct inode_operations udf_file_inode_operations = { + &udf_file_operations, + NULL, /* create */ + NULL, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + NULL, /* readlink */ + NULL, /* follow_link */ + udf_get_block, /* get_block */ + block_read_full_page, /* readpage */ + block_write_full_page, /* writepage */ +#if CONFIG_UDF_RW == 1 + udf_truncate, /* truncate */ +#else + NULL, /* truncate */ +#endif + NULL, /* permission */ + NULL /* revalidate */ +}; + +static struct file_operations udf_file_operations_adinicb = { + udf_file_llseek, /* llseek */ + generic_file_read, /* read */ + udf_file_write_adinicb, /* write */ + NULL, /* readdir */ + NULL, /* poll */ + udf_ioctl, /* ioctl */ + NULL, /* mmap */ + NULL, /* open */ + NULL, /* flush */ + udf_release_file, /* release */ + udf_sync_file_adinicb, /* fsync */ + NULL, /* fasync */ + NULL /* lock */ +}; + +struct inode_operations udf_file_inode_operations_adinicb = { + &udf_file_operations_adinicb, + NULL, /* create */ + NULL, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + NULL, /* readlink */ + NULL, /* follow_link */ + udf_get_block, /* get_block */ + udf_readpage_adinicb, /* readpage */ + udf_writepage_adinicb, /* writepage */ +#if CONFIG_UDF_RW == 1 + udf_truncate_adinicb, /* truncate */ +#else + NULL, /* truncate */ +#endif + NULL, /* permission */ + NULL /* revalidate */ +}; diff -ur --new-file old/linux/fs/udf/fsync.c new/linux/fs/udf/fsync.c --- old/linux/fs/udf/fsync.c Sat Sep 4 21:42:30 1999 +++ new/linux/fs/udf/fsync.c Tue Jan 25 20:19:04 2000 @@ -15,18 +15,18 @@ * ftp://prep.ai.mit.edu/pub/gnu/GPL * Each contributing author retains all rights to their own work. * - * (C) 1999 Ben Fennema - * (C) 1999 Stelias Computing Inc + * (C) 1999-2000 Ben Fennema + * (C) 1999-2000 Stelias Computing Inc * * HISTORY * * 05/22/99 blf Created. - * */ #include "udfdecl.h" #include +#include #include #include "udf_i.h" @@ -40,10 +40,21 @@ if (!bh) return 0; if (wait && buffer_req(bh) && !buffer_uptodate(bh)) { - brelse (bh); - return -1; + /* There can be a parallell read(2) that started read-I/O + on the buffer so we can't assume that there's been + an I/O error without first waiting I/O completation. */ + wait_on_buffer(bh); + if (!buffer_uptodate(bh)) + { + brelse (bh); + return -1; + } } if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) { + if (wait) + /* when we return from fsync all the blocks + must be _just_ stored on disk */ + wait_on_buffer(bh); brelse (bh); return 0; } @@ -89,8 +100,7 @@ int wait, err = 0; struct inode *inode = dentry->d_inode; - if ((S_ISLNK(inode->i_mode) && !(inode->i_blocks)) || - UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB) + if (S_ISLNK(inode->i_mode) && !(inode->i_blocks)) { /* * Don't sync fast links! or ICB_FLAG_AD_IN_ICB @@ -107,4 +117,9 @@ skip: err |= udf_sync_inode (inode); return err ? -EIO : 0; +} + +int udf_sync_file_adinicb(struct file * file, struct dentry *dentry) +{ + return udf_sync_inode(dentry->d_inode) ? -EIO : 0; } diff -ur --new-file old/linux/fs/udf/ialloc.c new/linux/fs/udf/ialloc.c --- old/linux/fs/udf/ialloc.c Sat Sep 4 21:42:30 1999 +++ new/linux/fs/udf/ialloc.c Tue Jan 25 20:19:04 2000 @@ -15,7 +15,7 @@ * ftp://prep.ai.mit.edu/pub/gnu/GPL * Each contributing author retains all rights to their own work. * - * (C) 1998-1999 Ben Fennema + * (C) 1998-2000 Ben Fennema * * HISTORY * @@ -148,16 +148,7 @@ inode->i_size = 0; UDF_I_LENEATTR(inode) = 0; UDF_I_LENALLOC(inode) = 0; - UDF_I_EXT0LOC(inode) = UDF_I_LOCATION(inode); - UDF_I_EXT0LEN(inode) = 0; -#if 1 - UDF_I_EXT0OFFS(inode) = sizeof(struct FileEntry); UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_IN_ICB; -#else - UDF_I_EXT0OFFS(inode) = 0; - UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG; -#endif - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; UDF_I_UMTIME(inode) = UDF_I_UATIME(inode) = UDF_I_UCTIME(inode) = CURRENT_UTIME; inode->i_op = NULL; diff -ur --new-file old/linux/fs/udf/inode.c new/linux/fs/udf/inode.c --- old/linux/fs/udf/inode.c Thu Jan 6 19:14:36 2000 +++ new/linux/fs/udf/inode.c Tue Jan 25 20:19:04 2000 @@ -16,8 +16,8 @@ * Each contributing author retains all rights to their own work. * * (C) 1998 Dave Boynton - * (C) 1998-1999 Ben Fennema - * (C) 1999 Stelias Computing Inc + * (C) 1998-2000 Ben Fennema + * (C) 1999-2000 Stelias Computing Inc * * HISTORY * @@ -31,7 +31,6 @@ * 03/07/99 rewrote udf_block_map (again) * New funcs, inode_bmap, udf_next_aext * 04/19/99 Support for writing device EA's for major/minor # - * */ #include "udfdecl.h" @@ -58,8 +57,6 @@ long_ad [EXTENT_MERGE_SIZE], int, int, lb_addr, Uint32, struct buffer_head **); -static DECLARE_MUTEX(read_semaphore); - /* * udf_put_inode * @@ -99,56 +96,14 @@ { inode->i_size = 0; if (inode->i_blocks) - udf_truncate(inode); + inode->i_op->truncate(inode); udf_free_inode(inode); } void udf_discard_prealloc(struct inode * inode) { -#ifdef UDF_PREALLOCATE - lb_addr bloc, eloc; - Uint32 extoffset, elen, nelen, offset, adsize = 0; - struct buffer_head *bh = NULL; - - if ((inode->i_size > 0) && - (inode_bmap(inode, (inode->i_size-1) >> inode->i_sb->s_blocksize_bits, - &bloc, &extoffset, &eloc, &elen, &offset, &bh) == - EXTENT_RECORDED_ALLOCATED)) - { - if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT) - adsize = sizeof(short_ad); - else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG) - adsize = sizeof(long_ad); - else - { - udf_release_data(bh); - return; - } - - nelen = (EXTENT_RECORDED_ALLOCATED << 30) | - ((((elen - 1) & ~(inode->i_sb->s_blocksize - 1)) | - ((inode->i_size - 1) & (inode->i_sb->s_blocksize - 1))) + 1); - - if (nelen != ((EXTENT_RECORDED_ALLOCATED << 30) | elen)) - { - extoffset -= adsize; - udf_write_aext(inode, bloc, &extoffset, eloc, nelen, &bh, 1); - } - - if (udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 0) == - EXTENT_NOT_RECORDED_ALLOCATED) - { - udf_free_blocks(inode, eloc, 0, elen >> inode->i_sb->s_blocksize_bits); - memset(&eloc, 0x00, sizeof(lb_addr)); - udf_write_aext(inode, bloc, &extoffset, eloc, 0, &bh, 1); - UDF_I_LENALLOC(inode) -= adsize; - udf_write_inode(inode); - } - udf_release_data(bh); - } - else if (bh) - udf_release_data(bh); -#endif + if (inode->i_size && UDF_I_ALLOCTYPE(inode) != ICB_FLAG_AD_IN_ICB) + udf_trunc(inode); } static int udf_alloc_block(struct inode *inode, Uint16 partition, @@ -162,108 +117,138 @@ return result; } -struct buffer_head * udf_expand_adinicb(struct inode *inode, int *block, int isdir, int *err) +void udf_expand_file_adinicb(struct file * filp, int newsize, int * err) { - if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB) - { - long_ad newad; - int newblock; - struct buffer_head *sbh = NULL, *dbh = NULL; + struct inode * inode = filp->f_dentry->d_inode; + struct buffer_head *bh = NULL; + struct page *page; + unsigned long kaddr = 0; - if (!UDF_I_LENALLOC(inode)) - { - UDF_I_EXT0OFFS(inode) = 0; - UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG; - mark_inode_dirty(inode); - if (inode->i_op == &udf_file_inode_operations_adinicb) - inode->i_op = &udf_file_inode_operations; - return NULL; - } + if (!UDF_I_LENALLOC(inode)) + { + UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG; + mark_inode_dirty(inode); + inode->i_op = &udf_file_inode_operations; + filp->f_op = inode->i_op->default_file_ops; + return; + } - /* alloc block, and copy data to it */ - *block = udf_alloc_block(inode, - UDF_I_LOCATION(inode).partitionReferenceNum, - UDF_I_LOCATION(inode).logicalBlockNum, err); + bh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize); + if (!bh) + return; + page = grab_cache_page(&inode->i_data, 0); + if (!PageLocked(page)) + BUG(); + if (!Page_Uptodate(page)) + { + kaddr = kmap(page); + memset((char *)kaddr + UDF_I_LENALLOC(inode), 0x00, + PAGE_CACHE_SIZE - UDF_I_LENALLOC(inode)); + memcpy((char *)kaddr, bh->b_data + udf_file_entry_alloc_offset(inode), + UDF_I_LENALLOC(inode)); + kunmap(page); + } + memset(bh->b_data + udf_file_entry_alloc_offset(inode), + 0, UDF_I_LENALLOC(inode)); + UDF_I_LENALLOC(inode) = 0; + UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG; + inode->i_blocks = inode->i_sb->s_blocksize / 512; + mark_buffer_dirty(bh, 1); + udf_release_data(bh); - if (!(*block)) - return NULL; - newblock = udf_get_pblock(inode->i_sb, *block, - UDF_I_LOCATION(inode).partitionReferenceNum, 0); - if (!newblock) - return NULL; - sbh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize); - if (!sbh) - return NULL; - dbh = udf_tread(inode->i_sb, newblock, inode->i_sb->s_blocksize); - if (!dbh) - return NULL; - - if (isdir) - { - struct udf_fileident_bh sfibh, dfibh; - loff_t f_pos = UDF_I_EXT0OFFS(inode) >> 2; - loff_t size = (UDF_I_EXT0OFFS(inode) + inode->i_size) >> 2; - struct FileIdentDesc cfi, *sfi, *dfi; - - sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2; - sfibh.sbh = sfibh.ebh = sbh; - dfibh.soffset = dfibh.eoffset = 0; - dfibh.sbh = dfibh.ebh = dbh; - while ( (f_pos < size) ) - { - sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL); - if (!sfi) - { - udf_release_data(sbh); - udf_release_data(dbh); - return NULL; - } - sfi->descTag.tagLocation = *block; - dfibh.soffset = dfibh.eoffset; - dfibh.eoffset += (sfibh.eoffset - sfibh.soffset); - dfi = (struct FileIdentDesc *)(dbh->b_data + dfibh.soffset); - if (udf_write_fi(sfi, dfi, &dfibh, sfi->impUse, - sfi->fileIdent + sfi->lengthOfImpUse)) - { - udf_release_data(sbh); - udf_release_data(dbh); - return NULL; - } - } - } - else - { - memcpy(dbh->b_data, sbh->b_data + udf_file_entry_alloc_offset(inode), - UDF_I_LENALLOC(inode)); - } - mark_buffer_dirty(dbh, 1); + block_write_full_page(filp->f_dentry, page); + UnlockPage(page); + page_cache_release(page); - memset(sbh->b_data + udf_file_entry_alloc_offset(inode), - 0, UDF_I_LENALLOC(inode)); + mark_inode_dirty(inode); + inode->i_version ++; + inode->i_op = &udf_file_inode_operations; + filp->f_op = inode->i_op->default_file_ops; +} - memset(&newad, 0x00, sizeof(long_ad)); - newad.extLength = UDF_I_EXT0LEN(inode) = inode->i_size; - newad.extLocation.logicalBlockNum = *block; - newad.extLocation.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; - UDF_I_EXT0LOC(inode) = newad.extLocation; - /* UniqueID stuff */ +struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err) +{ + long_ad newad; + int newblock; + struct buffer_head *sbh = NULL, *dbh = NULL; - memcpy(sbh->b_data + udf_file_entry_alloc_offset(inode), - &newad, sizeof(newad)); + struct udf_fileident_bh sfibh, dfibh; + loff_t f_pos = udf_ext0_offset(inode) >> 2; + int size = (udf_ext0_offset(inode) + inode->i_size) >> 2; + struct FileIdentDesc cfi, *sfi, *dfi; - UDF_I_LENALLOC(inode) = sizeof(newad); - UDF_I_EXT0OFFS(inode) = 0; + if (!inode->i_size) + { UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG; - inode->i_blocks += inode->i_sb->s_blocksize / 512; - udf_release_data(sbh); mark_inode_dirty(inode); - inode->i_version ++; - if (inode->i_op == &udf_file_inode_operations_adinicb) - inode->i_op = &udf_file_inode_operations; - return dbh; + return NULL; } - else + + /* alloc block, and copy data to it */ + *block = udf_alloc_block(inode, + UDF_I_LOCATION(inode).partitionReferenceNum, + UDF_I_LOCATION(inode).logicalBlockNum, err); + + if (!(*block)) + return NULL; + newblock = udf_get_pblock(inode->i_sb, *block, + UDF_I_LOCATION(inode).partitionReferenceNum, 0); + if (!newblock) + return NULL; + sbh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize); + if (!sbh) return NULL; + dbh = udf_tread(inode->i_sb, newblock, inode->i_sb->s_blocksize); + if (!dbh) + return NULL; + + sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2; + sfibh.sbh = sfibh.ebh = sbh; + dfibh.soffset = dfibh.eoffset = 0; + dfibh.sbh = dfibh.ebh = dbh; + while ( (f_pos < size) ) + { + sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL); + if (!sfi) + { + udf_release_data(sbh); + udf_release_data(dbh); + return NULL; + } + sfi->descTag.tagLocation = *block; + dfibh.soffset = dfibh.eoffset; + dfibh.eoffset += (sfibh.eoffset - sfibh.soffset); + dfi = (struct FileIdentDesc *)(dbh->b_data + dfibh.soffset); + if (udf_write_fi(sfi, dfi, &dfibh, sfi->impUse, + sfi->fileIdent + sfi->lengthOfImpUse)) + { + udf_release_data(sbh); + udf_release_data(dbh); + return NULL; + } + } + mark_buffer_dirty(dbh, 1); + + memset(sbh->b_data + udf_file_entry_alloc_offset(inode), + 0, UDF_I_LENALLOC(inode)); + + memset(&newad, 0x00, sizeof(long_ad)); + newad.extLength = inode->i_size; + newad.extLocation.logicalBlockNum = *block; + newad.extLocation.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; + /* UniqueID stuff */ + + memcpy(sbh->b_data + udf_file_entry_alloc_offset(inode), + &newad, sizeof(newad)); + + UDF_I_LENALLOC(inode) = sizeof(newad); + UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG; + inode->i_blocks = inode->i_sb->s_blocksize / 512; + mark_buffer_dirty(sbh, 1); + udf_release_data(sbh); + mark_inode_dirty(inode); + inode->i_version ++; + return dbh; } struct buffer_head * udf_getblk(struct inode * inode, long block, @@ -282,6 +267,8 @@ bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->s_blocksize); if (buffer_new(&dummy)) { + if (!buffer_uptodate(bh)) + wait_on_buffer(bh); memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); mark_buffer_uptodate(bh, 1); mark_buffer_dirty(bh, 1); @@ -310,6 +297,8 @@ } err = -EIO; + new = 0; + bh = NULL; lock_kernel(); @@ -479,7 +468,7 @@ } /* if the current extent is not recorded but allocated, get the - block in the extent corresponding to the requested block */ + block in the extent corresponding to the requested block */ if ((laarr[c].extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED) newblocknum = laarr[c].extLocation.logicalBlockNum + offset; else /* otherwise, allocate a new block */ @@ -522,12 +511,6 @@ udf_release_data(pbh); - if (pextoffset == udf_file_entry_alloc_offset(inode)) - { - UDF_I_EXT0LEN(inode) = laarr[0].extLength; - UDF_I_EXT0LOC(inode) = laarr[0].extLocation; - } - if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum, UDF_I_LOCATION(inode).partitionReferenceNum, 0))) { @@ -541,11 +524,9 @@ inode->i_ctime = CURRENT_TIME; UDF_I_UCTIME(inode) = CURRENT_UTIME; inode->i_blocks += inode->i_sb->s_blocksize / 512; -#if 0 - if (IS_SYNC(inode) || UDF_I_OSYNC(inode)) + if (IS_SYNC(inode)) udf_sync_inode(inode); else -#endif mark_inode_dirty(inode); return result; } @@ -830,9 +811,16 @@ * * 12/19/98 dgb Updated to fix size problems. */ + void udf_read_inode(struct inode *inode) { + memset(&UDF_I_LOCATION(inode), 0xFF, sizeof(lb_addr)); +} + +void +__udf_read_inode(struct inode *inode) +{ struct buffer_head *bh = NULL; struct FileEntry *fe; Uint16 ident; @@ -851,17 +839,9 @@ * i_op = NULL; */ - inode->i_blksize = inode->i_sb->s_blocksize; + inode->i_blksize = PAGE_SIZE; inode->i_version = 1; - UDF_I_EXT0LEN(inode)=0; - UDF_I_EXT0LOC(inode).logicalBlockNum = 0xFFFFFFFF; - UDF_I_EXT0LOC(inode).partitionReferenceNum = 0xFFFF; - UDF_I_EXT0OFFS(inode)=0; - UDF_I_ALLOCTYPE(inode)=0; - - memcpy(&UDF_I_LOCATION(inode), &UDF_SB_LOCATION(inode->i_sb), sizeof(lb_addr)); - bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident); if (!bh) @@ -904,11 +884,11 @@ if (ident == TID_FILE_ENTRY || ident == TID_EXTENDED_FILE_ENTRY) { - memcpy(&UDF_SB_LOCATION(inode->i_sb), &loc, sizeof(lb_addr)); + memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(lb_addr)); udf_release_data(bh); udf_release_data(ibh); udf_release_data(nbh); - udf_read_inode(inode); + __udf_read_inode(inode); return; } else @@ -957,11 +937,11 @@ else /* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */ UDF_I_STRAT4096(inode) = 1; - inode->i_uid = udf_convert_uid(le32_to_cpu(fe->uid)); - if ( !inode->i_uid ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid; + inode->i_uid = le32_to_cpu(fe->uid); + if ( inode->i_uid == -1 ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid; - inode->i_gid = udf_convert_gid(le32_to_cpu(fe->gid)); - if ( !inode->i_gid ) inode->i_gid = UDF_SB(inode->i_sb)->s_gid; + inode->i_gid = le32_to_cpu(fe->gid); + if ( inode->i_gid == -1 ) inode->i_gid = UDF_SB(inode->i_sb)->s_gid; inode->i_nlink = le16_to_cpu(fe->fileLinkCount); if (!inode->i_nlink) @@ -976,12 +956,6 @@ inode->i_mode = udf_convert_permissions(fe); inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask; -#ifdef UDF_PREALLOCATE -#if 0 - UDF_I_PREALLOC_BLOCK(inode) = 0; - UDF_I_PREALLOC_COUNT(inode) = 0; -#endif -#endif UDF_I_NEXT_ALLOC_BLOCK(inode) = 0; UDF_I_NEXT_ALLOC_GOAL(inode) = 0; @@ -1074,58 +1048,6 @@ alen = offset + UDF_I_LENALLOC(inode); } - switch (UDF_I_ALLOCTYPE(inode)) - { - case ICB_FLAG_AD_SHORT: - { - short_ad * sa; - - sa = udf_get_fileshortad(fe, alen, &offset, 1); - if (sa) - { - UDF_I_EXT0LEN(inode) = le32_to_cpu(sa->extLength); - UDF_I_EXT0LOC(inode).logicalBlockNum = le32_to_cpu(sa->extPosition); - UDF_I_EXT0LOC(inode).partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; - } - break; - } - case ICB_FLAG_AD_LONG: - { - long_ad * la; - - la = udf_get_filelongad(fe, alen, &offset, 1); - if (la) - { - UDF_I_EXT0LEN(inode) = le32_to_cpu(la->extLength); - UDF_I_EXT0LOC(inode).logicalBlockNum = le32_to_cpu(la->extLocation.logicalBlockNum); - UDF_I_EXT0LOC(inode).partitionReferenceNum = le16_to_cpu(la->extLocation.partitionReferenceNum); - } - break; - } - case ICB_FLAG_AD_EXTENDED: - { - extent_ad * ext; - - ext = udf_get_fileextent(fe, alen, &offset); - if ( (ext) && (ext->extLength) ) - { - UDF_I_EXT0LEN(inode) = le32_to_cpu(ext->extLength); -#if 0 - UDF_I_EXT0LOC(inode) = ext->extLocation; -#endif - } - break; - } - case ICB_FLAG_AD_IN_ICB: /* short directories */ - { - UDF_I_EXT0LEN(inode) = le32_to_cpu(fe->lengthAllocDescs); - UDF_I_EXT0LOC(inode) = UDF_I_LOCATION(inode); - UDF_I_EXT0OFFS(inode) = sizeof(struct FileEntry) + - le32_to_cpu(fe->lengthExtendedAttr); - break; - } - } /* end switch ad_type */ - switch (fe->icbTag.fileType) { case FILE_TYPE_DIRECTORY: @@ -1162,7 +1084,6 @@ } case FILE_TYPE_SYMLINK: { - /* untested! */ inode->i_op = &udf_symlink_inode_operations; inode->i_mode = S_IFLNK|S_IRWXUGO; break; @@ -1184,7 +1105,7 @@ if (dsea) { - init_special_inode(inode, inode->i_mode, + init_special_inode(inode, inode->i_mode, ((le32_to_cpu(dsea->majorDeviceIdent)) << 8) | (le32_to_cpu(dsea->minorDeviceIdent) & 0xFF)); /* Developer ID ??? */ @@ -1440,19 +1361,11 @@ block = udf_get_lb_pblock(sb, ino, 0); - down(&read_semaphore); /* serialize access to UDF_SB_LOCATION() */ - /* This is really icky.. should fix -- blf */ - - /* put the location where udf_read_inode can find it */ - memcpy(&UDF_SB_LOCATION(sb), &ino, sizeof(lb_addr)); - /* Get the inode */ inode = iget(sb, block); /* calls udf_read_inode() ! */ - up(&read_semaphore); - if (!inode) { printk(KERN_ERR "udf: iget() failed\n"); @@ -1463,6 +1376,12 @@ iput(inode); return NULL; } + else if (UDF_I_LOCATION(inode).logicalBlockNum == 0xFFFFFFFF && + UDF_I_LOCATION(inode).partitionReferenceNum == 0xFFFF) + { + memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(lb_addr)); + __udf_read_inode(inode); + } if ( ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum) ) { @@ -1732,6 +1651,14 @@ } break; } + case ICB_FLAG_AD_IN_ICB: + { + *bloc = *eloc = UDF_I_LOCATION(inode); + *elen = UDF_I_LENALLOC(inode); + *extoffset = udf_file_entry_alloc_offset(inode); + etype = EXTENT_RECORDED_ALLOCATED; + break; + } default: { udf_debug("alloc_type = %d unsupported\n", UDF_I_ALLOCTYPE(inode)); @@ -1741,7 +1668,8 @@ if (*elen) return etype; - udf_debug("Empty Extent!\n"); + udf_debug("Empty Extent, inode=%ld, alloctype=%d, elen=%d, etype=%d, extoffset=%d\n", + inode->i_ino, UDF_I_ALLOCTYPE(inode), *elen, etype, *extoffset); if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT) *extoffset -= sizeof(short_ad); else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG) @@ -1974,26 +1902,22 @@ return -1; } + *extoffset = udf_file_entry_alloc_offset(inode); + *elen = 0; b_off = block << inode->i_sb->s_blocksize_bits; *bloc = UDF_I_LOCATION(inode); - *eloc = UDF_I_EXT0LOC(inode); - *elen = UDF_I_EXT0LEN(inode) & UDF_EXTENT_LENGTH_MASK; - *extoffset = udf_file_entry_alloc_offset(inode); - if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT) - *extoffset += sizeof(short_ad); - else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG) - *extoffset += sizeof(long_ad); - etype = UDF_I_EXT0LEN(inode) >> 30; - while (lbcount + *elen <= b_off) + do { lbcount += *elen; + if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1) { *offset = (b_off - lbcount) >> inode->i_sb->s_blocksize_bits; return -1; } - } + } while (lbcount + *elen <= b_off); + *offset = (b_off - lbcount) >> inode->i_sb->s_blocksize_bits; return etype; @@ -2028,4 +1952,59 @@ ret = udf_locked_block_map(inode, block); unlock_kernel(); return ret; +} + +int udf_readpage_adinicb (struct dentry *dentry, struct page * page) +{ + struct inode *inode = dentry->d_inode; + + struct buffer_head *bh; + int block; + unsigned long kaddr = 0; + + if (!PageLocked(page)) + PAGE_BUG(page); + + kaddr = kmap(page); + memset((char *)kaddr, 0, PAGE_CACHE_SIZE); + block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); + bh = getblk (inode->i_dev, block, inode->i_sb->s_blocksize); + ll_rw_block (READ, 1, &bh); + wait_on_buffer(bh); + memcpy((char *)kaddr, bh->b_data + udf_ext0_offset(inode), + inode->i_size); + brelse(bh); + SetPageUptodate(page); + kunmap(page); + UnlockPage(page); + return 0; +} + +int udf_writepage_adinicb (struct dentry *dentry, struct page *page) +{ + struct inode *inode = dentry->d_inode; + + struct buffer_head *bh; + int block; + unsigned long kaddr = 0; + + if (!PageLocked(page)) + BUG(); + + kaddr = kmap(page); + block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); + bh = getblk (inode->i_dev, block, inode->i_sb->s_blocksize); + if (!buffer_uptodate(bh)) + { + ll_rw_block (READ, 1, &bh); + wait_on_buffer(bh); + } + memcpy(bh->b_data + udf_ext0_offset(inode), (char *)kaddr, + inode->i_size); + ll_rw_block (WRITE, 1, &bh); + wait_on_buffer(bh); + brelse(bh); + SetPageUptodate(page); + kunmap(page); + return 0; } diff -ur --new-file old/linux/fs/udf/lowlevel.c new/linux/fs/udf/lowlevel.c --- old/linux/fs/udf/lowlevel.c Thu Jan 6 19:14:36 2000 +++ new/linux/fs/udf/lowlevel.c Tue Jan 25 20:19:04 2000 @@ -15,7 +15,7 @@ * ftp://prep.ai.mit.edu/pub/gnu/GPL * Each contributing author retains all rights to their own work. * - * (C) 1999 Ben Fennema + * (C) 1999-2000 Ben Fennema * * HISTORY * @@ -47,16 +47,21 @@ vol_desc_start=0; ms_info.addr_format=CDROM_LBA; - i=ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long) &ms_info); + i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long) &ms_info); + #define WE_OBEY_THE_WRITTEN_STANDARDS 1 - if (i == 0) { + + if (i == 0) + { udf_debug("XA disk: %s, vol_desc_start=%d\n", (ms_info.xa_flag ? "yes" : "no"), ms_info.addr.lba); #if WE_OBEY_THE_WRITTEN_STANDARDS if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */ #endif vol_desc_start = ms_info.addr.lba; - } else { + } + else + { udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i); } return vol_desc_start; @@ -86,17 +91,20 @@ lblock = 0; ret = ioctl_by_bdev(bdev, BLKGETSIZE, (unsigned long) &lblock); - if (!ret && lblock != 0x7FFFFFFF) { - /* Hard Disk */ + if (!ret && lblock != 0x7FFFFFFF) /* Hard Disk */ + { if (mult) lblock *= mult; else if (div) lblock /= div; - } else { - /* CDROM */ + } + else /* CDROM */ + { ret = ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock); } + if (!ret && lblock) return lblock - 1; - return 0; + else + return 0; } diff -ur --new-file old/linux/fs/udf/misc.c new/linux/fs/udf/misc.c --- old/linux/fs/udf/misc.c Tue Jan 11 03:15:58 2000 +++ new/linux/fs/udf/misc.c Tue Jan 25 20:19:04 2000 @@ -16,8 +16,8 @@ * Each contributing author retains all rights to their own work. * * (C) 1998 Dave Boynton - * (C) 1998-1999 Ben Fennema - * (C) 1999 Stelias Computing Inc + * (C) 1998-2000 Ben Fennema + * (C) 1999-2000 Stelias Computing Inc * * HISTORY * @@ -64,20 +64,6 @@ return indat >> 32; } -uid_t udf_convert_uid(int uidin) -{ - if ( uidin == -1 ) - return 0; - return uidin; -} - -gid_t udf_convert_gid(int gidin) -{ - if ( gidin == -1 ) - return 0; - return gidin; -} - #if defined(__linux__) && defined(__KERNEL__) extern struct buffer_head * @@ -138,7 +124,6 @@ if (UDF_I_LENALLOC(inode)) { memmove(&ad[size], ad, UDF_I_LENALLOC(inode)); - UDF_I_EXT0OFFS(inode) += size; } if (UDF_I_LENEATTR(inode)) diff -ur --new-file old/linux/fs/udf/namei.c new/linux/fs/udf/namei.c --- old/linux/fs/udf/namei.c Tue Jan 4 22:02:23 2000 +++ new/linux/fs/udf/namei.c Tue Jan 25 20:19:04 2000 @@ -15,14 +15,13 @@ * ftp://prep.ai.mit.edu/pub/gnu/GPL * Each contributing author retains all rights to their own work. * - * (C) 1998-1999 Ben Fennema - * (C) 1999 Stelias Computing Inc + * (C) 1998-2000 Ben Fennema + * (C) 1999-2000 Stelias Computing Inc * * HISTORY * - * 12/12/98 blf Created. Split out the lookup code from dir.c - * 04/19/99 blf link, mknod, symlink support - * + * 12/12/98 blf Created. Split out the lookup code from dir.c + * 04/19/99 blf link, mknod, symlink support */ #include "udfdecl.h" @@ -153,7 +152,7 @@ char *nameptr; Uint8 lfi; Uint16 liu; - loff_t size = (UDF_I_EXT0OFFS(dir) + dir->i_size) >> 2; + loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; lb_addr bloc, eloc; Uint32 extoffset, elen, offset; struct buffer_head *bh = NULL; @@ -161,7 +160,7 @@ if (!dir) return NULL; - f_pos = (UDF_I_EXT0OFFS(dir) >> 2); + f_pos = (udf_ext0_offset(dir) >> 2); fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), @@ -297,6 +296,9 @@ struct FileIdentDesc cfi, *fi; struct udf_fileident_bh fibh; + if (dentry->d_name.len > UDF_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); + #ifdef UDF_RECOVERY /* temporary shorthand for specifying files by inode number */ if (!strncmp(dentry->d_name.name, ".B=", 3) ) @@ -336,7 +338,7 @@ loff_t f_pos; int flen; char *nameptr; - loff_t size = (UDF_I_EXT0OFFS(dir) + dir->i_size) >> 2; + loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; int nfidlen; Uint8 lfi; Uint16 liu; @@ -370,7 +372,7 @@ nfidlen = (sizeof(struct FileIdentDesc) + 0 + namelen + 3) & ~3; - f_pos = (UDF_I_EXT0OFFS(dir) >> 2); + f_pos = (udf_ext0_offset(dir) >> 2); fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), @@ -473,13 +475,13 @@ { udf_release_data(bh); bh = NULL; - fibh->soffset -= UDF_I_EXT0OFFS(dir); - fibh->eoffset -= UDF_I_EXT0OFFS(dir); - f_pos -= (UDF_I_EXT0OFFS(dir) >> 2); + fibh->soffset -= udf_ext0_offset(dir); + fibh->eoffset -= udf_ext0_offset(dir); + f_pos -= (udf_ext0_offset(dir) >> 2); if (fibh->sbh != fibh->ebh) udf_release_data(fibh->ebh); udf_release_data(fibh->sbh); - if (!(fibh->sbh = fibh->ebh = udf_expand_adinicb(dir, &block, 1, err))) + if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err))) return NULL; bloc = UDF_I_LOCATION(dir); extoffset = udf_file_entry_alloc_offset(dir); @@ -640,7 +642,7 @@ if (!inode) return err; - inode->i_op = &udf_file_inode_operations; + inode->i_op = &udf_file_inode_operations_adinicb; inode->i_mode = mode; mark_inode_dirty(inode); @@ -682,6 +684,7 @@ goto out; inode->i_uid = current->fsuid; + init_special_inode(inode, mode, rdev); inode->i_mode = mode; inode->i_op = NULL; if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) @@ -702,7 +705,6 @@ mark_inode_dirty(dir); dir->i_version = ++event; } - init_special_inode(inode, mode, rdev); mark_inode_dirty(inode); if (fibh.sbh != fibh.ebh) @@ -734,19 +736,9 @@ inode->i_op = &udf_dir_inode_operations; inode->i_size = (sizeof(struct FileIdentDesc) + 3) & ~3; - if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB) - { - UDF_I_EXT0LEN(inode) = inode->i_size; - UDF_I_EXT0LOC(inode) = UDF_I_LOCATION(inode); - UDF_I_LENALLOC(inode) = inode->i_size; - loc = UDF_I_LOCATION(inode).logicalBlockNum; - fibh.sbh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize); - } - else - { - fibh.sbh = udf_bread (inode, 0, 1, &err); - loc = UDF_I_EXT0LOC(inode).logicalBlockNum; - } + UDF_I_LENALLOC(inode) = inode->i_size; + loc = UDF_I_LOCATION(inode).logicalBlockNum; + fibh.sbh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize); if (!fibh.sbh) { @@ -809,13 +801,13 @@ struct FileIdentDesc *fi, cfi; struct udf_fileident_bh fibh; loff_t f_pos; - loff_t size = (UDF_I_EXT0OFFS(dir) + dir->i_size) >> 2; + loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; int block; lb_addr bloc, eloc; Uint32 extoffset, elen, offset; struct buffer_head *bh = NULL; - f_pos = (UDF_I_EXT0OFFS(dir) >> 2); + f_pos = (udf_ext0_offset(dir) >> 2); fibh.soffset = fibh.eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), @@ -1170,7 +1162,7 @@ } if (S_ISDIR(old_inode->i_mode)) { - Uint32 offset = UDF_I_EXT0OFFS(old_inode); + Uint32 offset = udf_ext0_offset(old_inode); if (new_inode) { @@ -1201,6 +1193,14 @@ goto end_rename; } new_dir->i_version = ++event; + + /* + * Like most other Unix systems, set the ctime for inodes on a + * rename. + */ + old_inode->i_ctime = CURRENT_TIME; + UDF_I_UCTIME(old_inode) = CURRENT_UTIME; + mark_inode_dirty(old_inode); /* * ok, that's it diff -ur --new-file old/linux/fs/udf/partition.c new/linux/fs/udf/partition.c --- old/linux/fs/udf/partition.c Sat Sep 4 21:42:30 1999 +++ new/linux/fs/udf/partition.c Tue Jan 25 20:19:04 2000 @@ -30,161 +30,204 @@ #include #include #include +#include -extern Uint32 udf_get_pblock(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset) +inline Uint32 udf_get_pblock(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset) { - Uint16 ident; - if (partition >= UDF_SB_NUMPARTS(sb)) { udf_debug("block=%d, partition=%d, offset=%d: invalid partition\n", block, partition, offset); return 0xFFFFFFFF; } - switch (UDF_SB_PARTTYPE(sb, partition)) + if (UDF_SB_PARTFUNC(sb, partition)) + return UDF_SB_PARTFUNC(sb, partition)(sb, block, partition, offset); + else + return UDF_SB_PARTROOT(sb, partition) + block + offset; +} + +Uint32 udf_get_pblock_virt15(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset) +{ + struct buffer_head *bh = NULL; + Uint32 newblock; + Uint32 index; + Uint32 loc; + + index = (sb->s_blocksize - UDF_SB_TYPEVIRT(sb,partition).s_start_offset) / sizeof(Uint32); + + if (block > UDF_SB_TYPEVIRT(sb,partition).s_num_entries) { - case UDF_TYPE1_MAP15: - { - return UDF_SB_PARTROOT(sb, partition) + block + offset; - } - case UDF_VIRTUAL_MAP15: - case UDF_VIRTUAL_MAP20: - { - struct buffer_head *bh = NULL; - Uint32 newblock; - Uint32 index; - Uint32 loc; + udf_debug("Trying to access block beyond end of VAT (%d max %d)\n", + block, UDF_SB_TYPEVIRT(sb,partition).s_num_entries); + return 0xFFFFFFFF; + } - index = (sb->s_blocksize - UDF_SB_TYPEVIRT(sb,partition).s_start_offset) / sizeof(Uint32); + if (block >= index) + { + block -= index; + newblock = 1 + (block / (sb->s_blocksize / sizeof(Uint32))); + index = block % (sb->s_blocksize / sizeof(Uint32)); + } + else + { + newblock = 0; + index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(Uint32) + block; + } + loc = udf_locked_block_map(UDF_SB_VAT(sb), newblock); - if (block > UDF_SB_TYPEVIRT(sb,partition).s_num_entries) - { - udf_debug("Trying to access block beyond end of VAT (%d max %d)\n", - block, UDF_SB_TYPEVIRT(sb,partition).s_num_entries); - return 0xFFFFFFFF; - } + if (!(bh = bread(sb->s_dev, loc, sb->s_blocksize))) + { + udf_debug("get_pblock(UDF_VIRTUAL_MAP:%p,%d,%d) VAT: %d[%d]\n", + sb, block, partition, loc, index); + return 0xFFFFFFFF; + } - if (block >= index) - { - block -= index; - newblock = 1 + (block / (sb->s_blocksize / sizeof(Uint32))); - index = block % (sb->s_blocksize / sizeof(Uint32)); - } - else - { - newblock = 0; - index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(Uint32) + block; - } + loc = le32_to_cpu(((Uint32 *)bh->b_data)[index]); - loc = udf_locked_block_map(UDF_SB_VAT(sb), newblock); + udf_release_data(bh); - if (!(bh = bread(sb->s_dev, loc, sb->s_blocksize))) - { - udf_debug("get_pblock(UDF_VIRTUAL_MAP:%p,%d,%d) VAT: %d[%d]\n", - sb, block, partition, loc, index); - return 0xFFFFFFFF; - } + if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition) + { + udf_debug("recursive call to udf_get_pblock!\n"); + return 0xFFFFFFFF; + } - loc = le32_to_cpu(((Uint32 *)bh->b_data)[index]); + return udf_get_pblock(sb, loc, UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum, offset); +} - udf_release_data(bh); +inline Uint32 udf_get_pblock_virt20(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset) +{ + return udf_get_pblock_virt15(sb, block, partition, offset); +} - if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition) - { - udf_debug("recursive call to udf_get_pblock!\n"); - return 0xFFFFFFFF; - } +Uint32 udf_get_pblock_spar15(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset) +{ + Uint32 packet = (block + offset) >> UDF_SB_TYPESPAR(sb,partition).s_spar_pshift; + Uint32 index = 0; - return udf_get_pblock(sb, loc, UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum, offset); - } - case UDF_SPARABLE_MAP15: - { - Uint32 newblock = UDF_SB_PARTROOT(sb, partition) + block + offset; - Uint32 spartable = UDF_SB_TYPESPAR(sb, partition).s_spar_loc; - Uint32 plength = UDF_SB_TYPESPAR(sb,partition).s_spar_plen; - Uint32 packet = (block + offset) & (~(plength-1)); - struct buffer_head *bh = NULL; - struct SparingTable *st; - SparingEntry *se; + if (UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize == 8) + index = UDF_SB_TYPESPAR(sb,partition).s_spar_remap.s_spar_remap8[packet]; + else if (UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize == 16) + index = UDF_SB_TYPESPAR(sb,partition).s_spar_remap.s_spar_remap16[packet]; + else if (UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize == 32) + index = UDF_SB_TYPESPAR(sb,partition).s_spar_remap.s_spar_remap32[packet]; - bh = udf_read_tagged(sb, spartable, spartable, &ident); + if (index == ((1 << UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize)-1)) + return UDF_SB_PARTROOT(sb,partition) + block + offset; - if (!bh) - { - printk(KERN_ERR "udf: udf_read_tagged(%p,%d,%d)\n", - sb, spartable, spartable); - return 0xFFFFFFFF; - } + packet = UDF_SB_TYPESPAR(sb,partition).s_spar_map[index]; + return packet + ((block + offset) & ((1 << UDF_SB_TYPESPAR(sb,partition).s_spar_pshift)-1)); +} + +void udf_fill_spartable(struct super_block *sb, struct udf_sparing_data *sdata, int partlen) +{ + Uint16 ident; + Uint32 spartable; + int i; + struct buffer_head *bh; + struct SparingTable *st; + + for (i=0; i<4; i++) + { + if (!(spartable = sdata->s_spar_loc[i])) + continue; + + bh = udf_read_tagged(sb, spartable, spartable, &ident); + + if (!bh) + { + sdata->s_spar_loc[i] = 0; + continue; + } + if (ident == 0) + { st = (struct SparingTable *)bh->b_data; - if (ident == 0) + if (!strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING))) { - if (!strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING))) - { - Uint16 rtl = le16_to_cpu(st->reallocationTableLen); - Uint16 index; + SparingEntry *se; + Uint16 rtl = le16_to_cpu(st->reallocationTableLen); + int index; - /* If the sparing table span multiple blocks, find out which block we are on */ - - se = &(st->mapEntry[0]); + if (!sdata->s_spar_map) + { + int num = 1, mapsize; + sdata->s_spar_indexsize = 8; + while (rtl*sizeof(Uint32) >= (1 << sdata->s_spar_indexsize)) + { + num ++; + sdata->s_spar_indexsize <<= 1; + } + mapsize = (rtl * sizeof(Uint32)) + + ((partlen/(1 << sdata->s_spar_pshift)) * sizeof(Uint8) * num); + sdata->s_spar_map = kmalloc(mapsize, GFP_KERNEL); + sdata->s_spar_remap.s_spar_remap32 = &sdata->s_spar_map[rtl]; + memset(sdata->s_spar_map, 0xFF, mapsize); + } - if (rtl * sizeof(SparingEntry) + sizeof(struct SparingTable) > sb->s_blocksize) + index = sizeof(struct SparingTable); + for (i=0; i sb->s_blocksize) { - index = (sb->s_blocksize - sizeof(struct SparingTable)) / sizeof(SparingEntry); - if (le32_to_cpu(se[index-1].origLocation) == packet) + udf_release_data(bh); + bh = udf_tread(sb, ++spartable, sb->s_blocksize); + if (!bh) { - udf_release_data(bh); - return le32_to_cpu(se[index].mappedLocation) | (newblock & (plength-1)); + sdata->s_spar_loc[i] = 0; + continue; } - else if (le32_to_cpu(se[index-1].origLocation) < packet) + index = 0; + } + se = (SparingEntry *)&(bh->b_data[index]); + index += sizeof(SparingEntry); + + if (sdata->s_spar_map[i] == 0xFFFFFFFF) + sdata->s_spar_map[i] = le32_to_cpu(se->mappedLocation); + else if (sdata->s_spar_map[i] != le32_to_cpu(se->mappedLocation)) + { + udf_debug("Found conflicting Sparing Data (%d vs %d for entry %d)\n", + sdata->s_spar_map[i], le32_to_cpu(se->mappedLocation), i); + } + + if (le32_to_cpu(se->origLocation) < 0xFFFFFFF0) + { + int packet = le32_to_cpu(se->origLocation) >> sdata->s_spar_pshift; + if (sdata->s_spar_indexsize == 8) { - do + if (sdata->s_spar_remap.s_spar_remap8[packet] == 0xFF) + sdata->s_spar_remap.s_spar_remap8[packet] = i; + else if (sdata->s_spar_remap.s_spar_remap8[packet] != i) { - udf_release_data(bh); - bh = udf_tread(sb, spartable, sb->s_blocksize); - if (!bh) - return 0xFFFFFFFF; - se = (SparingEntry *)bh->b_data; - spartable ++; - rtl -= index; - index = sb->s_blocksize / sizeof(SparingEntry); - - if (le32_to_cpu(se[index].origLocation) == packet) - { - udf_release_data(bh); - return le32_to_cpu(se[index].mappedLocation) | (newblock & (plength-1)); - } - } while (rtl * sizeof(SparingEntry) > sb->s_blocksize && - le32_to_cpu(se[index-1].origLocation) < packet); + udf_debug("Found conflicting Sparing Data (%d vs %d)\n", + sdata->s_spar_remap.s_spar_remap8[packet], i); + } } - } - - for (index=0; indexs_spar_indexsize == 16) { - udf_release_data(bh); - return le32_to_cpu(se[index].mappedLocation) | (newblock & (plength-1)); + if (sdata->s_spar_remap.s_spar_remap16[packet] == 0xFFFF) + sdata->s_spar_remap.s_spar_remap16[packet] = i; + else if (sdata->s_spar_remap.s_spar_remap16[packet] != i) + { + udf_debug("Found conflicting Sparing Data (%d vs %d)\n", + sdata->s_spar_remap.s_spar_remap16[packet], i); + } } - else if (le32_to_cpu(se[index].origLocation) > packet) + else if (sdata->s_spar_indexsize == 32) { - udf_release_data(bh); - return newblock; + if (sdata->s_spar_remap.s_spar_remap32[packet] == 0xFFFFFFFF) + sdata->s_spar_remap.s_spar_remap32[packet] = i; + else if (sdata->s_spar_remap.s_spar_remap32[packet] != i) + { + udf_debug("Found conflicting Sparing Data (%d vs %d)\n", + sdata->s_spar_remap.s_spar_remap32[packet], i); + } } } - - udf_release_data(bh); - return newblock; } } - udf_release_data(bh); } + udf_release_data(bh); } - return 0xFFFFFFFF; -} - -extern Uint32 udf_get_lb_pblock(struct super_block *sb, lb_addr loc, Uint32 offset) -{ - return udf_get_pblock(sb, loc.logicalBlockNum, loc.partitionReferenceNum, offset); } diff -ur --new-file old/linux/fs/udf/super.c new/linux/fs/udf/super.c --- old/linux/fs/udf/super.c Thu Jan 6 19:14:36 2000 +++ new/linux/fs/udf/super.c Tue Jan 25 20:19:04 2000 @@ -26,7 +26,8 @@ * Each contributing author retains all rights to their own work. * * (C) 1998 Dave Boynton - * (C) 1998-1999 Ben Fennema + * (C) 1998-2000 Ben Fennema + * (C) 2000 Stelias Computing Inc * * HISTORY * @@ -91,29 +92,27 @@ static void udf_open_lvid(struct super_block *); static void udf_close_lvid(struct super_block *); static unsigned int udf_count_free(struct super_block *); - -/* version specific functions */ static int udf_statfs(struct super_block *, struct statfs *, int); /* UDF filesystem type */ static struct file_system_type udf_fstype = { - "udf", /* name */ + "udf", /* name */ FS_REQUIRES_DEV, /* fs_flags */ udf_read_super, /* read_super */ - NULL /* next */ + NULL /* next */ }; /* Superblock operations */ static struct super_operations udf_sb_ops = { udf_read_inode, /* read_inode */ -#ifdef CONFIG_UDF_RW +#if CONFIG_UDF_RW == 1 udf_write_inode, /* write_inode */ #else NULL, /* write_inode */ #endif udf_put_inode, /* put_inode */ -#ifdef CONFIG_UDF_RW +#if CONFIG_UDF_RW == 1 udf_delete_inode, /* delete_inode */ #else NULL, /* delete_inode */ @@ -130,7 +129,6 @@ struct udf_options { unsigned char novrs; - unsigned char utf8; unsigned int blocksize; unsigned int session; unsigned int lastblock; @@ -143,7 +141,6 @@ mode_t umask; gid_t gid; uid_t uid; - char *iocharset; }; #if defined(MODULE) @@ -194,8 +191,8 @@ if ( size < sizeof(struct udf_sb_info) ) { printk(KERN_ERR "udf: Danger! Kernel was compiled without enough room for udf_sb_info\n"); - printk(KERN_ERR "udf: Kernel has room for %u bytes, udf needs %u\n", - size, sizeof(struct udf_sb_info)); + printk(KERN_ERR "udf: Kernel has room for %u bytes, udf needs %lu\n", + size, (unsigned long)sizeof(struct udf_sb_info)); return 0; } } @@ -217,8 +214,6 @@ * unhide Show otherwise hidden files. * undelete Show deleted files in lists. * strict Set strict conformance (unused) - * utf8 (unused) - * iocharset (unused) * * The remaining are for debugging and disaster recovery: * @@ -267,7 +262,6 @@ uopt->volume = 0xFFFFFFFF; uopt->rootdir = 0xFFFFFFFF; uopt->fileset = 0xFFFFFFFF; - uopt->iocharset = NULL; if (!options) return 1; @@ -280,8 +274,6 @@ *(val++) = 0; if (!strcmp(opt, "novrs") && !val) uopt->novrs = 1; - else if (!strcmp(opt, "utf8") && !val) - uopt->utf8 = 1; else if (!strcmp(opt, "bs") && val) uopt->blocksize = simple_strtoul(val, NULL, 0); else if (!strcmp(opt, "unhide") && !val) @@ -310,15 +302,6 @@ uopt->fileset = simple_strtoul(val, NULL, 0); else if (!strcmp(opt, "rootdir") && val) uopt->rootdir = simple_strtoul(val, NULL, 0); - else if (!strcmp(opt, "iocharset") && val) - { - uopt->iocharset = val; - while (*val && *val != ',') - val ++; - if (val == uopt->iocharset) - return 0; - *val = 0; - } else if (val) { printk(KERN_ERR "udf: bad mount option \"%s=%s\"\n", @@ -344,7 +327,6 @@ uopt.uid = UDF_SB(sb)->s_uid ; uopt.gid = UDF_SB(sb)->s_gid ; uopt.umask = UDF_SB(sb)->s_umask ; - uopt.utf8 = UDF_SB(sb)->s_utf8 ; if ( !udf_parse_options(options, &uopt) ) return -EINVAL; @@ -353,7 +335,6 @@ UDF_SB(sb)->s_uid = uopt.uid; UDF_SB(sb)->s_gid = uopt.gid; UDF_SB(sb)->s_umask = uopt.umask; - UDF_SB(sb)->s_utf8 = uopt.utf8; if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) return 0; @@ -841,6 +822,9 @@ UDF_SB_PARTROOT(sb,i) = le32_to_cpu(p->partitionStartingLocation) + UDF_SB_SESSION(sb); UDF_SB_PARTMAPS(sb)[i].s_uspace_bitmap = 0xFFFFFFFF; + if (UDF_SB_PARTTYPE(sb,i) == UDF_SPARABLE_MAP15) + udf_fill_spartable(sb, &UDF_SB_TYPESPAR(sb,i), UDF_SB_PARTLEN(sb,i)); + if (!strcmp(p->partitionContents.ident, PARTITION_CONTENTS_NSR02) || !strcmp(p->partitionContents.ident, PARTITION_CONTENTS_NSR03)) { @@ -882,7 +866,7 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, lb_addr *fileset) { struct LogicalVolDesc *lvd; - int i, offset; + int i, j, offset; Uint8 type; lvd = (struct LogicalVolDesc *)bh->b_data; @@ -902,6 +886,7 @@ UDF_SB_PARTTYPE(sb,i) = UDF_TYPE1_MAP15; UDF_SB_PARTVSN(sb,i) = le16_to_cpu(gpm1->volSeqNum); UDF_SB_PARTNUM(sb,i) = le16_to_cpu(gpm1->partitionNum); + UDF_SB_PARTFUNC(sb,i) = NULL; } else if (type == 2) { @@ -909,16 +894,29 @@ if (!strncmp(upm2->partIdent.ident, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL))) { if (le16_to_cpu(((Uint16 *)upm2->partIdent.identSuffix)[0]) == 0x0150) + { UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP15; + UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt15; + } else if (le16_to_cpu(((Uint16 *)upm2->partIdent.identSuffix)[0]) == 0x0200) + { UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP20; + UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt20; + } } else if (!strncmp(upm2->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE))) { + int plen; + struct SparablePartitionMap *spm = (struct SparablePartitionMap *)&(lvd->partitionMaps[offset]); UDF_SB_PARTTYPE(sb,i) = UDF_SPARABLE_MAP15; - UDF_SB_TYPESPAR(sb,i).s_spar_plen = le16_to_cpu(spm->packetLength); - UDF_SB_TYPESPAR(sb,i).s_spar_loc = le32_to_cpu(spm->locSparingTable[0]); + plen = le16_to_cpu(spm->packetLength); + UDF_SB_TYPESPAR(sb,i).s_spar_pshift = 0; + while (plen >>= 1) + UDF_SB_TYPESPAR(sb,i).s_spar_pshift ++; + for (j=0; jnumSparingTables; j++) + UDF_SB_TYPESPAR(sb,i).s_spar_loc[j] = le32_to_cpu(spm->locSparingTable[j]); + UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_spar15; } else { @@ -1190,7 +1188,7 @@ if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP15) { - UDF_SB_TYPEVIRT(sb,i).s_start_offset = UDF_I_EXT0OFFS(UDF_SB_VAT(sb)); + UDF_SB_TYPEVIRT(sb,i).s_start_offset = udf_ext0_offset(UDF_SB_VAT(sb)); UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size - 36) >> 2; } else if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP20) @@ -1201,8 +1199,8 @@ pos = udf_block_map(UDF_SB_VAT(sb), 0); bh = bread(sb->s_dev, pos, sb->s_blocksize); UDF_SB_TYPEVIRT(sb,i).s_start_offset = - le16_to_cpu(((struct VirtualAllocationTable20 *)bh->b_data + UDF_I_EXT0OFFS(UDF_SB_VAT(sb)))->lengthHeader) + - UDF_I_EXT0OFFS(UDF_SB_VAT(sb)); + le16_to_cpu(((struct VirtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) + + udf_ext0_offset(UDF_SB_VAT(sb)); UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size - UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2; udf_release_data(bh); @@ -1218,7 +1216,7 @@ static void udf_open_lvid(struct super_block *sb) { -#ifdef CONFIG_UDF_RW +#if CONFIG_UDF_RW == 1 if (UDF_SB_LVIDBH(sb)) { int i; @@ -1247,7 +1245,7 @@ static void udf_close_lvid(struct super_block *sb) { -#ifdef CONFIG_UDF_RW +#if CONFIG_UDF_RW == 1 if (UDF_SB_LVIDBH(sb) && UDF_SB_LVID(sb)->integrityType == INTEGRITY_TYPE_OPEN) { @@ -1301,10 +1299,9 @@ int i; uopt.flags = 0; - uopt.uid = 0; - uopt.gid = 0; + uopt.uid = -1; + uopt.gid = -1; uopt.umask = 0; - uopt.utf8 = 0; /* Lock the module in memory (if applicable) */ MOD_INC_USE_COUNT; @@ -1328,7 +1325,6 @@ UDF_SB(sb)->s_uid = uopt.uid; UDF_SB(sb)->s_gid = uopt.gid; UDF_SB(sb)->s_umask = uopt.umask; - UDF_SB(sb)->s_utf8 = uopt.utf8; /* Set the block size for all transfers */ if (!udf_set_blocksize(sb, uopt.blocksize)) @@ -1356,20 +1352,6 @@ goto error_out; } - UDF_SB_CHARSET(sb) = NULL; - -#ifdef CONFIG_NLS - if (uopt.utf8 == 0) - { - char *p = uopt.iocharset ? uopt.iocharset : "iso8859-1"; - UDF_SB_CHARSET(sb) = load_nls(p); - if (!UDF_SB_CHARSET(sb)) - if (uopt.iocharset) - goto error_out; - UDF_SB_CHARSET(sb) = load_nls_default(); - } -#endif - /* Fill in the rest of the superblock */ sb->s_op = &udf_sb_ops; sb->dq_op = NULL; @@ -1405,7 +1387,8 @@ { timestamp ts; udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb), 0); - udf_info("Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n", + udf_info("UDF %s (%s) Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n", + UDFFS_VERSION, UDFFS_DATE, UDF_SB_VOLIDENT(sb), ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.typeAndTimezone); } diff -ur --new-file old/linux/fs/udf/symlink.c new/linux/fs/udf/symlink.c --- old/linux/fs/udf/symlink.c Thu Dec 9 22:10:18 1999 +++ new/linux/fs/udf/symlink.c Tue Jan 25 20:19:04 2000 @@ -15,7 +15,7 @@ * ftp://prep.ai.mit.edu/pub/gnu/GPL * Each contributing author retains all rights to their own work. * - * (C) 1998-1999 Ben Fennema + * (C) 1998-2000 Ben Fennema * (C) 1999 Stelias Computing Inc * * HISTORY @@ -39,14 +39,17 @@ static void udf_pc_to_char(char *from, int fromlen, char *to) { struct PathComponent *pc; - int elen = 0, len = 0; + int elen = 0; char *p = to; - while (elen < fromlen) { + while (elen < fromlen) + { pc = (struct PathComponent *)(from + elen); - switch (pc->componentType) { + switch (pc->componentType) + { case 1: - if (pc->lengthComponentIdent == 0) { + if (pc->lengthComponentIdent == 0) + { p = to; *p++ = '/'; } @@ -61,17 +64,16 @@ /* that would be . - just ignore */ break; case 5: - memcpy(p+len, pc->componentIdent, - pc->lengthComponentIdent); + memcpy(p, pc->componentIdent, pc->lengthComponentIdent); p += pc->lengthComponentIdent; *p++ = '/'; } elen += sizeof(struct PathComponent) + pc->lengthComponentIdent; } - - if (p>to+1) { + if (p > to+1) p[-1] = '\0'; - } + else + p[0] = '\0'; } static int udf_symlink_filler(struct dentry * dentry, struct page *page) @@ -79,20 +81,20 @@ struct inode *inode = dentry->d_inode; struct buffer_head *bh = NULL; char *symlink; - int err; - - char *p = (char*)kmap(page); + int err = -EIO; + char *p = (char *)kmap(page); - err = -EIO; - if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB) { - bh = udf_tread(inode->i_sb, inode->i_ino, - inode->i_sb->s_blocksize); + if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB) + { + bh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize); if (!bh) goto out; symlink = bh->b_data + udf_file_entry_alloc_offset(inode); - } else { + } + else + { bh = bread(inode->i_dev, udf_block_map(inode, 0), inode->i_sb->s_blocksize); @@ -104,6 +106,7 @@ udf_pc_to_char(symlink, inode->i_size, p); udf_release_data(bh); + SetPageUptodate(page); kunmap(page); UnlockPage(page); @@ -112,14 +115,29 @@ SetPageError(page); kunmap(page); UnlockPage(page); - return -EIO; + return err; } /* * symlinks can't do much... */ struct inode_operations udf_symlink_inode_operations = { - readlink: page_readlink, - follow_link: page_follow_link, - readpage: udf_symlink_filler, + NULL, /* no file-operations */ + NULL, /* create */ + NULL, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + page_readlink, /* readlink */ + page_follow_link, /* follow_link */ + NULL, /* get_block */ + udf_symlink_filler, /* readpage */ + NULL, /* writepage */ + NULL, /* truncate */ + NULL, /* permission */ + NULL /* revalidate */ }; diff -ur --new-file old/linux/fs/udf/truncate.c new/linux/fs/udf/truncate.c --- old/linux/fs/udf/truncate.c Fri Nov 19 20:35:10 1999 +++ new/linux/fs/udf/truncate.c Tue Jan 25 20:19:04 2000 @@ -15,7 +15,7 @@ * ftp://prep.ai.mit.edu/pub/gnu/GPL * Each contributing author retains all rights to their own work. * - * (C) 1999 Ben Fennema + * (C) 1999-2000 Ben Fennema * (C) 1999 Stelias Computing Inc * * HISTORY @@ -33,32 +33,29 @@ #include "udf_sb.h" static void extent_trunc(struct inode * inode, lb_addr bloc, int *extoffset, - lb_addr eloc, Uint32 elen, struct buffer_head **bh, Uint32 offset) + lb_addr eloc, Uint8 etype, Uint32 elen, struct buffer_head **bh, Uint32 offset) { lb_addr neloc = { 0, 0 }; - int nelen = 0; + int nelen = 0; int blocks = inode->i_sb->s_blocksize / 512; int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits; if (offset) { - nelen = ((offset - 1) << inode->i_sb->s_blocksize_bits) + - (inode->i_size & (inode->i_sb->s_blocksize - 1)); + nelen = (etype << 30) | + (((offset - 1) << inode->i_sb->s_blocksize_bits) + + (inode->i_size & (inode->i_sb->s_blocksize - 1))); neloc = eloc; } - - inode->i_blocks -= (blocks * (last_block - offset)); + if (etype == EXTENT_RECORDED_ALLOCATED) + inode->i_blocks -= (blocks * (last_block - offset)); udf_write_aext(inode, bloc, extoffset, neloc, nelen, bh, 1); - if (!memcmp(&UDF_I_EXT0LOC(inode), &eloc, sizeof(lb_addr))) - { - UDF_I_EXT0LOC(inode) = neloc; - UDF_I_EXT0LEN(inode) = nelen; - } mark_inode_dirty(inode); - udf_free_blocks(inode, eloc, offset, last_block - offset); + if (etype != EXTENT_NOT_RECORDED_NOT_ALLOCATED) + udf_free_blocks(inode, eloc, offset, last_block - offset); } -static void trunc(struct inode * inode) +void udf_trunc(struct inode * inode) { lb_addr bloc, eloc, neloc = { 0, 0 }; Uint32 extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc; @@ -77,7 +74,7 @@ if ((etype = inode_bmap(inode, first_block, &bloc, &extoffset, &eloc, &elen, &offset, &bh)) != -1) { extoffset -= adsize; - extent_trunc(inode, bloc, &extoffset, eloc, elen, &bh, offset); + extent_trunc(inode, bloc, &extoffset, eloc, etype, elen, &bh, offset); if (offset) lenalloc = extoffset; @@ -124,10 +121,8 @@ else lelen = 1; } - else if (etype != EXTENT_NOT_RECORDED_NOT_ALLOCATED) - extent_trunc(inode, bloc, &extoffset, eloc, elen, &bh, 0); else - udf_write_aext(inode, bloc, &extoffset, neloc, nelen, &bh, 1); + extent_trunc(inode, bloc, &extoffset, eloc, etype, elen, &bh, 0); } if (lelen) @@ -151,8 +146,6 @@ } else if (inode->i_size) { - lb_addr e0loc = UDF_I_LOCATION(inode); - Uint32 ext0offset = udf_file_entry_alloc_offset(inode); char tetype; if (offset) @@ -164,8 +157,6 @@ extoffset -= adsize; elen = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) | (elen + (offset << inode->i_sb->s_blocksize_bits)); - if (ext0offset == extoffset && !memcmp(&e0loc, &bloc, sizeof(lb_addr))) - UDF_I_EXT0LEN(inode) = elen; udf_write_aext(inode, bloc, &extoffset, eloc, elen, &bh, 0); } else @@ -176,18 +167,11 @@ elen = (EXTENT_RECORDED_ALLOCATED << 30) | ((elen + inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize - 1)); - if (ext0offset == extoffset && !memcmp(&e0loc, &bloc, sizeof(lb_addr))) - UDF_I_EXT0LEN(inode) = elen; udf_write_aext(inode, bloc, &extoffset, eloc, elen, &bh, 1); } memset(&eloc, 0x00, sizeof(lb_addr)); elen = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) | (offset << inode->i_sb->s_blocksize_bits); - if (ext0offset == extoffset && !memcmp(&e0loc, &bloc, sizeof(lb_addr))) - { - UDF_I_EXT0LOC(inode) = eloc; - UDF_I_EXT0LEN(inode) = elen; - } udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1); } } @@ -204,12 +188,7 @@ if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) return; - if (!UDF_I_EXT0OFFS(inode)) - { - udf_discard_prealloc(inode); - - trunc(inode); - } + udf_trunc(inode); inode->i_mtime = inode->i_ctime = CURRENT_TIME; mark_inode_dirty(inode); @@ -222,6 +201,8 @@ return; if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) return; + + UDF_I_LENALLOC(inode) = inode->i_size; inode->i_mtime = inode->i_ctime = CURRENT_TIME; mark_inode_dirty(inode); diff -ur --new-file old/linux/fs/udf/udf_i.h new/linux/fs/udf/udf_i.h --- old/linux/fs/udf/udf_i.h Sat Sep 4 21:42:30 1999 +++ new/linux/fs/udf/udf_i.h Tue Jan 25 20:19:04 2000 @@ -1,11 +1,8 @@ #ifndef __LINUX_UDF_I_H #define __LINUX_UDF_I_H -#define UDF_I(X) (&((X)->u.udf_i)) +#define UDF_I(X) (&((X)->u.udf_i)) -#define UDF_I_EXT0LOC(X) ( UDF_I(X)->i_ext0Location ) -#define UDF_I_EXT0LEN(X) ( UDF_I(X)->i_ext0Length ) -#define UDF_I_EXT0OFFS(X) ( UDF_I(X)->i_ext0Offset ) #define UDF_I_LOCATION(X) ( UDF_I(X)->i_location ) #define UDF_I_LENEATTR(X) ( UDF_I(X)->i_lenEAttr ) #define UDF_I_LENALLOC(X) ( UDF_I(X)->i_lenAlloc ) @@ -13,8 +10,6 @@ #define UDF_I_ALLOCTYPE(X) ( UDF_I(X)->i_alloc_type ) #define UDF_I_EXTENDED_FE(X)( UDF_I(X)->i_extended_fe ) #define UDF_I_STRAT4096(X) ( UDF_I(X)->i_strat_4096 ) -#define UDF_I_PREALLOC_COUNT(X) ( UDF_I(X)->i_prealloc_count ) -#define UDF_I_PREALLOC_BLOCK(X) ( UDF_I(X)->i_prealloc_block ) #define UDF_I_NEXT_ALLOC_BLOCK(X) ( UDF_I(X)->i_next_alloc_block ) #define UDF_I_NEXT_ALLOC_GOAL(X) ( UDF_I(X)->i_next_alloc_goal ) #define UDF_I_UATIME(X) ( UDF_I(X)->i_uatime ) diff -ur --new-file old/linux/fs/udf/udf_sb.h new/linux/fs/udf/udf_sb.h --- old/linux/fs/udf/udf_sb.h Fri Nov 19 20:35:10 1999 +++ new/linux/fs/udf/udf_sb.h Tue Jan 25 20:19:04 2000 @@ -24,6 +24,7 @@ {\ UDF_SB_NUMPARTS(X) = Y;\ UDF_SB_PARTMAPS(X) = kmalloc(sizeof(struct udf_part_map) * Y, GFP_KERNEL);\ + memset(UDF_SB_PARTMAPS(X), 0x00, sizeof(struct udf_part_map) * Y);\ } #define IS_STRICT(X) ( UDF_SB(X)->s_flags & UDF_FLAG_STRICT ) @@ -43,9 +44,7 @@ #define UDF_SB_RECORDTIME(X) ( UDF_SB(X)->s_recordtime ) #define UDF_SB_VOLIDENT(X) ( UDF_SB(X)->s_volident ) #define UDF_SB_PARTMAPS(X) ( UDF_SB(X)->s_partmaps ) -#define UDF_SB_LOCATION(X) ( UDF_SB(X)->s_location ) #define UDF_SB_SERIALNUM(X) ( UDF_SB(X)->s_serialnum ) -#define UDF_SB_CHARSET(X) ( UDF_SB(X)->s_nls_iocharset ) #define UDF_SB_VAT(X) ( UDF_SB(X)->s_vat ) #define UDF_SB_BLOCK_BITMAP_NUMBER(X,Y) ( UDF_SB(X)->s_block_bitmap_number[Y] ) @@ -59,5 +58,6 @@ #define UDF_SB_PARTNUM(X,Y) ( UDF_SB_PARTMAPS(X)[Y].s_partition_num ) #define UDF_SB_TYPESPAR(X,Y) ( UDF_SB_PARTMAPS(X)[Y].s_type_specific.s_sparing ) #define UDF_SB_TYPEVIRT(X,Y) ( UDF_SB_PARTMAPS(X)[Y].s_type_specific.s_virtual ) +#define UDF_SB_PARTFUNC(X,Y) ( UDF_SB_PARTMAPS(X)[Y].s_partition_func ) #endif /* __LINUX_UDF_SB_H */ diff -ur --new-file old/linux/fs/udf/udfdecl.h new/linux/fs/udf/udfdecl.h --- old/linux/fs/udf/udfdecl.h Thu Jan 6 19:14:36 2000 +++ new/linux/fs/udf/udfdecl.h Tue Jan 25 20:19:04 2000 @@ -1,7 +1,7 @@ #ifndef __UDF_DECL_H #define __UDF_DECL_H -#define UDF_VERSION_NOTICE "v0.8.9.4" +#define UDF_VERSION_NOTICE "v0.9.0" #include #include @@ -39,6 +39,12 @@ sizeof(struct ExtendedFileEntry) :\ sizeof(struct FileEntry)) + UDF_I_LENEATTR(inode)) +#define udf_ext0_offset(inode)\ + (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB ?\ + udf_file_entry_alloc_offset(inode) : 0) + +#define udf_get_lb_pblock(sb,loc,offset) udf_get_pblock((sb), (loc).logicalBlockNum, (loc).partitionReferenceNum, (offset)) + #else #include @@ -128,9 +134,12 @@ /* inode.c */ extern struct inode *udf_iget(struct super_block *, lb_addr); extern int udf_sync_inode(struct inode *); -extern struct buffer_head * udf_expand_adinicb(struct inode *, int *, int, int *); +extern void udf_expand_file_adinicb(struct file *, int, int *); +extern struct buffer_head * udf_expand_dir_adinicb(struct inode *, int *, int *); extern struct buffer_head * udf_getblk(struct inode *, long, int, int *); extern int udf_get_block(struct inode *, long, struct buffer_head *, int); +extern int udf_readpage_adinicb (struct dentry *, struct page *); +extern int udf_writepage_adinicb (struct dentry *, struct page *); extern struct buffer_head * udf_bread(struct inode *, int, int, int *); extern void udf_read_inode(struct inode *); extern void udf_put_inode(struct inode *); @@ -163,7 +172,10 @@ /* partition.c */ extern Uint32 udf_get_pblock(struct super_block *, Uint32, Uint16, Uint32); -extern Uint32 udf_get_lb_pblock(struct super_block *, lb_addr, Uint32); +extern Uint32 udf_get_pblock_virt15(struct super_block *, Uint32, Uint16, Uint32); +extern Uint32 udf_get_pblock_virt20(struct super_block *, Uint32, Uint16, Uint32); +extern Uint32 udf_get_pblock_spar15(struct super_block *, Uint32, Uint16, Uint32); +extern void udf_fill_spartable(struct super_block *, struct udf_sparing_data *, int); /* unicode.c */ extern int udf_get_filename(Uint8 *, Uint8 *, int); @@ -173,6 +185,7 @@ extern struct inode * udf_new_inode (const struct inode *, int, int *); /* truncate.c */ +extern void udf_trunc(struct inode *); extern void udf_truncate(struct inode *); extern void udf_truncate_adinicb(struct inode *); @@ -181,6 +194,7 @@ extern int udf_alloc_blocks(const struct inode *, Uint16, Uint32, Uint32); extern int udf_new_block(const struct inode *, Uint16, Uint32, int *); extern int udf_sync_file(struct file *, struct dentry *); +extern int udf_sync_file_adinicb(struct file *, struct dentry *); /* directory.c */ extern Uint8 * udf_filead_read(struct inode *, Uint8 *, Uint8, lb_addr, int *, int *, struct buffer_head **, int *); @@ -207,8 +221,6 @@ extern Uint16 udf_crc(Uint8 *, Uint32, Uint16); /* misc.c */ -extern uid_t udf_convert_uid(int); -extern gid_t udf_convert_gid(int); extern Uint32 udf64_low32(Uint64); extern Uint32 udf64_high32(Uint64); extern void udf_update_tag(char *, int); diff -ur --new-file old/linux/fs/udf/udftime.c new/linux/fs/udf/udftime.c --- old/linux/fs/udf/udftime.c Sat Oct 30 18:42:30 1999 +++ new/linux/fs/udf/udftime.c Tue Jan 25 20:37:21 2000 @@ -139,7 +139,7 @@ gettimeofday(&tv, &sys_tz); #endif - offset = (-sys_tz.tz_minuteswest + (sys_tz.tz_dsttime ? 60 : 0)); + offset = (-sys_tz.tz_minuteswest); if (!dest) return NULL; diff -ur --new-file old/linux/fs/udf/unicode.c new/linux/fs/udf/unicode.c --- old/linux/fs/udf/unicode.c Sat Sep 4 21:42:30 1999 +++ new/linux/fs/udf/unicode.c Tue Jan 25 20:19:04 2000 @@ -38,24 +38,24 @@ { if ( (!dest) || (!src) || (!strlen) || (src->u_len > strlen) ) return 0; - memcpy(dest+1, src->u_name, src->u_len-1); + memcpy(dest+1, src->u_name, src->u_len); dest[0] = src->u_cmpID; - return src->u_len; + return src->u_len + 1; } int udf_ustr_to_char(Uint8 *dest, const struct ustr *src, int strlen) { if ( (!dest) || (!src) || (!strlen) || (src->u_len >= strlen) ) return 0; - memcpy(dest, src->u_name, src->u_len-1); - return src->u_len - 1; + memcpy(dest, src->u_name, src->u_len); + return src->u_len; } int udf_ustr_to_dstring(dstring *dest, const struct ustr *src, int dlength) { if ( udf_ustr_to_dchars(dest, src, dlength-1) ) { - dest[dlength-1] = src->u_len; + dest[dlength-1] = src->u_len + 1; return dlength; } else @@ -69,8 +69,8 @@ memset(dest, 0, sizeof(struct ustr)); memcpy(dest->u_name, src+1, strlen-1); dest->u_cmpID = src[0]; - dest->u_len = strlen; - return strlen; + dest->u_len = strlen-1; + return strlen-1; } int udf_char_to_ustr(struct ustr *dest, const Uint8 *src, int strlen) @@ -80,8 +80,8 @@ memset(dest, 0, sizeof(struct ustr)); memcpy(dest->u_name, src, strlen); dest->u_cmpID = 0x08; - dest->u_len = strlen + 1; - return strlen + 1; + dest->u_len = strlen; + return strlen; } @@ -182,38 +182,21 @@ /* Expand OSTA compressed Unicode to Unicode */ c = ocu[i++]; if (cmp_id == 16) - { c = (c << 8) | ocu[i++]; -#ifdef __KERNEL__ - if (c & 0xFF00) - udf_debug("cmd_id == 16 (0x%2x%2x)\n", - ((c >> 8) & 0xFF), (c & 0xFF)); -#endif - } /* Compress Unicode to UTF-8 */ if (c < 0x80U) utf_o->u_name[utf_o->u_len++] = (Uint8)c; - else if (c < 0x800U) { + else if (c < 0x800U) + { utf_o->u_name[utf_o->u_len++] = (Uint8)(0xc0 | (c >> 6)); utf_o->u_name[utf_o->u_len++] = (Uint8)(0x80 | (c & 0x3f)); -#ifdef __KERNEL__ - udf_debug("(0x%2x%2x) -> (%2x) (%2x)\n", - ((c >> 8) & 0xFF), (c & 0xFF), - utf_o->u_name[utf_o->u_len-2], - utf_o->u_name[utf_o->u_len-1]); -#endif - } else { + } + else + { utf_o->u_name[utf_o->u_len++] = (Uint8)(0xe0 | (c >> 12)); utf_o->u_name[utf_o->u_len++] = (Uint8)(0x80 | ((c >> 6) & 0x3f)); utf_o->u_name[utf_o->u_len++] = (Uint8)(0x80 | (c & 0x3f)); -#ifdef __KERNEL__ - udf_debug("(0x%2x%2x) -> (%2x) (%2x) (%2x)\n", - ((c >> 8) & 0xFF), (c & 0xFF), - utf_o->u_name[utf_o->u_len-3], - utf_o->u_name[utf_o->u_len-2], - utf_o->u_name[utf_o->u_len-1]); -#endif } } utf_o->u_cmpID=8; @@ -259,34 +242,49 @@ try_again: utf_char = 0U; utf_cnt = 0U; - for (i = 0U; i < utf->u_len; i++) { - c = (unsigned)utf->u_name[i]; + for (i = 0U; i < utf->u_len; i++) + { + c = (Uint8)utf->u_name[i]; /* Complete a multi-byte UTF-8 character */ - if (utf_cnt) { + if (utf_cnt) + { utf_char = (utf_char << 6) | (c & 0x3fU); if (--utf_cnt) continue; - } else { + } + else + { /* Check for a multi-byte UTF-8 character */ - if (c & 0x80U) { + if (c & 0x80U) + { /* Start a multi-byte UTF-8 character */ - if ((c & 0xe0U) == 0xc0U) { + if ((c & 0xe0U) == 0xc0U) + { utf_char = c & 0x1fU; utf_cnt = 1; - } else if ((c & 0xf0U) == 0xe0U) { + } + else if ((c & 0xf0U) == 0xe0U) + { utf_char = c & 0x0fU; utf_cnt = 2; - } else if ((c & 0xf8U) == 0xf0U) { + } + else if ((c & 0xf8U) == 0xf0U) + { utf_char = c & 0x07U; utf_cnt = 3; - } else if ((c & 0xfcU) == 0xf8U) { + } + else if ((c & 0xfcU) == 0xf8U) + { utf_char = c & 0x03U; utf_cnt = 4; - } else if ((c & 0xfeU) == 0xfcU) { + } + else if ((c & 0xfeU) == 0xfcU) + { utf_char = c & 0x01U; utf_cnt = 5; - } else + } + else goto error_out; continue; } else @@ -295,8 +293,10 @@ } /* Choose no compression if necessary */ - if (utf_char > max_val) { - if ( 0xffU == max_val ) { + if (utf_char > max_val) + { + if ( 0xffU == max_val ) + { max_val = 0xffffU; ocu[0] = (Uint8)0x10U; goto try_again; @@ -305,11 +305,15 @@ } if (max_val == 0xffffU) + { ocu[++u_len] = (Uint8)(utf_char >> 8); + } ocu[++u_len] = (Uint8)(utf_char & 0xffU); } - if (utf_cnt) { + + if (utf_cnt) + { error_out: #ifdef __KERNEL__ printk(KERN_ERR "udf: bad UTF-8 character\n"); @@ -317,8 +321,8 @@ return 0; } - ocu[length - 1] = (Uint8)u_len; - return u_len; + ocu[length - 1] = (Uint8)u_len + 1; + return u_len + 1; } #ifdef __KERNEL__ diff -ur --new-file old/linux/include/asm-alpha/ioctls.h new/linux/include/asm-alpha/ioctls.h --- old/linux/include/asm-alpha/ioctls.h Fri Feb 13 01:25:04 1998 +++ new/linux/include/asm-alpha/ioctls.h Fri Jan 28 01:40:09 2000 @@ -61,6 +61,9 @@ # define TIOCM_DSR 0x100 # define TIOCM_CD TIOCM_CAR # define TIOCM_RI TIOCM_RNG +# define TIOCM_OUT1 0x2000 +# define TIOCM_OUT2 0x4000 +# define TIOCM_LOOP 0x8000 #define TIOCGSOFTCAR 0x5419 #define TIOCSSOFTCAR 0x541A diff -ur --new-file old/linux/include/asm-alpha/parport.h new/linux/include/asm-alpha/parport.h --- old/linux/include/asm-alpha/parport.h Fri Aug 6 20:16:54 1999 +++ new/linux/include/asm-alpha/parport.h Thu Jan 27 17:58:15 2000 @@ -39,16 +39,16 @@ do { if (!*io_hi) *io_hi = 0x400 + *io; if (parport_pc_probe_port(*(io++), *(io_hi++), - *(irq++), *(dma++))) + *(irq++), *(dma++), NULL)) count++; } while (*io && (++i < PARPORT_PC_MAX_PORTS)); } else { /* Probe all the likely ports. */ - if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0])) + if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0], NULL)) count++; - if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0])) + if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0], NULL)) count++; - if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0])) + if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0], NULL)) count++; count += parport_pc_init_pci (irq[0], dma[0]); } diff -ur --new-file old/linux/include/asm-alpha/siginfo.h new/linux/include/asm-alpha/siginfo.h --- old/linux/include/asm-alpha/siginfo.h Wed Jul 28 19:30:10 1999 +++ new/linux/include/asm-alpha/siginfo.h Tue Jan 25 20:17:07 2000 @@ -149,7 +149,7 @@ #define CLD_TRAPPED 4 /* traced child has trapped */ #define CLD_STOPPED 5 /* child has stopped */ #define CLD_CONTINUED 6 /* stopped child has continued */ -#define NSIGCHLD +#define NSIGCHLD 6 /* * SIGPOLL si_codes diff -ur --new-file old/linux/include/asm-arm/parport.h new/linux/include/asm-arm/parport.h --- old/linux/include/asm-arm/parport.h Thu Oct 21 01:29:08 1999 +++ new/linux/include/asm-arm/parport.h Thu Jan 27 17:58:15 2000 @@ -39,16 +39,16 @@ do { if (!*io_hi) *io_hi = 0x400 + *io; if (parport_pc_probe_port(*(io++), *(io_hi++), - *(irq++), *(dma++))) + *(irq++), *(dma++), NULL)) count++; } while (*io && (++i < PARPORT_PC_MAX_PORTS)); } else { /* Probe all the likely ports. */ - if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0])) + if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0], NULL)) count++; - if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0])) + if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0], NULL)) count++; - if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0])) + if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0], NULL)) count++; count += parport_pc_init_pci (irq[0], dma[0]); } diff -ur --new-file old/linux/include/asm-arm/siginfo.h new/linux/include/asm-arm/siginfo.h --- old/linux/include/asm-arm/siginfo.h Tue Jan 11 03:15:58 2000 +++ new/linux/include/asm-arm/siginfo.h Tue Jan 25 20:17:07 2000 @@ -24,8 +24,7 @@ /* kill() */ struct { pid_t _pid; /* sender's pid */ - old_uid_t _uid; /* backwards compatibility */ - uid_t _uid32; /* sender's uid */ + uid_t _uid; /* sender's uid */ } _kill; /* POSIX.1b timers */ @@ -37,19 +36,17 @@ /* POSIX.1b signals */ struct { pid_t _pid; /* sender's pid */ - old_uid_t _uid; /* backwards compatibility */ + uid_t _uid; /* sender's uid */ sigval_t _sigval; - uid_t _uid32; /* sender's uid */ } _rt; /* SIGCHLD */ struct { pid_t _pid; /* which child */ - old_uid_t _uid; /* backwards compatibility */ + uid_t _uid; /* sender's uid */ int _status; /* exit code */ clock_t _utime; clock_t _stime; - uid_t _uid32; /* sender's uid */ } _sigchld; /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ @@ -65,18 +62,11 @@ } _sifields; } siginfo_t; -#define UID16_SIGINFO_COMPAT_NEEDED - /* * How these fields are to be accessed. */ #define si_pid _sifields._kill._pid -#ifdef __KERNEL__ -#define si_uid _sifields._kill._uid32 -#define si_uid16 _sifields._kill._uid -#else #define si_uid _sifields._kill._uid -#endif /* __KERNEL__ */ #define si_status _sifields._sigchld._status #define si_utime _sifields._sigchld._utime #define si_stime _sifields._sigchld._stime @@ -159,7 +149,7 @@ #define CLD_TRAPPED 4 /* traced child has trapped */ #define CLD_STOPPED 5 /* child has stopped */ #define CLD_CONTINUED 6 /* stopped child has continued */ -#define NSIGCHLD +#define NSIGCHLD 6 /* * SIGPOLL si_codes diff -ur --new-file old/linux/include/asm-arm/termios.h new/linux/include/asm-arm/termios.h --- old/linux/include/asm-arm/termios.h Thu Oct 28 02:04:51 1999 +++ new/linux/include/asm-arm/termios.h Fri Jan 28 01:40:09 2000 @@ -45,6 +45,7 @@ #define TIOCM_RI TIOCM_RNG #define TIOCM_OUT1 0x2000 #define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ diff -ur --new-file old/linux/include/asm-i386/parport.h new/linux/include/asm-i386/parport.h --- old/linux/include/asm-i386/parport.h Fri Aug 6 20:16:54 1999 +++ new/linux/include/asm-i386/parport.h Thu Jan 27 17:58:15 2000 @@ -39,16 +39,16 @@ do { if (!*io_hi) *io_hi = 0x400 + *io; if (parport_pc_probe_port(*(io++), *(io_hi++), - *(irq++), *(dma++))) + *(irq++), *(dma++), NULL)) count++; } while (*io && (++i < PARPORT_PC_MAX_PORTS)); } else { /* Probe all the likely ports. */ - if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0])) + if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0], NULL)) count++; - if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0])) + if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0], NULL)) count++; - if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0])) + if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0], NULL)) count++; count += parport_pc_init_pci (irq[0], dma[0]); } diff -ur --new-file old/linux/include/asm-i386/pci.h new/linux/include/asm-i386/pci.h --- old/linux/include/asm-i386/pci.h Tue Jan 11 23:22:31 2000 +++ new/linux/include/asm-i386/pci.h Fri Jan 28 17:01:55 2000 @@ -10,5 +10,136 @@ #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 +#ifdef __KERNEL__ + +/* Dynamic DMA mapping stuff. + * i386 has everything mapped statically. + */ + +#include +#include +#include +#include +#include + +struct pci_dev; + +/* Allocate and map kernel buffer using consistent mode DMA for a device. + * hwdev should be valid struct pci_dev pointer for PCI devices, + * NULL for PCI-like buses (ISA, EISA). + * Returns non-NULL cpu-view pointer to the buffer if successful and + * sets *dma_addrp to the pci side dma address as well, else *dma_addrp + * is undefined. + */ +extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, + dma_addr_t *dma_handle); + +/* Free and unmap a consistent DMA buffer. + * cpu_addr is what was returned from pci_alloc_consistent, + * size must be the same as what as passed into pci_alloc_consistent, + * and likewise dma_addr must be the same as what *dma_addrp was set to. + * + * References to the memory and mappings associated with cpu_addr/dma_addr + * past this call are illegal. + */ +extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle); + +/* Map a single buffer of the indicated size for DMA in streaming mode. + * The 32-bit bus address to use is returned. + * + * Once the device is given the dma address, the device owns this memory + * until either pci_unmap_single or pci_dma_sync_single is performed. + */ +extern inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, + size_t size) +{ + return virt_to_bus(ptr); +} + +/* Unmap a single streaming mode DMA translation. The dma_addr and size + * must match what was provided for in a previous pci_map_single call. All + * other usages are undefined. + * + * After this call, reads by the cpu to the buffer are guarenteed to see + * whatever the device wrote there. + */ +extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, + size_t size) +{ + /* Nothing to do */ +} + +/* Map a set of buffers described by scatterlist in streaming + * mode for DMA. This is the scather-gather version of the + * above pci_map_single interface. Here the scatter gather list + * elements are each tagged with the appropriate dma address + * and length. They are obtained via sg_dma_{address,length}(SG). + * + * NOTE: An implementation may be able to use a smaller number of + * DMA address/length pairs than there are SG table elements. + * (for example via virtual mapping capabilities) + * The routine returns the number of addr/length pairs actually + * used, at most nents. + * + * Device ownership issues as mentioned above for pci_map_single are + * the same here. + */ +extern inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nents) +{ + return nents; +} + +/* Unmap a set of streaming mode DMA translations. + * Again, cpu read rules concerning calls here are the same as for + * pci_unmap_single() above. + */ +extern inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nents) +{ + /* Nothing to do */ +} + +/* Make physical memory consistent for a single + * streaming mode DMA translation after a transfer. + * + * If you perform a pci_map_single() but wish to interrogate the + * buffer using the cpu, yet do not wish to teardown the PCI dma + * mapping, you must call this function before doing so. At the + * next point you give the PCI dma address back to the card, the + * device again owns the buffer. + */ +extern inline void pci_dma_sync_single(struct pci_dev *hwdev, + dma_addr_t dma_handle, + size_t size) +{ + /* Nothing to do */ +} + +/* Make physical memory consistent for a set of streaming + * mode DMA translations after a transfer. + * + * The same as pci_dma_sync_single but for a scatter-gather list, + * same rules and usage. + */ +extern inline void pci_dma_sync_sg(struct pci_dev *hwdev, + struct scatterlist *sg, + int nelems) +{ + /* Nothing to do */ +} + +/* These macros should be used after a pci_map_sg call has been done + * to get bus addresses of each of the SG entries and their lengths. + * You should only work with the number of sg entries pci_map_sg + * returns, or alternatively stop on the first sg_dma_len(sg) which + * is 0. + */ +#define sg_dma_address(sg) (virt_to_bus((sg)->address)) +#define sg_dma_len(sg) ((sg)->length) + +#endif /* __KERNEL__ */ + #endif /* __i386_PCI_H */ diff -ur --new-file old/linux/include/asm-i386/semaphore.h new/linux/include/asm-i386/semaphore.h --- old/linux/include/asm-i386/semaphore.h Fri Jan 21 01:05:31 2000 +++ new/linux/include/asm-i386/semaphore.h Fri Jan 28 17:01:07 2000 @@ -238,10 +238,17 @@ #define __RWSEM_DEBUG_INIT /* */ #endif -#define __RWSEM_INITIALIZER(name) \ -{ ATOMIC_INIT(RW_LOCK_BIAS), 0, 0, 0, 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \ +#define __RWSEM_INITIALIZER(name,count) \ +{ ATOMIC_INIT(count), 0, 0, 0, 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \ __WAIT_QUEUE_HEAD_INITIALIZER((name).write_bias_wait) \ __SEM_DEBUG_INIT(name) __RWSEM_DEBUG_INIT } + +#define __DECLARE_RWSEM_GENERIC(name,count) \ + struct rw_semaphore name = __RWSEM_INITIALIZER(name,count) + +#define DECLARE_RWSEM(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS) +#define DECLARE_RWSEM_READ_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS-1) +#define DECLARE_RWSEM_WRITE_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,0) extern inline void init_rwsem(struct rw_semaphore *sem) { diff -ur --new-file old/linux/include/asm-i386/siginfo.h new/linux/include/asm-i386/siginfo.h --- old/linux/include/asm-i386/siginfo.h Fri Jan 21 01:05:26 2000 +++ new/linux/include/asm-i386/siginfo.h Fri Jan 28 17:01:05 2000 @@ -24,8 +24,7 @@ /* kill() */ struct { pid_t _pid; /* sender's pid */ - old_uid_t _uid; /* backwards compatibility */ - uid_t _uid32; /* sender's uid */ + uid_t _uid; /* sender's uid */ } _kill; /* POSIX.1b timers */ @@ -37,19 +36,17 @@ /* POSIX.1b signals */ struct { pid_t _pid; /* sender's pid */ - old_uid_t _uid; /* backwards compatibility */ + uid_t _uid; /* sender's uid */ sigval_t _sigval; - uid_t _uid32; /* sender's uid */ } _rt; /* SIGCHLD */ struct { pid_t _pid; /* which child */ - old_uid_t _uid; /* backwards compatibility */ + uid_t _uid; /* sender's uid */ int _status; /* exit code */ clock_t _utime; clock_t _stime; - uid_t _uid32; /* sender's uid */ } _sigchld; /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ @@ -65,18 +62,11 @@ } _sifields; } siginfo_t; -#define UID16_SIGINFO_COMPAT_NEEDED - /* * How these fields are to be accessed. */ #define si_pid _sifields._kill._pid -#ifdef __KERNEL__ -#define si_uid _sifields._kill._uid32 -#define si_uid16 _sifields._kill._uid -#else #define si_uid _sifields._kill._uid -#endif /* __KERNEL__ */ #define si_status _sifields._sigchld._status #define si_utime _sifields._sigchld._utime #define si_stime _sifields._sigchld._stime @@ -159,7 +149,7 @@ #define CLD_TRAPPED 4 /* traced child has trapped */ #define CLD_STOPPED 5 /* child has stopped */ #define CLD_CONTINUED 6 /* stopped child has continued */ -#define NSIGCHLD +#define NSIGCHLD 6 /* * SIGPOLL si_codes diff -ur --new-file old/linux/include/asm-i386/termios.h new/linux/include/asm-i386/termios.h --- old/linux/include/asm-i386/termios.h Fri Jan 21 01:05:26 2000 +++ new/linux/include/asm-i386/termios.h Fri Jan 28 01:40:09 2000 @@ -35,6 +35,7 @@ #define TIOCM_RI TIOCM_RNG #define TIOCM_OUT1 0x2000 #define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ diff -ur --new-file old/linux/include/asm-i386/types.h new/linux/include/asm-i386/types.h --- old/linux/include/asm-i386/types.h Mon Jan 26 20:43:18 1998 +++ new/linux/include/asm-i386/types.h Thu Jan 27 17:58:15 2000 @@ -41,6 +41,10 @@ #define BITS_PER_LONG 32 +/* Dma addresses are 32-bits wide. */ + +typedef u32 dma_addr_t; + #endif /* __KERNEL__ */ #endif diff -ur --new-file old/linux/include/asm-i386/unistd.h new/linux/include/asm-i386/unistd.h --- old/linux/include/asm-i386/unistd.h Tue Jan 11 03:15:58 2000 +++ new/linux/include/asm-i386/unistd.h Wed Jan 26 21:32:02 2000 @@ -221,6 +221,7 @@ #define __NR_setgid32 214 #define __NR_setfsuid32 215 #define __NR_setfsgid32 216 +#define __NR_pivot_root 217 /* user-visible error numbers are in the range -1 - -124: see */ diff -ur --new-file old/linux/include/asm-m68k/amigahw.h new/linux/include/asm-m68k/amigahw.h --- old/linux/include/asm-m68k/amigahw.h Wed Sep 2 18:39:18 1998 +++ new/linux/include/asm-m68k/amigahw.h Wed Jan 26 21:44:21 2000 @@ -281,7 +281,7 @@ #define CHIP_PHYSADDR (0x000000) #define chipaddr ((unsigned long)(zTwoBase + CHIP_PHYSADDR)) void amiga_chip_init (void); -void *amiga_chip_alloc (long size); +void *amiga_chip_alloc (long size, const char *name); void amiga_chip_free (void *); unsigned long amiga_chip_avail( void ); /*MILAN*/ diff -ur --new-file old/linux/include/asm-m68k/apollodma.h new/linux/include/asm-m68k/apollodma.h --- old/linux/include/asm-m68k/apollodma.h Thu Jan 1 01:00:00 1970 +++ new/linux/include/asm-m68k/apollodma.h Fri Jan 28 17:04:58 2000 @@ -0,0 +1,248 @@ +/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $ + * linux/include/asm/dma.h: Defines for using and allocating dma channels. + * Written by Hennus Bergman, 1992. + * High DMA channel support & info by Hannu Savolainen + * and John Boyd, Nov. 1992. + */ + +#ifndef _ASM_APOLLO_DMA_H +#define _ASM_APOLLO_DMA_H + +#include /* need byte IO */ +#include /* And spinlocks */ +#include + + +#define dma_outb(val,addr) (*((volatile unsigned char *)(addr+IO_BASE)) = (val)) +#define dma_inb(addr) (*((volatile unsigned char *)(addr+IO_BASE))) + +/* + * NOTES about DMA transfers: + * + * controller 1: channels 0-3, byte operations, ports 00-1F + * controller 2: channels 4-7, word operations, ports C0-DF + * + * - ALL registers are 8 bits only, regardless of transfer size + * - channel 4 is not used - cascades 1 into 2. + * - channels 0-3 are byte - addresses/counts are for physical bytes + * - channels 5-7 are word - addresses/counts are for physical words + * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries + * - transfer count loaded to registers is 1 less than actual count + * - controller 2 offsets are all even (2x offsets for controller 1) + * - page registers for 5-7 don't use data bit 0, represent 128K pages + * - page registers for 0-3 use bit 0, represent 64K pages + * + * DMA transfers are limited to the lower 16MB of _physical_ memory. + * Note that addresses loaded into registers must be _physical_ addresses, + * not logical addresses (which may differ if paging is active). + * + * Address mapping for channels 0-3: + * + * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses) + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * P7 ... P0 A7 ... A0 A7 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Address mapping for channels 5-7: + * + * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses) + * | ... | \ \ ... \ \ \ ... \ \ + * | ... | \ \ ... \ \ \ ... \ (not used) + * | ... | \ \ ... \ \ \ ... \ + * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses + * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at + * the hardware level, so odd-byte transfers aren't possible). + * + * Transfer count (_not # bytes_) is limited to 64K, represented as actual + * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, + * and up to 128K bytes may be transferred on channels 5-7 in one operation. + * + */ + +#define MAX_DMA_CHANNELS 8 + +/* The maximum address that we can perform a DMA transfer to on this platform */#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x1000000) + +/* 8237 DMA controllers */ +#define IO_DMA1_BASE 0x10C00 /* 8 bit slave DMA, channels 0..3 */ +#define IO_DMA2_BASE 0x10D00 /* 16 bit master DMA, ch 4(=slave input)..7 */ + +/* DMA controller registers */ +#define DMA1_CMD_REG (IO_DMA1_BASE+0x08) /* command register (w) */ +#define DMA1_STAT_REG (IO_DMA1_BASE+0x08) /* status register (r) */ +#define DMA1_REQ_REG (IO_DMA1_BASE+0x09) /* request register (w) */ +#define DMA1_MASK_REG (IO_DMA1_BASE+0x0A) /* single-channel mask (w) */ +#define DMA1_MODE_REG (IO_DMA1_BASE+0x0B) /* mode register (w) */ +#define DMA1_CLEAR_FF_REG (IO_DMA1_BASE+0x0C) /* clear pointer flip-flop (w) */ +#define DMA1_TEMP_REG (IO_DMA1_BASE+0x0D) /* Temporary Register (r) */ +#define DMA1_RESET_REG (IO_DMA1_BASE+0x0D) /* Master Clear (w) */ +#define DMA1_CLR_MASK_REG (IO_DMA1_BASE+0x0E) /* Clear Mask */ +#define DMA1_MASK_ALL_REG (IO_DMA1_BASE+0x0F) /* all-channels mask (w) */ + +#define DMA2_CMD_REG (IO_DMA2_BASE+0x10) /* command register (w) */ +#define DMA2_STAT_REG (IO_DMA2_BASE+0x10) /* status register (r) */ +#define DMA2_REQ_REG (IO_DMA2_BASE+0x12) /* request register (w) */ +#define DMA2_MASK_REG (IO_DMA2_BASE+0x14) /* single-channel mask (w) */ +#define DMA2_MODE_REG (IO_DMA2_BASE+0x16) /* mode register (w) */ +#define DMA2_CLEAR_FF_REG (IO_DMA2_BASE+0x18) /* clear pointer flip-flop (w) */ +#define DMA2_TEMP_REG (IO_DMA2_BASE+0x1A) /* Temporary Register (r) */ +#define DMA2_RESET_REG (IO_DMA2_BASE+0x1A) /* Master Clear (w) */ +#define DMA2_CLR_MASK_REG (IO_DMA2_BASE+0x1C) /* Clear Mask */ +#define DMA2_MASK_ALL_REG (IO_DMA2_BASE+0x1E) /* all-channels mask (w) */ + +#define DMA_ADDR_0 (IO_DMA1_BASE+0x00) /* DMA address registers */ +#define DMA_ADDR_1 (IO_DMA1_BASE+0x02) +#define DMA_ADDR_2 (IO_DMA1_BASE+0x04) +#define DMA_ADDR_3 (IO_DMA1_BASE+0x06) +#define DMA_ADDR_4 (IO_DMA2_BASE+0x00) +#define DMA_ADDR_5 (IO_DMA2_BASE+0x04) +#define DMA_ADDR_6 (IO_DMA2_BASE+0x08) +#define DMA_ADDR_7 (IO_DMA2_BASE+0x0C) + +#define DMA_CNT_0 (IO_DMA1_BASE+0x01) /* DMA count registers */ +#define DMA_CNT_1 (IO_DMA1_BASE+0x03) +#define DMA_CNT_2 (IO_DMA1_BASE+0x05) +#define DMA_CNT_3 (IO_DMA1_BASE+0x07) +#define DMA_CNT_4 (IO_DMA2_BASE+0x02) +#define DMA_CNT_5 (IO_DMA2_BASE+0x06) +#define DMA_CNT_6 (IO_DMA2_BASE+0x0A) +#define DMA_CNT_7 (IO_DMA2_BASE+0x0E) + +#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ +#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ +#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ + +#define DMA_AUTOINIT 0x10 + +#define DMA_8BIT 0 +#define DMA_16BIT 1 +#define DMA_BUSMASTER 2 + +extern spinlock_t dma_spin_lock; + +static __inline__ unsigned long claim_dma_lock(void) +{ + unsigned long flags; + spin_lock_irqsave(&dma_spin_lock, flags); + return flags; +} + +static __inline__ void release_dma_lock(unsigned long flags) +{ + spin_unlock_irqrestore(&dma_spin_lock, flags); +} + +/* enable/disable a specific DMA channel */ +static __inline__ void enable_dma(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(dmanr, DMA1_MASK_REG); + else + dma_outb(dmanr & 3, DMA2_MASK_REG); +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(dmanr | 4, DMA1_MASK_REG); + else + dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while holding the DMA lock ! --- + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(0, DMA1_CLEAR_FF_REG); + else + dma_outb(0, DMA2_CLEAR_FF_REG); +} + +/* set mode (above) for a specific DMA channel */ +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + if (dmanr<=3) + dma_outb(mode | dmanr, DMA1_MODE_REG); + else + dma_outb(mode | (dmanr&3), DMA2_MODE_REG); +} + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) +{ + if (dmanr <= 3) { + dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + } else { + dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + } +} + + +/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for + * a specific DMA channel. + * You must ensure the parameters are valid. + * NOTE: from a manual: "the number of transfers is one more + * than the initial word count"! This is taken into account. + * Assumes dma flip-flop is clear. + * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. + */ +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + count--; + if (dmanr <= 3) { + dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + } else { + dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + } +} + + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE + : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; + + /* using short to get 16-bit wrap around */ + unsigned short count; + + count = 1 + dma_inb(io_port); + count += dma_inb(io_port) << 8; + + return (dmanr<=3)? count : (count<<1); +} + + +/* These are in kernel/dma.c: */ +extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ + +/* These are in arch/m68k/apollo/dma.c: */ +extern unsigned short dma_map_page(unsigned long phys_addr,int count,int type); +extern void dma_unmap_page(unsigned short dma_addr); + +#endif /* _ASM_APOLLO_DMA_H */ diff -ur --new-file old/linux/include/asm-m68k/apollohw.h new/linux/include/asm-m68k/apollohw.h --- old/linux/include/asm-m68k/apollohw.h Fri Feb 13 01:30:13 1998 +++ new/linux/include/asm-m68k/apollohw.h Wed Jan 26 21:44:21 2000 @@ -3,6 +3,18 @@ #ifndef _ASMm68k_APOLLOHW_H_ #define _ASMm68k_APOLLOHW_H_ +/* + apollo models +*/ + +extern u_long apollo_model; + +#define APOLLO_UNKNOWN (0) +#define APOLLO_DN3000 (1) +#define APOLLO_DN3010 (2) +#define APOLLO_DN3500 (3) +#define APOLLO_DN4000 (4) +#define APOLLO_DN4500 (5) /* see scn2681 data sheet for more info. @@ -52,16 +64,42 @@ unsigned char month, year; }; + #define IO_BASE 0x80000000 -#define SIO01_PHYSADDR 0x10400 -#define SIO23_PHYSADDR 0x10500 -#define RTC_PHYSADDR 0x10900 -#define PICA 0x11000 -#define PICB 0x11100 -#define sio01 ((*(volatile struct SCN2681 *)(IO_BASE + SIO01_PHYSADDR))) -#define sio23 ((*(volatile struct SCN2681 *)(IO_BASE + SIO01_PHYSADDR))) -#define rtc (((volatile struct mc146818 *)(IO_BASE + RTC_PHYSADDR))) +extern u_long sio01_physaddr; +extern u_long sio23_physaddr; +extern u_long rtc_physaddr; +extern u_long pica_physaddr; +extern u_long picb_physaddr; +extern u_long cpuctrl_physaddr; +extern u_long timer_physaddr; + +#define SAU7_SIO01_PHYSADDR 0x10400 +#define SAU7_SIO23_PHYSADDR 0x10500 +#define SAU7_RTC_PHYSADDR 0x10900 +#define SAU7_PICA 0x11000 +#define SAU7_PICB 0x11100 +#define SAU7_CPUCTRL 0x10100 +#define SAU7_TIMER 0x010800 + +#define SAU8_SIO01_PHYSADDR 0x8400 +#define SAU8_RTC_PHYSADDR 0x8900 +#define SAU8_PICA 0x9400 +#define SAU8_PICB 0x9500 +#define SAU8_CPUCTRL 0x8100 +#define SAU8_TIMER 0x8800 + +#define sio01 ((*(volatile struct SCN2681 *)(IO_BASE + sio01_physaddr))) +#define sio23 ((*(volatile struct SCN2681 *)(IO_BASE + sio23_physaddr))) +#define rtc (((volatile struct mc146818 *)(IO_BASE + rtc_physaddr))) +#define cpuctrl (*(volatile unsigned int *)(IO_BASE + cpuctrl_physaddr)) +#define pica (IO_BASE + pica_physaddr) +#define picb (IO_BASE + picb_physaddr) +#define timer (IO_BASE + timer_physaddr) +#define addr_xlat_map ((unsigned short *)(IO_BASE + 0x17000)) + +#define isaIO2mem(x) (((((x) & 0x3f8) << 7) | (((x) & 0xfc00) >> 6) | ((x) & 0x7)) + 0x40000 + IO_BASE) #define inb(addr) (*((volatile unsigned char *)(addr))) #define outb(val,addr) (*((volatile unsigned char *)(addr)) = (val)) diff -ur --new-file old/linux/include/asm-m68k/bootinfo.h new/linux/include/asm-m68k/bootinfo.h --- old/linux/include/asm-m68k/bootinfo.h Tue May 11 18:57:14 1999 +++ new/linux/include/asm-m68k/bootinfo.h Wed Jan 26 21:44:21 2000 @@ -103,6 +103,30 @@ #define ATARI_MACH_AB40 3 /* Afterburner040 on Falcon */ /* + * VME-specific tags + */ + +#define BI_VME_TYPE 0x8000 /* VME sub-architecture (u_long) */ +#define BI_VME_BRDINFO 0x8001 /* VME board information (struct) */ + +/* BI_VME_TYPE codes */ +#define VME_TYPE_TP34V 0x0034 /* Tadpole TP34V */ +#define VME_TYPE_MVME147 0x0147 /* Motorola MVME147 */ +#define VME_TYPE_MVME162 0x0162 /* Motorola MVME162 */ +#define VME_TYPE_MVME166 0x0166 /* Motorola MVME166 */ +#define VME_TYPE_MVME167 0x0167 /* Motorola MVME167 */ +#define VME_TYPE_MVME172 0x0172 /* Motorola MVME172 */ +#define VME_TYPE_MVME177 0x0177 /* Motorola MVME177 */ +#define VME_TYPE_BVME4000 0x4000 /* BVM Ltd. BVME4000 */ +#define VME_TYPE_BVME6000 0x6000 /* BVM Ltd. BVME6000 */ + +/* BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on + * Motorola VME boards. Contains board number, Bug version, board + * configuration options, etc. See include/asm/mvme16xhw.h for details. + */ + + + /* * Macintosh-specific tags (all u_long) */ @@ -182,6 +206,14 @@ mac_bi_data; #endif + + /* + * Apollo-specific tags + */ + +#define BI_APOLLO_MODEL 0x8000 /* model (u_long) */ + + /* * Stuff for bootinfo interface versioning diff -ur --new-file old/linux/include/asm-m68k/bvme6000hw.h new/linux/include/asm-m68k/bvme6000hw.h --- old/linux/include/asm-m68k/bvme6000hw.h Thu Dec 17 18:06:25 1998 +++ new/linux/include/asm-m68k/bvme6000hw.h Wed Jan 26 21:44:21 2000 @@ -95,6 +95,7 @@ #define BVME_SCC_A_ADDR 0xffb0000b #define BVME_SCC_B_ADDR 0xffb00003 +#define BVME_SCC_RTxC 7372800 #define BVME_CONFIG_REG 0xff500003 diff -ur --new-file old/linux/include/asm-m68k/cache.h new/linux/include/asm-m68k/cache.h --- old/linux/include/asm-m68k/cache.h Mon Aug 9 21:27:30 1999 +++ new/linux/include/asm-m68k/cache.h Wed Jan 26 21:44:21 2000 @@ -7,16 +7,4 @@ /* bytes per L1 cache line */ #define L1_CACHE_BYTES 16 -#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)) - -#define SMP_CACHE_BYTES L1_CACHE_BYTES - -#ifdef MODULE -#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES))) -#else -#define __cacheline_aligned \ - __attribute__((__aligned__(L1_CACHE_BYTES), \ - __section__(".data.cacheline_aligned"))) -#endif - #endif diff -ur --new-file old/linux/include/asm-m68k/div64.h new/linux/include/asm-m68k/div64.h --- old/linux/include/asm-m68k/div64.h Thu Jan 1 01:00:00 1970 +++ new/linux/include/asm-m68k/div64.h Wed Jan 26 21:44:21 2000 @@ -0,0 +1,35 @@ +#ifndef _M68K_DIV64_H +#define _M68K_DIV64_H + +/* n = n / base; return rem; */ + +#if 1 +#define do_div(n, base) ({ \ + union { \ + unsigned long n32[2]; \ + unsigned long long n64; \ + } __n; \ + unsigned long __rem, __upper; \ + \ + __n.n64 = (n); \ + if ((__upper = __n.n32[0])) { \ + asm ("divul.l %2,%1:%0" \ + : "=d" (__n.n32[0]), "=d" (__upper) \ + : "d" (base), "0" (__n.n32[0])); \ + } \ + asm ("divu.l %2,%1:%0" \ + : "=d" (__n.n32[1]), "=d" (__rem) \ + : "d" (base), "1" (__upper), "0" (__n.n32[1])); \ + (n) = __n.n64; \ + __rem; \ +}) +#else +#define do_div(n,base) ({ \ + int __res; \ + __res = ((unsigned long) n) % (unsigned) base; \ + n = ((unsigned long) n) / (unsigned) base; \ + __res; \ +}) +#endif + +#endif /* _M68K_DIV64_H */ diff -ur --new-file old/linux/include/asm-m68k/dma.h new/linux/include/asm-m68k/dma.h --- old/linux/include/asm-m68k/dma.h Fri Apr 26 11:12:24 1996 +++ new/linux/include/asm-m68k/dma.h Fri Jan 28 17:04:58 2000 @@ -1,12 +1,21 @@ #ifndef _M68K_DMA_H #define _M68K_DMA_H 1 -/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k and any - occurrence should be flagged as an error. */ +#include + +/* it's useless on the m68k, but unfortunately needed by the new + bootmem allocator (but this should do it for this) */ +#define MAX_DMA_ADDRESS PAGE_OFFSET #define MAX_DMA_CHANNELS 8 extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ extern void free_dma(unsigned int dmanr); /* release it again */ + +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy; +#else +#define isa_dma_bridge_buggy (0) +#endif #endif /* _M68K_DMA_H */ diff -ur --new-file old/linux/include/asm-m68k/entry.h new/linux/include/asm-m68k/entry.h --- old/linux/include/asm-m68k/entry.h Sat Sep 4 22:06:41 1999 +++ new/linux/include/asm-m68k/entry.h Wed Jan 26 21:44:21 2000 @@ -34,10 +34,6 @@ * the whole kernel. */ -#ifdef __ASSEMBLY__ - -#define curptr a2 - /* the following macro is used when enabling interrupts */ #if defined(MACH_ATARI_ONLY) && !defined(CONFIG_HADES) /* block out HSYNC on the atari */ @@ -49,6 +45,10 @@ #define MAX_NOINT_IPL 0 #endif /* machine compilation types */ +#ifdef __ASSEMBLY__ + +#define curptr a2 + LFLUSH_I_AND_D = 0x00000808 LSIGTRAP = 5 @@ -162,7 +162,7 @@ #endif #define GET_CURRENT(tmp) \ "movel %%sp,"#tmp"\n\t" \ - "andw #-KTHREAD_SIZE,"#tmp"\n\t" \ + "andw #-"STR(KTHREAD_SIZE)","#tmp"\n\t" \ "movel "#tmp",%%a2" #endif diff -ur --new-file old/linux/include/asm-m68k/fcntl.h new/linux/include/asm-m68k/fcntl.h --- old/linux/include/asm-m68k/fcntl.h Tue Dec 14 09:53:27 1999 +++ new/linux/include/asm-m68k/fcntl.h Wed Jan 26 21:44:21 2000 @@ -18,6 +18,8 @@ #define FASYNC 020000 /* fcntl, for BSD compatibility */ #define O_DIRECTORY 040000 /* must be a directory */ #define O_NOFOLLOW 0100000 /* don't follow links */ +#define O_DIRECT 0200000 /* direct disk access hint - currently ignored */ +#define O_LARGEFILE 0400000 #define F_DUPFD 0 /* dup */ #define F_GETFD 1 /* get f_flags */ diff -ur --new-file old/linux/include/asm-m68k/hardirq.h new/linux/include/asm-m68k/hardirq.h --- old/linux/include/asm-m68k/hardirq.h Mon Aug 9 21:27:30 1999 +++ new/linux/include/asm-m68k/hardirq.h Wed Jan 26 21:44:21 2000 @@ -10,8 +10,8 @@ #define hardirq_trylock(cpu) (local_irq_count[cpu] == 0) #define hardirq_endlock(cpu) do { } while (0) -#define hardirq_enter(cpu) (local_irq_count[cpu]++) -#define hardirq_exit(cpu) (local_irq_count[cpu]--) +#define irq_enter(cpu) (local_irq_count[cpu]++) +#define irq_exit(cpu) (local_irq_count[cpu]--) #define synchronize_irq() barrier() diff -ur --new-file old/linux/include/asm-m68k/mmu_context.h new/linux/include/asm-m68k/mmu_context.h --- old/linux/include/asm-m68k/mmu_context.h Fri Nov 12 13:29:47 1999 +++ new/linux/include/asm-m68k/mmu_context.h Wed Jan 26 21:44:21 2000 @@ -7,6 +7,7 @@ #include #include +#include extern inline void init_new_context(struct task_struct *tsk, struct mm_struct *mm) diff -ur --new-file old/linux/include/asm-m68k/movs.h new/linux/include/asm-m68k/movs.h --- old/linux/include/asm-m68k/movs.h Sat Sep 4 22:06:41 1999 +++ new/linux/include/asm-m68k/movs.h Wed Jan 26 21:44:21 2000 @@ -10,46 +10,46 @@ /* Set DFC register value */ #define SET_DFC(x) \ - __asm__ __volatile__ (" movec %0,%/dfc" : : "d" (x)); + __asm__ __volatile__ ("movec %0,%%dfc" : : "r" (x)) /* Get DFC register value */ #define GET_DFC(x) \ - __asm__ __volatile__ (" movec %/dfc, %0" : "=d" (x) : ); + __asm__ __volatile__ ("movec %%dfc,%0" : "=r" (x)) /* Set SFC register value */ #define SET_SFC(x) \ - __asm__ __volatile__ (" movec %0,%/sfc" : : "d" (x)); + __asm__ __volatile__ ("movec %0,%%sfc" : : "r" (x)) /* Get SFC register value */ #define GET_SFC(x) \ - __asm__ __volatile__ (" movec %/sfc, %0" : "=d" (x) : ); + __asm__ __volatile__ ("movec %%sfc,%0" : "=r" (x)) #define SET_VBR(x) \ - __asm__ __volatile__ (" movec %0,%/vbr" : : "r" (x)); + __asm__ __volatile__ ("movec %0,%%vbr" : : "r" (x)) #define GET_VBR(x) \ - __asm__ __volatile__ (" movec %/vbr, %0" : "=g" (x) : ); + __asm__ __volatile__ ("movec %%vbr,%0" : "=r" (x)) -/* Set a byte using the "movs" instruction */ +/* Set a byte using the "moves" instruction */ #define SET_CONTROL_BYTE(addr,value) \ - __asm__ __volatile__ (" movsb %0, %1@" : : "d" (value), "a" (addr)); + __asm__ __volatile__ ("movesb %1,%0" : "=m" (addr) : "d" (value)) -/* Get a byte using the "movs" instruction */ +/* Get a byte using the "moves" instruction */ #define GET_CONTROL_BYTE(addr,value) \ - __asm__ __volatile__ (" movsb %1@, %0" : "=d" (value) : "a" (addr)); + __asm__ __volatile__ ("movesb %1,%0" : "=d" (value) : "m" (addr)) -/* Set a (long)word using the "movs" instruction */ +/* Set a (long)word using the "moves" instruction */ #define SET_CONTROL_WORD(addr,value) \ - __asm__ __volatile__ (" movsl %0, %1@" : : "d" (value), "a" (addr)); + __asm__ __volatile__ ("movesl %1,%0" : "=m" (addr) : "r" (value)) -/* Get a (long)word using the "movs" instruction */ +/* Get a (long)word using the "moves" instruction */ #define GET_CONTROL_WORD(addr,value) \ - __asm__ __volatile__ (" movsl %1@, %0" : "=d" (value) : "a" (addr)); + __asm__ __volatile__ ("movesl %1,%0" : "=d" (value) : "m" (addr)) #endif diff -ur --new-file old/linux/include/asm-m68k/mvme147hw.h new/linux/include/asm-m68k/mvme147hw.h --- old/linux/include/asm-m68k/mvme147hw.h Tue May 11 18:57:14 1999 +++ new/linux/include/asm-m68k/mvme147hw.h Wed Jan 26 21:44:21 2000 @@ -85,11 +85,12 @@ #define M147_SCC_A_ADDR 0xfffe3002 #define M147_SCC_B_ADDR 0xfffe3000 +#define M147_SCC_PCLK 5000000 #define MVME147_IRQ_SCSI_PORT 0x45 #define MVME147_IRQ_SCSI_DMA 0x46 -/* SCC interrupts, for MVME162 */ +/* SCC interrupts, for MVME147 */ #define MVME147_IRQ_TYPE_PRIO 0 #define MVME147_IRQ_SCC_BASE 0x60 diff -ur --new-file old/linux/include/asm-m68k/mvme16xhw.h new/linux/include/asm-m68k/mvme16xhw.h --- old/linux/include/asm-m68k/mvme16xhw.h Sat Jun 13 22:14:33 1998 +++ new/linux/include/asm-m68k/mvme16xhw.h Wed Jan 26 21:44:21 2000 @@ -62,6 +62,7 @@ #define MVME_SCC_A_ADDR 0xfff45005 #define MVME_SCC_B_ADDR 0xfff45001 +#define MVME_SCC_PCLK 10000000 #define MVME162_IRQ_TYPE_PRIO 0 diff -ur --new-file old/linux/include/asm-m68k/page.h new/linux/include/asm-m68k/page.h --- old/linux/include/asm-m68k/page.h Sat Sep 4 22:06:41 1999 +++ new/linux/include/asm-m68k/page.h Wed Jan 26 21:44:21 2000 @@ -25,16 +25,14 @@ #ifndef __ASSEMBLY__ -#define STRICT_MM_TYPECHECKS - -#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) +#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) #define free_user_page(page, addr) free_page(addr) /* * We don't need to check for alignment etc. */ #ifdef CPU_M68040_OR_M68060_ONLY -static inline void copy_page(unsigned long to, unsigned long from) +static inline void copy_page(void *to, void *from) { unsigned long tmp; @@ -49,11 +47,10 @@ ); } -static inline void clear_page(unsigned long page) +static inline void clear_page(void *page) { - unsigned long data, sp, tmp; - - sp = page; + unsigned long data, tmp; + void *sp = page; data = 0; @@ -75,11 +72,10 @@ } #else -#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) -#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) +#define clear_page(page) memset((page), 0, PAGE_SIZE) +#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) #endif -#ifdef STRICT_MM_TYPECHECKS /* * These are used to make use of C type-checking.. */ @@ -98,55 +94,29 @@ #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -#else -/* - * .. while these make it easier on the compiler - */ -typedef unsigned long pte_t; -typedef struct { unsigned long pmd[16]; } pmd_t; -typedef unsigned long pgd_t; -typedef unsigned long pgprot_t; +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) -#define pte_val(x) (x) -#define pmd_val(x) ((&x)->pmd[0]) -#define pgd_val(x) (x) -#define pgprot_val(x) (x) +#endif /* !__ASSEMBLY__ */ -#define __pte(x) (x) -#define __pmd(x) ((pmd_t) { (x) } ) -#define __pgd(x) (x) -#define __pgprot(x) (x) +#include -#endif +#define PAGE_OFFSET (PAGE_OFFSET_RAW) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) +#ifndef __ASSEMBLY__ -/* This handles the memory map.. */ #ifndef CONFIG_SUN3 -#define PAGE_OFFSET 0 + +#ifdef CONFIG_SINGLE_MEMORY_CHUNK +extern unsigned long m68k_memoffset; + +#define __pa(vaddr) ((unsigned long)(vaddr)+m68k_memoffset) +#define __va(paddr) ((void *)((unsigned long)(paddr)-m68k_memoffset)) #else -#define PAGE_OFFSET 0x0E000000 +#define __pa(vaddr) virt_to_phys((void *)vaddr) +#define __va(paddr) phys_to_virt((unsigned long)paddr) #endif -#ifndef CONFIG_SUN3 -#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) -/* - * A hacky workaround for the problems with mmap() of frame buffer - * memory in the lower 16MB physical memoryspace. - * - * This is a short term solution, we will have to deal properly - * with this in 2.3.x. - */ -extern inline void *__va(unsigned long physaddr) -{ -#ifdef CONFIG_AMIGA - if (MACH_IS_AMIGA && (physaddr < 16*1024*1024)) - return (void *)0xffffffff; - else -#endif - return (void *)(physaddr+PAGE_OFFSET); -} #else /* !CONFIG_SUN3 */ /* This #define is a horrible hack to suppress lots of warnings. --m */ #define __pa(x) ___pa((unsigned long)x) @@ -172,9 +142,7 @@ } #endif /* CONFIG_SUN3 */ -#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT) - -#endif /* !__ASSEMBLY__ */ +#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT) #ifndef CONFIG_SUN3 #define BUG() do { \ @@ -191,6 +159,8 @@ #define PAGE_BUG(page) do { \ BUG(); \ } while (0) + +#endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff -ur --new-file old/linux/include/asm-m68k/page_offset.h new/linux/include/asm-m68k/page_offset.h --- old/linux/include/asm-m68k/page_offset.h Thu Jan 1 01:00:00 1970 +++ new/linux/include/asm-m68k/page_offset.h Wed Jan 26 21:44:21 2000 @@ -0,0 +1,9 @@ +#include + +/* This handles the memory map.. */ +#ifndef CONFIG_SUN3 +#define PAGE_OFFSET_RAW 0x00000000 +#else +#define PAGE_OFFSET_RAW 0x0E000000 +#endif + diff -ur --new-file old/linux/include/asm-m68k/pci.h new/linux/include/asm-m68k/pci.h --- old/linux/include/asm-m68k/pci.h Thu Jan 1 01:00:00 1970 +++ new/linux/include/asm-m68k/pci.h Wed Jan 26 21:44:21 2000 @@ -0,0 +1,38 @@ +#ifndef _ASM_M68K_PCI_H +#define _ASM_M68K_PCI_H + +/* + * asm-m68k/pci_m68k.h - m68k specific PCI declarations. + * + * Written by Wout Klaren. + */ + +struct pci_ops; + +/* + * Structure with hardware dependent information and functions of the + * PCI bus. + */ + +struct pci_bus_info +{ + /* + * Resources of the PCI bus. + */ + + struct resource mem_space; + struct resource io_space; + + /* + * System dependent functions. + */ + + struct pci_ops *m68k_pci_ops; + + void (*fixup)(int pci_modify); + void (*conf_device)(unsigned char bus, unsigned char device_fn); +}; + +#define pcibios_assign_all_busses() 0 + +#endif /* _ASM_M68K_PCI_H */ diff -ur --new-file old/linux/include/asm-m68k/pgalloc.h new/linux/include/asm-m68k/pgalloc.h --- old/linux/include/asm-m68k/pgalloc.h Thu Jan 1 01:00:00 1970 +++ new/linux/include/asm-m68k/pgalloc.h Wed Jan 26 21:44:21 2000 @@ -0,0 +1,399 @@ +#ifndef _M68K_PGALLOC_H +#define _M68K_PGALLOC_H + +#include +#include + +extern struct pgtable_cache_struct { + unsigned long *pmd_cache; + unsigned long *pte_cache; +/* This counts in units of pointer tables, of which can be eight per page. */ + unsigned long pgtable_cache_sz; +} quicklists; + +#define pgd_quicklist ((unsigned long *)0) +#define pmd_quicklist (quicklists.pmd_cache) +#define pte_quicklist (quicklists.pte_cache) +/* This isn't accurate because of fragmentation of allocated pages for + pointer tables, but that should not be a problem. */ +#define pgtable_cache_size ((quicklists.pgtable_cache_sz+7)/8) + +extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset); +extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset); + +extern pmd_t *get_pointer_table(void); +extern int free_pointer_table(pmd_t *); + +extern inline pte_t *get_pte_fast(void) +{ + unsigned long *ret; + + ret = pte_quicklist; + if (ret) { + pte_quicklist = (unsigned long *)*ret; + ret[0] = 0; + quicklists.pgtable_cache_sz -= 8; + } + return (pte_t *)ret; +} + +extern inline void free_pte_fast(pte_t *pte) +{ + *(unsigned long *)pte = (unsigned long)pte_quicklist; + pte_quicklist = (unsigned long *)pte; + quicklists.pgtable_cache_sz += 8; +} + +extern inline void free_pte_slow(pte_t *pte) +{ + cache_page((unsigned long)pte); + free_page((unsigned long) pte); +} + +extern inline pmd_t *get_pmd_fast(void) +{ + unsigned long *ret; + + ret = pmd_quicklist; + if (ret) { + pmd_quicklist = (unsigned long *)*ret; + ret[0] = 0; + quicklists.pgtable_cache_sz--; + } + return (pmd_t *)ret; +} + +extern inline void free_pmd_fast(pmd_t *pmd) +{ + *(unsigned long *)pmd = (unsigned long)pmd_quicklist; + pmd_quicklist = (unsigned long *) pmd; + quicklists.pgtable_cache_sz++; +} + +extern inline int free_pmd_slow(pmd_t *pmd) +{ + return free_pointer_table(pmd); +} + +/* The pgd cache is folded into the pmd cache, so these are dummy routines. */ +extern inline pgd_t *get_pgd_fast(void) +{ + return (pgd_t *)0; +} + +extern inline void free_pgd_fast(pgd_t *pgd) +{ +} + +extern inline void free_pgd_slow(pgd_t *pgd) +{ +} + +extern void __bad_pte(pmd_t *pmd); +extern void __bad_pmd(pgd_t *pgd); + +extern inline void pte_free(pte_t *pte) +{ + free_pte_fast(pte); +} + +extern inline pte_t *pte_alloc(pmd_t *pmd, unsigned long address) +{ + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); + if (pmd_none(*pmd)) { + pte_t *page = get_pte_fast(); + + if (!page) + return get_pte_slow(pmd, address); + pmd_set(pmd,page); + return page + address; + } + if (pmd_bad(*pmd)) { + __bad_pte(pmd); + return NULL; + } + return (pte_t *)__pmd_page(*pmd) + address; +} + +extern inline void pmd_free(pmd_t *pmd) +{ + free_pmd_fast(pmd); +} + +extern inline pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address) +{ + address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); + if (pgd_none(*pgd)) { + pmd_t *page = get_pmd_fast(); + + if (!page) + return get_pmd_slow(pgd, address); + pgd_set(pgd, page); + return page + address; + } + if (pgd_bad(*pgd)) { + __bad_pmd(pgd); + return NULL; + } + return (pmd_t *)__pgd_page(*pgd) + address; +} + +extern inline void pte_free_kernel(pte_t *pte) +{ + free_pte_fast(pte); +} + +extern inline pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address) +{ + return pte_alloc(pmd, address); +} + +extern inline void pmd_free_kernel(pmd_t *pmd) +{ + free_pmd_fast(pmd); +} + +extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address) +{ + return pmd_alloc(pgd, address); +} + +extern inline void pgd_free(pgd_t *pgd) +{ + free_pmd_fast((pmd_t *)pgd); +} + +extern inline pgd_t *pgd_alloc(void) +{ + pgd_t *pgd = (pgd_t *)get_pmd_fast(); + if (!pgd) + pgd = (pgd_t *)get_pointer_table(); + return pgd; +} + +extern int do_check_pgt_cache(int, int); + +extern inline void set_pgdir(unsigned long address, pgd_t entry) +{ +} + + +/* + * Cache handling functions + */ + +#define flush_icache() \ +({ \ + if (CPU_IS_040_OR_060) \ + __asm__ __volatile__("nop\n\t" \ + ".chip 68040\n\t" \ + "cinva %%ic\n\t" \ + ".chip 68k" : ); \ + else { \ + unsigned long _tmp; \ + __asm__ __volatile__("movec %%cacr,%0\n\t" \ + "orw %1,%0\n\t" \ + "movec %0,%%cacr" \ + : "=&d" (_tmp) \ + : "id" (FLUSH_I)); \ + } \ +}) + +/* + * invalidate the cache for the specified memory range. + * It starts at the physical address specified for + * the given number of bytes. + */ +extern void cache_clear(unsigned long paddr, int len); +/* + * push any dirty cache in the specified memory range. + * It starts at the physical address specified for + * the given number of bytes. + */ +extern void cache_push(unsigned long paddr, int len); + +/* + * push and invalidate pages in the specified user virtual + * memory range. + */ +extern void cache_push_v(unsigned long vaddr, int len); + +/* cache code */ +#define FLUSH_I_AND_D (0x00000808) +#define FLUSH_I (0x00000008) + +/* This is needed whenever the virtual mapping of the current + process changes. */ +#define __flush_cache_all() \ +({ \ + if (CPU_IS_040_OR_060) \ + __asm__ __volatile__("nop\n\t" \ + ".chip 68040\n\t" \ + "cpusha %dc\n\t" \ + ".chip 68k"); \ + else { \ + unsigned long _tmp; \ + __asm__ __volatile__("movec %%cacr,%0\n\t" \ + "orw %1,%0\n\t" \ + "movec %0,%%cacr" \ + : "=&d" (_tmp) \ + : "di" (FLUSH_I_AND_D)); \ + } \ +}) + +#define __flush_cache_030() \ +({ \ + if (CPU_IS_020_OR_030) { \ + unsigned long _tmp; \ + __asm__ __volatile__("movec %%cacr,%0\n\t" \ + "orw %1,%0\n\t" \ + "movec %0,%%cacr" \ + : "=&d" (_tmp) \ + : "di" (FLUSH_I_AND_D)); \ + } \ +}) + +#define flush_cache_all() __flush_cache_all() + +extern inline void flush_cache_mm(struct mm_struct *mm) +{ + if (mm == current->mm) + __flush_cache_030(); +} + +extern inline void flush_cache_range(struct mm_struct *mm, + unsigned long start, + unsigned long end) +{ + if (mm == current->mm) + __flush_cache_030(); +} + +extern inline void flush_cache_page(struct vm_area_struct *vma, + unsigned long vmaddr) +{ + if (vma->vm_mm == current->mm) + __flush_cache_030(); +} + +/* Push the page at kernel virtual address and clear the icache */ +#define flush_page_to_ram(page) __flush_page_to_ram(page_address(page)) +extern inline void __flush_page_to_ram(unsigned long address) +{ + if (CPU_IS_040_OR_060) { + __asm__ __volatile__("nop\n\t" + ".chip 68040\n\t" + "cpushp %%dc,(%0)\n\t" + "cinvp %%ic,(%0)\n\t" + ".chip 68k" + : : "a" (__pa((void *)address))); + } else { + unsigned long _tmp; + __asm__ __volatile__("movec %%cacr,%0\n\t" + "orw %1,%0\n\t" + "movec %0,%%cacr" + : "=&d" (_tmp) + : "di" (FLUSH_I)); + } +} + +/* Push n pages at kernel virtual address and clear the icache */ +extern inline void flush_icache_range (unsigned long address, + unsigned long endaddr) +{ + if (CPU_IS_040_OR_060) { + short n = (endaddr - address + PAGE_SIZE - 1) / PAGE_SIZE; + + while (--n >= 0) { + __asm__ __volatile__("nop\n\t" + ".chip 68040\n\t" + "cpushp %%dc,(%0)\n\t" + "cinvp %%ic,(%0)\n\t" + ".chip 68k" + : : "a" (virt_to_phys((void *)address))); + address += PAGE_SIZE; + } + } else { + unsigned long tmp; + __asm__ __volatile__("movec %%cacr,%0\n\t" + "orw %1,%0\n\t" + "movec %0,%%cacr" + : "=&d" (tmp) + : "di" (FLUSH_I)); + } +} + + +/* + * flush all user-space atc entries. + */ +static inline void __flush_tlb(void) +{ + if (CPU_IS_040_OR_060) + __asm__ __volatile__(".chip 68040\n\t" + "pflushan\n\t" + ".chip 68k"); + else + __asm__ __volatile__("pflush #0,#4"); +} + +static inline void __flush_tlb_one(unsigned long addr) +{ + if (CPU_IS_040_OR_060) { + __asm__ __volatile__(".chip 68040\n\t" + "pflush (%0)\n\t" + ".chip 68k" + : : "a" (addr)); + } else + __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr)); +} + +#define flush_tlb() __flush_tlb() + +/* + * flush all atc entries (both kernel and user-space entries). + */ +static inline void flush_tlb_all(void) +{ + if (CPU_IS_040_OR_060) + __asm__ __volatile__(".chip 68040\n\t" + "pflusha\n\t" + ".chip 68k"); + else + __asm__ __volatile__("pflusha"); +} + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + if (mm == current->mm) + __flush_tlb(); +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) +{ + if (vma->vm_mm == current->mm) + __flush_tlb_one(addr); +} + +static inline void flush_tlb_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + if (mm == current->mm) + __flush_tlb(); +} + +extern inline void flush_tlb_kernel_page(unsigned long addr) +{ + if (CPU_IS_040_OR_060) { + mm_segment_t old_fs = get_fs(); + set_fs(KERNEL_DS); + __asm__ __volatile__(".chip 68040\n\t" + "pflush (%0)\n\t" + ".chip 68k" + : : "a" (addr)); + set_fs(old_fs); + } else + __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr)); +} + +#endif /* _M68K_PGALLOC_H */ diff -ur --new-file old/linux/include/asm-m68k/pgtable.h new/linux/include/asm-m68k/pgtable.h --- old/linux/include/asm-m68k/pgtable.h Sat Sep 4 22:06:41 1999 +++ new/linux/include/asm-m68k/pgtable.h Wed Jan 26 21:44:21 2000 @@ -15,226 +15,6 @@ #include -/* - * Cache handling functions - */ - -#define flush_icache() \ -do { \ - if (CPU_IS_040_OR_060) \ - asm __volatile__ ("nop\n\t" \ - ".chip 68040\n\t" \ - "cinva %%ic\n\t" \ - ".chip 68k" : ); \ - else { \ - unsigned long _tmp; \ - asm __volatile__ ("movec %%cacr,%0\n\t" \ - "orw %1,%0\n\t" \ - "movec %0,%%cacr" \ - : "=&d" (_tmp) \ - : "id" (FLUSH_I)); \ - } \ -} while (0) - -/* - * invalidate the cache for the specified memory range. - * It starts at the physical address specified for - * the given number of bytes. - */ -extern void cache_clear (unsigned long paddr, int len); -/* - * push any dirty cache in the specified memory range. - * It starts at the physical address specified for - * the given number of bytes. - */ -extern void cache_push (unsigned long paddr, int len); - -/* - * push and invalidate pages in the specified user virtual - * memory range. - */ -extern void cache_push_v (unsigned long vaddr, int len); - -/* cache code */ -#define FLUSH_I_AND_D (0x00000808) -#define FLUSH_I (0x00000008) - -/* This is needed whenever the virtual mapping of the current - process changes. */ -#define __flush_cache_all() \ - do { \ - if (CPU_IS_040_OR_060) \ - __asm__ __volatile__ ("nop\n\t" \ - ".chip 68040\n\t" \ - "cpusha %dc\n\t" \ - ".chip 68k"); \ - else { \ - unsigned long _tmp; \ - __asm__ __volatile__ ("movec %%cacr,%0\n\t" \ - "orw %1,%0\n\t" \ - "movec %0,%%cacr" \ - : "=&d" (_tmp) \ - : "di" (FLUSH_I_AND_D)); \ - } \ - } while (0) - -#define __flush_cache_030() \ - do { \ - if (CPU_IS_020_OR_030) { \ - unsigned long _tmp; \ - __asm__ __volatile__ ("movec %%cacr,%0\n\t" \ - "orw %1,%0\n\t" \ - "movec %0,%%cacr" \ - : "=&d" (_tmp) \ - : "di" (FLUSH_I_AND_D)); \ - } \ - } while (0) - -#define flush_cache_all() __flush_cache_all() - -extern inline void flush_cache_mm(struct mm_struct *mm) -{ - if (mm == current->mm) - __flush_cache_030(); -} - -extern inline void flush_cache_range(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (mm == current->mm) - __flush_cache_030(); -} - -extern inline void flush_cache_page(struct vm_area_struct *vma, - unsigned long vmaddr) -{ - if (vma->vm_mm == current->mm) - __flush_cache_030(); -} - -/* Push the page at kernel virtual address and clear the icache */ -extern inline void flush_page_to_ram (unsigned long address) -{ - if (CPU_IS_040_OR_060) { - __asm__ __volatile__ ("nop\n\t" - ".chip 68040\n\t" - "cpushp %%dc,(%0)\n\t" - "cinvp %%ic,(%0)\n\t" - ".chip 68k" - : : "a" (virt_to_phys((void *)address))); - } - else { - unsigned long _tmp; - __asm volatile ("movec %%cacr,%0\n\t" - "orw %1,%0\n\t" - "movec %0,%%cacr" - : "=&d" (_tmp) - : "di" (FLUSH_I)); - } -} - -/* Push n pages at kernel virtual address and clear the icache */ -extern inline void flush_icache_range (unsigned long address, - unsigned long endaddr) -{ - if (CPU_IS_040_OR_060) { - short n = (endaddr - address + PAGE_SIZE - 1) / PAGE_SIZE; - - while (n--) { - __asm__ __volatile__ ("nop\n\t" - ".chip 68040\n\t" - "cpushp %%dc,(%0)\n\t" - "cinvp %%ic,(%0)\n\t" - ".chip 68k" - : : "a" (virt_to_phys((void *)address))); - address += PAGE_SIZE; - } - } - else { - unsigned long _tmp; - __asm volatile ("movec %%cacr,%0\n\t" - "orw %1,%0\n\t" - "movec %0,%%cacr" - : "=&d" (_tmp) - : "di" (FLUSH_I)); - } -} - - -/* - * flush all user-space atc entries. - */ -static inline void __flush_tlb(void) -{ - if (CPU_IS_040_OR_060) - __asm__ __volatile__(".chip 68040\n\t" - "pflushan\n\t" - ".chip 68k"); - else - __asm__ __volatile__("pflush #0,#4"); -} - -static inline void __flush_tlb_one(unsigned long addr) -{ - if (CPU_IS_040_OR_060) { - __asm__ __volatile__(".chip 68040\n\t" - "pflush (%0)\n\t" - ".chip 68k" - : : "a" (addr)); - } else - __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr)); -} - -#define flush_tlb() __flush_tlb() - -/* - * flush all atc entries (both kernel and user-space entries). - */ -static inline void flush_tlb_all(void) -{ - if (CPU_IS_040_OR_060) - __asm__ __volatile__(".chip 68040\n\t" - "pflusha\n\t" - ".chip 68k"); - else - __asm__ __volatile__("pflusha"); -} - -static inline void flush_tlb_mm(struct mm_struct *mm) -{ - if (mm == current->mm) - __flush_tlb(); -} - -static inline void flush_tlb_page(struct vm_area_struct *vma, - unsigned long addr) -{ - if (vma->vm_mm == current->mm) - __flush_tlb_one(addr); -} - -static inline void flush_tlb_range(struct mm_struct *mm, - unsigned long start, unsigned long end) -{ - if (mm == current->mm) - __flush_tlb(); -} - -extern inline void flush_tlb_kernel_page(unsigned long addr) -{ - if (CPU_IS_040_OR_060) { - mm_segment_t old_fs = get_fs(); - set_fs(KERNEL_DS); - __asm__ __volatile__(".chip 68040\n\t" - "pflush (%0)\n\t" - ".chip 68k" - : : "a" (addr)); - set_fs(old_fs); - } else - __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr)); -} - /* Certain architectures need to do special things when pte's * within a page table are directly modified. Thus, the following * hook is made available. @@ -391,7 +171,7 @@ #define BAD_PAGETABLE __bad_pagetable() #define BAD_PAGE __bad_page() -#define ZERO_PAGE(vaddr) empty_zero_page +#define ZERO_PAGE(vaddr) (mem_map + MAP_NR(empty_zero_page)) /* number of bits that fit into a memory pointer */ #define BITS_PER_PTR (8*sizeof(unsigned long)) @@ -403,67 +183,78 @@ /* 64-bit machines, beware! SRB. */ #define SIZEOF_PTR_LOG2 2 -/* to find an entry in a page-table */ -#define PAGE_PTR(address) \ -((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) - /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ -#define mk_pte(page, pgprot) \ -({ pte_t __pte; pte_val(__pte) = virt_to_phys((void *)page) + pgprot_val(pgprot); __pte; }) +#define __mk_pte(page, pgprot) \ +({ \ + pte_t __pte; \ + \ + pte_val(__pte) = __pa((void *)page) + pgprot_val(pgprot); \ + __pte; \ +}) +#define mk_pte(page, pgprot) __mk_pte(page_address(page), (pgprot)) #define mk_pte_phys(physpage, pgprot) \ -({ pte_t __pte; pte_val(__pte) = (unsigned long)physpage + pgprot_val(pgprot); __pte; }) +({ \ + pte_t __pte; \ + \ + pte_val(__pte) = (physpage) + pgprot_val(pgprot); \ + __pte; \ +}) extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep) { - int i; - unsigned long ptbl; - ptbl = virt_to_phys(ptep) | _PAGE_TABLE | _PAGE_ACCESSED; - for (i = 0; i < 16; i++, ptbl += (sizeof(pte_t)*PTRS_PER_PTE/16)) - pmdp->pmd[i] = ptbl; + unsigned long ptbl = virt_to_phys(ptep) | _PAGE_TABLE | _PAGE_ACCESSED; + unsigned long *ptr = pmdp->pmd; + short i = 16; + while (--i >= 0) { + *ptr++ = ptbl; + ptbl += (sizeof(pte_t)*PTRS_PER_PTE/16); + } } extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp) -{ pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | virt_to_phys(pmdp); } - -extern inline unsigned long pte_page(pte_t pte) -{ return (unsigned long)phys_to_virt(pte_val(pte) & PAGE_MASK); } - -extern inline unsigned long pmd_page2(pmd_t *pmd) -{ return (unsigned long)phys_to_virt(pmd_val(*pmd) & _TABLE_MASK); } -#define pmd_page(pmd) pmd_page2(&(pmd)) - -extern inline unsigned long pgd_page(pgd_t pgd) -{ return (unsigned long)phys_to_virt(pgd_val(pgd) & _TABLE_MASK); } - -extern inline int pte_none(pte_t pte) { return !pte_val(pte); } -extern inline int pte_present(pte_t pte) { return pte_val(pte) & (_PAGE_PRESENT | _PAGE_FAKE_SUPER); } -extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; } - -extern inline int pmd_none2(pmd_t *pmd) { return !pmd_val(*pmd); } -#define pmd_none(pmd) pmd_none2(&(pmd)) -extern inline int pmd_bad2(pmd_t *pmd) { return (pmd_val(*pmd) & _DESCTYPE_MASK) != _PAGE_TABLE; } -#define pmd_bad(pmd) pmd_bad2(&(pmd)) -extern inline int pmd_present2(pmd_t *pmd) { return pmd_val(*pmd) & _PAGE_TABLE; } -#define pmd_present(pmd) pmd_present2(&(pmd)) -extern inline void pmd_clear(pmd_t * pmdp) -{ - short i; - - for (i = 15; i >= 0; i--) - pmdp->pmd[i] = 0; -} +{ pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | __pa(pmdp); } -extern inline int pgd_none(pgd_t pgd) { return !pgd_val(pgd); } -extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE; } -extern inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) & _PAGE_TABLE; } - -extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; } +#define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK)) +#define __pmd_page(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK)) +#define __pgd_page(pgd) ((unsigned long)__va(pgd_val(pgd) & _TABLE_MASK)) + +#define pte_none(pte) (!pte_val(pte)) +#define pte_present(pte) (pte_val(pte) & (_PAGE_PRESENT | _PAGE_FAKE_SUPER)) +#define pte_clear(ptep) ({ pte_val(*(ptep)) = 0; }) +#define pte_pagenr(pte) ((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT) + +#define pmd_none(pmd) (!pmd_val(pmd)) +#define pmd_bad(pmd) ((pmd_val(pmd) & _DESCTYPE_MASK) != _PAGE_TABLE) +#define pmd_present(pmd) (pmd_val(pmd) & _PAGE_TABLE) +#define pmd_clear(pmdp) ({ \ + unsigned long *__ptr = pmdp->pmd; \ + short __i = 16; \ + while (--__i >= 0) \ + *__ptr++ = 0; \ +}) + +#define pgd_none(pgd) (!pgd_val(pgd)) +#define pgd_bad(pgd) ((pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE) +#define pgd_present(pgd) (pgd_val(pgd) & _PAGE_TABLE) +#define pgd_clear(pgdp) ({ pgd_val(*pgdp) = 0; }) + +/* Permanent address of a page. */ +#define page_address(page) ({ if (!(page)->virtual) BUG(); (page)->virtual; }) +#define __page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT)) +#define pte_page(pte) (mem_map+pte_pagenr(pte)) + +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %p(%08lx).\n", __FILE__, __LINE__, &(e), pte_val(e)) +#define pmd_ERROR(e) \ + printk("%s:%d: bad pmd %p(%08lx).\n", __FILE__, __LINE__, &(e), pmd_val(e)) +#define pgd_ERROR(e) \ + printk("%s:%d: bad pgd %p(%08lx).\n", __FILE__, __LINE__, &(e), pgd_val(e)) /* * The following only work if pte_present() is true. @@ -512,13 +303,13 @@ /* Find an entry in the second-level page table.. */ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) { - return (pmd_t *) pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1)); + return (pmd_t *)__pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1)); } /* Find an entry in the third-level page table.. */ extern inline pte_t * pte_offset(pmd_t * pmdp, unsigned long address) { - return (pte_t *) pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); + return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); } /* @@ -559,178 +350,6 @@ } } -extern struct pgtable_cache_struct { - unsigned long *pmd_cache; - unsigned long *pte_cache; -/* This counts in units of pointer tables, of which can be eight per page. */ - unsigned long pgtable_cache_sz; -} quicklists; - -#define pgd_quicklist ((unsigned long *)0) -#define pmd_quicklist (quicklists.pmd_cache) -#define pte_quicklist (quicklists.pte_cache) -/* This isn't accurate because of fragmentation of allocated pages for - pointer tables, but that should not be a problem. */ -#define pgtable_cache_size ((quicklists.pgtable_cache_sz+7)/8) - -extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset); -extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset); - -extern pmd_t *get_pointer_table(void); -extern int free_pointer_table(pmd_t *); - -extern __inline__ pte_t *get_pte_fast(void) -{ - unsigned long *ret; - - ret = pte_quicklist; - if (ret) { - pte_quicklist = (unsigned long *)*ret; - ret[0] = 0; - quicklists.pgtable_cache_sz -= 8; - } - return (pte_t *)ret; -} - -extern __inline__ void free_pte_fast(pte_t *pte) -{ - *(unsigned long *)pte = (unsigned long)pte_quicklist; - pte_quicklist = (unsigned long *)pte; - quicklists.pgtable_cache_sz += 8; -} - -extern __inline__ void free_pte_slow(pte_t *pte) -{ - cache_page((unsigned long)pte); - free_page((unsigned long) pte); -} - -extern __inline__ pmd_t *get_pmd_fast(void) -{ - unsigned long *ret; - - ret = pmd_quicklist; - if (ret) { - pmd_quicklist = (unsigned long *)*ret; - ret[0] = 0; - quicklists.pgtable_cache_sz--; - } - return (pmd_t *)ret; -} - -extern __inline__ void free_pmd_fast(pmd_t *pmd) -{ - *(unsigned long *)pmd = (unsigned long)pmd_quicklist; - pmd_quicklist = (unsigned long *) pmd; - quicklists.pgtable_cache_sz++; -} - -extern __inline__ int free_pmd_slow(pmd_t *pmd) -{ - return free_pointer_table(pmd); -} - -/* The pgd cache is folded into the pmd cache, so these are dummy routines. */ -extern __inline__ pgd_t *get_pgd_fast(void) -{ - return (pgd_t *)0; -} - -extern __inline__ void free_pgd_fast(pgd_t *pgd) -{ -} - -extern __inline__ void free_pgd_slow(pgd_t *pgd) -{ -} - -extern void __bad_pte(pmd_t *pmd); -extern void __bad_pmd(pgd_t *pgd); - -extern inline void pte_free(pte_t * pte) -{ - free_pte_fast(pte); -} - -extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address) -{ - address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); - if (pmd_none(*pmd)) { - pte_t * page = get_pte_fast(); - - if (!page) - return get_pte_slow(pmd, address); - pmd_set(pmd,page); - return page + address; - } - if (pmd_bad(*pmd)) { - __bad_pte(pmd); - return NULL; - } - return (pte_t *) pmd_page(*pmd) + address; -} - -extern inline void pmd_free(pmd_t * pmd) -{ - free_pmd_fast(pmd); -} - -extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address) -{ - address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); - if (pgd_none(*pgd)) { - pmd_t *page = get_pmd_fast(); - - if (!page) - return get_pmd_slow(pgd, address); - pgd_set(pgd, page); - return page + address; - } - if (pgd_bad(*pgd)) { - __bad_pmd(pgd); - return NULL; - } - return (pmd_t *) pgd_page(*pgd) + address; -} - -extern inline void pte_free_kernel(pte_t * pte) -{ - free_pte_fast(pte); -} - -extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) -{ - return pte_alloc(pmd, address); -} - -extern inline void pmd_free_kernel(pmd_t * pmd) -{ - free_pmd_fast(pmd); -} - -extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address) -{ - return pmd_alloc(pgd, address); -} - -extern inline void pgd_free(pgd_t * pgd) -{ - free_pmd_fast((pmd_t *)pgd); -} - -extern inline pgd_t * pgd_alloc(void) -{ - pgd_t *pgd = (pgd_t *)get_pmd_fast(); - if (!pgd) - pgd = (pgd_t *)get_pointer_table(); - return pgd; -} - -extern int do_check_pgt_cache(int, int); - -extern inline void set_pgdir(unsigned long address, pgd_t entry) -{ -} /* * Check if the addr/len goes up to the end of a physical @@ -760,21 +379,12 @@ { } -/* - * I don't know what is going on here, but since these were changed, - * swapping hasn't been working on the 68040. - */ -/* With the new handling of PAGE_NONE the old definitions definitely - don't work any more. */ - -#define SWP_TYPE(entry) (((entry) >> 2) & 0x7f) -#if 0 -#define SWP_OFFSET(entry) ((entry) >> 9) -#define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << 9)) -#else -#define SWP_OFFSET(entry) ((entry) >> PAGE_SHIFT) -#define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << PAGE_SHIFT)) -#endif +/* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */ +#define SWP_TYPE(x) (((x).val >> 1) & 0xff) +#define SWP_OFFSET(x) ((x).val >> 10) +#define SWP_ENTRY(type, offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 10) }) +#define pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define swp_entry_to_pte(x) ((pte_t) { (x).val }) #endif /* __ASSEMBLY__ */ diff -ur --new-file old/linux/include/asm-m68k/poll.h new/linux/include/asm-m68k/poll.h --- old/linux/include/asm-m68k/poll.h Wed May 14 07:41:17 1997 +++ new/linux/include/asm-m68k/poll.h Wed Jan 26 21:44:21 2000 @@ -11,6 +11,7 @@ #define POLLWRNORM POLLOUT #define POLLRDBAND 128 #define POLLWRBAND 256 +#define POLLMSG 0x0400 struct pollfd { int fd; diff -ur --new-file old/linux/include/asm-m68k/semaphore.h new/linux/include/asm-m68k/semaphore.h --- old/linux/include/asm-m68k/semaphore.h Wed Sep 8 20:54:14 1999 +++ new/linux/include/asm-m68k/semaphore.h Wed Jan 26 21:44:21 2000 @@ -1,6 +1,8 @@ #ifndef _M68K_SEMAPHORE_H #define _M68K_SEMAPHORE_H +#ifndef __ASSEMBLY__ + #include #include #include @@ -9,13 +11,14 @@ #include /* - * SMP- and interrupt-safe semaphores.. + * Interrupt-safe semaphores.. * * (C) Copyright 1996 Linus Torvalds * * m68k version by Andreas Schwab */ + struct semaphore { atomic_t count; atomic_t waking; @@ -179,5 +182,175 @@ : "a" (sem1) : "memory"); } + + +/* rw mutexes (should that be mutices? =) -- throw rw + * spinlocks and semaphores together, and this is what we + * end up with... + * + * m68k version by Roman Zippel + */ + +struct rw_semaphore { + atomic_t count; + volatile unsigned char write_bias_granted; + volatile unsigned char read_bias_granted; + volatile unsigned char pad1; + volatile unsigned char pad2; + wait_queue_head_t wait; + wait_queue_head_t write_bias_wait; +#if WAITQUEUE_DEBUG + long __magic; + atomic_t readers; + atomic_t writers; +#endif +}; +#endif /* __ASSEMBLY__ */ + +#define RW_LOCK_BIAS 0x01000000 + +#ifndef __ASSEMBLY__ + +extern inline void down_read(struct rw_semaphore *sem) +{ + register struct rw_semaphore *__sem __asm__ ("%a1") = sem; + +#if WAITQUEUE_DEBUG + if (sem->__magic != (long)&sem->__magic) + BUG(); +#endif + __asm__ __volatile__( + "| atomic down_read operation\n\t" + "subql #1,%0@\n\t" + "jmi 2f\n" + "1:\n" + ".section .text.lock,\"ax\"\n" + ".even\n" + "2:\n\t" + "pea 1b\n\t" + "jbra __down_read_failed\n" + ".previous" + : /* no outputs */ + : "a" (__sem) + : "memory"); +#if WAITQUEUE_DEBUG + if (sem->write_bias_granted) + BUG(); + if (atomic_read(&sem->writers)) + BUG(); + atomic_inc(&sem->readers); +#endif +} + +extern inline void down_write(struct rw_semaphore *sem) +{ + register struct rw_semaphore *__sem __asm__ ("%a1") = sem; + +#if WAITQUEUE_DEBUG + if (sem->__magic != (long)&sem->__magic) + BUG(); +#endif + __asm__ __volatile__( + "| atomic down_write operation\n\t" + "subl %1,%0@\n\t" + "jne 2f\n" + "1:\n" + ".section .text.lock,\"ax\"\n" + ".even\n" + "2:\n\t" + "pea 1b\n\t" + "jbra __down_write_failed\n" + ".previous" + : /* no outputs */ + : "a" (__sem), "id" (RW_LOCK_BIAS) + : "memory"); +#if WAITQUEUE_DEBUG + if (atomic_read(&sem->writers)) + BUG(); + if (atomic_read(&sem->readers)) + BUG(); + if (sem->read_bias_granted) + BUG(); + if (sem->write_bias_granted) + BUG(); + atomic_inc(&sem->writers); +#endif +} + +/* When a reader does a release, the only significant + * case is when there was a writer waiting, and we've + * bumped the count to 0: we must wake the writer up. + */ +extern inline void __up_read(struct rw_semaphore *sem) +{ + register struct rw_semaphore *__sem __asm__ ("%a1") = sem; + + __asm__ __volatile__( + "| atomic up_read operation\n\t" + "addql #1,%0@\n\t" + "jeq 2f\n" + "1:\n" + ".section .text.lock,\"ax\"\n" + ".even\n" + "2:\n\t" + "pea 1b\n\t" + "jbra __rwsem_wake\n" + ".previous" + : /* no outputs */ + : "a" (__sem) + : "memory"); +} + +extern inline void up_read(struct rw_semaphore *sem) +{ +#if WAITQUEUE_DEBUG + if (sem->write_bias_granted) + BUG(); + if (atomic_read(&sem->writers)) + BUG(); + atomic_dec(&sem->readers); +#endif + __up_read(sem); +} + +/* releasing the writer is easy -- just release it and + * wake up any sleepers. + */ +extern inline void __up_write(struct rw_semaphore *sem) +{ + register struct rw_semaphore *__sem __asm__ ("%a1") = sem; + + __asm__ __volatile__( + "| atomic up_write operation\n\t" + "addl %1,%0@\n\t" + "jcs 2f\n" + "1:\n" + ".section .text.lock,\"ax\"\n" + ".even\n" + "2:\n\t" + "pea 1b\n\t" + "jbra __rwsem_wake\n" + ".previous" + : /* no outputs */ + : "a" (__sem), "id" (RW_LOCK_BIAS) + : "memory"); +} + +extern inline void up_write(struct rw_semaphore *sem) +{ +#if WAITQUEUE_DEBUG + if (sem->read_bias_granted) + BUG(); + if (sem->write_bias_granted) + BUG(); + if (atomic_read(&sem->readers)) + BUG(); + if (atomic_read(&sem->writers) != 1) + BUG(); + atomic_dec(&sem->writers); +#endif + __up_write(sem); +} +#endif /* __ASSEMBLY__ */ #endif diff -ur --new-file old/linux/include/asm-m68k/setup.h new/linux/include/asm-m68k/setup.h --- old/linux/include/asm-m68k/setup.h Sat Sep 4 22:06:41 1999 +++ new/linux/include/asm-m68k/setup.h Wed Jan 26 21:44:21 2000 @@ -246,6 +246,9 @@ extern unsigned long m68k_cputype; extern unsigned long m68k_fputype; extern unsigned long m68k_mmutype; /* Not really used yet */ +#ifdef CONFIG_VME +extern unsigned long vme_brdtype; +#endif /* * m68k_is040or060 is != 0 for a '040 or higher; diff -ur --new-file old/linux/include/asm-m68k/siginfo.h new/linux/include/asm-m68k/siginfo.h --- old/linux/include/asm-m68k/siginfo.h Tue Jan 11 03:15:58 2000 +++ new/linux/include/asm-m68k/siginfo.h Wed Jan 26 21:44:21 2000 @@ -24,8 +24,7 @@ /* kill() */ struct { pid_t _pid; /* sender's pid */ - old_uid_t _uid; /* backwards compatibility */ - uid_t _uid32; /* sender's uid */ + uid_t _uid; /* sender's uid */ } _kill; /* POSIX.1b timers */ @@ -37,19 +36,17 @@ /* POSIX.1b signals */ struct { pid_t _pid; /* sender's pid */ - old_uid_t _uid; /* backwards compatibility */ + uid_t _uid; /* sender's uid */ sigval_t _sigval; - uid_t _uid32; /* sender's uid */ } _rt; /* SIGCHLD */ struct { pid_t _pid; /* which child */ - old_uid_t _uid; /* backwards compatibility */ + uid_t _uid; /* sender's uid */ int _status; /* exit code */ clock_t _utime; clock_t _stime; - uid_t _uid32; /* sender's uid */ } _sigchld; /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ @@ -65,18 +62,11 @@ } _sifields; } siginfo_t; -#define UID16_SIGINFO_COMPAT_NEEDED - /* * How these fields are to be accessed. */ #define si_pid _sifields._kill._pid -#ifdef __KERNEL__ -#define si_uid _sifields._kill._uid32 -#define si_uid16 _sifields._kill._uid -#else #define si_uid _sifields._kill._uid -#endif /* __KERNEL__ */ #define si_status _sifields._sigchld._status #define si_utime _sifields._sigchld._utime #define si_stime _sifields._sigchld._stime diff -ur --new-file old/linux/include/asm-m68k/stat.h new/linux/include/asm-m68k/stat.h --- old/linux/include/asm-m68k/stat.h Fri Dec 17 01:25:37 1999 +++ new/linux/include/asm-m68k/stat.h Wed Jan 26 21:44:21 2000 @@ -38,8 +38,40 @@ unsigned long __unused5; }; -/* stat64 struct goes here -- someone please make - * it mesh with whatever glibc does in userland on - * m68k's. +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. */ +struct stat64 { + unsigned short st_dev; + unsigned char __pad0[10]; + + unsigned long st_ino; + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned short st_rdev; + unsigned char __pad3[10]; + + long long st_size; + unsigned long st_blksize; + + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + unsigned long __pad4; /* future possible st_blocks high bits */ + + unsigned long st_atime; + unsigned long __pad5; + + unsigned long st_mtime; + unsigned long __pad6; + + unsigned long st_ctime; + unsigned long __pad7; /* will be high 32 bits of ctime someday */ + + unsigned long __unused1; + unsigned long __unused2; +}; + #endif /* _M68K_STAT_H */ diff -ur --new-file old/linux/include/asm-m68k/system.h new/linux/include/asm-m68k/system.h --- old/linux/include/asm-m68k/system.h Mon Aug 9 21:27:31 1999 +++ new/linux/include/asm-m68k/system.h Wed Jan 26 21:44:21 2000 @@ -4,6 +4,7 @@ #include /* get configuration macros */ #include #include +#include #define prepare_to_switch() do { } while(0) @@ -44,35 +45,51 @@ (last) = _last; \ } + +/* interrupt control.. */ +#if 0 +#define __sti() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory") +#else +#include +#define __sti() ({ \ + if (!local_irq_count[smp_processor_id()]) \ + asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory"); \ +}) +#endif +#define __cli() asm volatile ("oriw #0x0700,%%sr": : : "memory") +#define __save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory") +#define __restore_flags(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory") + +/* For spinlocks etc */ +#define local_irq_save(x) ({ __save_flags(x); __cli(); }) +#define local_irq_restore(x) __restore_flags(x) +#define local_irq_disable() __cli() +#define local_irq_enable() __sti() + +#define cli() __cli() +#define sti() __sti() +#define save_flags(x) __save_flags(x) +#define restore_flags(x) __restore_flags(x) + + +/* + * Force strict CPU ordering. + * Not really required on m68k... + */ +#define nop() asm volatile ("nop"::) +#define mb() asm volatile ("" : : :"memory") +#define rmb() asm volatile ("" : : :"memory") +#define wmb() asm volatile ("" : : :"memory") +#define set_rmb(var, value) do { xchg(&var, value); } while (0) +#define set_mb(var, value) set_rmb(var, value) +#define set_wmb(var, value) do { var = value; wmb(); } while (0) + + #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) #define tas(ptr) (xchg((ptr),1)) struct __xchg_dummy { unsigned long a[100]; }; #define __xg(x) ((volatile struct __xchg_dummy *)(x)) - -#if defined(MACH_ATARI_ONLY) && !defined(CONFIG_HADES) -/* block out HSYNC on the atari */ -#define __sti() __asm__ __volatile__ ("andiw #0xfbff,%/sr": : : "memory") -#else /* portable version */ -#define __sti() __asm__ __volatile__ ("andiw #0xf8ff,%/sr": : : "memory") -#endif /* machine compilation types */ -#define __cli() __asm__ __volatile__ ("oriw #0x0700,%/sr": : : "memory") -#define nop() __asm__ __volatile__ ("nop"::) -#define mb() __asm__ __volatile__ ("" : : :"memory") -#define rmb() __asm__ __volatile__ ("" : : :"memory") -#define wmb() __asm__ __volatile__ ("" : : :"memory") - -#define __save_flags(x) \ -__asm__ __volatile__("movew %/sr,%0":"=d" (x) : /* no input */ :"memory") - -#define __restore_flags(x) \ -__asm__ __volatile__("movew %0,%/sr": /* no outputs */ :"d" (x) : "memory") - -#define cli() __cli() -#define sti() __sti() -#define save_flags(x) __save_flags(x) -#define restore_flags(x) __restore_flags(x) -#define save_and_cli(flags) do { save_flags(flags); cli(); } while(0) #ifndef CONFIG_RMW_INSNS static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) diff -ur --new-file old/linux/include/asm-m68k/termios.h new/linux/include/asm-m68k/termios.h --- old/linux/include/asm-m68k/termios.h Thu Oct 28 02:04:51 1999 +++ new/linux/include/asm-m68k/termios.h Fri Jan 28 01:40:09 2000 @@ -43,6 +43,9 @@ #define TIOCM_DSR 0x100 #define TIOCM_CD TIOCM_CAR #define TIOCM_RI TIOCM_RNG +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ diff -ur --new-file old/linux/include/asm-m68k/uaccess.h new/linux/include/asm-m68k/uaccess.h --- old/linux/include/asm-m68k/uaccess.h Tue May 11 18:57:14 1999 +++ new/linux/include/asm-m68k/uaccess.h Wed Jan 26 21:44:21 2000 @@ -799,32 +799,45 @@ /* * Return the size of a string (including the ending 0) * - * Return 0 for error + * Return 0 on exception, a value greater than N if too long */ -static inline long strlen_user(const char * src) +static inline long strnlen_user(const char *src, long n) { - long res = -(long) src; - __asm__ __volatile__ - ("1: movesb (%1)+,%%d0\n" - "12:tstb %%d0\n" - " jne 1b\n" - " addl %1,%0\n" - "2:\n" - ".section .fixup,\"ax\"\n" - " .even\n" - "3: moveq %2,%0\n" - " jra 2b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 1b,3b\n" - " .long 12b,3b\n" - ".previous" - : "=d"(res), "=a"(src) - : "i"(0), "0"(res), "1"(src) - : "d0"); - return res; + long res; + + res = -(long)src; + __asm__ __volatile__ + ("1:\n" + " tstl %2\n" + " jeq 3f\n" + "2: movesb (%1)+,%%d0\n" + "22:\n" + " subql #1,%2\n" + " tstb %%d0\n" + " jne 1b\n" + " jra 4f\n" + "3:\n" + " addql #1,%0\n" + "4:\n" + " addl %1,%0\n" + "5:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "6: moveq %3,%0\n" + " jra 5b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 2b,6b\n" + " .long 22b,6b\n" + ".previous" + : "=d"(res), "=a"(src), "=d"(n) + : "i"(0), "0"(res), "1"(src), "2"(n) + : "d0"); + return res; } + +#define strlen_user(str) strnlen_user(str, 32767) /* * Zero Userspace diff -ur --new-file old/linux/include/asm-m68k/virtconvert.h new/linux/include/asm-m68k/virtconvert.h --- old/linux/include/asm-m68k/virtconvert.h Sat Sep 4 22:06:41 1999 +++ new/linux/include/asm-m68k/virtconvert.h Wed Jan 26 21:44:21 2000 @@ -9,6 +9,7 @@ #include #include +#include #ifdef CONFIG_AMIGA #include @@ -34,22 +35,22 @@ #endif #ifdef CONFIG_SINGLE_MEMORY_CHUNK -extern inline unsigned long virt_to_phys(volatile void * address) +extern inline unsigned long virt_to_phys(volatile void *vaddr) { - unsigned long voff = (unsigned long) address; + unsigned long voff = (unsigned long)vaddr - PAGE_OFFSET; if (voff < m68k_memory[0].size) - return m68k_memory[0].addr + voff; - else - return mm_vtop_fallback(voff); + return voff + m68k_memory[0].addr; + return mm_vtop_fallback((unsigned long)vaddr); } extern inline void * phys_to_virt(unsigned long paddr) { - unsigned long base = m68k_memory[0].addr; + unsigned long poff = paddr - m68k_memory[0].addr; + + if (poff < m68k_memory[0].size) + return (void *)(poff + PAGE_OFFSET); - if ((paddr >= base) && (paddr < (base + m68k_memory[0].size))) - return (void *)(paddr - base); #ifdef CONFIG_AMIGA /* * if on an amiga and address is in first 16M, move it diff -ur --new-file old/linux/include/asm-mips/siginfo.h new/linux/include/asm-mips/siginfo.h --- old/linux/include/asm-mips/siginfo.h Wed Jul 28 19:30:10 1999 +++ new/linux/include/asm-mips/siginfo.h Tue Jan 25 20:17:07 2000 @@ -157,7 +157,7 @@ #define CLD_TRAPPED 4 /* traced child has trapped */ #define CLD_STOPPED 5 /* child has stopped */ #define CLD_CONTINUED 6 /* stopped child has continued */ -#define NSIGCHLD +#define NSIGCHLD 6 /* * SIGPOLL si_codes diff -ur --new-file old/linux/include/asm-mips/termios.h new/linux/include/asm-mips/termios.h --- old/linux/include/asm-mips/termios.h Thu Oct 28 02:04:51 1999 +++ new/linux/include/asm-mips/termios.h Fri Jan 28 01:40:09 2000 @@ -83,6 +83,7 @@ #define TIOCM_DSR 0x400 /* data set ready */ #define TIOCM_OUT1 0x2000 #define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 /* line disciplines */ #define N_TTY 0 diff -ur --new-file old/linux/include/asm-ppc/siginfo.h new/linux/include/asm-ppc/siginfo.h --- old/linux/include/asm-ppc/siginfo.h Sun Nov 28 00:42:33 1999 +++ new/linux/include/asm-ppc/siginfo.h Tue Jan 25 20:17:07 2000 @@ -149,7 +149,7 @@ #define CLD_TRAPPED 4 /* traced child has trapped */ #define CLD_STOPPED 5 /* child has stopped */ #define CLD_CONTINUED 6 /* stopped child has continued */ -#define NSIGCHLD +#define NSIGCHLD 6 /* * SIGPOLL si_codes diff -ur --new-file old/linux/include/asm-ppc/termios.h new/linux/include/asm-ppc/termios.h --- old/linux/include/asm-ppc/termios.h Sun Nov 28 00:42:33 1999 +++ new/linux/include/asm-ppc/termios.h Fri Jan 28 01:40:09 2000 @@ -166,6 +166,9 @@ #define TIOCM_DSR 0x100 #define TIOCM_CD TIOCM_CAR #define TIOCM_RI TIOCM_RNG +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff -ur --new-file old/linux/include/asm-sparc/asm_offsets.h new/linux/include/asm-sparc/asm_offsets.h --- old/linux/include/asm-sparc/asm_offsets.h Thu Jan 13 21:03:00 2000 +++ new/linux/include/asm-sparc/asm_offsets.h Sat Jan 22 03:22:54 2000 @@ -159,32 +159,32 @@ #define AOFF_task_semsleeping 0x00000238 #define ASIZ_task_semsleeping 0x00000004 #define AOFF_task_thread 0x00000240 -#define ASIZ_task_thread 0x00000388 -#define AOFF_task_fs 0x000005c8 +#define ASIZ_task_thread 0x00000380 +#define AOFF_task_fs 0x000005c0 #define ASIZ_task_fs 0x00000004 -#define AOFF_task_files 0x000005cc +#define AOFF_task_files 0x000005c4 #define ASIZ_task_files 0x00000004 -#define AOFF_task_sigmask_lock 0x000005d0 +#define AOFF_task_sigmask_lock 0x000005c8 #define ASIZ_task_sigmask_lock 0x00000000 -#define AOFF_task_sig 0x000005d0 +#define AOFF_task_sig 0x000005c8 #define ASIZ_task_sig 0x00000004 -#define AOFF_task_signal 0x000005d4 +#define AOFF_task_signal 0x000005cc #define ASIZ_task_signal 0x00000008 -#define AOFF_task_blocked 0x000005dc +#define AOFF_task_blocked 0x000005d4 #define ASIZ_task_blocked 0x00000008 -#define AOFF_task_sigqueue 0x000005e4 +#define AOFF_task_sigqueue 0x000005dc #define ASIZ_task_sigqueue 0x00000004 -#define AOFF_task_sigqueue_tail 0x000005e8 +#define AOFF_task_sigqueue_tail 0x000005e0 #define ASIZ_task_sigqueue_tail 0x00000004 -#define AOFF_task_sas_ss_sp 0x000005ec +#define AOFF_task_sas_ss_sp 0x000005e4 #define ASIZ_task_sas_ss_sp 0x00000004 -#define AOFF_task_sas_ss_size 0x000005f0 +#define AOFF_task_sas_ss_size 0x000005e8 #define ASIZ_task_sas_ss_size 0x00000004 -#define AOFF_task_parent_exec_id 0x000005f4 +#define AOFF_task_parent_exec_id 0x000005ec #define ASIZ_task_parent_exec_id 0x00000004 -#define AOFF_task_self_exec_id 0x000005f8 +#define AOFF_task_self_exec_id 0x000005f0 #define ASIZ_task_self_exec_id 0x00000004 -#define AOFF_task_exit_sem 0x000005fc +#define AOFF_task_exit_sem 0x000005f4 #define ASIZ_task_exit_sem 0x0000001c #define AOFF_mm_mmap 0x00000000 #define ASIZ_mm_mmap 0x00000004 @@ -248,45 +248,41 @@ #define ASIZ_thread_uwinmask 0x00000004 #define AOFF_thread_kregs 0x00000004 #define ASIZ_thread_kregs 0x00000004 -#define AOFF_thread_sig_address 0x00000008 -#define ASIZ_thread_sig_address 0x00000004 -#define AOFF_thread_sig_desc 0x0000000c -#define ASIZ_thread_sig_desc 0x00000004 -#define AOFF_thread_ksp 0x00000010 +#define AOFF_thread_ksp 0x00000008 #define ASIZ_thread_ksp 0x00000004 -#define AOFF_thread_kpc 0x00000014 +#define AOFF_thread_kpc 0x0000000c #define ASIZ_thread_kpc 0x00000004 -#define AOFF_thread_kpsr 0x00000018 +#define AOFF_thread_kpsr 0x00000010 #define ASIZ_thread_kpsr 0x00000004 -#define AOFF_thread_kwim 0x0000001c +#define AOFF_thread_kwim 0x00000014 #define ASIZ_thread_kwim 0x00000004 -#define AOFF_thread_fork_kpsr 0x00000020 +#define AOFF_thread_fork_kpsr 0x00000018 #define ASIZ_thread_fork_kpsr 0x00000004 -#define AOFF_thread_fork_kwim 0x00000024 +#define AOFF_thread_fork_kwim 0x0000001c #define ASIZ_thread_fork_kwim 0x00000004 -#define AOFF_thread_reg_window 0x00000028 +#define AOFF_thread_reg_window 0x00000020 #define ASIZ_thread_reg_window 0x00000200 -#define AOFF_thread_rwbuf_stkptrs 0x00000228 +#define AOFF_thread_rwbuf_stkptrs 0x00000220 #define ASIZ_thread_rwbuf_stkptrs 0x00000020 -#define AOFF_thread_w_saved 0x00000248 +#define AOFF_thread_w_saved 0x00000240 #define ASIZ_thread_w_saved 0x00000004 -#define AOFF_thread_float_regs 0x00000250 +#define AOFF_thread_float_regs 0x00000248 #define ASIZ_thread_float_regs 0x00000080 -#define AOFF_thread_fsr 0x000002d0 +#define AOFF_thread_fsr 0x000002c8 #define ASIZ_thread_fsr 0x00000004 -#define AOFF_thread_fpqdepth 0x000002d4 +#define AOFF_thread_fpqdepth 0x000002cc #define ASIZ_thread_fpqdepth 0x00000004 -#define AOFF_thread_fpqueue 0x000002d8 +#define AOFF_thread_fpqueue 0x000002d0 #define ASIZ_thread_fpqueue 0x00000080 -#define AOFF_thread_flags 0x00000358 +#define AOFF_thread_flags 0x00000350 #define ASIZ_thread_flags 0x00000004 -#define AOFF_thread_current_ds 0x0000035c +#define AOFF_thread_current_ds 0x00000354 #define ASIZ_thread_current_ds 0x00000004 -#define AOFF_thread_core_exec 0x00000360 +#define AOFF_thread_core_exec 0x00000358 #define ASIZ_thread_core_exec 0x00000020 -#define AOFF_thread_new_signal 0x00000380 +#define AOFF_thread_new_signal 0x00000378 #define ASIZ_thread_new_signal 0x00000004 -#define AOFF_thread_refcount 0x00000384 +#define AOFF_thread_refcount 0x0000037c #define ASIZ_thread_refcount 0x00000004 #else /* CONFIG_SMP */ @@ -444,32 +440,32 @@ #define AOFF_task_semsleeping 0x00000338 #define ASIZ_task_semsleeping 0x00000004 #define AOFF_task_thread 0x00000340 -#define ASIZ_task_thread 0x00000388 -#define AOFF_task_fs 0x000006c8 +#define ASIZ_task_thread 0x00000380 +#define AOFF_task_fs 0x000006c0 #define ASIZ_task_fs 0x00000004 -#define AOFF_task_files 0x000006cc +#define AOFF_task_files 0x000006c4 #define ASIZ_task_files 0x00000004 -#define AOFF_task_sigmask_lock 0x000006d0 +#define AOFF_task_sigmask_lock 0x000006c8 #define ASIZ_task_sigmask_lock 0x00000008 -#define AOFF_task_sig 0x000006d8 +#define AOFF_task_sig 0x000006d0 #define ASIZ_task_sig 0x00000004 -#define AOFF_task_signal 0x000006dc +#define AOFF_task_signal 0x000006d4 #define ASIZ_task_signal 0x00000008 -#define AOFF_task_blocked 0x000006e4 +#define AOFF_task_blocked 0x000006dc #define ASIZ_task_blocked 0x00000008 -#define AOFF_task_sigqueue 0x000006ec +#define AOFF_task_sigqueue 0x000006e4 #define ASIZ_task_sigqueue 0x00000004 -#define AOFF_task_sigqueue_tail 0x000006f0 +#define AOFF_task_sigqueue_tail 0x000006e8 #define ASIZ_task_sigqueue_tail 0x00000004 -#define AOFF_task_sas_ss_sp 0x000006f4 +#define AOFF_task_sas_ss_sp 0x000006ec #define ASIZ_task_sas_ss_sp 0x00000004 -#define AOFF_task_sas_ss_size 0x000006f8 +#define AOFF_task_sas_ss_size 0x000006f0 #define ASIZ_task_sas_ss_size 0x00000004 -#define AOFF_task_parent_exec_id 0x000006fc +#define AOFF_task_parent_exec_id 0x000006f4 #define ASIZ_task_parent_exec_id 0x00000004 -#define AOFF_task_self_exec_id 0x00000700 +#define AOFF_task_self_exec_id 0x000006f8 #define ASIZ_task_self_exec_id 0x00000004 -#define AOFF_task_exit_sem 0x00000704 +#define AOFF_task_exit_sem 0x000006fc #define ASIZ_task_exit_sem 0x00000024 #define AOFF_mm_mmap 0x00000000 #define ASIZ_mm_mmap 0x00000004 @@ -533,45 +529,41 @@ #define ASIZ_thread_uwinmask 0x00000004 #define AOFF_thread_kregs 0x00000004 #define ASIZ_thread_kregs 0x00000004 -#define AOFF_thread_sig_address 0x00000008 -#define ASIZ_thread_sig_address 0x00000004 -#define AOFF_thread_sig_desc 0x0000000c -#define ASIZ_thread_sig_desc 0x00000004 -#define AOFF_thread_ksp 0x00000010 +#define AOFF_thread_ksp 0x00000008 #define ASIZ_thread_ksp 0x00000004 -#define AOFF_thread_kpc 0x00000014 +#define AOFF_thread_kpc 0x0000000c #define ASIZ_thread_kpc 0x00000004 -#define AOFF_thread_kpsr 0x00000018 +#define AOFF_thread_kpsr 0x00000010 #define ASIZ_thread_kpsr 0x00000004 -#define AOFF_thread_kwim 0x0000001c +#define AOFF_thread_kwim 0x00000014 #define ASIZ_thread_kwim 0x00000004 -#define AOFF_thread_fork_kpsr 0x00000020 +#define AOFF_thread_fork_kpsr 0x00000018 #define ASIZ_thread_fork_kpsr 0x00000004 -#define AOFF_thread_fork_kwim 0x00000024 +#define AOFF_thread_fork_kwim 0x0000001c #define ASIZ_thread_fork_kwim 0x00000004 -#define AOFF_thread_reg_window 0x00000028 +#define AOFF_thread_reg_window 0x00000020 #define ASIZ_thread_reg_window 0x00000200 -#define AOFF_thread_rwbuf_stkptrs 0x00000228 +#define AOFF_thread_rwbuf_stkptrs 0x00000220 #define ASIZ_thread_rwbuf_stkptrs 0x00000020 -#define AOFF_thread_w_saved 0x00000248 +#define AOFF_thread_w_saved 0x00000240 #define ASIZ_thread_w_saved 0x00000004 -#define AOFF_thread_float_regs 0x00000250 +#define AOFF_thread_float_regs 0x00000248 #define ASIZ_thread_float_regs 0x00000080 -#define AOFF_thread_fsr 0x000002d0 +#define AOFF_thread_fsr 0x000002c8 #define ASIZ_thread_fsr 0x00000004 -#define AOFF_thread_fpqdepth 0x000002d4 +#define AOFF_thread_fpqdepth 0x000002cc #define ASIZ_thread_fpqdepth 0x00000004 -#define AOFF_thread_fpqueue 0x000002d8 +#define AOFF_thread_fpqueue 0x000002d0 #define ASIZ_thread_fpqueue 0x00000080 -#define AOFF_thread_flags 0x00000358 +#define AOFF_thread_flags 0x00000350 #define ASIZ_thread_flags 0x00000004 -#define AOFF_thread_current_ds 0x0000035c +#define AOFF_thread_current_ds 0x00000354 #define ASIZ_thread_current_ds 0x00000004 -#define AOFF_thread_core_exec 0x00000360 +#define AOFF_thread_core_exec 0x00000358 #define ASIZ_thread_core_exec 0x00000020 -#define AOFF_thread_new_signal 0x00000380 +#define AOFF_thread_new_signal 0x00000378 #define ASIZ_thread_new_signal 0x00000004 -#define AOFF_thread_refcount 0x00000384 +#define AOFF_thread_refcount 0x0000037c #define ASIZ_thread_refcount 0x00000004 #endif /* CONFIG_SMP */ diff -ur --new-file old/linux/include/asm-sparc/hdreg.h new/linux/include/asm-sparc/hdreg.h --- old/linux/include/asm-sparc/hdreg.h Thu Jan 1 01:00:00 1970 +++ new/linux/include/asm-sparc/hdreg.h Sat Jan 22 03:22:54 2000 @@ -0,0 +1,13 @@ +/* $Id: hdreg.h,v 1.1 2000/01/21 04:56:27 zaitcev Exp $ + * hdreg.h: SPARC PCI specific IDE glue. + * + * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) + */ + +#ifndef __SPARC_HDREG_H +#define __SPARC_HDREG_H + +typedef unsigned int ide_ioreg_t; + +#endif /* __SPARC_HDREG_H */ diff -ur --new-file old/linux/include/asm-sparc/ide.h new/linux/include/asm-sparc/ide.h --- old/linux/include/asm-sparc/ide.h Thu Jan 1 01:00:00 1970 +++ new/linux/include/asm-sparc/ide.h Sat Jan 22 03:22:54 2000 @@ -0,0 +1,289 @@ +/* $Id: ide.h,v 1.2 2000/01/21 04:56:27 zaitcev Exp $ + * ide.h: SPARC PCI specific IDE glue. + * + * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) + * Adaptation from sparc64 version to sparc by Pete Zaitcev. + */ + +#ifndef _SPARC_IDE_H +#define _SPARC_IDE_H + +#ifdef __KERNEL__ + +#include +#include +#include +#include + +#undef MAX_HWIFS +#define MAX_HWIFS 2 + +#define ide__sti() __sti() + +static __inline__ int ide_default_irq(ide_ioreg_t base) +{ + return 0; +} + +static __inline__ ide_ioreg_t ide_default_io_base(int index) +{ + return 0; +} + +/* + * Doing any sort of ioremap() here does not work + * because this function may be called with null aguments. + */ +static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = 0; + } + if (irq != NULL) + *irq = 0; +} + +/* + * This registers the standard ports for this architecture with the IDE + * driver. + */ +static __inline__ void ide_init_default_hwifs(void) +{ +#ifdef __DO_I_NEED_THIS + hw_regs_t hw; + int index; + + for (index = 0; index < MAX_HWIFS; index++) { + ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, 0); + hw.irq = ide_default_irq(ide_default_io_base(index)); + ide_register_hw(&hw, NULL); + } +#endif /* __DO_I_NEED_THIS */ +} + +typedef union { + unsigned int all : 8; /* all of the bits together */ + struct { + unsigned int bit7 : 1; + unsigned int lba : 1; + unsigned int bit5 : 1; + unsigned int unit : 1; + unsigned int head : 4; + } b; +} select_t; + +static __inline__ int ide_request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *name, void *devid) +{ + return request_irq(irq, handler, SA_SHIRQ, name, devid); +} + +static __inline__ void ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static __inline__ int ide_check_region(ide_ioreg_t base, unsigned int size) +{ + /* We leave these empty because pcic.c calls sparc_alloc_io() */ + return 0; +} + +static __inline__ void ide_request_region(ide_ioreg_t base, unsigned int size, + const char *name) +{ +} + +static __inline__ void ide_release_region(ide_ioreg_t base, unsigned int size) +{ +} + +#undef SUPPORT_SLOW_DATA_PORTS +#define SUPPORT_SLOW_DATA_PORTS 0 + +#undef SUPPORT_VLB_SYNC +#define SUPPORT_VLB_SYNC 0 + +#undef HD_DATA +#define HD_DATA ((ide_ioreg_t)0) + +/* From m68k code... */ + +#ifdef insl +#undef insl +#endif +#ifdef outsl +#undef outsl +#endif +#ifdef insw +#undef insw +#endif +#ifdef outsw +#undef outsw +#endif + +#define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1) +#define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1) + +#define insw(port, buf, nr) ide_insw((port), (buf), (nr)) +#define outsw(port, buf, nr) ide_outsw((port), (buf), (nr)) + +static __inline__ void ide_insw(unsigned long port, + void *dst, + unsigned long count) +{ + volatile unsigned short *data_port; + /* unsigned long end = (unsigned long)dst + (count << 1); */ /* P3 */ + u16 *ps = dst; + u32 *pi; + + data_port = (volatile unsigned short *)port; + + if(((unsigned long)ps) & 0x2) { + *ps++ = *data_port; + count--; + } + pi = (u32 *)ps; + while(count >= 2) { + u32 w; + + w = (*data_port) << 16; + w |= (*data_port); + *pi++ = w; + count -= 2; + } + ps = (u16 *)pi; + if(count) + *ps++ = *data_port; + + /* __flush_dcache_range((unsigned long)dst, end); */ /* P3 see hme */ +} + +static __inline__ void ide_outsw(unsigned long port, + const void *src, + unsigned long count) +{ + volatile unsigned short *data_port; + /* unsigned long end = (unsigned long)src + (count << 1); */ + const u16 *ps = src; + const u32 *pi; + + data_port = (volatile unsigned short *)port; + + if(((unsigned long)src) & 0x2) { + *data_port = *ps++; + count--; + } + pi = (const u32 *)ps; + while(count >= 2) { + u32 w; + + w = *pi++; + *data_port = (w >> 16); + *data_port = w; + count -= 2; + } + ps = (const u16 *)pi; + if(count) + *data_port = *ps; + + /* __flush_dcache_range((unsigned long)src, end); */ /* P3 see hme */ +} + +#define T_CHAR (0x0000) /* char: don't touch */ +#define T_SHORT (0x4000) /* short: 12 -> 21 */ +#define T_INT (0x8000) /* int: 1234 -> 4321 */ +#define T_TEXT (0xc000) /* text: 12 -> 21 */ + +#define T_MASK_TYPE (0xc000) +#define T_MASK_COUNT (0x3fff) + +#define D_CHAR(cnt) (T_CHAR | (cnt)) +#define D_SHORT(cnt) (T_SHORT | (cnt)) +#define D_INT(cnt) (T_INT | (cnt)) +#define D_TEXT(cnt) (T_TEXT | (cnt)) + +static u_short driveid_types[] = { + D_SHORT(10), /* config - vendor2 */ + D_TEXT(20), /* serial_no */ + D_SHORT(3), /* buf_type - ecc_bytes */ + D_TEXT(48), /* fw_rev - model */ + D_CHAR(2), /* max_multsect - vendor3 */ + D_SHORT(1), /* dword_io */ + D_CHAR(2), /* vendor4 - capability */ + D_SHORT(1), /* reserved50 */ + D_CHAR(4), /* vendor5 - tDMA */ + D_SHORT(4), /* field_valid - cur_sectors */ + D_INT(1), /* cur_capacity */ + D_CHAR(2), /* multsect - multsect_valid */ + D_INT(1), /* lba_capacity */ + D_SHORT(194) /* dma_1word - reservedyy */ +}; + +#define num_driveid_types (sizeof(driveid_types)/sizeof(*driveid_types)) + +static __inline__ void ide_fix_driveid(struct hd_driveid *id) +{ + u_char *p = (u_char *)id; + int i, j, cnt; + u_char t; + + for (i = 0; i < num_driveid_types; i++) { + cnt = driveid_types[i] & T_MASK_COUNT; + switch (driveid_types[i] & T_MASK_TYPE) { + case T_CHAR: + p += cnt; + break; + case T_SHORT: + for (j = 0; j < cnt; j++) { + t = p[0]; + p[0] = p[1]; + p[1] = t; + p += 2; + } + break; + case T_INT: + for (j = 0; j < cnt; j++) { + t = p[0]; + p[0] = p[3]; + p[3] = t; + t = p[1]; + p[1] = p[2]; + p[2] = t; + p += 4; + } + break; + case T_TEXT: + for (j = 0; j < cnt; j += 2) { + t = p[0]; + p[0] = p[1]; + p[1] = t; + p += 2; + } + break; + }; + } +} + +/* + * The following are not needed for the non-m68k ports + */ +#define ide_ack_intr(hwif) (1) +/* #define ide_ack_intr(hwif) ((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1) */ +#define ide_release_lock(lock) do {} while (0) +#define ide_get_lock(lock, hdlr, data) do {} while (0) + +#endif /* __KERNEL__ */ + +#endif /* _SPARC_IDE_H */ diff -ur --new-file old/linux/include/asm-sparc/io.h new/linux/include/asm-sparc/io.h --- old/linux/include/asm-sparc/io.h Tue Dec 21 07:05:52 1999 +++ new/linux/include/asm-sparc/io.h Mon Jan 24 04:48:47 2000 @@ -1,5 +1,5 @@ /* - * $Id: io.h,v 1.24 1999/12/20 04:58:40 davem Exp $ + * $Id: io.h,v 1.25 2000/01/22 07:35:46 zaitcev Exp $ */ #ifndef __SPARC_IO_H #define __SPARC_IO_H @@ -12,7 +12,7 @@ #include #define virt_to_bus virt_to_phys - +#define bus_to_virt phys_to_virt extern __inline__ unsigned flip_dword (unsigned d) { return ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff); @@ -77,6 +77,13 @@ #define outw(b, addr) writew(b, addr) #define outl(b, addr) writel(b, addr) #define outb_p(b, addr) writeb(b, addr) + +extern void outsb(unsigned long addr, const void *src, unsigned long cnt); +extern void outsw(unsigned long addr, const void *src, unsigned long cnt); +extern void outsl(unsigned long addr, const void *src, unsigned long cnt); +extern void insb(unsigned long addr, void *dst, unsigned long count); +extern void insw(unsigned long addr, void *dst, unsigned long count); +extern void insl(unsigned long addr, void *dst, unsigned long count); #define IO_SPACE_LIMIT 0xffffffff diff -ur --new-file old/linux/include/asm-sparc/irq.h new/linux/include/asm-sparc/irq.h --- old/linux/include/asm-sparc/irq.h Tue Aug 31 20:23:30 1999 +++ new/linux/include/asm-sparc/irq.h Mon Jan 24 04:48:47 2000 @@ -1,4 +1,4 @@ -/* $Id: irq.h,v 1.27 1999/08/14 03:52:02 anton Exp $ +/* $Id: irq.h,v 1.28 2000/01/22 06:06:58 zaitcev Exp $ * irq.h: IRQ registers on the Sparc. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -49,6 +49,7 @@ BTFIXUPDEF_CALL(void, clear_profile_irq, int) BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int) +#define disable_irq_nosync disable_irq #define disable_irq(irq) BTFIXUP_CALL(disable_irq)(irq) #define enable_irq(irq) BTFIXUP_CALL(enable_irq)(irq) #define disable_pil_irq(irq) BTFIXUP_CALL(disable_pil_irq)(irq) diff -ur --new-file old/linux/include/asm-sparc/pci.h new/linux/include/asm-sparc/pci.h --- old/linux/include/asm-sparc/pci.h Wed Sep 8 20:14:32 1999 +++ new/linux/include/asm-sparc/pci.h Mon Jan 24 04:48:47 2000 @@ -7,4 +7,7 @@ */ #define pcibios_assign_all_busses() 0 +#define PCIBIOS_MIN_IO 0UL +#define PCIBIOS_MIN_MEM 0UL + #endif /* __SPARC_PCI_H */ diff -ur --new-file old/linux/include/asm-sparc/processor.h new/linux/include/asm-sparc/processor.h --- old/linux/include/asm-sparc/processor.h Thu Jan 13 21:03:00 2000 +++ new/linux/include/asm-sparc/processor.h Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: processor.h,v 1.76 2000/01/09 09:13:38 anton Exp $ +/* $Id: processor.h,v 1.77 2000/01/21 11:39:17 jj Exp $ * include/asm-sparc/processor.h * * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) @@ -58,10 +58,6 @@ unsigned long uwinmask __attribute__ ((aligned (8))); struct pt_regs *kregs; - /* For signal handling */ - unsigned long sig_address __attribute__ ((aligned (8))); - unsigned long sig_desc; - /* Context switch saved kernel state. */ unsigned long ksp __attribute__ ((aligned (8))); unsigned long kpc; @@ -99,8 +95,8 @@ NULL, __pgprot(0x0) , VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL } #define INIT_THREAD { \ -/* uwinmask, kregs, sig_address, sig_desc, ksp, kpc, kpsr, kwim */ \ - 0, 0, 0, 0, 0, 0, 0, 0, \ +/* uwinmask, kregs, ksp, kpc, kpsr, kwim */ \ + 0, 0, 0, 0, 0, 0, \ /* fork_kpsr, fork_kwim */ \ 0, 0, \ /* reg_window */ \ diff -ur --new-file old/linux/include/asm-sparc/sbus.h new/linux/include/asm-sparc/sbus.h --- old/linux/include/asm-sparc/sbus.h Mon Jan 3 21:01:31 2000 +++ new/linux/include/asm-sparc/sbus.h Thu Jan 27 17:58:15 2000 @@ -101,9 +101,9 @@ #define sbus_can_burst64(sdev) (1) extern void sbus_set_sbus64(struct sbus_dev *, int); -/* These yield IOMMU mappings in consistant mode. */ -extern void *sbus_alloc_consistant(struct sbus_dev *, long, u32 *dma_addrp); -extern void sbus_free_consistant(struct sbus_dev *, long, void *, u32); +/* These yield IOMMU mappings in consistent mode. */ +extern void *sbus_alloc_consistent(struct sbus_dev *, long, u32 *dma_addrp); +extern void sbus_free_consistent(struct sbus_dev *, long, void *, u32); /* All the rest use streaming mode mappings. */ extern u32 sbus_map_single(struct sbus_dev *, void *, long); diff -ur --new-file old/linux/include/asm-sparc/semaphore.h new/linux/include/asm-sparc/semaphore.h --- old/linux/include/asm-sparc/semaphore.h Mon Jan 3 21:01:31 2000 +++ new/linux/include/asm-sparc/semaphore.h Thu Jan 27 15:32:14 2000 @@ -250,10 +250,17 @@ #define __RWSEM_DEBUG_INIT /* */ #endif -#define __RWSEM_INITIALIZER(name) \ -{ RW_LOCK_BIAS, 0, 0xff, 0xff, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \ +#define __RWSEM_INITIALIZER(name,count) \ +{ (count), 0, 0xff, 0xff, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \ __WAIT_QUEUE_HEAD_INITIALIZER((name).write_bias_wait) \ __SEM_DEBUG_INIT(name) __RWSEM_DEBUG_INIT } + +#define __DECLARE_RWSEM_GENERIC(name,count) \ + struct rw_semaphore name = __RWSEM_INITIALIZER(name,count) + +#define DECLARE_RWSEM(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS) +#define DECLARE_RWSEM_READ_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS-1) +#define DECLARE_RWSEM_WRITE_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,0) extern inline void init_rwsem(struct rw_semaphore *sem) { diff -ur --new-file old/linux/include/asm-sparc/sembuf.h new/linux/include/asm-sparc/sembuf.h --- old/linux/include/asm-sparc/sembuf.h Thu Jan 13 21:03:00 2000 +++ new/linux/include/asm-sparc/sembuf.h Sat Jan 22 03:22:54 2000 @@ -8,7 +8,7 @@ * * Pad space is left for: * - 64-bit time_t to solve y2038 problem - * - 2 miscellaneous 64-bit values + * - 2 miscellaneous 32-bit values */ struct semid64_ds { diff -ur --new-file old/linux/include/asm-sparc/siginfo.h new/linux/include/asm-sparc/siginfo.h --- old/linux/include/asm-sparc/siginfo.h Tue Aug 3 07:07:16 1999 +++ new/linux/include/asm-sparc/siginfo.h Tue Jan 25 20:17:07 2000 @@ -1,4 +1,4 @@ -/* $Id: siginfo.h,v 1.5 1999/07/29 12:56:57 jj Exp $ +/* $Id: siginfo.h,v 1.6 2000/01/21 11:39:17 jj Exp $ * siginfo.c: */ @@ -81,6 +81,11 @@ #define si_band _sifields._sigpoll._band #define si_fd _sifields._sigpoll._fd +#ifdef __KERNEL__ +#define __SI_MASK 0 +#define __SI_FAULT 0 +#endif + /* * si_code values * Digital reserves positive values for kernel-generated signals. @@ -127,7 +132,7 @@ * SIGSEGV si_codes */ #define SEGV_MAPERR 1 /* address not mapped to object */ -#define SRGV_ACCERR 2 /* invalid permissions for mapped object */ +#define SEGV_ACCERR 2 /* invalid permissions for mapped object */ #define NSIGSEGV 2 /* @@ -154,7 +159,7 @@ #define CLD_TRAPPED 4 /* traced child has trapped */ #define CLD_STOPPED 5 /* child has stopped */ #define CLD_CONTINUED 6 /* stopped child has continued */ -#define NSIGCHLD +#define NSIGCHLD 6 /* * SIGPOLL si_codes diff -ur --new-file old/linux/include/asm-sparc/smp.h new/linux/include/asm-sparc/smp.h --- old/linux/include/asm-sparc/smp.h Tue Aug 31 20:23:30 1999 +++ new/linux/include/asm-sparc/smp.h Sat Jan 22 03:22:54 2000 @@ -92,13 +92,17 @@ unsigned long arg3, unsigned long arg4, unsigned long arg5) { smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); } -extern __volatile__ int cpu_number_map[NR_CPUS]; +extern __volatile__ int __cpu_number_map[NR_CPUS]; extern __volatile__ int __cpu_logical_map[NR_CPUS]; extern unsigned long smp_proc_in_lock[NR_CPUS]; extern __inline__ int cpu_logical_map(int cpu) { return __cpu_logical_map[cpu]; +} +extern __inline__ int cpu_number_map(int cpu) +{ + return __cpu_number_map[cpu]; } extern __inline__ int hard_smp4m_processor_id(void) diff -ur --new-file old/linux/include/asm-sparc/stat.h new/linux/include/asm-sparc/stat.h --- old/linux/include/asm-sparc/stat.h Wed Dec 22 06:56:42 1999 +++ new/linux/include/asm-sparc/stat.h Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: stat.h,v 1.10 1999/12/21 14:09:41 jj Exp $ */ +/* $Id: stat.h,v 1.11 2000/01/16 15:22:53 jj Exp $ */ #ifndef _SPARC_STAT_H #define _SPARC_STAT_H @@ -19,23 +19,23 @@ }; struct stat { - dev_t st_dev; - ino_t st_ino; - mode_t st_mode; - short st_nlink; - uid_t st_uid; - gid_t st_gid; - dev_t st_rdev; - off_t st_size; - time_t st_atime; - unsigned long __unused1; - time_t st_mtime; - unsigned long __unused2; - time_t st_ctime; - unsigned long __unused3; - off_t st_blksize; - off_t st_blocks; - unsigned long __unused4[2]; + unsigned short st_dev; + unsigned long st_ino; + unsigned short st_mode; + short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + long st_size; + long st_atime; + unsigned long __unused1; + long st_mtime; + unsigned long __unused2; + long st_ctime; + unsigned long __unused3; + long st_blksize; + long st_blocks; + unsigned long __unused4[2]; }; struct stat64 { diff -ur --new-file old/linux/include/asm-sparc/termbits.h new/linux/include/asm-sparc/termbits.h --- old/linux/include/asm-sparc/termbits.h Thu Mar 11 01:53:37 1999 +++ new/linux/include/asm-sparc/termbits.h Fri Jan 28 01:40:09 2000 @@ -203,6 +203,9 @@ #define TIOCM_DSR 0x100 #define TIOCM_CD TIOCM_CAR #define TIOCM_RI TIOCM_RNG +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff -ur --new-file old/linux/include/asm-sparc/unistd.h new/linux/include/asm-sparc/unistd.h --- old/linux/include/asm-sparc/unistd.h Fri Jan 14 23:52:08 2000 +++ new/linux/include/asm-sparc/unistd.h Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: unistd.h,v 1.63 2000/01/12 11:47:40 anton Exp $ */ +/* $Id: unistd.h,v 1.64 2000/01/16 06:20:32 davem Exp $ */ #ifndef _SPARC_UNISTD_H #define _SPARC_UNISTD_H diff -ur --new-file old/linux/include/asm-sparc64/asm_offsets.h new/linux/include/asm-sparc64/asm_offsets.h --- old/linux/include/asm-sparc64/asm_offsets.h Thu Jan 13 21:03:00 2000 +++ new/linux/include/asm-sparc64/asm_offsets.h Sat Jan 22 03:22:54 2000 @@ -165,34 +165,34 @@ #define AOFF_task_semsleeping 0x00000378 #define ASIZ_task_semsleeping 0x00000008 #define AOFF_task_thread 0x00000380 -#define ASIZ_task_thread 0x00000460 -#define AOFF_task_fs 0x000007e0 +#define ASIZ_task_thread 0x00000450 +#define AOFF_task_fs 0x000007d0 #define ASIZ_task_fs 0x00000008 -#define AOFF_task_files 0x000007e8 +#define AOFF_task_files 0x000007d8 #define ASIZ_task_files 0x00000008 -#define AOFF_task_sigmask_lock 0x000007f0 +#define AOFF_task_sigmask_lock 0x000007e0 #define ASIZ_task_sigmask_lock 0x00000000 -#define AOFF_task_sig 0x000007f0 +#define AOFF_task_sig 0x000007e0 #define ASIZ_task_sig 0x00000008 -#define AOFF_task_signal 0x000007f8 +#define AOFF_task_signal 0x000007e8 #define ASIZ_task_signal 0x00000008 -#define AOFF_task_blocked 0x00000800 +#define AOFF_task_blocked 0x000007f0 #define ASIZ_task_blocked 0x00000008 -#define AOFF_task_sigqueue 0x00000808 +#define AOFF_task_sigqueue 0x000007f8 #define ASIZ_task_sigqueue 0x00000008 -#define AOFF_task_sigqueue_tail 0x00000810 +#define AOFF_task_sigqueue_tail 0x00000800 #define ASIZ_task_sigqueue_tail 0x00000008 -#define AOFF_task_sas_ss_sp 0x00000818 +#define AOFF_task_sas_ss_sp 0x00000808 #define ASIZ_task_sas_ss_sp 0x00000008 -#define AOFF_task_sas_ss_size 0x00000820 +#define AOFF_task_sas_ss_size 0x00000810 #define ASIZ_task_sas_ss_size 0x00000008 -#define AOFF_task_parent_exec_id 0x00000828 +#define AOFF_task_parent_exec_id 0x00000818 #define ASIZ_task_parent_exec_id 0x00000004 -#define AOFF_task_self_exec_id 0x0000082c +#define AOFF_task_self_exec_id 0x0000081c #define ASIZ_task_self_exec_id 0x00000004 -#define AOFF_task_exit_sem 0x00000830 +#define AOFF_task_exit_sem 0x00000820 #define ASIZ_task_exit_sem 0x00000030 -#define ASIZ_task 0x00000860 +#define ASIZ_task 0x00000850 #define AOFF_mm_mmap 0x00000000 #define ASIZ_mm_mmap 0x00000008 #define AOFF_mm_mmap_avl 0x00000008 @@ -278,29 +278,23 @@ #define ASIZ_thread_gsr 0x00000007 #define AOFF_thread___pad2 0x0000002f #define ASIZ_thread___pad2 0x00000001 -#define AOFF_thread_sig_address 0x00000030 -#define ASIZ_thread_sig_address 0x00000008 -#define AOFF_thread_sig_desc 0x00000038 -#define ASIZ_thread_sig_desc 0x00000008 -#define AOFF_thread_xfsr 0x00000040 +#define AOFF_thread_xfsr 0x00000030 #define ASIZ_thread_xfsr 0x00000038 -#define AOFF_thread___pad3 0x00000078 -#define ASIZ_thread___pad3 0x00000008 -#define AOFF_thread_reg_window 0x00000080 +#define AOFF_thread_reg_window 0x00000068 #define ASIZ_thread_reg_window 0x00000380 -#define AOFF_thread_rwbuf_stkptrs 0x00000400 +#define AOFF_thread_rwbuf_stkptrs 0x000003e8 #define ASIZ_thread_rwbuf_stkptrs 0x00000038 -#define AOFF_thread_user_cntd0 0x00000438 +#define AOFF_thread_user_cntd0 0x00000420 #define ASIZ_thread_user_cntd0 0x00000008 -#define AOFF_thread_user_cntd1 0x00000440 +#define AOFF_thread_user_cntd1 0x00000428 #define ASIZ_thread_user_cntd1 0x00000008 -#define AOFF_thread_kernel_cntd0 0x00000448 +#define AOFF_thread_kernel_cntd0 0x00000430 #define ASIZ_thread_kernel_cntd0 0x00000008 -#define AOFF_thread_kernel_cntd1 0x00000450 +#define AOFF_thread_kernel_cntd1 0x00000438 #define ASIZ_thread_kernel_cntd1 0x00000008 -#define AOFF_thread_pcr_reg 0x00000458 +#define AOFF_thread_pcr_reg 0x00000440 #define ASIZ_thread_pcr_reg 0x00000008 -#define ASIZ_thread 0x00000460 +#define ASIZ_thread 0x00000450 #else /* CONFIG_SMP */ @@ -459,34 +453,34 @@ #define AOFF_task_semsleeping 0x00000570 #define ASIZ_task_semsleeping 0x00000008 #define AOFF_task_thread 0x00000580 -#define ASIZ_task_thread 0x00000460 -#define AOFF_task_fs 0x000009e0 +#define ASIZ_task_thread 0x00000450 +#define AOFF_task_fs 0x000009d0 #define ASIZ_task_fs 0x00000008 -#define AOFF_task_files 0x000009e8 +#define AOFF_task_files 0x000009d8 #define ASIZ_task_files 0x00000008 -#define AOFF_task_sigmask_lock 0x000009f0 +#define AOFF_task_sigmask_lock 0x000009e0 #define ASIZ_task_sigmask_lock 0x00000001 -#define AOFF_task_sig 0x000009f8 +#define AOFF_task_sig 0x000009e8 #define ASIZ_task_sig 0x00000008 -#define AOFF_task_signal 0x00000a00 +#define AOFF_task_signal 0x000009f0 #define ASIZ_task_signal 0x00000008 -#define AOFF_task_blocked 0x00000a08 +#define AOFF_task_blocked 0x000009f8 #define ASIZ_task_blocked 0x00000008 -#define AOFF_task_sigqueue 0x00000a10 +#define AOFF_task_sigqueue 0x00000a00 #define ASIZ_task_sigqueue 0x00000008 -#define AOFF_task_sigqueue_tail 0x00000a18 +#define AOFF_task_sigqueue_tail 0x00000a08 #define ASIZ_task_sigqueue_tail 0x00000008 -#define AOFF_task_sas_ss_sp 0x00000a20 +#define AOFF_task_sas_ss_sp 0x00000a10 #define ASIZ_task_sas_ss_sp 0x00000008 -#define AOFF_task_sas_ss_size 0x00000a28 +#define AOFF_task_sas_ss_size 0x00000a18 #define ASIZ_task_sas_ss_size 0x00000008 -#define AOFF_task_parent_exec_id 0x00000a30 +#define AOFF_task_parent_exec_id 0x00000a20 #define ASIZ_task_parent_exec_id 0x00000004 -#define AOFF_task_self_exec_id 0x00000a34 +#define AOFF_task_self_exec_id 0x00000a24 #define ASIZ_task_self_exec_id 0x00000004 -#define AOFF_task_exit_sem 0x00000a38 +#define AOFF_task_exit_sem 0x00000a28 #define ASIZ_task_exit_sem 0x00000038 -#define ASIZ_task 0x00000a70 +#define ASIZ_task 0x00000a60 #define AOFF_mm_mmap 0x00000000 #define ASIZ_mm_mmap 0x00000008 #define AOFF_mm_mmap_avl 0x00000008 @@ -572,29 +566,23 @@ #define ASIZ_thread_gsr 0x00000007 #define AOFF_thread___pad2 0x0000002f #define ASIZ_thread___pad2 0x00000001 -#define AOFF_thread_sig_address 0x00000030 -#define ASIZ_thread_sig_address 0x00000008 -#define AOFF_thread_sig_desc 0x00000038 -#define ASIZ_thread_sig_desc 0x00000008 -#define AOFF_thread_xfsr 0x00000040 +#define AOFF_thread_xfsr 0x00000030 #define ASIZ_thread_xfsr 0x00000038 -#define AOFF_thread___pad3 0x00000078 -#define ASIZ_thread___pad3 0x00000008 -#define AOFF_thread_reg_window 0x00000080 +#define AOFF_thread_reg_window 0x00000068 #define ASIZ_thread_reg_window 0x00000380 -#define AOFF_thread_rwbuf_stkptrs 0x00000400 +#define AOFF_thread_rwbuf_stkptrs 0x000003e8 #define ASIZ_thread_rwbuf_stkptrs 0x00000038 -#define AOFF_thread_user_cntd0 0x00000438 +#define AOFF_thread_user_cntd0 0x00000420 #define ASIZ_thread_user_cntd0 0x00000008 -#define AOFF_thread_user_cntd1 0x00000440 +#define AOFF_thread_user_cntd1 0x00000428 #define ASIZ_thread_user_cntd1 0x00000008 -#define AOFF_thread_kernel_cntd0 0x00000448 +#define AOFF_thread_kernel_cntd0 0x00000430 #define ASIZ_thread_kernel_cntd0 0x00000008 -#define AOFF_thread_kernel_cntd1 0x00000450 +#define AOFF_thread_kernel_cntd1 0x00000438 #define ASIZ_thread_kernel_cntd1 0x00000008 -#define AOFF_thread_pcr_reg 0x00000458 +#define AOFF_thread_pcr_reg 0x00000440 #define ASIZ_thread_pcr_reg 0x00000008 -#define ASIZ_thread 0x00000460 +#define ASIZ_thread 0x00000450 #else /* SPIN_LOCK_DEBUG */ @@ -751,34 +739,34 @@ #define AOFF_task_semsleeping 0x00000578 #define ASIZ_task_semsleeping 0x00000008 #define AOFF_task_thread 0x00000580 -#define ASIZ_task_thread 0x00000460 -#define AOFF_task_fs 0x000009e0 +#define ASIZ_task_thread 0x00000450 +#define AOFF_task_fs 0x000009d0 #define ASIZ_task_fs 0x00000008 -#define AOFF_task_files 0x000009e8 +#define AOFF_task_files 0x000009d8 #define ASIZ_task_files 0x00000008 -#define AOFF_task_sigmask_lock 0x000009f0 +#define AOFF_task_sigmask_lock 0x000009e0 #define ASIZ_task_sigmask_lock 0x0000000c -#define AOFF_task_sig 0x00000a00 +#define AOFF_task_sig 0x000009f0 #define ASIZ_task_sig 0x00000008 -#define AOFF_task_signal 0x00000a08 +#define AOFF_task_signal 0x000009f8 #define ASIZ_task_signal 0x00000008 -#define AOFF_task_blocked 0x00000a10 +#define AOFF_task_blocked 0x00000a00 #define ASIZ_task_blocked 0x00000008 -#define AOFF_task_sigqueue 0x00000a18 +#define AOFF_task_sigqueue 0x00000a08 #define ASIZ_task_sigqueue 0x00000008 -#define AOFF_task_sigqueue_tail 0x00000a20 +#define AOFF_task_sigqueue_tail 0x00000a10 #define ASIZ_task_sigqueue_tail 0x00000008 -#define AOFF_task_sas_ss_sp 0x00000a28 +#define AOFF_task_sas_ss_sp 0x00000a18 #define ASIZ_task_sas_ss_sp 0x00000008 -#define AOFF_task_sas_ss_size 0x00000a30 +#define AOFF_task_sas_ss_size 0x00000a20 #define ASIZ_task_sas_ss_size 0x00000008 -#define AOFF_task_parent_exec_id 0x00000a38 +#define AOFF_task_parent_exec_id 0x00000a28 #define ASIZ_task_parent_exec_id 0x00000004 -#define AOFF_task_self_exec_id 0x00000a3c +#define AOFF_task_self_exec_id 0x00000a2c #define ASIZ_task_self_exec_id 0x00000004 -#define AOFF_task_exit_sem 0x00000a40 +#define AOFF_task_exit_sem 0x00000a30 #define ASIZ_task_exit_sem 0x00000040 -#define ASIZ_task 0x00000a80 +#define ASIZ_task 0x00000a70 #define AOFF_mm_mmap 0x00000000 #define ASIZ_mm_mmap 0x00000008 #define AOFF_mm_mmap_avl 0x00000008 @@ -864,29 +852,23 @@ #define ASIZ_thread_gsr 0x00000007 #define AOFF_thread___pad2 0x0000002f #define ASIZ_thread___pad2 0x00000001 -#define AOFF_thread_sig_address 0x00000030 -#define ASIZ_thread_sig_address 0x00000008 -#define AOFF_thread_sig_desc 0x00000038 -#define ASIZ_thread_sig_desc 0x00000008 -#define AOFF_thread_xfsr 0x00000040 +#define AOFF_thread_xfsr 0x00000030 #define ASIZ_thread_xfsr 0x00000038 -#define AOFF_thread___pad3 0x00000078 -#define ASIZ_thread___pad3 0x00000008 -#define AOFF_thread_reg_window 0x00000080 +#define AOFF_thread_reg_window 0x00000068 #define ASIZ_thread_reg_window 0x00000380 -#define AOFF_thread_rwbuf_stkptrs 0x00000400 +#define AOFF_thread_rwbuf_stkptrs 0x000003e8 #define ASIZ_thread_rwbuf_stkptrs 0x00000038 -#define AOFF_thread_user_cntd0 0x00000438 +#define AOFF_thread_user_cntd0 0x00000420 #define ASIZ_thread_user_cntd0 0x00000008 -#define AOFF_thread_user_cntd1 0x00000440 +#define AOFF_thread_user_cntd1 0x00000428 #define ASIZ_thread_user_cntd1 0x00000008 -#define AOFF_thread_kernel_cntd0 0x00000448 +#define AOFF_thread_kernel_cntd0 0x00000430 #define ASIZ_thread_kernel_cntd0 0x00000008 -#define AOFF_thread_kernel_cntd1 0x00000450 +#define AOFF_thread_kernel_cntd1 0x00000438 #define ASIZ_thread_kernel_cntd1 0x00000008 -#define AOFF_thread_pcr_reg 0x00000458 +#define AOFF_thread_pcr_reg 0x00000440 #define ASIZ_thread_pcr_reg 0x00000008 -#define ASIZ_thread 0x00000460 +#define ASIZ_thread 0x00000450 #endif /* SPIN_LOCK_DEBUG */ #endif /* CONFIG_SMP */ diff -ur --new-file old/linux/include/asm-sparc64/checksum.h new/linux/include/asm-sparc64/checksum.h --- old/linux/include/asm-sparc64/checksum.h Fri Jan 7 01:17:19 2000 +++ new/linux/include/asm-sparc64/checksum.h Sat Jan 22 20:54:56 2000 @@ -1,4 +1,4 @@ -/* $Id: checksum.h,v 1.14 2000/01/05 21:27:42 davem Exp $ */ +/* $Id: checksum.h,v 1.15 2000/01/19 04:06:09 davem Exp $ */ #ifndef __SPARC64_CHECKSUM_H #define __SPARC64_CHECKSUM_H @@ -37,12 +37,6 @@ * here even more important to align src and dst on a 32-bit (or even * better 64-bit) boundary */ -/* FIXME: Remove these macros ASAP */ -#define csum_partial_copy(src, dst, len, sum) \ - csum_partial_copy_nocheck(src,dst,len,sum) -#define csum_partial_copy_fromuser(s, d, l, w) \ - csum_partial_copy_from_user((char *) (s), (d), (l), (w), NULL) - extern unsigned int csum_partial_copy_sparc64(const char *src, char *dst, int len, unsigned int sum); extern __inline__ unsigned int @@ -66,15 +60,19 @@ return csum_partial_copy_sparc64(src, dst, len, sum); } -#if 0 -/* XXX should implement this now... -DaveM */ +/* + * Copy and checksum to user + */ +#define HAVE_CSUM_COPY_USER +extern unsigned int csum_partial_copy_user_sparc64(const char *src, char *dst, int len, unsigned int sum); extern __inline__ unsigned int -csum_partial_copy_to_user(const char *src, char *dst, int len, - unsigned int sum, int *err) +csum_and_copy_to_user(const char *src, char *dst, int len, + unsigned int sum, int *err) { - return 0; + __asm__ __volatile__ ("stx %0, [%%sp + 0x7ff + 128]" + : : "r" (err)); + return csum_partial_copy_user_sparc64(src, dst, len, sum); } -#endif /* ihl is always 5 or greater, almost always is 5, and iph is word aligned * the majority of the time. diff -ur --new-file old/linux/include/asm-sparc64/dma.h new/linux/include/asm-sparc64/dma.h --- old/linux/include/asm-sparc64/dma.h Tue Dec 21 07:05:52 1999 +++ new/linux/include/asm-sparc64/dma.h Thu Jan 27 17:58:15 2000 @@ -218,4 +218,10 @@ #define isa_dma_bridge_buggy (0) #endif +/* We support dynamic DMA remapping and adjacent SG entries + * which have addresses modulo DMA_CHUNK_SIZE will be merged + * by dma_prepare_sg(). + */ +#define DMA_CHUNK_SIZE 8192 + #endif /* !(_ASM_SPARC64_DMA_H) */ diff -ur --new-file old/linux/include/asm-sparc64/floppy.h new/linux/include/asm-sparc64/floppy.h --- old/linux/include/asm-sparc64/floppy.h Thu Jan 13 21:03:00 2000 +++ new/linux/include/asm-sparc64/floppy.h Thu Jan 27 17:58:15 2000 @@ -270,7 +270,10 @@ #include static struct linux_ebus_dma *sun_pci_fd_ebus_dma; +static struct pci_dev *sun_pci_ebus_dev; static int sun_pci_broken_drive = -1; +static unsigned int sun_pci_dma_addr = -1U; +static int sun_pci_dma_len; extern void floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs); @@ -363,6 +366,11 @@ writel(dcsr, &sun_pci_fd_ebus_dma->dcsr); } } + if (sun_pci_dma_addr != -1U) + pci_unmap_single(sun_pci_ebus_dev, + sun_pci_dma_addr, + sun_pci_dma_len); + sun_pci_dma_addr = -1U; } static void sun_pci_fd_set_dma_mode(int mode) @@ -389,12 +397,17 @@ static void sun_pci_fd_set_dma_count(int length) { + sun_pci_dma_len = length; writel(length, &sun_pci_fd_ebus_dma->dbcr); } static void sun_pci_fd_set_dma_addr(char *buffer) { - unsigned int addr = virt_to_bus(buffer); + unsigned int addr; + + addr = sun_pci_dma_addr = pci_map_single(sun_pci_ebus_dev, + buffer, + sun_pci_dma_len); writel(addr, &sun_pci_fd_ebus_dma->dacr); } @@ -598,6 +611,8 @@ */ auxio_reg = edev->resource[2].start; writel(readl(auxio_reg)|0x2, auxio_reg); + + sun_pci_ebus_dev = ebus->self; sun_pci_fd_ebus_dma = (struct linux_ebus_dma *) edev->resource[1].start; diff -ur --new-file old/linux/include/asm-sparc64/io.h new/linux/include/asm-sparc64/io.h --- old/linux/include/asm-sparc64/io.h Tue Dec 21 07:05:52 1999 +++ new/linux/include/asm-sparc64/io.h Thu Jan 27 17:58:15 2000 @@ -13,7 +13,7 @@ #define __SLOW_DOWN_IO do { } while (0) #define SLOW_DOWN_IO do { } while (0) -#undef NEW_PCI_DMA_MAP +#define NEW_PCI_DMA_MAP #ifndef NEW_PCI_DMA_MAP #define PCI_DVMA_HASHSZ 256 diff -ur --new-file old/linux/include/asm-sparc64/parport.h new/linux/include/asm-sparc64/parport.h --- old/linux/include/asm-sparc64/parport.h Thu Jan 13 21:03:00 2000 +++ new/linux/include/asm-sparc64/parport.h Thu Jan 27 17:58:15 2000 @@ -149,7 +149,7 @@ if (parport_pc_probe_port(base, base + 0x400, edev->irqs[0], - count)) + count, ebus->self)) count++; } } diff -ur --new-file old/linux/include/asm-sparc64/pci.h new/linux/include/asm-sparc64/pci.h --- old/linux/include/asm-sparc64/pci.h Thu Jan 13 21:03:00 2000 +++ new/linux/include/asm-sparc64/pci.h Thu Jan 27 17:58:15 2000 @@ -1,8 +1,6 @@ #ifndef __SPARC64_PCI_H #define __SPARC64_PCI_H -#include - /* Can be used to override the logic in pci_scan_bus for skipping * already-configured bus numbers - to be used for buggy BIOSes * or architectures with incomplete PCI setup by the loader. @@ -12,32 +10,37 @@ #define PCIBIOS_MIN_IO 0UL #define PCIBIOS_MIN_MEM 0UL +#ifdef __KERNEL__ + +/* Dynamic DMA mapping stuff. + */ + +#include + struct pci_dev; -/* Allocate and map kernel buffer using consistant mode DMA for PCI device. - * Returns non-NULL cpu-view pointer to the buffer if successful and - * sets *dma_addrp to the pci side dma address as well, else *dma_addrp - * is undefined. - */ -extern void *pci_alloc_consistant(struct pci_dev *pdev, long size, u32 *dma_addrp); - -/* Free and unmap a consistant DMA buffer. - * cpu_addr is what was returned from pci_alloc_consistant, - * size must be the same as what as passed into pci_alloc_consistant, +/* Allocate and map kernel buffer using consistent mode DMA for a device. + * hwdev should be valid struct pci_dev pointer for PCI devices. + */ +extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle); + +/* Free and unmap a consistent DMA buffer. + * cpu_addr is what was returned from pci_alloc_consistent, + * size must be the same as what as passed into pci_alloc_consistent, * and likewise dma_addr must be the same as what *dma_addrp was set to. * * References to the memory and mappings assosciated with cpu_addr/dma_addr * past this call are illegal. */ -extern void pci_free_consistant(struct pci_dev *pdev, long size, void *cpu_addr, u32 dma_addr); +extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); -/* Map a single buffer of the indicate size for PCI DMA in streaming mode. - * The 32-bit PCI bus mastering address to use is returned. +/* Map a single buffer of the indicated size for DMA in streaming mode. + * The 32-bit bus address to use is returned. * * Once the device is given the dma address, the device owns this memory - * until either pci_unmap_single or pci_sync_single is performed. + * until either pci_unmap_single or pci_dma_sync_single is performed. */ -extern u32 pci_map_single(struct pci_dev *pdev, void *buffer, long size); +extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size); /* Unmap a single streaming mode DMA translation. The dma_addr and size * must match what was provided for in a previous pci_map_single call. All @@ -46,32 +49,32 @@ * After this call, reads by the cpu to the buffer are guarenteed to see * whatever the device wrote there. */ -extern void pci_unmap_single(struct pci_dev *pdev, u32 dma_addr, long size); +extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size); /* Map a set of buffers described by scatterlist in streaming - * mode for PCI DMA. This is the scather-gather version of the + * mode for DMA. This is the scather-gather version of the * above pci_map_single interface. Here the scatter gather list - * elements are each tagged with the appropriate PCI dma address + * elements are each tagged with the appropriate dma address * and length. They are obtained via sg_dma_{address,length}(SG). * * NOTE: An implementation may be able to use a smaller number of * DMA address/length pairs than there are SG table elements. * (for example via virtual mapping capabilities) - * The routine returns the number of addr/length pairs actually - * used, at most nents. + * The routine returns the number of addr/length pairs actually + * used, at most nents. * * Device ownership issues as mentioned above for pci_map_single are * the same here. */ -extern int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents); +extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents); /* Unmap a set of streaming mode DMA translations. * Again, cpu read rules concerning calls here are the same as for * pci_unmap_single() above. */ -extern void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents); +extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nhwents); -/* Make physical memory consistant for a single +/* Make physical memory consistent for a single * streaming mode DMA translation after a transfer. * * If you perform a pci_map_single() but wish to interrogate the @@ -80,14 +83,16 @@ * next point you give the PCI dma address back to the card, the * device again owns the buffer. */ -extern void pci_dma_sync_single(struct pci_dev *, u32, long); +extern void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size); -/* Make physical memory consistant for a set of streaming +/* Make physical memory consistent for a set of streaming * mode DMA translations after a transfer. * * The same as pci_dma_sync_single but for a scatter-gather list, * same rules and usage. */ -extern void pci_dma_sync_sg(struct pci_dev *, struct scatterlist *, int); +extern void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nelems); + +#endif /* __KERNEL__ */ #endif /* __SPARC64_PCI_H */ diff -ur --new-file old/linux/include/asm-sparc64/processor.h new/linux/include/asm-sparc64/processor.h --- old/linux/include/asm-sparc64/processor.h Fri Jan 7 21:59:42 2000 +++ new/linux/include/asm-sparc64/processor.h Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: processor.h,v 1.60 2000/01/07 20:21:45 davem Exp $ +/* $Id: processor.h,v 1.61 2000/01/21 11:39:22 jj Exp $ * include/asm-sparc64/processor.h * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -56,16 +56,11 @@ unsigned char __pad1[3]; struct pt_regs *kregs; - /* D$ line 2 */ + /* D$ line 2, 3, 4 */ unsigned long *utraps; unsigned char gsr[7]; unsigned char __pad2; - unsigned long sig_address; - unsigned long sig_desc; - - /* D$ lines 3 and 4 */ unsigned long xfsr[7]; - unsigned long __pad3; struct reg_window reg_window[NSWINS]; unsigned long rwbuf_stkptrs[NSWINS]; @@ -92,10 +87,8 @@ 0, 0, 0, 0, KERNEL_DS, \ /* w_saved, fpdepth, fpsaved, pad1, kregs, */ \ 0, 0, { 0 }, { 0 }, 0, \ -/* utraps, gsr, pad2, sig_address, sig_desc, */ \ - 0, { 0 }, 0, 0, 0, \ -/* xfsr, pad3, */ \ - { 0 }, 0, \ +/* utraps, gsr, pad2, xfsr, */ \ + 0, { 0 }, 0, { 0 }, \ /* reg_window */ \ { { { 0, }, { 0, } }, }, \ /* rwbuf_stkptrs */ \ diff -ur --new-file old/linux/include/asm-sparc64/sbus.h new/linux/include/asm-sparc64/sbus.h --- old/linux/include/asm-sparc64/sbus.h Tue Dec 21 07:05:52 1999 +++ new/linux/include/asm-sparc64/sbus.h Thu Jan 27 17:58:15 2000 @@ -94,18 +94,18 @@ #define sbus_can_burst64(sdev) (1) extern void sbus_set_sbus64(struct sbus_dev *, int); -/* These yield IOMMU mappings in consistant mode. */ -extern void *sbus_alloc_consistant(struct sbus_dev *, long, u32 *dma_addrp); -extern void sbus_free_consistant(struct sbus_dev *, long, void *, u32); +/* These yield IOMMU mappings in consistent mode. */ +extern void *sbus_alloc_consistent(struct sbus_dev *, size_t, dma_addr_t *dma_addrp); +extern void sbus_free_consistent(struct sbus_dev *, size_t, void *, dma_addr_t); /* All the rest use streaming mode mappings. */ -extern u32 sbus_map_single(struct sbus_dev *, void *, long); -extern void sbus_unmap_single(struct sbus_dev *, u32, long); +extern dma_addr_t sbus_map_single(struct sbus_dev *, void *, size_t); +extern void sbus_unmap_single(struct sbus_dev *, dma_addr_t, size_t); extern int sbus_map_sg(struct sbus_dev *, struct scatterlist *, int); extern void sbus_unmap_sg(struct sbus_dev *, struct scatterlist *, int); /* Finally, allow explicit synchronization of streamable mappings. */ -extern void sbus_dma_sync_single(struct sbus_dev *, u32, long); +extern void sbus_dma_sync_single(struct sbus_dev *, dma_addr_t, size_t); extern void sbus_dma_sync_sg(struct sbus_dev *, struct scatterlist *, int); #endif /* !(_SPARC64_SBUS_H) */ diff -ur --new-file old/linux/include/asm-sparc64/semaphore.h new/linux/include/asm-sparc64/semaphore.h --- old/linux/include/asm-sparc64/semaphore.h Tue Jan 4 20:17:47 2000 +++ new/linux/include/asm-sparc64/semaphore.h Thu Jan 27 15:32:14 2000 @@ -253,10 +253,17 @@ #define __RWSEM_DEBUG_INIT /* */ #endif -#define __RWSEM_INITIALIZER(name) \ -{ RW_LOCK_BIAS, 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \ +#define __RWSEM_INITIALIZER(name,count) \ +{ (count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \ __WAIT_QUEUE_HEAD_INITIALIZER((name).write_bias_wait) \ __SEM_DEBUG_INIT(name) __RWSEM_DEBUG_INIT } + +#define __DECLARE_RWSEM_GENERIC(name,count) \ + struct rw_semaphore name = __RWSEM_INITIALIZER(name,count) + +#define DECLARE_RWSEM(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS) +#define DECLARE_RWSEM_READ_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS-1) +#define DECLARE_RWSEM_WRITE_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,0) extern inline void init_rwsem(struct rw_semaphore *sem) { diff -ur --new-file old/linux/include/asm-sparc64/siginfo.h new/linux/include/asm-sparc64/siginfo.h --- old/linux/include/asm-sparc64/siginfo.h Tue Aug 3 07:07:16 1999 +++ new/linux/include/asm-sparc64/siginfo.h Tue Jan 25 20:17:08 2000 @@ -141,6 +141,11 @@ #define si_band _sifields._sigpoll._band #define si_fd _sifields._sigpoll._fd +#ifdef __KERNEL__ +#define __SI_MASK 0 +#define __SI_FAULT 0 +#endif + /* * si_code values * Digital reserves positive values for kernel-generated signals. @@ -187,7 +192,7 @@ * SIGSEGV si_codes */ #define SEGV_MAPERR 1 /* address not mapped to object */ -#define SRGV_ACCERR 2 /* invalid permissions for mapped object */ +#define SEGV_ACCERR 2 /* invalid permissions for mapped object */ #define NSIGSEGV 2 /* @@ -214,7 +219,7 @@ #define CLD_TRAPPED 4 /* traced child has trapped */ #define CLD_STOPPED 5 /* child has stopped */ #define CLD_CONTINUED 6 /* stopped child has continued */ -#define NSIGCHLD +#define NSIGCHLD 6 /* * SIGPOLL si_codes diff -ur --new-file old/linux/include/asm-sparc64/smp.h new/linux/include/asm-sparc64/smp.h --- old/linux/include/asm-sparc64/smp.h Tue Dec 21 07:05:52 1999 +++ new/linux/include/asm-sparc64/smp.h Sat Jan 22 03:22:54 2000 @@ -68,12 +68,16 @@ extern void smp_boot_cpus(void); extern void smp_store_cpu_info(int id); -extern __volatile__ int cpu_number_map[NR_CPUS]; +extern __volatile__ int __cpu_number_map[NR_CPUS]; extern __volatile__ int __cpu_logical_map[NR_CPUS]; extern __inline__ int cpu_logical_map(int cpu) { return __cpu_logical_map[cpu]; +} +extern __inline__ int cpu_number_map(int cpu) +{ + return __cpu_number_map[cpu]; } extern __inline__ int hard_smp_processor_id(void) diff -ur --new-file old/linux/include/asm-sparc64/termbits.h new/linux/include/asm-sparc64/termbits.h --- old/linux/include/asm-sparc64/termbits.h Thu Mar 11 01:53:38 1999 +++ new/linux/include/asm-sparc64/termbits.h Fri Jan 28 01:40:09 2000 @@ -204,6 +204,9 @@ #define TIOCM_DSR 0x100 #define TIOCM_CD TIOCM_CAR #define TIOCM_RI TIOCM_RNG +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff -ur --new-file old/linux/include/asm-sparc64/types.h new/linux/include/asm-sparc64/types.h --- old/linux/include/asm-sparc64/types.h Tue Jan 13 00:15:58 1998 +++ new/linux/include/asm-sparc64/types.h Thu Jan 27 17:58:15 2000 @@ -45,6 +45,10 @@ #define BITS_PER_LONG 64 +/* Dma addresses are 32-bits wide for now. */ + +typedef u32 dma_addr_t; + #endif /* __KERNEL__ */ #endif /* defined(_SPARC64_TYPES_H) */ diff -ur --new-file old/linux/include/asm-sparc64/unistd.h new/linux/include/asm-sparc64/unistd.h --- old/linux/include/asm-sparc64/unistd.h Fri Jan 14 23:52:08 2000 +++ new/linux/include/asm-sparc64/unistd.h Sat Jan 22 03:22:54 2000 @@ -1,4 +1,4 @@ -/* $Id: unistd.h,v 1.39 2000/01/11 17:34:05 jj Exp $ */ +/* $Id: unistd.h,v 1.40 2000/01/16 06:20:38 davem Exp $ */ #ifndef _SPARC64_UNISTD_H #define _SPARC64_UNISTD_H diff -ur --new-file old/linux/include/linux/acpi.h new/linux/include/linux/acpi.h --- old/linux/include/linux/acpi.h Fri Jan 21 01:06:39 2000 +++ new/linux/include/linux/acpi.h Fri Jan 28 17:04:58 2000 @@ -24,7 +24,6 @@ #include #include #ifdef __KERNEL__ -#include #include #include #endif /* __KERNEL__ */ @@ -57,138 +56,9 @@ typedef int acpi_dstate_t; -/* - * HID (PnP) values - */ -enum -{ - ACPI_UNKNOWN_HID = 0x00000000, /* generic */ - ACPI_KBC_HID = 0x41d00303, /* keyboard controller */ - ACPI_COM_HID = 0x41d00500, /* serial port */ - ACPI_FDC_HID = 0x41d00700, /* floppy controller */ - ACPI_VGA_HID = 0x41d00900, /* VGA controller */ - ACPI_ISA_HID = 0x41d00a00, /* ISA bus */ - ACPI_EISA_HID = 0x41d00a01, /* EISA bus */ - ACPI_PCI_HID = 0x41d00a03, /* PCI bus */ -}; - -typedef int acpi_hid_t; - #ifdef __KERNEL__ -/* - * Device types - */ -enum -{ - ACPI_SYS_DEV, /* system device (fan, KB controller, ...) */ - ACPI_PCI_DEV, /* generic PCI device */ - ACPI_PCI_BUS, /* PCI bus */ - ACPI_ISA_DEV, /* generic ISA device */ - ACPI_ISA_BUS, /* ISA bus */ - ACPI_USB_DEV, /* generic USB device */ - ACPI_USB_HUB, /* USB hub device */ - ACPI_USB_CTRL, /* USB controller */ - ACPI_SCSI_DEV, /* generic SCSI device */ - ACPI_SCSI_CTRL, /* SCSI controller */ -}; - -typedef int acpi_dev_t; - -/* - * Device addresses - */ -#define ACPI_PCI_ADR(dev) ((dev)->bus->number << 16 | (dev)->devfn) - -struct acpi_dev; - -/* - * Device state transition function - */ -typedef int (*acpi_transition)(struct acpi_dev *dev, acpi_dstate_t state); - -/* - * Static device information - */ -struct acpi_dev_info -{ - acpi_dev_t type; /* device type */ - acpi_hid_t hid; /* PnP identifier */ - acpi_transition transition; /* state transition callback */ - - /* other information like D-states supported, - * D-state latencies, and in-rush current needs - * will go here - */ -}; - -/* - * Dynamic device information - */ -struct acpi_dev -{ - struct acpi_dev_info info; /* static device info */ - unsigned long adr; /* bus address or unique id */ - acpi_dstate_t state; /* current D-state */ - unsigned long accessed; /* last access time */ - unsigned long idle; /* last idle time */ - struct list_head entry; /* linked list entry */ -}; - -#ifdef CONFIG_ACPI - -extern wait_queue_head_t acpi_control_wait; - -/* - * Register a device with the ACPI subsystem - */ -struct acpi_dev *acpi_register(struct acpi_dev_info *info, unsigned long adr); - -/* - * Unregister a device with ACPI - */ -void acpi_unregister(struct acpi_dev *dev); - -/* - * Update device access time and wake up device, if necessary - */ -extern inline void acpi_access(struct acpi_dev *dev) -{ - extern void acpi_wakeup(struct acpi_dev*); - if (dev) { - if (dev->state != ACPI_D0) - acpi_wakeup(dev); - dev->accessed = jiffies; - } -} - -/* - * Identify device as currently being idle - */ -extern inline void acpi_dev_idle(struct acpi_dev *dev) -{ - if (dev) { - dev->idle = jiffies; - if (waitqueue_active(&acpi_control_wait)) - wake_up(&acpi_control_wait); - } -} - extern int acpi_active; - -#else /* CONFIG_ACPI */ - -extern inline struct acpi_dev* -acpi_register(struct acpi_dev_info *info, unsigned long adr) -{ - return 0; -} - -extern inline void acpi_unregister(struct acpi_dev *dev) {} -extern inline void acpi_access(struct acpi_dev *dev) {} -extern inline void acpi_dev_idle(struct acpi_dev *dev) {} - -#endif /* CONFIG_ACPI */ extern void (*acpi_idle)(void); extern void (*acpi_power_off)(void); diff -ur --new-file old/linux/include/linux/auto_fs.h new/linux/include/linux/auto_fs.h --- old/linux/include/linux/auto_fs.h Fri Jan 21 01:06:22 2000 +++ new/linux/include/linux/auto_fs.h Fri Jan 28 17:01:52 2000 @@ -20,7 +20,8 @@ #include #include -#define AUTOFS_PROTO_VERSION 3 +#define AUTOFS_MIN_PROTO_VERSION 3 /* Min version we support */ +#define AUTOFS_PROTO_VERSION 4 /* Current version */ /* * Architectures where both 32- and 64-bit binaries can be executed @@ -46,6 +47,7 @@ enum autofs_packet_type { autofs_ptype_missing, /* Missing entry (mount request) */ autofs_ptype_expire, /* Expire entry (umount request) */ + autofs_ptype_expire_multi, /* Expire entry (umount request) */ }; struct autofs_packet_hdr { @@ -60,18 +62,35 @@ char name[NAME_MAX+1]; }; +/* v3 expire (via ioctl) */ struct autofs_packet_expire { struct autofs_packet_hdr hdr; int len; char name[NAME_MAX+1]; }; +/* v4 multi expire (via pipe) */ +struct autofs_packet_expire_multi { + struct autofs_packet_hdr hdr; + autofs_wqt_t wait_queue_token; + int len; + char name[NAME_MAX+1]; +}; + +union autofs_packet_union { + struct autofs_packet_hdr hdr; + struct autofs_packet_missing missing; + struct autofs_packet_expire expire; + struct autofs_packet_expire_multi expire_multi; +}; + #define AUTOFS_IOC_READY _IO(0x93,0x60) #define AUTOFS_IOC_FAIL _IO(0x93,0x61) #define AUTOFS_IOC_CATATONIC _IO(0x93,0x62) #define AUTOFS_IOC_PROTOVER _IOR(0x93,0x63,int) #define AUTOFS_IOC_SETTIMEOUT _IOWR(0x93,0x64,unsigned long) #define AUTOFS_IOC_EXPIRE _IOR(0x93,0x65,struct autofs_packet_expire) +#define AUTOFS_IOC_EXPIRE_MULTI _IOW(0x93,0x66,int) #ifdef __KERNEL__ diff -ur --new-file old/linux/include/linux/blkdev.h new/linux/include/linux/blkdev.h --- old/linux/include/linux/blkdev.h Fri Jan 21 01:05:41 2000 +++ new/linux/include/linux/blkdev.h Fri Jan 28 17:01:15 2000 @@ -25,7 +25,8 @@ int errors; unsigned long sector; unsigned long nr_sectors; - unsigned long nr_segments; + unsigned int nr_segments; + unsigned int nr_hw_segments; unsigned long current_nr_sectors; void * special; char * buffer; diff -ur --new-file old/linux/include/linux/cdrom.h new/linux/include/linux/cdrom.h --- old/linux/include/linux/cdrom.h Fri Jan 21 01:05:29 2000 +++ new/linux/include/linux/cdrom.h Fri Jan 28 17:01:06 2000 @@ -872,6 +872,10 @@ __u32 last_rec_address; } track_information; +extern int cdrom_get_disc_info(kdev_t dev, disc_information *di); +extern int cdrom_get_track_info(kdev_t dev, __u16 track, __u8 type, + track_information *ti); + /* The SCSI spec says there could be 256 slots. */ #define CDROM_MAX_SLOTS 256 diff -ur --new-file old/linux/include/linux/cyclomx.h new/linux/include/linux/cyclomx.h --- old/linux/include/linux/cyclomx.h Sun Jan 9 06:36:20 2000 +++ new/linux/include/linux/cyclomx.h Sat Jan 22 21:31:10 2000 @@ -13,6 +13,8 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* 2000/01/21 acme rename cyclomx_open to cyclomx_mod_inc_use_count +* and cyclomx_close to cyclomx_mod_dec_use_count * 1999/05/19 acme wait_queue_head_t wait_stats(support for 2.3.*) * 1999/01/03 acme judicious use of data types * 1998/12/27 acme cleanup: PACKED not needed @@ -80,8 +82,8 @@ } cycx_t; /* Public Functions */ -void cyclomx_open (cycx_t *card); /* cycx_main.c */ -void cyclomx_close (cycx_t *card); /* cycx_main.c */ +void cyclomx_mod_inc_use_count (cycx_t *card); /* cycx_main.c */ +void cyclomx_mod_dec_use_count (cycx_t *card); /* cycx_main.c */ void cyclomx_set_state (cycx_t *card, int state); /* cycx_main.c */ #ifdef CONFIG_CYCLOMX_X25 diff -ur --new-file old/linux/include/linux/etherdevice.h new/linux/include/linux/etherdevice.h --- old/linux/include/linux/etherdevice.h Fri Jan 21 01:05:30 2000 +++ new/linux/include/linux/etherdevice.h Tue Jan 25 20:41:20 2000 @@ -24,7 +24,6 @@ #ifndef _LINUX_ETHERDEVICE_H #define _LINUX_ETHERDEVICE_H -#include #include #ifdef __KERNEL__ @@ -41,7 +40,7 @@ unsigned char *haddr); extern struct net_device * init_etherdev(struct net_device *, int); -#ifdef CONFIG_IP_ROUTER +#if 1 /*def CONFIG_IP_ROUTER*/ static __inline__ void eth_copy_and_sum (struct sk_buff *dest, unsigned char *src, int len, int base) { memcpy (dest->data, src, len); diff -ur --new-file old/linux/include/linux/fs.h new/linux/include/linux/fs.h --- old/linux/include/linux/fs.h Fri Jan 21 01:05:31 2000 +++ new/linux/include/linux/fs.h Fri Jan 28 17:01:11 2000 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -66,10 +67,6 @@ #define WRITERAW 5 /* raw write - don't play with buffer lists */ -#ifndef NULL -#define NULL ((void *) 0) -#endif - #define NIL_FILP ((struct file *)0) #define SEL_IN 1 #define SEL_OUT 2 @@ -783,9 +780,9 @@ extern int unregister_chrdev(unsigned int, const char *); extern int chrdev_open(struct inode *, struct file *); extern struct file_operations def_chr_fops; -extern char * bdevname(kdev_t); -extern char * cdevname(kdev_t); -extern char * kdevname(kdev_t); +extern const char * bdevname(kdev_t); +extern const char * cdevname(kdev_t); +extern const char * kdevname(kdev_t); extern void init_special_inode(struct inode *, umode_t, int); extern struct inode_operations fifo_inode_operations; @@ -1001,8 +998,8 @@ extern ssize_t generic_file_write(struct file *, const char *, size_t, loff_t *, writepage_t); extern void do_generic_file_read(struct file *, loff_t *, read_descriptor_t *, read_actor_t); -extern int vfs_readlink(struct dentry *, char *, int, char *); -extern struct dentry *vfs_follow_link(struct dentry *, struct dentry *, unsigned, char *); +extern int vfs_readlink(struct dentry *, char *, int, const char *); +extern struct dentry *vfs_follow_link(struct dentry *, struct dentry *, unsigned, const char *); extern int page_readlink(struct dentry *, char *, int); extern struct dentry *page_follow_link(struct dentry *, struct dentry *, unsigned); diff -ur --new-file old/linux/include/linux/hdreg.h new/linux/include/linux/hdreg.h --- old/linux/include/linux/hdreg.h Fri Jan 21 01:05:29 2000 +++ new/linux/include/linux/hdreg.h Fri Jan 28 17:01:06 2000 @@ -49,6 +49,7 @@ #define WIN_SEEK 0x70 #define WIN_DIAGNOSE 0x90 #define WIN_SPECIFY 0x91 /* set drive geometry translation */ +#define WIN_IDLEIMMEDIATE 0xE1 /* force drive to become "ready" */ #define WIN_SETIDLE1 0xE3 #define WIN_SETIDLE2 0x97 diff -ur --new-file old/linux/include/linux/hfs_sysdep.h new/linux/include/linux/hfs_sysdep.h --- old/linux/include/linux/hfs_sysdep.h Fri Jan 21 01:07:58 2000 +++ new/linux/include/linux/hfs_sysdep.h Fri Jan 28 17:03:26 2000 @@ -121,7 +121,7 @@ sys_mdb->s_dirt = 1; } -extern inline char *hfs_mdb_name(hfs_sysmdb sys_mdb) { +extern inline const char *hfs_mdb_name(hfs_sysmdb sys_mdb) { return kdevname(sys_mdb->s_dev); } diff -ur --new-file old/linux/include/linux/highuid.h new/linux/include/linux/highuid.h --- old/linux/include/linux/highuid.h Fri Jan 21 01:05:29 2000 +++ new/linux/include/linux/highuid.h Fri Jan 28 17:01:06 2000 @@ -63,13 +63,6 @@ #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid) #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid) -/* specific to kernel/signal.c */ -#ifdef UID16_SIGINFO_COMPAT_NEEDED -#define SET_SIGINFO_UID16(var, uid) var = high2lowuid(uid) -#else -#define SET_SIGINFO_UID16(var, uid) do { ; } while (0) -#endif - #else #define SET_UID16(var, uid) do { ; } while (0) @@ -81,8 +74,6 @@ #define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = gid #define SET_STAT_UID(stat, uid) (stat).st_uid = uid #define SET_STAT_GID(stat, gid) (stat).st_gid = gid - -#define SET_SIGINFO_UID16(var, uid) do { ; } while (0) #endif /* CONFIG_UID16 */ diff -ur --new-file old/linux/include/linux/ide.h new/linux/include/linux/ide.h --- old/linux/include/linux/ide.h Fri Jan 21 01:05:38 2000 +++ new/linux/include/linux/ide.h Fri Jan 28 17:01:21 2000 @@ -373,7 +373,10 @@ ide_selectproc_t *selectproc; /* tweaks hardware to select drive */ ide_resetproc_t *resetproc; /* routine to reset controller after a disk reset */ ide_dmaproc_t *dmaproc; /* dma read/write/abort routine */ - unsigned long *dmatable; /* dma physical region descriptor table */ + unsigned int *dmatable_cpu; /* dma physical region descriptor table (cpu view) */ + u32 dmatable_dma; /* dma physical region descriptor table (dma view) */ + struct scatterlist *sg_table; /* Scatter-gather list used to build the above */ + int sg_nents; /* Current number of entries in it */ struct hwif_s *mate; /* other hwif from same PCI chip */ unsigned long dma_base; /* base addr for dma ports */ unsigned dma_extra; /* extra addr for dma ports */ @@ -836,6 +839,7 @@ #define BAD_DMA_DRIVE 0 #define GOOD_DMA_DRIVE 1 int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func); +void ide_destroy_dmatable (ide_drive_t *drive); ide_startstop_t ide_dma_intr (ide_drive_t *drive); int check_drive_lists (ide_drive_t *drive, int good_bad); int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive); diff -ur --new-file old/linux/include/linux/init.h new/linux/include/linux/init.h --- old/linux/include/linux/init.h Fri Jan 21 01:05:29 2000 +++ new/linux/include/linux/init.h Fri Jan 28 17:01:37 2000 @@ -90,7 +90,7 @@ #define __exit #define __initdata #define __exitdata -#define __initcall +#define __initcall(fn) /* For assembly routines */ #define __INIT #define __FINIT diff -ur --new-file old/linux/include/linux/input.h new/linux/include/linux/input.h --- old/linux/include/linux/input.h Thu Jan 20 18:48:48 2000 +++ new/linux/include/linux/input.h Tue Jan 25 03:23:15 2000 @@ -285,11 +285,16 @@ #define BTN_MODE 0x13c #define BTN_DIGI 0x140 -#define BTN_PEN 0x140 -#define BTN_RUBBER 0x141 -#define BTN_PEN_SIDE 0x142 -#define BTN_PEN_SIDE2 0x143 -#define BTN_NEAR 0x144 +#define BTN_TOOL_PEN 0x140 +#define BTN_TOOL_RUBBER 0x141 +#define BTN_TOOL_BRUSH 0x142 +#define BTN_TOOL_PENCIL 0x143 +#define BTN_TOOL_AIRBRUSH 0x144 +#define BTN_TOOL_FINGER 0x145 +#define BTN_TOOL_MOUSE 0x146 +#define BTN_TOUCH 0x147 +#define BTN_STYLUS 0x148 +#define BTN_STYLUS2 0x149 #define KEY_MAX 0x1ff diff -ur --new-file old/linux/include/linux/isapnp.h new/linux/include/linux/isapnp.h --- old/linux/include/linux/isapnp.h Fri Jan 21 01:05:26 2000 +++ new/linux/include/linux/isapnp.h Fri Jan 28 17:02:22 2000 @@ -128,7 +128,7 @@ struct isapnp_resources *next; /* next resource */ }; -#if defined(CONFIG_ISAPNP) || defined(CONFIG_ISAPNP_MODULE) +#if defined(CONFIG_ISAPNP) || (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE)) #define __ISAPNP__ diff -ur --new-file old/linux/include/linux/kdev_t.h new/linux/include/linux/kdev_t.h --- old/linux/include/linux/kdev_t.h Sat Nov 23 11:29:04 1996 +++ new/linux/include/linux/kdev_t.h Mon Jan 24 20:04:37 2000 @@ -73,7 +73,7 @@ #define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi)) #define B_FREE 0xffff /* yuk */ -extern char * kdevname(kdev_t); /* note: returns pointer to static data! */ +extern const char * kdevname(kdev_t); /* note: returns pointer to static data! */ /* As long as device numbers in the outside world have 16 bits only, diff -ur --new-file old/linux/include/linux/mm.h new/linux/include/linux/mm.h --- old/linux/include/linux/mm.h Fri Jan 21 01:05:41 2000 +++ new/linux/include/linux/mm.h Fri Jan 28 17:01:13 2000 @@ -451,24 +451,22 @@ * GFP bitmasks.. */ #define __GFP_WAIT 0x01 -#define __GFP_LOW 0x02 -#define __GFP_MED 0x04 -#define __GFP_HIGH 0x08 -#define __GFP_IO 0x10 -#define __GFP_SWAP 0x20 +#define __GFP_HIGH 0x02 +#define __GFP_IO 0x04 +#define __GFP_SWAP 0x08 #ifdef CONFIG_HIGHMEM -#define __GFP_HIGHMEM 0x40 +#define __GFP_HIGHMEM 0x10 #else #define __GFP_HIGHMEM 0x0 /* noop */ #endif -#define __GFP_DMA 0x80 +#define __GFP_DMA 0x20 -#define GFP_BUFFER (__GFP_LOW | __GFP_WAIT) +#define GFP_BUFFER (__GFP_WAIT) #define GFP_ATOMIC (__GFP_HIGH) -#define GFP_USER (__GFP_LOW | __GFP_WAIT | __GFP_IO) +#define GFP_USER (__GFP_WAIT | __GFP_IO) #define GFP_HIGHUSER (GFP_USER | __GFP_HIGHMEM) -#define GFP_KERNEL (__GFP_MED | __GFP_WAIT | __GFP_IO) +#define GFP_KERNEL (__GFP_HIGH | __GFP_WAIT | __GFP_IO) #define GFP_NFS (__GFP_HIGH | __GFP_WAIT | __GFP_IO) #define GFP_KSWAPD (__GFP_IO | __GFP_SWAP) diff -ur --new-file old/linux/include/linux/parport_pc.h new/linux/include/linux/parport_pc.h --- old/linux/include/linux/parport_pc.h Fri Jan 21 01:06:46 2000 +++ new/linux/include/linux/parport_pc.h Fri Jan 28 17:02:31 2000 @@ -37,6 +37,8 @@ /* buffer suitable for DMA, if DMA enabled */ char *dma_buf; + dma_addr_t dma_handle; + struct pci_dev *dev; }; extern __inline__ void parport_pc_write_data(struct parport *p, unsigned char d) @@ -175,6 +177,7 @@ /* PCMCIA code will want to get us to look at a port. Provide a mechanism. */ extern struct parport *parport_pc_probe_port (unsigned long base, unsigned long base_hi, - int irq, int dma); + int irq, int dma, + struct pci_dev *dev); #endif diff -ur --new-file old/linux/include/linux/pci.h new/linux/include/linux/pci.h --- old/linux/include/linux/pci.h Fri Jan 21 01:05:26 2000 +++ new/linux/include/linux/pci.h Fri Jan 28 17:02:03 2000 @@ -315,6 +315,11 @@ struct pci_driver *driver; /* which driver has allocated this device */ void *driver_data; /* data private to the driver */ + dma_addr_t dma_mask; /* Mask of the bits of bus address this + device implements. Normally this is + 0xffffffff. You only need to change + this if your device has broken DMA + or supports 64-bit transfers. */ /* device is compatible with these IDs */ unsigned short vendor_compatible[DEVICE_COUNT_COMPATIBLE]; @@ -462,16 +467,16 @@ void pci_name_device(struct pci_dev *dev); char *pci_class_name(u32 class); void pci_read_bridge_bases(struct pci_bus *child); -struct resource *pci_find_parent_resource(struct pci_dev *dev, struct resource *res); +struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res); int pci_setup_device(struct pci_dev * dev); /* Generic PCI functions exported to card drivers */ -struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, struct pci_dev *from); +struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from); struct pci_dev *pci_find_subsys (unsigned int vendor, unsigned int device, unsigned int ss_vendor, unsigned int ss_device, - struct pci_dev *from); -struct pci_dev *pci_find_class (unsigned int class, struct pci_dev *from); + const struct pci_dev *from); +struct pci_dev *pci_find_class (unsigned int class, const struct pci_dev *from); struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); int pci_find_capability (struct pci_dev *dev, int cap); @@ -526,8 +531,8 @@ void pci_unregister_driver(struct pci_driver *); void pci_insert_device(struct pci_dev *, struct pci_bus *); void pci_remove_device(struct pci_dev *); -struct pci_driver *pci_dev_driver(struct pci_dev *); -const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, struct pci_dev *dev); +struct pci_driver *pci_dev_driver(const struct pci_dev *); +const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev); /* * If the system does not have PCI, clearly these return errors. Define diff -ur --new-file old/linux/include/linux/pci_ids.h new/linux/include/linux/pci_ids.h --- old/linux/include/linux/pci_ids.h Fri Jan 14 09:50:53 2000 +++ new/linux/include/linux/pci_ids.h Fri Jan 28 01:40:09 2000 @@ -828,6 +828,7 @@ #define PCI_VENDOR_ID_ATT 0x11c1 #define PCI_DEVICE_ID_ATT_L56XMF 0x0440 +#define PCI_DEVICE_ID_ATT_VENUS_MODEM 0x480 #define PCI_VENDOR_ID_SPECIALIX 0x11cb #define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000 @@ -1019,7 +1020,15 @@ #define PCI_DEVICE_ID_NETGEAR_GA620 0x620a #define PCI_VENDOR_ID_LAVA 0x1407 -#define PCI_DEVICE_ID_LAVA_DUAL_SERIAL 0x0100 +#define PCI_DEVICE_ID_LAVA_DSERIAL 0x0100 /* 2x 16550 */ +#define PCI_DEVICE_ID_LAVA_QUATRO_A 0x0101 /* 2x 16550, half of 4 port */ +#define PCI_DEVICE_ID_LAVA_QUATRO_B 0x0102 /* 2x 16550, half of 4 port */ +#define PCI_DEVICE_ID_LAVA_PORT_PLUS 0x0200 /* 2x 16650 */ +#define PCI_DEVICE_ID_LAVA_QUAD_A 0x0201 /* 2x 16650, half of 4 port */ +#define PCI_DEVICE_ID_LAVA_QUAD_B 0x0202 /* 2x 16650, half of 4 port */ +#define PCI_DEVICE_ID_LAVA_SSERIAL 0x0500 /* 1x 16550 */ +#define PCI_DEVICE_ID_LAVA_PORT_650 0x0600 /* 1x 16650 */ + #define PCI_DEVICE_ID_LAVA_PARALLEL 0x8000 #define PCI_DEVICE_ID_LAVA_DUAL_PAR_A 0x8002 /* The Lava Dual Parallel is */ #define PCI_DEVICE_ID_LAVA_DUAL_PAR_B 0x8003 /* two PCI devices on a card */ @@ -1030,6 +1039,8 @@ #define PCI_VENDOR_ID_OXSEMI 0x1415 #define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501 +#define PCI_DEVICE_ID_OXSEMI_16PCI952 0x950A +#define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511 #define PCI_VENDOR_ID_PANACOM 0x14d4 #define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400 diff -ur --new-file old/linux/include/linux/pm.h new/linux/include/linux/pm.h --- old/linux/include/linux/pm.h Thu Jan 1 01:00:00 1970 +++ new/linux/include/linux/pm.h Fri Jan 28 17:04:58 2000 @@ -0,0 +1,157 @@ +/* + * pm.h - Power management interface + * + * Copyright (C) 2000 Andrew Henroid + * + * 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 _LINUX_PM_H +#define _LINUX_PM_H + +#include +#include + +/* + * Power management requests + */ +enum +{ + PM_SUSPEND, /* enter D1-D3 */ + PM_RESUME, /* enter D0 */ + + /* enable wake-on */ + PM_SET_WAKEUP, + + /* bus resource management */ + PM_GET_RESOURCES, + PM_SET_RESOURCES, + + /* base station management */ + PM_EJECT, + PM_LOCK, +}; + +typedef int pm_request_t; + +/* + * Device types + */ +enum +{ + PM_UNKNOWN_DEV = 0, /* generic */ + PM_SYS_DEV, /* system device (fan, KB controller, ...) */ + PM_PCI_DEV, /* PCI device */ + PM_USB_DEV, /* USB device */ + PM_SCSI_DEV, /* SCSI device */ + PM_ISA_DEV, /* ISA device */ +}; + +typedef int pm_dev_t; + +/* + * System device hardware ID (PnP) values + */ +enum +{ + PM_SYS_UNKNOWN = 0x00000000, /* generic */ + PM_SYS_KBC = 0x41d00303, /* keyboard controller */ + PM_SYS_COM = 0x41d00500, /* serial port */ + PM_SYS_FDC = 0x41d00700, /* floppy controller */ + PM_SYS_VGA = 0x41d00900, /* VGA controller */ +}; + +/* + * Device identifier + */ +#define PM_PCI_ID(dev) ((dev)->bus->number << 16 | (dev)->devfn) + +/* + * Request handler callback + */ +struct pm_dev; + +typedef int (*pm_callback)(struct pm_dev *dev, pm_request_t rqst, void *data); + +/* + * Dynamic device information + */ +struct pm_dev +{ + pm_dev_t type; + unsigned long id; + pm_callback callback; + void *data; + + unsigned long flags; + unsigned long status; + + struct list_head entry; +}; + +#if defined(CONFIG_ACPI) || defined(CONFIG_APM) + +/* + * Register a device with power management + */ +struct pm_dev *pm_register(pm_dev_t type, + unsigned long id, + pm_callback callback); + +/* + * Unregister a device with power management + */ +void pm_unregister(struct pm_dev *dev); + +/* + * Send a request to all devices + */ +int pm_send_request(pm_request_t rqst, void *data); + +/* + * Find a device + */ +struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from); + +extern inline void pm_access(struct pm_dev *dev) {} +extern inline void pm_dev_idle(struct pm_dev *dev) {} + +#else // CONFIG_ACPI || CONFIG_APM + +extern inline struct pm_dev *pm_register(pm_dev_t type, + unsigned long id, + pm_callback callback) +{ + return 0; +} + +extern inline void pm_unregister(struct pm_dev *dev) {} + +extern inline int pm_send_request(pm_request_t rqst, void *data) +{ + return 0; +} + +extern inline struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from) +{ + return 0; +} + +extern inline void pm_access(struct pm_dev *dev) {} +extern inline void pm_dev_idle(struct pm_dev *dev) {} + +#endif // CONFIG_ACPI || CONFIG_APM + +#endif /* _LINUX_PM_H */ diff -ur --new-file old/linux/include/linux/random.h new/linux/include/linux/random.h --- old/linux/include/linux/random.h Thu Jan 6 19:14:36 2000 +++ new/linux/include/linux/random.h Tue Jan 25 23:13:46 2000 @@ -46,6 +46,8 @@ extern void rand_initialize_irq(int irq); extern void rand_initialize_blkdev(int irq, int mode); +extern void batch_entropy_store(u32 a, u32 b, int num); + extern void add_keyboard_randomness(unsigned char scancode); extern void add_mouse_randomness(__u32 mouse_data); extern void add_interrupt_randomness(int irq); diff -ur --new-file old/linux/include/linux/sdla_chdlc.h new/linux/include/linux/sdla_chdlc.h --- old/linux/include/linux/sdla_chdlc.h Thu Jan 1 01:00:00 1970 +++ new/linux/include/linux/sdla_chdlc.h Wed Jan 26 22:25:58 2000 @@ -0,0 +1,808 @@ +/************************************************************************* + sdla_chdlc.h Sangoma Cisco HDLC firmware API definitions + + Author: Gideon Hack + Nenad Corbic + + Copyright: (c) 1995-1999 Sangoma Technologies Inc. + + This program is free software; you can redistribute it and/or + modify it under the term 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. + +=========================================================================== + Oct 04, 1999 Nenad Corbic Updated API support + Jun 02, 1999 Gideon Hack Changes for S514 usage. + Oct 28, 1998 Jaspreet Singh Made changes for Dual Port CHDLC. + Jun 11, 1998 David Fong Initial version. +=========================================================================== + + Organization + - Compatibility notes + - Constants defining the shared memory control block (mailbox) + - Interface commands + - Return code from interface commands + - Constants for the commands (structures for casting data) + - UDP Management constants and structures + +*************************************************************************/ + +#ifndef _SDLA_CHDLC_H +# define _SDLC_CHDLC_H + +/*------------------------------------------------------------------------ + Notes: + + All structres defined in this file are byte-aligned. + + Compiler Platform + ------------------------ + GNU C Linux + +------------------------------------------------------------------------*/ + +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif /* PACKED */ + + +/* ---------------------------------------------------------------------------- + * Constants defining the shared memory control block (mailbox) + * --------------------------------------------------------------------------*/ + +#define PRI_BASE_ADDR_MB_STRUCT 0xE000 /* the base address of the mailbox structure on the adapter */ +#define SEC_BASE_ADDR_MB_STRUCT 0xE800 /* the base address of the mailbox structure on the adapter */ +#define SIZEOF_MB_DATA_BFR 2032 /* the size of the actual mailbox data area */ +#define NUMBER_MB_RESERVED_BYTES 0x0B /* the number of reserved bytes in the mailbox header area */ + + +#define MIN_LGTH_CHDLC_DATA_CFG 300 /* min length of the CHDLC data field (for configuration purposes) */ +#define PRI_MAX_NO_DATA_BYTES_IN_FRAME 15354 /* PRIMARY - max length of the CHDLC data field */ + +typedef struct { + unsigned char opp_flag PACKED; /* the opp flag */ + unsigned char command PACKED; /* the user command */ + unsigned short buffer_length PACKED; /* the data length */ + unsigned char return_code PACKED; /* the return code */ + unsigned char MB_reserved[NUMBER_MB_RESERVED_BYTES] PACKED; /* reserved for later */ + unsigned char data[SIZEOF_MB_DATA_BFR] PACKED; /* the data area */ +} CHDLC_MAILBOX_STRUCT; + +typedef struct { + pid_t pid_num PACKED; + CHDLC_MAILBOX_STRUCT cmdarea PACKED; + +} CMDBLOCK_STRUCT; + + + + +/* ---------------------------------------------------------------------------- + * Interface commands + * --------------------------------------------------------------------------*/ + +/* global interface commands */ +#define READ_GLOBAL_EXCEPTION_CONDITION 0x01 +#define SET_GLOBAL_CONFIGURATION 0x02 +#define READ_GLOBAL_CONFIGURATION 0x03 +#define READ_GLOBAL_STATISTICS 0x04 +#define FLUSH_GLOBAL_STATISTICS 0x05 +#define SET_MODEM_STATUS 0x06 /* set status of DTR or RTS */ +#define READ_MODEM_STATUS 0x07 /* read status of CTS and DCD */ +#define READ_COMMS_ERROR_STATS 0x08 +#define FLUSH_COMMS_ERROR_STATS 0x09 +#define SET_TRACE_CONFIGURATION 0x0A /* set the line trace config */ +#define READ_TRACE_CONFIGURATION 0x0B /* read the line trace config */ +#define READ_TRACE_STATISTICS 0x0C /* read the trace statistics */ +#define FLUSH_TRACE_STATISTICS 0x0D /* flush the trace statistics */ +#define FT1_MONITOR_STATUS_CTRL 0x1C /* set the status of the S508/FT1 monitoring */ +#define SET_FT1_CONFIGURATION 0x18 /* set the FT1 configuration */ +#define READ_FT1_CONFIGURATION 0x19 /* read the FT1 configuration */ +#define TRANSMIT_ASYNC_DATA_TO_FT1 0x1A /* output asynchronous data to the FT1 */ +#define RECEIVE_ASYNC_DATA_FROM_FT1 0x1B /* receive asynchronous data from the FT1 */ +#define FT1_MONITOR_STATUS_CTRL 0x1C /* set the status of the FT1 monitoring */ + +#define READ_FT1_OPERATIONAL_STATS 0x1D /* read the S508/FT1 operational statistics */ +#define SET_FT1_MODE 0x1E /* set the operational mode of the S508/FT1 module */ + +/* CHDLC-level interface commands */ +#define READ_CHDLC_CODE_VERSION 0x20 +#define READ_CHDLC_EXCEPTION_CONDITION 0x21 /* read exception condition from the adapter */ +#define SET_CHDLC_CONFIGURATION 0x22 +#define READ_CHDLC_CONFIGURATION 0x23 +#define ENABLE_CHDLC_COMMUNICATIONS 0x24 +#define DISABLE_CHDLC_COMMUNICATIONS 0x25 +#define READ_CHDLC_LINK_STATUS 0x26 +#define READ_CHDLC_OPERATIONAL_STATS 0x27 +#define FLUSH_CHDLC_OPERATIONAL_STATS 0x28 +#define SET_CHDLC_INTERRUPT_TRIGGERS 0x30 /* set application interrupt triggers */ +#define READ_CHDLC_INTERRUPT_TRIGGERS 0x31 /* read application interrupt trigger configuration */ + +/* Special UDP drivers management commands */ +#define CPIPE_ENABLE_TRACING 0x50 +#define CPIPE_DISABLE_TRACING 0x51 +#define CPIPE_GET_TRACE_INFO 0x52 +#define CPIPE_GET_IBA_DATA 0x53 +#define CPIPE_FT1_READ_STATUS 0x54 +#define CPIPE_DRIVER_STAT_IFSEND 0x55 +#define CPIPE_DRIVER_STAT_INTR 0x56 +#define CPIPE_DRIVER_STAT_GEN 0x57 +#define CPIPE_FLUSH_DRIVER_STATS 0x58 +#define CPIPE_ROUTER_UP_TIME 0x59 + +/* Driver specific commands for API */ +#define CHDLC_READ_TRACE_DATA 0xE4 /* read trace data */ +#define TRACE_ALL 0x00 +#define TRACE_PROT 0x01 +#define TRACE_DATA 0x02 + +/* ---------------------------------------------------------------------------- + * Return codes from interface commands + * --------------------------------------------------------------------------*/ + +#define COMMAND_OK 0x00 + +/* return codes from global interface commands */ +#define NO_GLOBAL_EXCEP_COND_TO_REPORT 0x01 /* there is no CHDLC exception condition to report */ +#define LGTH_GLOBAL_CFG_DATA_INVALID 0x01 /* the length of the passed global configuration data is invalid */ +#define LGTH_TRACE_CFG_DATA_INVALID 0x01 /* the length of the passed trace configuration data is invalid */ +#define IRQ_TIMEOUT_VALUE_INVALID 0x02 /* an invalid application IRQ timeout value was selected */ +#define TRACE_CONFIG_INVALID 0x02 /* the passed line trace configuration is invalid */ +#define ADAPTER_OPERATING_FREQ_INVALID 0x03 /* an invalid adapter operating frequency was selected */ +#define TRC_DEAC_TMR_INVALID 0x03 /* the trace deactivation timer is invalid */ +#define S508_FT1_ADPTR_NOT_PRESENT 0x0C /* the S508/FT1 adapter is not present */ +#define INVALID_FT1_STATUS_SELECTION 0x0D /* the S508/FT1 status selection is invalid */ +#define FT1_OP_STATS_NOT_ENABLED 0x0D /* the FT1 operational statistics have not been enabled */ +#define FT1_OP_STATS_NOT_AVAILABLE 0x0E /* the FT1 operational statistics are not currently available */ +#define S508_FT1_MODE_SELECTION_BUSY 0x0E /* the S508/FT1 adapter is busy selecting the operational mode */ + +/* return codes from command READ_GLOBAL_EXCEPTION_CONDITION */ +#define EXCEP_MODEM_STATUS_CHANGE 0x10 /* a modem status change occurred */ +#define EXCEP_TRC_DISABLED 0x11 /* the trace has been disabled */ +#define EXCEP_IRQ_TIMEOUT 0x12 /* IRQ timeout */ + +/* return codes from CHDLC-level interface commands */ +#define NO_CHDLC_EXCEP_COND_TO_REPORT 0x21 /* there is no CHDLC exception condition to report */ +#define CHDLC_COMMS_DISABLED 0x21 /* communications are not currently enabled */ +#define CHDLC_COMMS_ENABLED 0x21 /* communications are currently enabled */ +#define DISABLE_CHDLC_COMMS_BEFORE_CFG 0x21 /* CHDLC communications must be disabled before setting the configuration */ +#define ENABLE_CHDLC_COMMS_BEFORE_CONN 0x21 /* communications must be enabled before using the CHDLC_CONNECT conmmand */ +#define CHDLC_CFG_BEFORE_COMMS_ENABLED 0x22 /* perform a SET_CHDLC_CONFIGURATION before enabling comms */ +#define LGTH_CHDLC_CFG_DATA_INVALID 0x22 /* the length of the passed CHDLC configuration data is invalid */ +#define LGTH_INT_TRIGGERS_DATA_INVALID 0x22 /* the length of the passed interrupt trigger data is invalid */ +#define INVALID_IRQ_SELECTED 0x23 /* in invalid IRQ was selected in the SET_CHDLC_INTERRUPT_TRIGGERS */ +#define INVALID_CHDLC_CFG_DATA 0x23 /* the passed CHDLC configuration data is invalid */ +#define IRQ_TMR_VALUE_INVALID 0x24 /* an invalid application IRQ timer value was selected */ +#define LARGER_PERCENT_TX_BFR_REQUIRED 0x24 /* a larger Tx buffer percentage is required */ +#define LARGER_PERCENT_RX_BFR_REQUIRED 0x25 /* a larger Rx buffer percentage is required */ +#define S514_BOTH_PORTS_SAME_CLK_MODE 0x26 /* S514 - both ports must have same clock mode */ +#define INVALID_CMND_HDLC_STREAM_MODE 0x4E /* the CHDLC interface command is invalid for HDLC streaming mode */ +#define INVALID_CHDLC_COMMAND 0x4F /* the defined CHDLC interface command is invalid */ + +/* return codes from command READ_CHDLC_EXCEPTION_CONDITION */ +#define EXCEP_LINK_ACTIVE 0x30 /* the CHDLC link has become active */ +#define EXCEP_LINK_INACTIVE_MODEM 0x31 /* the CHDLC link has become inactive (modem status) */ +#define EXCEP_LINK_INACTIVE_KPALV 0x32 /* the CHDLC link has become inactive (keepalive status) */ +#define EXCEP_IP_ADDRESS_DISCOVERED 0x33 /* the IP address has been discovered */ +#define EXCEP_LOOPBACK_CONDITION 0x34 /* a loopback condition has occurred */ + + +/* return code from command CHDLC_SEND_WAIT and CHDLC_SEND_NO_WAIT */ +#define LINK_DISCONNECTED 0x21 +#define NO_TX_BFRS_AVAIL 0x24 + + +/* ---------------------------------------------------------------------------- + * Constants for the SET_GLOBAL_CONFIGURATION/READ_GLOBAL_CONFIGURATION commands + * --------------------------------------------------------------------------*/ + +/* the global configuration structure */ +typedef struct { + unsigned short adapter_config_options PACKED; /* adapter config options */ + unsigned short app_IRQ_timeout PACKED; /* application IRQ timeout */ + unsigned long adapter_operating_frequency PACKED; /* adapter operating frequency */ +} GLOBAL_CONFIGURATION_STRUCT; + +/* settings for the 'app_IRQ_timeout' */ +#define MAX_APP_IRQ_TIMEOUT_VALUE 5000 /* the maximum permitted IRQ timeout */ + + + +/* ---------------------------------------------------------------------------- + * Constants for the READ_GLOBAL_STATISTICS command + * --------------------------------------------------------------------------*/ + +/* the global statistics structure */ +typedef struct { + unsigned short app_IRQ_timeout_count PACKED; +} GLOBAL_STATS_STRUCT; + + + +/* ---------------------------------------------------------------------------- + * Constants for the READ_COMMS_ERROR_STATS command + * --------------------------------------------------------------------------*/ + +/* the communications error statistics structure */ +typedef struct { + unsigned short Rx_overrun_err_count PACKED; + unsigned short CRC_err_count PACKED; /* receiver CRC error count */ + unsigned short Rx_abort_count PACKED; /* abort frames recvd count */ + unsigned short Rx_dis_pri_bfrs_full_count PACKED;/* receiver disabled */ + unsigned short comms_err_stat_reserved_1 PACKED;/* reserved for later */ + unsigned short sec_Tx_abort_msd_Tx_int_count PACKED; /* secondary - abort frames transmitted count (missed Tx interrupt) */ + unsigned short missed_Tx_und_int_count PACKED; /* missed tx underrun interrupt count */ + unsigned short sec_Tx_abort_count PACKED; /*secondary-abort frames tx count */ + unsigned short DCD_state_change_count PACKED; /* DCD state change */ + unsigned short CTS_state_change_count PACKED; /* CTS state change */ +} COMMS_ERROR_STATS_STRUCT; + + + +/* ---------------------------------------------------------------------------- + * Constants used for line tracing + * --------------------------------------------------------------------------*/ + +/* the trace configuration structure (SET_TRACE_CONFIGURATION/READ_TRACE_CONFIGURATION commands) */ +typedef struct { + unsigned char trace_config PACKED; /* trace configuration */ + unsigned short trace_deactivation_timer PACKED; /* trace deactivation timer */ + unsigned long ptr_trace_stat_el_cfg_struct PACKED; /* a pointer to the line trace element configuration structure */ +} LINE_TRACE_CONFIG_STRUCT; + +/* 'trace_config' bit settings */ +#define TRACE_INACTIVE 0x00 /* trace is inactive */ +#define TRACE_ACTIVE 0x01 /* trace is active */ +#define TRACE_DELAY_MODE 0x04 /* operate the trace in delay mode */ +#define TRACE_DATA_FRAMES 0x08 /* trace Data frames */ +#define TRACE_SLARP_FRAMES 0x10 /* trace SLARP frames */ +#define TRACE_CDP_FRAMES 0x20 /* trace CDP frames */ + +/* the line trace status element configuration structure */ +typedef struct { + unsigned short number_trace_status_elements PACKED; /* number of line trace elements */ + unsigned long base_addr_trace_status_elements PACKED; /* base address of the trace element list */ + unsigned long next_trace_element_to_use PACKED; /* pointer to the next trace element to be used */ + unsigned long base_addr_trace_buffer PACKED; /* base address of the trace data buffer */ + unsigned long end_addr_trace_buffer PACKED; /* end address of the trace data buffer */ +} TRACE_STATUS_EL_CFG_STRUCT; + +/* the line trace status element structure */ +typedef struct { + unsigned char opp_flag PACKED; /* opp flag */ + unsigned short trace_length PACKED; /* trace length */ + unsigned char trace_type PACKED; /* trace type */ + unsigned short trace_time_stamp PACKED; /* time stamp */ + unsigned short trace_reserved_1 PACKED; /* reserved for later use */ + unsigned long trace_reserved_2 PACKED; /* reserved for later use */ + unsigned long ptr_data_bfr PACKED; /* ptr to the trace data buffer */ +} TRACE_STATUS_ELEMENT_STRUCT; + +/* "trace_type" bit settings */ +#define TRACE_INCOMING 0x00 +#define TRACE_OUTGOINGING 0x01 +#define TRACE_INCOMING_ABORTED 0x10 +#define TRACE_INCOMING_CRC_ERROR 0x20 +#define TRACE_INCOMING_OVERRUN_ERROR 0x40 + + + +/* the line trace statistics structure */ +typedef struct { + unsigned long frames_traced_count PACKED; /* number of frames traced */ + unsigned long trc_frms_not_recorded_count PACKED; /* number of trace frames discarded */ +} LINE_TRACE_STATS_STRUCT; + + +/* ---------------------------------------------------------------------------- + * Constants for the FT1_MONITOR_STATUS_CTRL command + * --------------------------------------------------------------------------*/ + +#define DISABLE_FT1_STATUS_STATISTICS 0x00 /* disable the FT1 status and statistics monitoring */ +#define ENABLE_READ_FT1_STATUS 0x01 /* read the FT1 operational status */ +#define ENABLE_READ_FT1_OP_STATS 0x02 /* read the FT1 operational statistics */ +#define FLUSH_FT1_OP_STATS 0x04 /* flush the FT1 operational statistics */ + + + + +/* ---------------------------------------------------------------------------- + * Constants for the SET_CHDLC_CONFIGURATION command + * --------------------------------------------------------------------------*/ + +/* the CHDLC configuration structure */ +typedef struct { + unsigned long baud_rate PACKED; /* the baud rate */ + unsigned short line_config_options PACKED; /* line configuration options */ + unsigned short modem_config_options PACKED; /* modem configration options */ + unsigned short modem_status_timer PACKED; /* timer for monitoring modem status changes */ + unsigned short CHDLC_API_options PACKED; /* CHDLC API options */ + unsigned short CHDLC_protocol_options PACKED; /* CHDLC protocol options */ + unsigned short percent_data_buffer_for_Tx PACKED; /* percentage data buffering used for Tx */ + unsigned short CHDLC_statistics_options PACKED; /* CHDLC operational statistics options */ + unsigned short max_CHDLC_data_field_length PACKED; /* the maximum length of the CHDLC Data field */ + unsigned short transmit_keepalive_timer PACKED; /* the transmit keepalive timer */ + unsigned short receive_keepalive_timer PACKED; /* the receive keepalive timer */ + unsigned short keepalive_error_tolerance PACKED; /* the receive keepalive error tolerance */ + unsigned short SLARP_request_timer PACKED; /* the SLARP request timer */ + unsigned long IP_address PACKED; /* the IP address */ + unsigned long IP_netmask PACKED; /* the IP netmask */ + unsigned long ptr_shared_mem_info_struct PACKED; /* a pointer to the shared memory area information structure */ + unsigned long ptr_CHDLC_Tx_stat_el_cfg_struct PACKED; /* a pointer to the transmit status element configuration structure */ + unsigned long ptr_CHDLC_Rx_stat_el_cfg_struct PACKED; /* a pointer to the receive status element configuration structure */ +} CHDLC_CONFIGURATION_STRUCT; + +/* settings for the 'line_config_options' */ +#define INTERFACE_LEVEL_V35 0x0000 /* V.35 interface level */ +#define INTERFACE_LEVEL_RS232 0x0001 /* RS-232 interface level */ + +/* settings for the 'modem_config_options' */ + +#define DONT_RAISE_DTR_RTS_ON_EN_COMMS 0x0001 +/* don't automatically raise DTR and RTS when performing an + ENABLE_CHDLC_COMMUNICATIONS command */ + +#define DONT_REPORT_CHG_IN_MODEM_STAT 0x0002 +/* don't report changes in modem status to the application */ + + +/* bit settings for the 'CHDLC_protocol_options' byte */ + +#define IGNORE_DCD_FOR_LINK_STAT 0x0001 +/* ignore DCD in determining the CHDLC link status */ + +#define IGNORE_CTS_FOR_LINK_STAT 0x0002 +/* ignore CTS in determining the CHDLC link status */ + +#define IGNORE_KPALV_FOR_LINK_STAT 0x0004 +/* ignore keepalive frames in determining the CHDLC link status */ + +#define HDLC_STREAMING_MODE 0x8000 + +/* settings for the 'CHDLC_statistics_options' */ + +#define CHDLC_TX_DATA_BYTE_COUNT_STAT 0x0001 +/* record the number of Data bytes transmitted */ + +#define CHDLC_RX_DATA_BYTE_COUNT_STAT 0x0002 +/* record the number of Data bytes received */ + +#define CHDLC_TX_THROUGHPUT_STAT 0x0004 +/* compute the Data frame transmit throughput */ + +#define CHDLC_RX_THROUGHPUT_STAT 0x0008 +/* compute the Data frame receive throughput */ + + +/* permitted minimum and maximum values for setting the CHDLC configuration */ +#define PRI_MAX_BAUD_RATE_S508 2666666 /* PRIMARY - maximum baud rate (S508) */ +#define SEC_MAX_BAUD_RATE_S508 258064 /* SECONDARY - maximum baud rate (S508) */ +#define PRI_MAX_BAUD_RATE_S514 2750000 /* PRIMARY - maximum baud rate (S508) */ +#define SEC_MAX_BAUD_RATE_S514 515625 /* SECONDARY - maximum baud rate (S508) */ + +#define MIN_MODEM_TIMER 0 /* minimum modem status timer */ +#define MAX_MODEM_TIMER 5000 /* maximum modem status timer */ + +#define SEC_MAX_NO_DATA_BYTES_IN_FRAME 2048 /* SECONDARY - max length of the CHDLC data field */ + +#define MIN_Tx_KPALV_TIMER 0 /* minimum transmit keepalive timer */ +#define MAX_Tx_KPALV_TIMER 60000 /* maximum transmit keepalive timer */ +#define DEFAULT_Tx_KPALV_TIMER 10000 /* default transmit keepalive timer */ + +#define MIN_Rx_KPALV_TIMER 10 /* minimum receive keepalive timer */ +#define MAX_Rx_KPALV_TIMER 60000 /* maximum receive keepalive timer */ +#define DEFAULT_Rx_KPALV_TIMER 10000 /* default receive keepalive timer */ + +#define MIN_KPALV_ERR_TOL 1 /* min kpalv error tolerance count */ +#define MAX_KPALV_ERR_TOL 20 /* max kpalv error tolerance count */ +#define DEFAULT_KPALV_ERR_TOL 3 /* default value */ + +#define MIN_SLARP_REQ_TIMER 0 /* min transmit SLARP Request timer */ +#define MAX_SLARP_REQ_TIMER 60000 /* max transmit SLARP Request timer */ +#define DEFAULT_SLARP_REQ_TIMER 0 /* default value -- no SLARP */ + + + +/* ---------------------------------------------------------------------------- + * Constants for the READ_CHDLC_LINK_STATUS command + * --------------------------------------------------------------------------*/ + +/* the CHDLC status structure */ +typedef struct { + unsigned char CHDLC_link_status PACKED; /* CHDLC link status */ + unsigned char no_Data_frms_for_app PACKED; /* number of Data frames available for the application */ + unsigned char receiver_status PACKED; /* enabled/disabled */ + unsigned char SLARP_state PACKED; /* internal SLARP state */ +} CHDLC_LINK_STATUS_STRUCT; + +/* settings for the 'CHDLC_link_status' variable */ +#define CHDLC_LINK_INACTIVE 0x00 /* the CHDLC link is inactive */ +#define CHDLC_LINK_ACTIVE 0x01 /* the CHDLC link is active */ + + + +/* ---------------------------------------------------------------------------- + * Constants for the READ_CHDLC_OPERATIONAL_STATS command + * --------------------------------------------------------------------------*/ + +/* the CHDLC operational statistics structure */ +typedef struct { + + /* Data frame transmission statistics */ + unsigned long Data_frames_Tx_count PACKED; /* # of frames transmitted */ + unsigned long Data_bytes_Tx_count PACKED; /* # of bytes transmitted */ + unsigned long Data_Tx_throughput PACKED; /* transmit throughput */ + unsigned long no_ms_for_Data_Tx_thruput_comp PACKED; /* millisecond time used for the Tx throughput computation */ + unsigned long Tx_Data_discard_lgth_err_count PACKED; /* number of Data frames discarded (length error) */ + unsigned long reserved_Data_frm_Tx_stat1 PACKED; /* reserved for later */ + unsigned long reserved_Data_frm_Tx_stat2 PACKED; /* reserved for later */ + unsigned long reserved_Data_frm_Tx_stat3 PACKED; /* reserved for later */ + + /* Data frame reception statistics */ + unsigned long Data_frames_Rx_count PACKED; /* number of frames received */ + unsigned long Data_bytes_Rx_count PACKED; /* number of bytes received */ + unsigned long Data_Rx_throughput PACKED; /* receive throughput */ + unsigned long no_ms_for_Data_Rx_thruput_comp PACKED; /* millisecond time used for the Rx throughput computation */ + unsigned long Rx_Data_discard_short_count PACKED; /* received Data frames discarded (too short) */ + unsigned long Rx_Data_discard_long_count PACKED; /* received Data frames discarded (too long) */ + unsigned long Rx_Data_discard_inactive_count PACKED; /* received Data frames discarded (link inactive) */ + unsigned long reserved_Data_frm_Rx_stat1 PACKED; /* reserved for later */ + + /* SLARP frame transmission/reception statistics */ + unsigned long CHDLC_SLARP_REQ_Tx_count PACKED; /* number of SLARP Request frames transmitted */ + unsigned long CHDLC_SLARP_REQ_Rx_count PACKED; /* number of SLARP Request frames received */ + unsigned long CHDLC_SLARP_REPLY_Tx_count PACKED; /* number of SLARP Reply frames transmitted */ + unsigned long CHDLC_SLARP_REPLY_Rx_count PACKED; /* number of SLARP Reply frames received */ + unsigned long CHDLC_SLARP_KPALV_Tx_count PACKED; /* number of SLARP keepalive frames transmitted */ + unsigned long CHDLC_SLARP_KPALV_Rx_count PACKED; /* number of SLARP keepalive frames received */ + unsigned long reserved_SLARP_stat1 PACKED; /* reserved for later */ + unsigned long reserved_SLARP_stat2 PACKED; /* reserved for later */ + + /* CDP frame transmission/reception statistics */ + unsigned long CHDLC_CDP_Tx_count PACKED; /* number of CDP frames transmitted */ + unsigned long CHDLC_CDP_Rx_count PACKED; /* number of CDP frames received */ + unsigned long reserved_CDP_stat1 PACKED; /* reserved for later */ + unsigned long reserved_CDP_stat2 PACKED; /* reserved for later */ + unsigned long reserved_CDP_stat3 PACKED; /* reserved for later */ + unsigned long reserved_CDP_stat4 PACKED; /* reserved for later */ + unsigned long reserved_CDP_stat5 PACKED; /* reserved for later */ + unsigned long reserved_CDP_stat6 PACKED; /* reserved for later */ + + /* Incomming frames with a format error statistics */ + unsigned short Rx_frm_incomp_CHDLC_hdr_count PACKED; /* frames received of with incomplete Cisco HDLC header */ + unsigned short Rx_frms_too_long_count PACKED; /* frames received of excessive length count */ + unsigned short Rx_invalid_CHDLC_addr_count PACKED; /* frames received with an invalid CHDLC address count */ + unsigned short Rx_invalid_CHDLC_ctrl_count PACKED; /* frames received with an invalid CHDLC control field count */ + unsigned short Rx_invalid_CHDLC_type_count PACKED; /* frames received of an invalid CHDLC frame type count */ + unsigned short Rx_SLARP_invalid_code_count PACKED; /* SLARP frame received with an invalid packet code */ + unsigned short Rx_SLARP_Reply_bad_IP_addr PACKED; /* SLARP Reply received - bad IP address */ + unsigned short Rx_SLARP_Reply_bad_netmask PACKED; /* SLARP Reply received - bad netmask */ + unsigned long reserved_frm_format_err1 PACKED; /* reserved for later */ + unsigned long reserved_frm_format_err2 PACKED; /* reserved for later */ + unsigned long reserved_frm_format_err3 PACKED; /* reserved for later */ + unsigned long reserved_frm_format_err4 PACKED; /* reserved for later */ + + /* CHDLC timeout/retry statistics */ + unsigned short SLARP_Rx_keepalive_TO_count PACKED; /* timeout count for incomming SLARP frames */ + unsigned short SLARP_Request_TO_count PACKED; /* timeout count for SLARP Request frames */ + unsigned long To_retry_reserved_stat1 PACKED; /* reserved for later */ + unsigned long To_retry_reserved_stat2 PACKED; /* reserved for later */ + unsigned long To_retry_reserved_stat3 PACKED; /* reserved for later */ + + /* CHDLC link active/inactive and loopback statistics */ + unsigned short link_active_count PACKED; /* number of times that the link went active */ + unsigned short link_inactive_modem_count PACKED; /* number of times that the link went inactive (modem failure) */ + unsigned short link_inactive_keepalive_count PACKED; /* number of times that the link went inactive (keepalive failure) */ + unsigned short link_looped_count PACKED; /* link looped count */ + unsigned long link_status_reserved_stat1 PACKED; /* reserved for later use */ + unsigned long link_status_reserved_stat2 PACKED; /* reserved for later use */ + + /* miscellaneous statistics */ + unsigned long reserved_misc_stat1 PACKED; /* reserved for later */ + unsigned long reserved_misc_stat2 PACKED; /* reserved for later */ + unsigned long reserved_misc_stat3 PACKED; /* reserved for later */ + unsigned long reserved_misc_stat4 PACKED; /* reserved for later */ + +} CHDLC_OPERATIONAL_STATS_STRUCT; + + + +/* ---------------------------------------------------------------------------- + * Constants for using application interrupts + * --------------------------------------------------------------------------*/ + +/* the structure used for the SET_CHDLC_INTERRUPT_TRIGGERS/READ_CHDLC_INTERRUPT_TRIGGERS command */ +typedef struct { + unsigned char CHDLC_interrupt_triggers PACKED; /* CHDLC interrupt trigger configuration */ + unsigned char IRQ PACKED; /* IRQ to be used */ + unsigned short interrupt_timer PACKED; /* interrupt timer */ + unsigned short misc_interrupt_bits PACKED; /* miscellaneous bits */ +} CHDLC_INT_TRIGGERS_STRUCT; + +/* 'CHDLC_interrupt_triggers' bit settings */ +#define APP_INT_ON_RX_FRAME 0x01 /* interrupt on Data frame reception */ +#define APP_INT_ON_TX_FRAME 0x02 /* interrupt when an Data frame may be transmitted */ +#define APP_INT_ON_COMMAND_COMPLETE 0x04 /* interrupt when an interface command is complete */ +#define APP_INT_ON_TIMER 0x08 /* interrupt on a defined millisecond timeout */ +#define APP_INT_ON_GLOBAL_EXCEP_COND 0x10 /* interrupt on a global exception condition */ +#define APP_INT_ON_CHDLC_EXCEP_COND 0x20 /* interrupt on an CHDLC exception condition */ +#define APP_INT_ON_TRACE_DATA_AVAIL 0x80 /* interrupt when trace data is available */ + +/* interrupt types indicated at 'interrupt_type' byte of the INTERRUPT_INFORMATION_STRUCT */ +#define NO_APP_INTS_PEND 0x00 /* no interrups are pending */ +#define RX_APP_INT_PEND 0x01 /* a receive interrupt is pending */ +#define TX_APP_INT_PEND 0x02 /* a transmit interrupt is pending */ +#define COMMAND_COMPLETE_APP_INT_PEND 0x04 /* a 'command complete' interrupt is pending */ +#define TIMER_APP_INT_PEND 0x08 /* a timer interrupt is pending */ +#define GLOBAL_EXCEP_COND_APP_INT_PEND 0x10 /* a global exception condition interrupt is pending */ +#define CHDLC_EXCEP_COND_APP_INT_PEND 0x20 /* an CHDLC exception condition interrupt is pending */ +#define TRACE_DATA_AVAIL_APP_INT_PEND 0x80 /* a trace data available interrupt is pending */ + + +/* modem status changes */ +#define DCD_HIGH 0x08 +#define CTS_HIGH 0x20 + + +/* ---------------------------------------------------------------------------- + * Constants for Data frame transmission + * --------------------------------------------------------------------------*/ + +/* the Data frame transmit status element configuration structure */ +typedef struct { + unsigned short number_Tx_status_elements PACKED; /* number of transmit status elements */ + unsigned long base_addr_Tx_status_elements PACKED; /* base address of the transmit element list */ + unsigned long next_Tx_status_element_to_use PACKED; /* pointer to the next transmit element to be used */ +} CHDLC_TX_STATUS_EL_CFG_STRUCT; + +/* the Data frame transmit status element structure */ +typedef struct { + unsigned char opp_flag PACKED; /* opp flag */ + unsigned short frame_length PACKED; /* length of the frame to be transmitted */ + unsigned char reserved_1 PACKED; /* reserved for internal use */ + unsigned long reserved_2 PACKED; /* reserved for internal use */ + unsigned long reserved_3 PACKED; /* reserved for internal use */ + unsigned long ptr_data_bfr PACKED; /* pointer to the data area */ +} CHDLC_DATA_TX_STATUS_EL_STRUCT; + + + +/* ---------------------------------------------------------------------------- + * Constants for Data frame reception + * --------------------------------------------------------------------------*/ + +/* the Data frame receive status element configuration structure */ +typedef struct { + unsigned short number_Rx_status_elements PACKED; /* number of receive status elements */ + unsigned long base_addr_Rx_status_elements PACKED; /* base address of the receive element list */ + unsigned long next_Rx_status_element_to_use PACKED; /* pointer to the next receive element to be used */ + unsigned long base_addr_Rx_buffer PACKED; /* base address of the receive data buffer */ + unsigned long end_addr_Rx_buffer PACKED; /* end address of the receive data buffer */ +} CHDLC_RX_STATUS_EL_CFG_STRUCT; + +/* the Data frame receive status element structure */ +typedef struct { + unsigned char opp_flag PACKED; /* opp flag */ + unsigned short frame_length PACKED; /* length of the received frame */ + unsigned char error_flag PACKED; /* frame errors (HDLC_STREAMING_MODE)*/ + unsigned short time_stamp PACKED; /* receive time stamp (HDLC_STREAMING_MODE) */ + unsigned long reserved_1 PACKED; /* reserved for internal use */ + unsigned short reserved_2 PACKED; /* reserved for internal use */ + unsigned long ptr_data_bfr PACKED; /* pointer to the data area */ +} CHDLC_DATA_RX_STATUS_EL_STRUCT; + + + +/* ---------------------------------------------------------------------------- + * Constants defining the shared memory information area + * --------------------------------------------------------------------------*/ + +/* the global information structure */ +typedef struct { + unsigned char global_status PACKED; /* global status */ + unsigned char modem_status PACKED; /* current modem status */ + unsigned char global_excep_conditions PACKED; /* global exception conditions */ + unsigned char glob_info_reserved[5] PACKED; /* reserved */ + unsigned char codename[4] PACKED; /* Firmware name */ + unsigned char codeversion[4] PACKED; /* Firmware version */ +} GLOBAL_INFORMATION_STRUCT; + +/* the CHDLC information structure */ +typedef struct { + unsigned char CHDLC_status PACKED; /* CHDLC status */ + unsigned char CHDLC_excep_conditions PACKED; /* CHDLC exception conditions */ + unsigned char CHDLC_info_reserved[14] PACKED; /* reserved */ +} CHDLC_INFORMATION_STRUCT; + +/* the interrupt information structure */ +typedef struct { + unsigned char interrupt_type PACKED; /* type of interrupt triggered */ + unsigned char interrupt_permission PACKED; /* interrupt permission mask */ + unsigned char int_info_reserved[14] PACKED; /* reserved */ +} INTERRUPT_INFORMATION_STRUCT; + +/* the S508/FT1 information structure */ +typedef struct { + unsigned char parallel_port_A_input PACKED; /* input - parallel port A */ + unsigned char parallel_port_B_input PACKED; /* input - parallel port B */ + unsigned char FT1_info_reserved[14] PACKED; /* reserved */ +} FT1_INFORMATION_STRUCT; + +/* the shared memory area information structure */ +typedef struct { + GLOBAL_INFORMATION_STRUCT global_info_struct PACKED; /* the global information structure */ + CHDLC_INFORMATION_STRUCT CHDLC_info_struct PACKED; /* the CHDLC information structure */ + INTERRUPT_INFORMATION_STRUCT interrupt_info_struct PACKED; /* the interrupt information structure */ + FT1_INFORMATION_STRUCT FT1_info_struct PACKED; /* the S508/FT1 information structure */ +} SHARED_MEMORY_INFO_STRUCT; + +/* ---------------------------------------------------------------------------- + * UDP Management constants and structures + * --------------------------------------------------------------------------*/ + +/* The embedded control block for UDP mgmt + This is essentially a mailbox structure, without the large data field */ + +typedef struct { + unsigned char opp_flag PACKED; /* the opp flag */ + unsigned char command PACKED; /* the user command */ + unsigned short buffer_length PACKED; /* the data length */ + unsigned char return_code PACKED; /* the return code */ + unsigned char MB_reserved[NUMBER_MB_RESERVED_BYTES] PACKED; /* reserved for later */ +} cblock_t; + + +/* UDP management packet layout (data area of ip packet) */ +/* +typedef struct { + unsigned char signature[8] PACKED; + unsigned char request_reply PACKED; + unsigned char id PACKED; + unsigned char reserved[6] PACKED; + cblock_t cblock PACKED; + unsigned char num_frames PACKED; + unsigned char ismoredata PACKED; + unsigned char data[SIZEOF_MB_DATA_BFR] PACKED; +} udp_management_packet_t; + +*/ + +typedef struct { + unsigned char num_frames PACKED; + unsigned char ismoredata PACKED; +} trace_info_t; + +typedef struct { + ip_pkt_t ip_pkt PACKED; + udp_pkt_t udp_pkt PACKED; + wp_mgmt_t wp_mgmt PACKED; + cblock_t cblock PACKED; + trace_info_t trace_info PACKED; + unsigned char data[SIZEOF_MB_DATA_BFR] PACKED; +} chdlc_udp_pkt_t; + +typedef struct ft1_exec_cmd{ + unsigned char command PACKED; /* the user command */ + unsigned short buffer_length PACKED; /* the data length */ + unsigned char return_code PACKED; /* the return code */ + unsigned char MB_reserved[NUMBER_MB_RESERVED_BYTES] PACKED; +} ft1_exec_cmd_t; + +typedef struct { + unsigned char opp_flag PACKED; + ft1_exec_cmd_t cmd PACKED; + unsigned char data[SIZEOF_MB_DATA_BFR] PACKED; +} ft1_exec_t; + +#define UDPMGMT_SIGNATURE "CTPIPEAB" + + +/* UDP/IP packet (for UDP management) layout */ +/* +typedef struct { + unsigned char reserved[2] PACKED; + unsigned short ip_length PACKED; + unsigned char reserved2[4] PACKED; + unsigned char ip_ttl PACKED; + unsigned char ip_protocol PACKED; + unsigned short ip_checksum PACKED; + unsigned long ip_src_address PACKED; + unsigned long ip_dst_address PACKED; + unsigned short udp_src_port PACKED; + unsigned short udp_dst_port PACKED; + unsigned short udp_length PACKED; + unsigned short udp_checksum PACKED; + udp_management_packet_t um_packet PACKED; +} ip_packet_t; +*/ + +/* valid ip_protocol for UDP management */ +#define UDPMGMT_UDP_PROTOCOL 0x11 + + +typedef struct { + unsigned char status PACKED; + unsigned char data_avail PACKED; + unsigned short real_length PACKED; + unsigned short time_stamp PACKED; + unsigned char data[1] PACKED; +} trace_pkt_t; + +typedef struct { + unsigned char error_flag PACKED; + unsigned short time_stamp PACKED; + unsigned char reserved[13] PACKED; +} api_rx_hdr_t; + +typedef struct { + api_rx_hdr_t api_rx_hdr PACKED; + void * data PACKED; +} api_rx_element_t; + +typedef struct { + unsigned char attr PACKED; + unsigned char reserved[15] PACKED; +} api_tx_hdr_t; + +typedef struct { + api_tx_hdr_t api_tx_hdr PACKED; + void * data PACKED; +} api_tx_element_t; + +/* ---------------------------------------------------------------------------- + * Constants for the SET_FT1_CONFIGURATION/READ_FT1_CONFIGURATION command + * --------------------------------------------------------------------------*/ + +/* the FT1 configuration structure */ +typedef struct { + unsigned short framing_mode; + unsigned short encoding_mode; + unsigned short line_build_out; + unsigned short channel_base; + unsigned short baud_rate_kbps; /* the baud rate (in kbps) */ + unsigned short clock_mode; +} ft1_config_t; + +/* settings for the 'framing_mode' */ +#define ESF_FRAMING 0x00 /* ESF framing */ +#define D4_FRAMING 0x01 /* D4 framing */ + +/* settings for the 'encoding_mode' */ +#define B8ZS_ENCODING 0x00 /* B8ZS encoding */ +#define AMI_ENCODING 0x01 /* AMI encoding */ + +/* settings for the 'line_build_out' */ +#define LN_BLD_CSU_0dB_DSX1_0_to_133 0x00 /* set build out to CSU (0db) or DSX-1 (0-133ft) */ +#define LN_BLD_DSX1_133_to_266 0x01 /* set build out DSX-1 (133-266ft) */ +#define LN_BLD_DSX1_266_to_399 0x02 /* set build out DSX-1 (266-399ft) */ +#define LN_BLD_DSX1_399_to_533 0x03 /* set build out DSX-1 (399-533ft) */ +#define LN_BLD_DSX1_533_to_655 0x04 /* set build out DSX-1 (533-655ft) */ +#define LN_BLD_CSU_NEG_7dB 0x05 /* set build out to CSU (-7.5db) */ +#define LN_BLD_CSU_NEG_15dB 0x06 /* set build out to CSU (-15db) */ +#define LN_BLD_CSU_NEG_22dB 0x07 /* set build out to CSU (-22.5db) */ + +/* settings for the 'channel_base' */ +#define MIN_CHANNEL_BASE_VALUE 1 /* the minimum permitted channel base value */ +#define MAX_CHANNEL_BASE_VALUE 24 /* the maximum permitted channel base value */ + +/* settings for the 'baud_rate_kbps' */ +#define MIN_BAUD_RATE_KBPS 0 /* the minimum permitted baud rate (kbps) */ +#define MAX_BAUD_RATE_KBPS 1536 /* the maximum permitted baud rate (kbps) */ +#define BAUD_RATE_FT1_AUTO_CONFIG 0xFFFF /* the baud rate used to trigger an automatic FT1 configuration */ + +/* settings for the 'clock_mode' */ +#define CLOCK_MODE_NORMAL 0x00 /* clock mode set to normal (slave) */ +#define CLOCK_MODE_MASTER 0x01 /* clock mode set to master */ + + +#define BAUD_RATE_FT1_AUTO_CONFIG 0xFFFF +#define AUTO_FT1_CONFIG_NOT_COMPLETE 0x08 +#define AUTO_FT1_CFG_FAIL_OP_MODE 0x0C +#define AUTO_FT1_CFG_FAIL_INVALID_LINE 0x0D + + +#ifdef _MSC_ +# pragma pack() +#endif +#endif /* _SDLA_CHDLC_H */ diff -ur --new-file old/linux/include/linux/sdla_fr.h new/linux/include/linux/sdla_fr.h --- old/linux/include/linux/sdla_fr.h Mon Jan 12 23:46:26 1998 +++ new/linux/include/linux/sdla_fr.h Wed Jan 26 22:25:58 2000 @@ -1,16 +1,18 @@ /***************************************************************************** * sdla_fr.h Sangoma frame relay firmware API definitions. * -* Author: Jaspreet Singh -* Gene Kozin <74604.152@compuserve.com> +* Author: Gideon Hack +* Nenad Corbic * -* Copyright: (c) 1995-1996 Sangoma Technologies Inc. +* Copyright: (c) 1995-1999 Sangoma Technologies 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. * ============================================================================ +* Oct 04, 1999 Gideon Hack Updated API structures +* Jun 02, 1999 Gideon Hack Modifications for S514 support * Oct 12, 1997 Jaspreet Singh Added FR_READ_DLCI_IB_MAPPING * Jul 21, 1997 Jaspreet Singh Changed FRRES_TOO_LONG and FRRES_TOO_MANY to * 0x05 and 0x06 respectively. @@ -24,26 +26,16 @@ /*---------------------------------------------------------------------------- * Notes: * ------ - * 1. All structures defined in this file are byte-alined. To ensure - * portability of this code between different platforms and compilers, one - * of the following defines must be defined before including this file: + * 1. All structures defined in this file are byte-alined. * - * Compiler Platform Define Use option - * -------- -------- ------ ---------- - * GNU C Linux _GNUC_ - - * Microsoft C DOS/Windows _MSC_ - + * Compiler Platform + * -------- -------- + * GNU C Linux */ -#ifdef _GNUC_ -# ifndef PACKED +#ifndef PACKED # define PACKED __attribute__((packed)) -# endif /* PACKED */ -#else -# define PACKED -#endif -#ifdef _MSC_ -# pragma pack(1) -#endif +#endif /* PACKED */ /* Adapter memory layout */ #define FR_MB_VECTOR 0xE000 /* mailbox window vector */ @@ -59,6 +51,11 @@ /* Important constants */ #define FR502_MAX_DATA 4096 /* maximum data buffer length */ #define FR508_MAX_DATA 4080 /* maximum data buffer length */ +#define MIN_LGTH_FR_DATA_CFG 300 /* min Information frame length +(for configuration purposes) */ +#define FR_MAX_NO_DATA_BYTES_IN_FRAME 15354 /* max Information frame length */ + +#define HIGHEST_VALID_DLCI 991 /****** Data Structures *****************************************************/ @@ -90,6 +87,7 @@ #define FR_FLUSH_STATISTICS 0x16 #define FR_LIST_ACTIVE_DLCI 0x17 #define FR_FLUSH_DATA_BUFFERS 0x18 +#define FR_READ_ADD_DLC_STATS 0x19 #define FR_ADD_DLCI 0x20 #define FR_DELETE_DLCI 0x21 #define FR_ACTIVATE_DLCI 0x22 @@ -102,6 +100,20 @@ #define FR_READ_CODE_VERSION 0x40 #define FR_SET_INTR_MODE 0x50 #define FR_READ_INTR_MODE 0x51 +#define FR_SET_TRACE_CONFIG 0x60 +#define FR_FT1_STATUS_CTRL 0x80 +#define FR_SET_FT1_MODE 0x81 + +/* Special UDP drivers management commands */ +#define FPIPE_ENABLE_TRACING 0x41 +#define FPIPE_DISABLE_TRACING 0x42 +#define FPIPE_GET_TRACE_INFO 0x43 +#define FPIPE_FT1_READ_STATUS 0x44 +#define FPIPE_DRIVER_STAT_IFSEND 0x45 +#define FPIPE_DRIVER_STAT_INTR 0x46 +#define FPIPE_DRIVER_STAT_GEN 0x47 +#define FPIPE_FLUSH_DRIVER_STATS 0x48 +#define FPIPE_ROUTER_UP_TIME 0x49 /* 'result' field defines */ #define FRRES_OK 0x00 /* command executed successfully */ @@ -169,7 +181,7 @@ } fr508_flags_t; /* 'event' field defines */ -#define FR_EVENT_STATUS 0x01 /* channel status change ??? */ +#define FR_EVENT_STATUS 0x01 /* channel status change */ #define FR_EVENT_DLC_STATUS 0x02 /* DLC status change */ #define FR_EVENT_BAD_DLCI 0x04 /* FSR included wrong DLCI */ #define FR_EVENT_LINK_DOWN 0x40 /* DCD or CTS low */ @@ -185,6 +197,8 @@ #define FR_INTR_READY 0x08 /* interface command completed */ #define FR_INTR_DLC 0x10 /* DLC status change */ #define FR_INTR_TIMER 0x20 /* millisecond timer */ +#define FR_INTR_TX_MULT_DLCIs 0x80 /* Tx interrupt on multiple DLCIs */ + /*---------------------------------------------------------------------------- * Receive Buffer Configuration Info. S508 only! @@ -206,7 +220,7 @@ * 'rse_base' field of the frBufInfo_t structure into absolute adapter * memory address space. */ -typedef struct fr_buf_ctl +typedef struct fr_rx_buf_ctl { unsigned char flag PACKED; /* 00h: ready flag */ unsigned short length PACKED; /* 01h: frame length */ @@ -215,7 +229,18 @@ unsigned short tmstamp PACKED; /* 06h: time stamp */ unsigned short rsrv[2] PACKED; /* 08h: */ unsigned long offset PACKED; /* 0Ch: buffer absolute address */ -} fr_buf_ctl_t; +} fr_rx_buf_ctl_t; + +typedef struct fr_tx_buf_ctl +{ + unsigned char flag PACKED; /* 00h: ready flag */ + unsigned short rsrv0[2] PACKED; /* 01h: */ + unsigned short length PACKED; /* 05h: frame length */ + unsigned short dlci PACKED; /* 07h: DLCI */ + unsigned char attr PACKED; /* 09h: FECN/BECN/DE/CR */ + unsigned short rsrv1 PACKED; /* 0Ah: */ + unsigned long offset PACKED; /* 0Ch: buffer absolute address */ +} fr_tx_buf_ctl_t; /*---------------------------------------------------------------------------- * Global Configuration Block. Passed to FR_SET_CONFIG command when dlci == 0. @@ -271,6 +296,52 @@ #define FRCFG_MODE_V35 0x0000 /* S508 only */ #define FRCFG_MODE_RS232 0x0002 /* S508 only */ +/* defines for line tracing */ + +/* the line trace status element presented by the frame relay code */ +typedef struct { + unsigned char flag PACKED; /* ready flag */ + unsigned short length PACKED; /* trace length */ + unsigned char rsrv0[2] PACKED; /* reserved */ + unsigned char attr PACKED; /* trace attributes */ + unsigned short tmstamp PACKED; /* time stamp */ + unsigned char rsrv1[4] PACKED; /* reserved */ + unsigned long offset PACKED; /* buffer absolute address */ +} fr_trc_el_t; + +typedef struct { + unsigned char status PACKED; /* status flag */ + unsigned char data_passed PACKED; /* 0 if no data passed, 1 if */ + /* data passed */ + unsigned short length PACKED; /* frame length */ + unsigned short tmstamp PACKED; /* time stamp */ +} fpipemon_trc_hdr_t; + +typedef struct { + fpipemon_trc_hdr_t fpipemon_trc_hdr PACKED; + unsigned char data[FR_MAX_NO_DATA_BYTES_IN_FRAME] PACKED; +} fpipemon_trc_t; + +/* bit settings for the 'status' byte - note that bits 1, 2 and 3 are used */ +/* for returning the number of frames being passed to fpipemon */ +#define TRC_OUTGOING_FRM 0x01 +#define TRC_ABORT_ERROR 0x10 +#define TRC_CRC_ERROR 0x20 +#define TRC_OVERRUN_ERROR 0x40 +#define MORE_TRC_DATA 0x80 + +#define MAX_FRMS_TRACED 0x07 + +#define NO_TRC_ELEMENTS_OFF 0x9000 +#define BASE_TRC_ELEMENTS_OFF 0x9002 +#define TRC_ACTIVE 0x01 +#define FLUSH_TRC_BUFFERS 0x02 +#define FLUSH_TRC_STATISTICS 0x04 +#define TRC_SIGNALLING_FRMS 0x10 +#define TRC_INFO_FRMS 0x20 +#define ACTIVATE_TRC (TRC_ACTIVE | TRC_SIGNALLING_FRMS | TRC_INFO_FRMS) +#define RESET_TRC (FLUSH_TRC_BUFFERS | FLUSH_TRC_STATISTICS) + /*---------------------------------------------------------------------------- * Channel configuration. * This structure is passed to the FR_SET_CONFIG command when dlci != 0. @@ -414,6 +485,151 @@ */ #define FR_ISF_LVE 2 /* issue Link Verification Enquiry */ #define FR_ISF_FSE 3 /* issue Full Status Enquiry */ + +/*---------------------------------------------------------------------------- + * Frame Relay ARP Header -- Used for Dynamic route creation with InvARP + */ + +typedef struct arphdr_fr + { + unsigned short ar_hrd PACKED; /* format of hardware addr */ + unsigned short ar_pro PACKED; /* format of protocol addr */ + unsigned char ar_hln PACKED; /* length of hardware addr */ + unsigned char ar_pln PACKED; /* length of protocol addr */ + unsigned short ar_op PACKED; /* ARP opcode */ + unsigned short ar_sha PACKED; /* Sender DLCI addr 2 bytes */ + unsigned long ar_sip PACKED; /* Sender IP addr 4 bytes */ + unsigned short ar_tha PACKED; /* Target DLCI addr 2 bytes */ + unsigned long ar_tip PACKED; /* Target IP addr 4 bytes */ + } arphdr_fr_t; + +/*---------------------------------------------------------------------------- + * Frame Relay RFC 1490 SNAP Header -- Used to check for ARP packets + */ +typedef struct arphdr_1490 + { + unsigned char control PACKED; /* UI, etc... */ + unsigned char pad PACKED; /* Pad */ + unsigned char NLPID PACKED; /* SNAP */ + unsigned char OUI[3] PACKED; /* Ethertype, etc... */ + unsigned short PID PACKED; /* ARP, IP, etc... */ + } arphdr_1490_t; + +/* UDP/IP packet (for UDP management) layout */ + +/* The embedded control block for UDP mgmt + This is essentially a mailbox structure, without the large data field */ + +typedef struct { + unsigned char opp_flag PACKED; /* the opp flag */ + unsigned char command PACKED; /* command code */ + unsigned short length PACKED; /* length of data buffer */ + unsigned char result PACKED; /* return code */ + unsigned short dlci PACKED; /* DLCI number */ + unsigned char attr PACKED; /* FECN, BECN, DE and C/R bits */ + unsigned short rxlost1 PACKED; /* frames discarded at int. level */ + unsigned long rxlost2 PACKED; /* frames discarded at app. level */ + unsigned char rsrv[2] PACKED; /* reserved for future use */ +} cblock_t; + + +/* UDP management packet layout (data area of ip packet) */ + +typedef struct { + unsigned char control PACKED; + unsigned char NLPID PACKED; +} fr_encap_hdr_t; + +typedef struct { + fr_encap_hdr_t fr_encap_hdr PACKED; + ip_pkt_t ip_pkt PACKED; + udp_pkt_t udp_pkt PACKED; + wp_mgmt_t wp_mgmt PACKED; + cblock_t cblock PACKED; + unsigned char data[4080] PACKED; +} fr_udp_pkt_t; + + +/* valid ip_protocol for UDP management */ +#define UDPMGMT_UDP_PROTOCOL 0x11 + +#define UDPMGMT_FPIPE_SIGNATURE "FPIPE8ND" +#define UDPMGMT_DRVRSTATS_SIGNATURE "DRVSTATS" + +/* values for request/reply byte */ +#define UDPMGMT_REQUEST 0x01 +#define UDPMGMT_REPLY 0x02 +#define UDP_OFFSET 12 + +typedef struct { + unsigned long if_send_entry; + unsigned long if_send_skb_null; + unsigned long if_send_broadcast; + unsigned long if_send_multicast; + unsigned long if_send_critical_ISR; + unsigned long if_send_critical_non_ISR; + unsigned long if_send_busy; + unsigned long if_send_busy_timeout; + unsigned long if_send_DRVSTATS_request; + unsigned long if_send_FPIPE_request; + unsigned long if_send_wan_disconnected; + unsigned long if_send_dlci_disconnected; + unsigned long if_send_no_bfrs; + unsigned long if_send_adptr_bfrs_full; + unsigned long if_send_bfrs_passed_to_adptr; + unsigned long if_send_consec_send_fail; +} drvstats_if_send_t; + +typedef struct { + unsigned long rx_intr_no_socket; + unsigned long rx_intr_dev_not_started; + unsigned long rx_intr_DRVSTATS_request; + unsigned long rx_intr_FPIPE_request; + unsigned long rx_intr_bfr_not_passed_to_stack; + unsigned long rx_intr_bfr_passed_to_stack; + } drvstats_rx_intr_t; + +typedef struct { + unsigned long UDP_FPIPE_mgmt_kmalloc_err; + unsigned long UDP_FPIPE_mgmt_direction_err; + unsigned long UDP_FPIPE_mgmt_adptr_type_err; + unsigned long UDP_FPIPE_mgmt_adptr_cmnd_OK; + unsigned long UDP_FPIPE_mgmt_adptr_cmnd_timeout; + unsigned long UDP_FPIPE_mgmt_adptr_send_passed; + unsigned long UDP_FPIPE_mgmt_adptr_send_failed; + unsigned long UDP_FPIPE_mgmt_not_passed_to_stack; + unsigned long UDP_FPIPE_mgmt_passed_to_stack; + unsigned long UDP_FPIPE_mgmt_no_socket; + unsigned long UDP_DRVSTATS_mgmt_kmalloc_err; + unsigned long UDP_DRVSTATS_mgmt_adptr_cmnd_OK; + unsigned long UDP_DRVSTATS_mgmt_adptr_cmnd_timeout; + unsigned long UDP_DRVSTATS_mgmt_adptr_send_passed; + unsigned long UDP_DRVSTATS_mgmt_adptr_send_failed; + unsigned long UDP_DRVSTATS_mgmt_not_passed_to_stack; + unsigned long UDP_DRVSTATS_mgmt_passed_to_stack; + unsigned long UDP_DRVSTATS_mgmt_no_socket; +} drvstats_gen_t; + +typedef struct { + unsigned char attr PACKED; + unsigned short time_stamp PACKED; + unsigned char reserved[13] PACKED; +} api_rx_hdr_t; + +typedef struct { + api_rx_hdr_t api_rx_hdr PACKED; + void * data PACKED; +} api_rx_element_t; + +typedef struct { + unsigned char attr PACKED; + unsigned char reserved[15] PACKED; +} api_tx_hdr_t; + +typedef struct { + api_tx_hdr_t api_tx_hdr PACKED; + void * data PACKED; +} api_tx_element_t; #ifdef _MSC_ # pragma pack() diff -ur --new-file old/linux/include/linux/sdla_ppp.h new/linux/include/linux/sdla_ppp.h --- old/linux/include/linux/sdla_ppp.h Sun Feb 2 14:18:47 1997 +++ new/linux/include/linux/sdla_ppp.h Wed Jan 26 22:25:58 2000 @@ -19,38 +19,25 @@ /*---------------------------------------------------------------------------- * Notes: * ------ - * 1. All structures defined in this file are byte-alined. To ensure - * portability of this code between different platforms and compilers, one - * of the following defines must be defined before including this file: + * 1. All structures defined in this file are byte-alined. * - * Compiler Platform Define Use option - * -------- -------- ------ ---------- - * GNU C Linux _GNUC_ - - * Microsoft C DOS/Windows _MSC_ - + * Compiler Platform + * -------- -------- + * GNU C Linux */ -#ifdef _GNUC_ -# ifndef PACKED +#ifndef PACKED # define PACKED __attribute__((packed)) -# endif /* PACKED */ -#else -# define PACKED -#endif -#ifdef _MSC_ -# pragma pack(1) -#endif +#endif /* PACKED */ /* Adapter memory layout and important constants */ - -#define PPP502_MB_VECT 0xA000 /* mailbox window vector */ -#define PPP502_MB_OFFS 0x1C00 /* mailbox offset */ -#define PPP502_FLG_OFFS 0 /* status flags offset */ -#define PPP502_BUF_OFFS 0x0010 /* buffer info block offset */ - #define PPP508_MB_VECT 0xE000 /* mailbox window vector */ -#define PPP508_MB_OFFS 0 /* mailbox offset */ +#define PPP508_MB_OFFS 0 /* mailbox offset */ #define PPP508_FLG_OFFS 0x1000 /* status flags offset */ #define PPP508_BUF_OFFS 0x1100 /* buffer info block offset */ +#define PPP514_MB_OFFS 0xE000 /* mailbox offset */ +#define PPP514_FLG_OFFS 0xF000 /* status flags offset */ +#define PPP514_BUF_OFFS 0xF100 /* buffer info block offset */ #define PPP_MAX_DATA 1008 /* command block data buffer length */ @@ -59,14 +46,46 @@ /*---------------------------------------------------------------------------- * PPP Command Block. */ -typedef struct ppp_cmd -{ +typedef struct ppp_cmd{ unsigned char command PACKED; /* command code */ unsigned short length PACKED; /* length of data buffer */ unsigned char result PACKED; /* return code */ unsigned char rsrv[11] PACKED; /* reserved for future use */ } ppp_cmd_t; +typedef struct cblock{ + unsigned char opp_flag PACKED; + unsigned char command PACKED; /* command code */ + unsigned short length PACKED; /* length of data buffer */ + unsigned char result PACKED; /* return code */ + unsigned char rsrv[11] PACKED; /* reserved for future use */ +} cblock_t; + +typedef struct ppp_udp_pkt{ + ip_pkt_t ip_pkt PACKED; + udp_pkt_t udp_pkt PACKED; + wp_mgmt_t wp_mgmt PACKED; + cblock_t cblock PACKED; + unsigned char data[MAX_LGTH_UDP_MGNT_PKT] PACKED; +} ppp_udp_pkt_t; + +typedef struct { + unsigned char status PACKED; + unsigned char data_avail PACKED; + unsigned short real_length PACKED; + unsigned short time_stamp PACKED; + unsigned char data[1] PACKED; +} trace_pkt_t; + + +typedef struct { + unsigned char opp_flag PACKED; + unsigned char trace_type PACKED; + unsigned short trace_length PACKED; + unsigned short trace_data_ptr PACKED; + unsigned short trace_time_stamp PACKED; +} trace_element_t; + /* 'command' field defines */ #define PPP_READ_CODE_VERSION 0x10 /* configuration commands */ #define PPP_SET_CONFIG 0x05 @@ -145,26 +164,46 @@ #define PPP_INTR_DISC 0x10 /* data link disconnected */ #define PPP_INTR_OPEN 0x20 /* data link open */ #define PPP_INTR_DROP_DTR 0x40 /* DTR drop timeout expired */ +#define PPP_INTR_TIMER 0x80 /* timer interrupt */ + /* 'mstatus' defines */ #define PPP_MDM_DCD 0x08 /* mdm_status: DCD */ #define PPP_MDM_CTS 0x20 /* mdm_status: CTS */ -/*---------------------------------------------------------------------------- - * PPP Buffer Info. - * This structure is located at offset PPP502_BUF_OFFS into - * PPP502_MB_VECT. - */ -typedef struct ppp502_buf_info -{ - unsigned short txb_num PACKED; /* 00: number of transmit buffers */ - unsigned short txb_offs PACKED; /* 02: offset of the buffer ctl. */ - unsigned char rsrv1[4] PACKED; - unsigned short rxb_num PACKED; /* 08: number of receive buffers */ - unsigned short rxb_offs PACKED; /* 0A: offset of the buffer ctl. */ - unsigned char rsrv2[2] PACKED; - unsigned short rxb_next PACKED; /* 0E: index of the next buffer */ -} ppp502_buf_info_t; +/* 'disc_cause' defines */ +#define PPP_LOCAL_TERMINATION 0x0001 /* Local Request by PPP termination phase */ +#define PPP_DCD_CTS_DROP 0x0002 /* DCD and/or CTS dropped. Link down */ +#define PPP_REMOTE_TERMINATION 0x0800 /* Remote Request by PPP termination phase */ + +/* 'misc_config_bits' defines */ +#define DONT_RE_TX_ABORTED_I_FRAMES 0x01 +#define TX_FRM_BYTE_COUNT_STATS 0x02 +#define RX_FRM_BYTE_COUNT_STATS 0x04 +#define TIME_STAMP_IN_RX_FRAMES 0x08 +#define NON_STD_ADPTR_FREQ 0x10 +#define INTERFACE_LEVEL_RS232 0x20 +#define AUTO_LINK_RECOVERY 0x100 +#define DONT_TERMINATE_LNK_MAX_CONFIG 0x200 + +/* 'authentication options' defines */ +#define NO_AUTHENTICATION 0x00 +#define INBOUND_AUTH 0x80 +#define PAP_AUTH 0x01 +#define CHAP_AUTH 0x02 + +/* 'ip options' defines */ +#define L_AND_R_IP_NO_ASSIG 0x00 +#define L_IP_LOCAL_ASSIG 0x01 +#define L_IP_REMOTE_ASSIG 0x02 +#define R_IP_LOCAL_ASSIG 0x04 +#define R_IP_REMOTE_ASSIG 0x08 +#define ENABLE_IP 0x80 + +/* 'ipx options' defines */ +#define ROUTING_PROT_DEFAULT 0x20 +#define ENABLE_IPX 0x80 +#define DISABLE_IPX 0x00 /*---------------------------------------------------------------------------- * PPP Buffer Info. @@ -203,37 +242,6 @@ } ppp_buf_ctl_t; /*---------------------------------------------------------------------------- - * S502 Adapter Configuration Block (passed to the PPP_SET_CONFIG command). - */ -typedef struct ppp502_conf -{ - unsigned char line_speed PACKED; /* 00: 0 - external clk. */ - unsigned short txbuf_num PACKED; /* 01: number of Tx buffers */ - unsigned short conf_flags PACKED; /* 03: configuration bits */ - unsigned short mtu_local PACKED; /* 05: local MTU */ - unsigned short mtu_remote PACKED; /* 07: remote MTU */ - unsigned short restart_tmr PACKED; /* 09: restart timer */ - unsigned short auth_rsrt_tmr PACKED; /* 0B: authentication timer */ - unsigned short auth_wait_tmr PACKED; /* 0D: authentication timer */ - unsigned short mdm_fail_tmr PACKED; /* 0F: modem failure timer */ - unsigned short dtr_drop_tmr PACKED; /* 11: DTR drop timer */ - unsigned short connect_tmout PACKED; /* 13: connection timeout */ - unsigned short conf_retry PACKED; /* 15: max. retry */ - unsigned short term_retry PACKED; /* 17: max. retry */ - unsigned short fail_retry PACKED; /* 19: max. retry */ - unsigned short auth_retry PACKED; /* 1B: max. retry */ - unsigned char auth_options PACKED; /* 1D: authentication opt. */ - unsigned char ip_options PACKED; /* 1E: IP options */ - unsigned char ip_local[4] PACKED; /* 1F: local IP address */ - unsigned char ip_remote[4] PACKED; /* 23: remote IP address */ - unsigned char ipx_options PACKED; /* 27: IPX options */ - unsigned char ipx_netno[4] PACKED; /* 28: IPX net number */ - unsigned char ipx_local[6] PACKED; /* 2C: local IPX node number*/ - unsigned char ipx_remote[6] PACKED; /* 32: remote IPX node num.*/ - unsigned char ipx_router[48] PACKED; /* 38: IPX router name*/ -} ppp502_conf_t; - -/*---------------------------------------------------------------------------- * S508 Adapter Configuration Block (passed to the PPP_SET_CONFIG command). */ typedef struct ppp508_conf @@ -255,8 +263,8 @@ unsigned short auth_retry PACKED; /* 1E: max. retry */ unsigned char auth_options PACKED; /* 20: authentication opt. */ unsigned char ip_options PACKED; /* 21: IP options */ - unsigned char ip_local[4] PACKED; /* 22: local IP address */ - unsigned char ip_remote[4] PACKED; /* 26: remote IP address */ + unsigned long ip_local PACKED; /* 22: local IP address */ + unsigned long ip_remote PACKED; /* 26: remote IP address */ unsigned char ipx_options PACKED; /* 2A: IPX options */ unsigned char ipx_netno[4] PACKED; /* 2B: IPX net number */ unsigned char ipx_local[6] PACKED; /* 2F: local IPX node number*/ @@ -265,6 +273,25 @@ unsigned long alt_cpu_clock PACKED; /* 6B: */ } ppp508_conf_t; +/*---------------------------------------------------------------------------- + * S508 Adapter Read Connection Information Block + * Returned by the PPP_GET_CONNECTION_INFO command + */ +typedef struct ppp508_connect_info +{ + unsigned short mru PACKED; /* 00-01 Remote Max Rec' Unit */ + unsigned char ip_options PACKED; /* 02: Negotiated ip options */ + unsigned long ip_local PACKED; /* 03-06: local IP address */ + unsigned long ip_remote PACKED; /* 07-0A: remote IP address */ + unsigned char ipx_options PACKED; /* 0B: Negotiated ipx options */ + unsigned char ipx_netno[4] PACKED; /* 0C-0F: IPX net number */ + unsigned char ipx_local[6] PACKED; /* 10-1F: local IPX node # */ + unsigned char ipx_remote[6] PACKED; /* 16-1B: remote IPX node # */ + unsigned char ipx_router[48] PACKED; /* 1C-4B: IPX router name */ + unsigned char auth_status PACKED; /* 4C: Authentication Status */ + unsigned char inbd_auth_peerID[1] PACKED; /* 4D: variable length inbound authenticated peer ID */ +} ppp508_connect_info_t; + /* 'line_speed' field */ #define PPP_BITRATE_1200 0x01 #define PPP_BITRATE_2400 0x02 @@ -303,16 +330,6 @@ #define PPP_IPX_ENABLE 0x80 /*---------------------------------------------------------------------------- - * S502 Adapter Configuration Block (returned by the PPP_READ_CONFIG command). - */ -typedef struct ppp502_get_conf -{ - ppp502_conf_t conf PACKED; /* 00: requested config. */ - unsigned short txb_num PACKED; /* 68: number of Tx buffers */ - unsigned short rxb_num PACKED; /* 6A: number of Rx buffers */ -} ppp502_get_conf_t; - -/*---------------------------------------------------------------------------- * S508 Adapter Configuration Block (returned by the PPP_READ_CONFIG command). */ typedef struct ppp508_get_conf @@ -324,20 +341,6 @@ } ppp508_get_conf_t; /*---------------------------------------------------------------------------- - * S502 Operational Statistics (returned by the PPP_READ_STATISTIC command). - */ -typedef struct ppp502_Stats -{ - unsigned short rx_lost_intr PACKED; /* 00: */ - unsigned short rx_lost_buff PACKED; /* 02: */ - unsigned short tx_abort PACKED; /* 04: */ - unsigned long tx_frames PACKED; /* 06: */ - unsigned long tx_bytes PACKED; /* 0A: */ - unsigned long rx_frames PACKED; /* 0E: */ - unsigned long rx_bytes PACKED; /* 12: */ -} ppp502_Stats_t; - -/*---------------------------------------------------------------------------- * S508 Operational Statistics (returned by the PPP_READ_STATISTIC command). */ typedef struct ppp508_stats @@ -529,6 +532,40 @@ unsigned char auth_status PACKED; /* 4C: */ unsigned char peer_id[0] PACKED; /* 4D: */ } ppp_conn_info_t; + +/* Data structure for SET_TRIGGER_INTR command + */ + +typedef struct ppp_intr_info{ + unsigned char i_enable PACKED; /* 0 Interrupt enable bits */ + unsigned char irq PACKED; /* 1 Irq number */ + unsigned short timer_len PACKED; /* 2 Timer delay */ +} ppp_intr_info_t; + + +#define FT1_MONITOR_STATUS_CTRL 0x80 +#define SET_FT1_MODE 0x81 + + + +/* Special UDP drivers management commands */ +#define PPIPE_ENABLE_TRACING 0x20 +#define PPIPE_DISABLE_TRACING 0x21 +#define PPIPE_GET_TRACE_INFO 0x22 +#define PPIPE_GET_IBA_DATA 0x23 +#define PPIPE_KILL_BOARD 0x24 +#define PPIPE_FT1_READ_STATUS 0x25 +#define PPIPE_DRIVER_STAT_IFSEND 0x26 +#define PPIPE_DRIVER_STAT_INTR 0x27 +#define PPIPE_DRIVER_STAT_GEN 0x28 +#define PPIPE_FLUSH_DRIVER_STATS 0x29 +#define PPIPE_ROUTER_UP_TIME 0x30 + +#define DISABLE_TRACING 0x00 +#define TRACE_SIGNALLING_FRAMES 0x01 +#define TRACE_DATA_FRAMES 0x02 + + #ifdef _MSC_ # pragma pack() diff -ur --new-file old/linux/include/linux/sdladrv.h new/linux/include/linux/sdladrv.h --- old/linux/include/linux/sdladrv.h Fri Oct 9 20:56:59 1998 +++ new/linux/include/linux/sdladrv.h Wed Jan 26 22:25:58 2000 @@ -1,15 +1,16 @@ /***************************************************************************** * sdladrv.h SDLA Support Module. Kernel API Definitions. * -* Author: Gene Kozin +* Author: Gideon Hack * -* Copyright: (c) 1995-1996 Sangoma Technologies Inc. +* Copyright: (c) 1995-1999 Sangoma Technologies 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. * ============================================================================ +* Jun 02, 1999 Gideon Hack Added support for the S514 PCI adapter. * Dec 11, 1996 Gene Kozin Complete overhaul. * Oct 17, 1996 Gene Kozin Minor bug fixes. * Jun 12, 1996 Gene Kozin Added support for S503 card. @@ -18,6 +19,11 @@ #ifndef _SDLADRV_H #define _SDLADRV_H +#include +#if LINUX_VERSION_CODE >= 0x020100 +#define LINUX_2_1 +#endif + #define SDLA_MAXIORANGE 4 /* maximum I/O port range */ #define SDLA_WINDOWSIZE 0x2000 /* default dual-port memory window size */ @@ -33,6 +39,14 @@ unsigned fwid; /* firmware ID */ unsigned port; /* adapter I/O port base */ int irq; /* interrupt request level */ + char S514_cpu_no[1]; /* PCI CPU Number */ + unsigned char S514_slot_no; /* PCI Slot Number */ +#ifdef LINUX_2_1 + struct pci_dev *pci_dev; /* PCI device */ +#else + unsigned char pci_bus; /* PCI bus number */ + unsigned char pci_dev_func; /* PCI device/function number */ +#endif void * dpmbase; /* dual-port memory base */ unsigned dpmsize; /* dual-port memory size */ unsigned pclk; /* CPU clock rate, kHz */ @@ -50,6 +64,8 @@ extern int sdla_inten (sdlahw_t* hw); extern int sdla_intde (sdlahw_t* hw); extern int sdla_intack (sdlahw_t* hw); +extern void S514_intack (sdlahw_t* hw, u32 int_status); +extern void read_S514_int_stat (sdlahw_t* hw, u32* int_status); extern int sdla_intr (sdlahw_t* hw); extern int sdla_mapmem (sdlahw_t* hw, unsigned long addr); extern int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf, diff -ur --new-file old/linux/include/linux/sdlapci.h new/linux/include/linux/sdlapci.h --- old/linux/include/linux/sdlapci.h Thu Jan 1 01:00:00 1970 +++ new/linux/include/linux/sdlapci.h Wed Jan 26 22:25:58 2000 @@ -0,0 +1,68 @@ +/***************************************************************************** +* sdlapci.h WANPIPE(tm) Multiprotocol WAN Link Driver. +* Definitions for the SDLA PCI adapter. +* +* Author: Gideon Hack +* +* Copyright: (c) 1999 Sangoma Technologies 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. +* ============================================================================ +* Jun 02, 1999 Gideon Hack Initial version. +*****************************************************************************/ +#ifndef _SDLAPCI_H +#define _SDLAPCI_H + +/****** Defines *************************************************************/ + +/* Definitions for identifying and finding S514 PCI adapters */ +#define V3_VENDOR_ID 0x11B0 /* V3 vendor ID number */ +#define V3_DEVICE_ID 0x0002 /* V3 device ID number */ +#define SANGOMA_SUBSYS_VENDOR 0x4753 /* ID for Sangoma */ +#define PCI_DEV_SLOT_MASK 0x1F /* mask for slot numbering */ +#define PCI_IRQ_NOT_ALLOCATED 0xFF /* interrupt line for no IRQ */ + +/* Local PCI register offsets */ +#define PCI_VENDOR_ID_WORD 0x00 /* vendor ID */ +#define PCI_IO_BASE_DWORD 0x10 /* IO base */ +#define PCI_MEM_BASE0_DWORD 0x14 /* memory base - apperture 0 */ +#define PCI_MEM_BASE1_DWORD 0x18 /* memory base - apperture 1 */ +#define PCI_SUBSYS_VENDOR_WORD 0x2C /* subsystem vendor ID */ +#define PCI_INT_LINE_BYTE 0x3C /* interrupt line */ +#define PCI_INT_PIN_BYTE 0x3D /* interrupt pin */ +#define PCI_MAP0_DWORD 0x40 /* PCI to local bus address 0 */ +#define PCI_MAP1_DWORD 0x44 /* PCI to local bus address 1 */ +#define PCI_INT_STATUS 0x48 /* interrupt status */ +#define PCI_INT_CONFIG 0x4C /* interrupt configuration */ + +/* Local PCI register usage */ +#define PCI_MEMORY_ENABLE 0x00000003 /* enable PCI memory */ +#define PCI_CPU_A_MEM_DISABLE 0x00000002 /* disable CPU A memory */ +#define PCI_CPU_B_MEM_DISABLE 0x00100002 /* disable CPU B memory */ +#define PCI_ENABLE_IRQ_CPU_A 0x005A0004 /* enable IRQ for CPU A */ +#define PCI_ENABLE_IRQ_CPU_B 0x005A0008 /* enable IRQ for CPU B */ +#define PCI_DISABLE_IRQ_CPU_A 0x00000004 /* disable IRQ for CPU A */ +#define PCI_DISABLE_IRQ_CPU_B 0x00000008 /* disable IRQ for CPU B */ + +/* Setting for the Interrupt Status register */ +#define IRQ_CPU_A 0x04 /* IRQ for CPU A */ +#define IRQ_CPU_B 0x08 /* IRQ for CPU B */ + +/* The maximum size of the S514 memory */ +#define MAX_SIZEOF_S514_MEMORY (256 * 1024) + +/* S514 control register offsets within the memory address space */ +#define S514_CTRL_REG_BYTE 0x80000 + +/* S514 adapter control bytes */ +#define S514_CPU_HALT 0x00 +#define S514_CPU_START 0x01 + +/* The maximum number of S514 adapters supported */ +#define MAX_S514_CARDS 8 + +#endif /* _SDLAPCI_H */ + diff -ur --new-file old/linux/include/linux/sdlasfm.h new/linux/include/linux/sdlasfm.h --- old/linux/include/linux/sdlasfm.h Sun Feb 2 14:18:47 1997 +++ new/linux/include/linux/sdlasfm.h Wed Jan 26 22:25:58 2000 @@ -2,15 +2,16 @@ * sdlasfm.h WANPIPE(tm) Multiprotocol WAN Link Driver. * Definitions for the SDLA Firmware Module (SFM). * -* Author: Gene Kozin <74604.152@compuserve.com> +* Author: Gideon Hack * -* Copyright: (c) 1995-1996 Sangoma Technologies Inc. +* Copyright: (c) 1995-1999 Sangoma Technologies 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. * ============================================================================ +* Jun 02, 1999 Gideon Hack Added support for the S514 adapter. * Dec 11, 1996 Gene Kozin Cosmetic changes * Apr 16, 1996 Gene Kozin Changed adapter & firmware IDs. Version 2 * Dec 15, 1995 Gene Kozin Structures chaned @@ -36,6 +37,12 @@ #define SDLA_S508 5080 #define SDLA_S507 5070 #define SDLA_S509 5090 +#define SDLA_S514 5140 + +/* S514 PCI adapter CPU numbers */ +#define S514_CPU_A 'A' +#define S514_CPU_B 'B' + /* Firmware identification numbers: * 0 .. 999 Test & Diagnostics @@ -46,6 +53,7 @@ * 5000 .. 5999 X.25 * 6000 .. 6999 Frame Relay * 7000 .. 7999 PPP + * 8000 .. 8999 Cisco HDLC */ #define SFID_CALIB502 200 #define SFID_STRM502 1200 @@ -53,12 +61,16 @@ #define SFID_BSC502 2200 #define SFID_SDLC502 3200 #define SFID_HDLC502 4200 +#define SFID_HDLC508 4800 #define SFID_X25_502 5200 #define SFID_X25_508 5800 #define SFID_FR502 6200 #define SFID_FR508 6800 #define SFID_PPP502 7200 #define SFID_PPP508 7800 +#define SFID_PPP514 7140 +#define SFID_CHDLC508 8800 +#define SFID_CHDLC514 8140 /****** Data Types **********************************************************/ diff -ur --new-file old/linux/include/linux/serial.h new/linux/include/linux/serial.h --- old/linux/include/linux/serial.h Fri Nov 19 20:30:54 1999 +++ new/linux/include/linux/serial.h Fri Jan 28 01:40:09 2000 @@ -38,20 +38,6 @@ #define ASYNC_CLOSING_WAIT_NONE 65535 /* - * The size of the serial xmit buffer is 1 page, or 4096 bytes - */ -#define SERIAL_XMIT_SIZE 4096 - -/* - * Counters of the input lines (CTS, DSR, RI, CD) interrupts - */ -struct async_icount { - __u32 cts, dsr, rng, dcd, tx, rx; - __u32 frame, parity, overrun, brk; - __u32 buf_overrun; -}; - -/* * These are the supported serial types. */ #define PORT_UNKNOWN 0 diff -ur --new-file old/linux/include/linux/serialP.h new/linux/include/linux/serialP.h --- old/linux/include/linux/serialP.h Fri Jan 21 01:06:40 2000 +++ new/linux/include/linux/serialP.h Fri Jan 28 17:02:20 2000 @@ -19,11 +19,18 @@ * For definitions of the flags field, see tty.h */ -#include #include #include #include +/* + * Counters of the input lines (CTS, DSR, RI, CD) interrupts + */ +struct async_icount { + __u32 cts, dsr, rng, dcd, tx, rx; + __u32 frame, parity, overrun, brk; + __u32 buf_overrun; +}; struct serial_state { int magic; @@ -158,7 +165,7 @@ }; struct pci_board_inst { - struct pci_board *board; + struct pci_board board; struct pci_dev *dev; }; @@ -172,7 +179,28 @@ #define SPCI_FL_BASE2 0x0002 #define SPCI_FL_BASE3 0x0003 #define SPCI_FL_BASE4 0x0004 -#define SPCI_FL_IOMEM 0x0008 /* Use I/O mapped memory */ -#define SPCI_FL_BASE_TABLE 0x0010 /* Use base address table for UART */ +#define SPCI_FL_GET_BASE(x) (x & SPCI_FL_BASE_MASK) +#define SPCI_FL_IRQ_MASK (0x0007 << 4) +#define SPCI_FL_IRQBASE0 (0x0000 << 4) +#define SPCI_FL_IRQBASE1 (0x0001 << 4) +#define SPCI_FL_IRQBASE2 (0x0002 << 4) +#define SPCI_FL_IRQBASE3 (0x0003 << 4) +#define SPCI_FL_IRQBASE4 (0x0004 << 4) +#define SPCI_FL_GET_IRQBASE(x) ((x & SPCI_FL_IRQ_MASK) >> 4) + +/* Use sucessiveentries base resource table */ +#define SPCI_FL_BASE_TABLE 0x0100 + +/* Use successive entries in the irq resource table */ +#define SPCI_FL_IRQ_TABLE 0x0200 + +/* Use the irq resource table instead of dev->irq */ +#define SPCI_FL_IRQRESOURCE 0x0400 + +/* Use the Base address register size to cap number of ports */ +#define SPCI_FL_REGION_SZ_CAP 0x0800 + +#define SPCI_FL_PNPDEFAULT (SPCI_FL_IRQRESOURCE) + #endif /* _LINUX_SERIAL_H */ diff -ur --new-file old/linux/include/linux/skbuff.h new/linux/include/linux/skbuff.h --- old/linux/include/linux/skbuff.h Fri Jan 21 01:06:15 2000 +++ new/linux/include/linux/skbuff.h Fri Jan 28 17:01:31 2000 @@ -202,16 +202,25 @@ return (list->next == (struct sk_buff *) list); } +extern __inline__ struct sk_buff *skb_get(struct sk_buff *skb) +{ + atomic_inc(&skb->users); + return skb; +} + +/* If users==1, we are the only owner and are can avoid redundant + * atomic change. + */ extern __inline__ void kfree_skb(struct sk_buff *skb) { - if (atomic_dec_and_test(&skb->users)) + if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users)) __kfree_skb(skb); } /* Use this if you didn't touch the skb state [for fast switching] */ extern __inline__ void kfree_skb_fast(struct sk_buff *skb) { - if (atomic_dec_and_test(&skb->users)) + if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users)) kfree_skbmem(skb); } diff -ur --new-file old/linux/include/linux/slab.h new/linux/include/linux/slab.h --- old/linux/include/linux/slab.h Fri Jan 21 01:05:42 2000 +++ new/linux/include/linux/slab.h Fri Jan 28 17:01:16 2000 @@ -22,7 +22,8 @@ #define SLAB_NFS GFP_NFS #define SLAB_DMA GFP_DMA -#define SLAB_LEVEL_MASK 0x0000007fUL +#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_SWAP| \ + __GFP_HIGHMEM) #define SLAB_NO_GROW 0x00001000UL /* don't grow a cache */ /* flags to pass to kmem_cache_create(). diff -ur --new-file old/linux/include/linux/smp.h new/linux/include/linux/smp.h --- old/linux/include/linux/smp.h Fri Jan 21 01:05:30 2000 +++ new/linux/include/linux/smp.h Fri Jan 28 17:01:06 2000 @@ -80,6 +80,7 @@ #define smp_threads_ready 1 #define kernel_lock() #define cpu_logical_map(cpu) 0 +#define cpu_number_map(cpu) 0 #define smp_call_function(func,info,retry,wait) ({ 0; }) #endif diff -ur --new-file old/linux/include/linux/sockios.h new/linux/include/linux/sockios.h --- old/linux/include/linux/sockios.h Fri Aug 28 04:33:08 1998 +++ new/linux/include/linux/sockios.h Sat Jan 22 20:54:57 2000 @@ -20,6 +20,10 @@ #include +/* Linux-specific socket ioctls */ +#define SIOCINQ FIONREAD +#define SIOCOUTQ TIOCOUTQ + /* Routing table calls. */ #define SIOCADDRT 0x890B /* add routing table entry */ #define SIOCDELRT 0x890C /* delete routing table entry */ diff -ur --new-file old/linux/include/linux/sysctl.h new/linux/include/linux/sysctl.h --- old/linux/include/linux/sysctl.h Tue Jan 11 03:15:58 2000 +++ new/linux/include/linux/sysctl.h Sat Jan 22 20:54:57 2000 @@ -251,7 +251,12 @@ NET_IPV4_INET_PEER_MINTTL=70, NET_IPV4_INET_PEER_MAXTTL=71, NET_IPV4_INET_PEER_GC_MINTIME=72, - NET_IPV4_INET_PEER_GC_MAXTIME=73 + NET_IPV4_INET_PEER_GC_MAXTIME=73, + NET_TCP_ORPHAN_RETRIES=74, + NET_TCP_ABORT_ON_OVERFLOW=75, + NET_TCP_SYNACK_RETRIES=76, + NET_TCP_MAX_ORPHANS=77, + NET_TCP_MAX_TW_BUCKETS=78, }; enum { diff -ur --new-file old/linux/include/linux/tcp.h new/linux/include/linux/tcp.h --- old/linux/include/linux/tcp.h Fri Jan 21 01:06:15 2000 +++ new/linux/include/linux/tcp.h Fri Jan 28 17:01:51 2000 @@ -124,5 +124,6 @@ #define TCP_SYNCNT 7 /* Number of SYN retransmits */ #define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */ #define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */ +#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */ #endif /* _LINUX_TCP_H */ diff -ur --new-file old/linux/include/linux/udf_fs.h new/linux/include/linux/udf_fs.h --- old/linux/include/linux/udf_fs.h Fri Nov 19 20:35:10 1999 +++ new/linux/include/linux/udf_fs.h Tue Jan 25 20:19:04 2000 @@ -1,7 +1,17 @@ /* * udf_fs.h * - * Included by fs/filesystems.c + * PURPOSE + * Included by fs/filesystems.c + * + * DESCRIPTION + * OSTA-UDF(tm) = Optical Storage Technology Association + * Universal Disk Format. + * + * This code is based on version 2.00 of the UDF specification, + * and revision 3 of the ECMA 167 standard [equivalent to ISO 13346]. + * http://www.osta.org/ * http://www.ecma.ch/ + * http://www.iso.org/ * * CONTACTS * E-mail regarding any portion of the Linux UDF file system should be @@ -14,15 +24,17 @@ * ftp://prep.ai.mit.edu/pub/gnu/GPL * Each contributing author retains all rights to their own work. * + * (C) 1999-2000 Ben Fennema + * (C) 1999-2000 Stelias Computing Inc + * * HISTORY - * July 21, 1997 - Andrew E. Mileski - * Written, tested, and released. * - * 10/2/98 dgb rearranged all headers - * 11/26/98 bf added byte order macros - * 12/5/98 dgb removed other includes to reduce kernel namespace pollution. + * 10/02/98 dgb rearranged all headers + * 11/26/98 blf added byte order macros + * 12/05/98 dgb removed other includes to reduce kernel namespace pollution. * This should only be included by the kernel now! */ + #if !defined(_LINUX_UDF_FS_H) #define _LINUX_UDF_FS_H @@ -30,8 +42,8 @@ #define UDF_DEFAULT_PREALLOC_BLOCKS 8 #define UDF_DEFAULT_PREALLOC_DIR_BLOCKS 0 -#define UDFFS_DATE "99/11/18" -#define UDFFS_VERSION "0.8.9.4" +#define UDFFS_DATE "2000/01/17" +#define UDFFS_VERSION "0.9.0" #define UDFFS_DEBUG #ifdef UDFFS_DEBUG @@ -47,15 +59,6 @@ #define udf_info(f, a...) \ printk (KERN_INFO "UDF-fs INFO " ## f, ## a); - -struct udf_addr -{ - __u32 block; - __u16 partition; - unsigned error : 1; - unsigned reserved : 15; -}; - /* Prototype for fs/filesystem.c (the only thing really required in this file) */ extern int init_udf_fs(void); diff -ur --new-file old/linux/include/linux/udf_fs_i.h new/linux/include/linux/udf_fs_i.h --- old/linux/include/linux/udf_fs_i.h Sat Sep 4 21:42:30 1999 +++ new/linux/include/linux/udf_fs_i.h Tue Jan 25 20:19:04 2000 @@ -34,10 +34,7 @@ long i_umtime; long i_uctime; /* Physical address of inode */ - lb_addr i_ext0Location; /* partition relative */ lb_addr i_location; - __u32 i_ext0Length; /* in blocks */ - __u32 i_ext0Offset; /* for short directories */ __u64 i_unique; __u32 i_lenEAttr; __u32 i_lenAlloc; diff -ur --new-file old/linux/include/linux/udf_fs_sb.h new/linux/include/linux/udf_fs_sb.h --- old/linux/include/linux/udf_fs_sb.h Sat Sep 4 21:42:30 1999 +++ new/linux/include/linux/udf_fs_sb.h Tue Jan 25 20:19:04 2000 @@ -29,14 +29,22 @@ struct udf_sparing_data { - __u32 s_spar_loc; - __u16 s_spar_plen; + __u32 s_spar_loc[4]; + __u8 s_spar_pshift; + __u8 s_spar_indexsize; + __u32 *s_spar_map; + union + { + __u8 *s_spar_remap8; + __u16 *s_spar_remap16; + __u32 *s_spar_remap32; + } s_spar_remap; }; struct udf_virtual_data { - __u32 s_num_entries; - __u16 s_start_offset; + __u32 s_num_entries; + __u16 s_start_offset; }; struct udf_part_map @@ -51,6 +59,7 @@ struct udf_sparing_data s_sparing; struct udf_virtual_data s_virtual; } s_type_specific; + __u32 (*s_partition_func)(struct super_block *, __u32, __u16, __u32); __u16 s_volumeseqnum; }; @@ -72,8 +81,6 @@ struct buffer_head *s_lvidbh; - lb_addr s_location; - __u16 s_loaded_block_bitmaps; __u32 s_block_bitmap_number[UDF_MAX_BLOCK_LOADED]; struct buffer_head *s_block_bitmap[UDF_MAX_BLOCK_LOADED]; @@ -89,20 +96,11 @@ /* Fileset Info */ __u16 s_serialnum; - /* Character Mapping Info */ - struct nls_table *s_nls_iocharset; - __u8 s_utf8; - /* Miscellaneous flags */ __u32 s_flags; /* VAT inode */ struct inode *s_vat; - -#if LINUX_VERSION_CODE < 0x020206 - int s_rename_lock; - struct wait_queue * s_rename_wait; -#endif }; #endif /* !defined(_LINUX_UDF_FS_SB_H) */ diff -ur --new-file old/linux/include/linux/udf_udf.h new/linux/include/linux/udf_udf.h --- old/linux/include/linux/udf_udf.h Sat Sep 4 21:42:30 1999 +++ new/linux/include/linux/udf_udf.h Tue Jan 25 20:19:04 2000 @@ -101,8 +101,7 @@ Uint8 numSparingTables; Uint8 reserved2[1]; /* #00 */ Uint32 sizeSparingTable; - Uint32 locSparingTable[0]; - Uint8 pad[0]; + Uint32 locSparingTable[4]; }; /* DVD Copyright Management Info, see UDF 1.02 3.3.4.5.1.2 */ diff -ur --new-file old/linux/include/linux/utsname.h new/linux/include/linux/utsname.h --- old/linux/include/linux/utsname.h Sat Jun 13 20:45:09 1998 +++ new/linux/include/linux/utsname.h Thu Jan 27 15:32:14 2000 @@ -32,5 +32,5 @@ extern struct new_utsname system_utsname; -extern struct semaphore uts_sem; +extern struct rw_semaphore uts_sem; #endif diff -ur --new-file old/linux/include/linux/videodev.h new/linux/include/linux/videodev.h --- old/linux/include/linux/videodev.h Thu Dec 30 02:08:55 1999 +++ new/linux/include/linux/videodev.h Wed Jan 26 22:29:39 2000 @@ -370,6 +370,7 @@ #define VID_HARDWARE_CPIA 24 #define VID_HARDWARE_ZR36120 25 /* Zoran ZR36120/ZR36125 */ #define VID_HARDWARE_ZR36067 26 /* Zoran ZR36067/36060 */ +#define VID_HARDWARE_OV511 27 /* * Initialiser list diff -ur --new-file old/linux/include/linux/wanpipe.h new/linux/include/linux/wanpipe.h --- old/linux/include/linux/wanpipe.h Wed Aug 18 20:38:47 1999 +++ new/linux/include/linux/wanpipe.h Wed Jan 26 22:25:58 2000 @@ -2,16 +2,23 @@ * wanpipe.h WANPIPE(tm) Multiprotocol WAN Link Driver. * User-level API definitions. * -* Author: Gene Kozin -* Jaspreet Singh +* Author: Nenad Corbic +* Gideon Hack * -* Copyright: (c) 1995-1997 Sangoma Technologies Inc. +* Copyright: (c) 1995-1999 Sangoma Technologies 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. * ============================================================================ +* Oct 04, 1999 Nenad Corbic New CHDLC and FRAME RELAY code, SMP support +* Jun 02, 1999 Gideon Hack Added 'update_call_count' for Cisco HDLC +* support +* Jun 26, 1998 David Fong Added 'ip_mode' in sdla_t.u.p for dynamic IP +* routing mode configuration +* Jun 12, 1998 David Fong Added Cisco HDLC union member in sdla_t +* Dec 08, 1997 Jaspreet Singh Added 'authenticator' in union of 'sdla_t' * Nov 26, 1997 Jaspreet Singh Added 'load_sharing' structure. Also added * 'devs_struct','dev_to_devtint_next' to 'sdla_t' * Nov 24, 1997 Jaspreet Singh Added 'irq_dis_if_send_count', @@ -28,6 +35,10 @@ #ifndef _WANPIPE_H #define _WANPIPE_H +#ifdef __SMP__ +#include /* Support for SMP Locking */ +#endif + #include /* Defines */ @@ -42,6 +53,16 @@ #define WANPIPE_DUMP (ROUTER_USER+0) /* dump adapter's memory */ #define WANPIPE_EXEC (ROUTER_USER+1) /* execute firmware command */ +#define TRACE_ALL 0x00 +#define TRACE_PROT 0x01 +#define TRACE_DATA 0x02 + +/* values for request/reply byte */ +#define UDPMGMT_REQUEST 0x01 +#define UDPMGMT_REPLY 0x02 +#define UDP_OFFSET 12 + + /* * Data structures for IOCTL calls. */ @@ -97,16 +118,86 @@ } global_stats_t; -/* This structure is used for maitaining a circular linked list of all - * interfaces(devices) per card. It is used in the Interrupt Service routine - * for a transmit interrupt where the start of the loop to dev_tint all - * interfaces changes. - */ -typedef struct load_sharing -{ - struct net_device* dev_ptr; - struct load_sharing* next; -} load_sharing_t; + +typedef struct{ + unsigned short udp_src_port PACKED; + unsigned short udp_dst_port PACKED; + unsigned short udp_length PACKED; + unsigned short udp_checksum PACKED; +} udp_pkt_t; + + +typedef struct { + unsigned char ver_inet_hdr_length PACKED; + unsigned char service_type PACKED; + unsigned short total_length PACKED; + unsigned short identifier PACKED; + unsigned short flags_frag_offset PACKED; + unsigned char ttl PACKED; + unsigned char protocol PACKED; + unsigned short hdr_checksum PACKED; + unsigned long ip_src_address PACKED; + unsigned long ip_dst_address PACKED; +} ip_pkt_t; + + +typedef struct { + unsigned char signature[8] PACKED; + unsigned char request_reply PACKED; + unsigned char id PACKED; + unsigned char reserved[6] PACKED; +} wp_mgmt_t; + +/************************************************************************* + Data Structure for if_send statistics +*************************************************************************/ +typedef struct if_send_stat{ + unsigned long if_send_entry; + unsigned long if_send_skb_null; + unsigned long if_send_broadcast; + unsigned long if_send_multicast; + unsigned long if_send_critical_ISR; + unsigned long if_send_critical_non_ISR; + unsigned long if_send_tbusy; + unsigned long if_send_tbusy_timeout; + unsigned long if_send_PIPE_request; + unsigned long if_send_wan_disconnected; + unsigned long if_send_dlci_disconnected; + unsigned long if_send_no_bfrs; + unsigned long if_send_adptr_bfrs_full; + unsigned long if_send_bfr_passed_to_adptr; + unsigned long if_send_protocol_error; + unsigned long if_send_bfr_not_passed_to_adptr; + unsigned long if_send_tx_int_enabled; + unsigned long if_send_consec_send_fail; +} if_send_stat_t; + +typedef struct rx_intr_stat{ + unsigned long rx_intr_no_socket; + unsigned long rx_intr_dev_not_started; + unsigned long rx_intr_PIPE_request; + unsigned long rx_intr_bfr_not_passed_to_stack; + unsigned long rx_intr_bfr_passed_to_stack; +} rx_intr_stat_t; + +typedef struct pipe_mgmt_stat{ + unsigned long UDP_PIPE_mgmt_kmalloc_err; + unsigned long UDP_PIPE_mgmt_direction_err; + unsigned long UDP_PIPE_mgmt_adptr_type_err; + unsigned long UDP_PIPE_mgmt_adptr_cmnd_OK; + unsigned long UDP_PIPE_mgmt_adptr_cmnd_timeout; + unsigned long UDP_PIPE_mgmt_adptr_send_passed; + unsigned long UDP_PIPE_mgmt_adptr_send_failed; + unsigned long UDP_PIPE_mgmt_not_passed_to_stack; + unsigned long UDP_PIPE_mgmt_passed_to_stack; + unsigned long UDP_PIPE_mgmt_no_socket; + unsigned long UDP_PIPE_mgmt_passed_to_adptr; +} pipe_mgmt_stat_t; + + + +#define MAX_LGTH_UDP_MGNT_PKT 2000 + /* This is used for interrupt testing */ #define INTR_TEST_MODE 0x02 @@ -154,23 +245,23 @@ char in_isr; /* interrupt-in-service flag */ char buff_int_mode_unbusy; /* flag for carrying out dev_tint */ char dlci_int_mode_unbusy; /* flag for carrying out dev_tint */ + char configured; /* flag for previous configurations */ unsigned short irq_dis_if_send_count; /* Disabling irqs in if_send*/ unsigned short irq_dis_poll_count; /* Disabling irqs in poll routine*/ + unsigned short force_enable_irq; + char TracingEnabled; /* flag for enabling trace */ global_stats_t statistics; /* global statistics */ - - /* The following is used as a pointer to the structure in our - circular linked list which changes the start of the loop for - dev_tint of all interfaces */ - - load_sharing_t* dev_to_devtint_next; - load_sharing_t* devs_struct; - +#ifdef __SMP__ + spinlock_t lock; /* Support for SMP Locking */ +#endif void* mbox; /* -> mailbox */ void* rxmb; /* -> receive mailbox */ void* flags; /* -> adapter status flags */ void (*isr)(struct sdla* card); /* interrupt service routine */ void (*poll)(struct sdla* card); /* polling routine */ int (*exec)(struct sdla* card, void* u_cmd, void* u_data); + + struct sdla *next; /* Secondary Port Device: Piggibacking */ union { struct @@ -188,6 +279,19 @@ unsigned rx_top; /* S508 receive buffer end */ unsigned short node_dlci[100]; unsigned short dlci_num; + struct net_device *dlci_to_dev_map[991 + 1]; + unsigned tx_interrupts_pending; + unsigned short timer_int_enabled; + unsigned short udp_pkt_lgth; + int udp_type; + char udp_pkt_src; + unsigned udp_dlci; + char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT]; + void* trc_el_base; /* first trace element */ + void* trc_el_last; /* last trace element */ + void *curr_trc_el; /* current trace element */ + unsigned short trc_bfr_space; /* trace buffer space */ + unsigned char update_comms_stats; } f; struct /****** PPP-specific data ***********/ { @@ -199,7 +303,53 @@ void* rxbuf_last; /* -> last Rx buffer */ unsigned rx_base; /* S508 receive buffer base */ unsigned rx_top; /* S508 receive buffer end */ + char ip_mode; /* STATIC/HOST/PEER IP Mode */ + char authenticator; /* Authenticator for PAP/CHAP */ } p; + struct /* Cisco HDLC-specific data */ + { + char if_name[WAN_IFNAME_SZ+1]; /* interface name */ + unsigned char comm_port;/* Communication Port O or 1 */ + unsigned char usedby; /* Used by WANPIPE or API */ + void* rxmb; /* Receive mail box */ + void* flags; /* flags */ + void* tx_status; /* Tx status element */ + void* rx_status; /* Rx status element */ + void* txbuf; /* -> current Tx buffer */ + void* txbuf_base; /* -> first Tx buffer */ + void* txbuf_last; /* -> last Tx buffer */ + void* rxbuf_base; /* -> first Rx buffer */ + void* rxbuf_last; /* -> last Rx buffer */ + unsigned rx_base; /* S508 receive buffer base */ + unsigned rx_top; /* S508 receive buffer end */ + unsigned short protocol_options; + unsigned short kpalv_tx; /* Tx kpalv timer */ + unsigned short kpalv_rx; /* Rx kpalv timer */ + unsigned short kpalv_err; /* Error tolerance */ + unsigned short slarp_timer; /* SLARP req timer */ + unsigned state; /* state of the link */ + unsigned char api_status; + unsigned char update_call_count; + } c; + struct + { + void* tx_status; /* Tx status element */ + void* rx_status; /* Rx status element */ + void* trace_status; /* Trace status element */ + void* txbuf; /* -> current Tx buffer */ + void* txbuf_base; /* -> first Tx buffer */ + void* txbuf_last; /* -> last Tx buffer */ + void* rxbuf_base; /* -> first Rx buffer */ + void* rxbuf_last; /* -> last Rx buffer */ + void* tracebuf; /* -> current Trace buffer */ + void* tracebuf_base; /* -> current Trace buffer */ + void* tracebuf_last; /* -> current Trace buffer */ + unsigned rx_base; /* receive buffer base */ + unsigned rx_end; /* receive buffer end */ + unsigned trace_base; /* trace buffer base */ + unsigned trace_end; /* trace buffer end */ + + } h; } u; } sdla_t; @@ -212,6 +362,10 @@ int wpx_init (sdla_t* card, wandev_conf_t* conf); /* wpx.c */ int wpf_init (sdla_t* card, wandev_conf_t* conf); /* wpf.c */ int wpp_init (sdla_t* card, wandev_conf_t* conf); /* wpp.c */ +int wpc_init (sdla_t* card, wandev_conf_t* conf); /* Cisco HDLC */ +int bsc_init (sdla_t* card, wandev_conf_t* conf); /* BSC streaming */ +int hdlc_init(sdla_t* card, wandev_conf_t* conf); /* HDLC support */ +int wpft1_init (sdla_t* card, wandev_conf_t* conf); /* FT1 Config support */ #endif /* __KERNEL__ */ #endif /* _WANPIPE_H */ diff -ur --new-file old/linux/include/linux/wanrouter.h new/linux/include/linux/wanrouter.h --- old/linux/include/linux/wanrouter.h Fri Jan 21 01:08:39 2000 +++ new/linux/include/linux/wanrouter.h Fri Jan 28 17:04:15 2000 @@ -1,21 +1,29 @@ /***************************************************************************** -* router.h Definitions for the WAN Multiprotocol Router Module. +* wanrouter.h Definitions for the WAN Multiprotocol Router Module. * This module provides API and common services for WAN Link * Drivers and is completely hardware-independent. * -* Author: Gene Kozin -* Jaspreet Singh +* Author: Nenad Corbic +* Gideon Hack * Additions: Arnaldo Carvalho de Melo * -* Copyright: (c) 1995-1997 Sangoma Technologies Inc. +* Copyright: (c) 1995-1999 Sangoma Technologies 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. * ============================================================================ +* Oct 04, 1999 Nenad Corbic Updated for 2.1.0 release +* Jun 02, 1999 Gideon Hack Added support for the S514 adapter. * May 23, 1999 Arnaldo Melo Added local_addr to wanif_conf_t * WAN_DISCONNECTING state added +* Jul 20, 1998 David Fong Added Inverse ARP options to 'wanif_conf_t' +* Jun 12, 1998 David Fong Added Cisco HDLC support. +* Dec 16, 1997 Jaspreet Singh Moved 'enable_IPX' and 'network_number' to +* 'wanif_conf_t' +* Dec 05, 1997 Jaspreet Singh Added 'pap', 'chap' to 'wanif_conf_t' +* Added 'authenticator' to 'wan_ppp_conf_t' * Nov 06, 1997 Jaspreet Singh Changed Router Driver version to 1.1 from 1.0 * Oct 20, 1997 Jaspreet Singh Added 'cir','bc','be' and 'mc' to 'wanif_conf_t' * Added 'enable_IPX' and 'network_number' to @@ -32,6 +40,12 @@ * Jan 16, 1997 Gene Kozin router_devlist made public * Jan 02, 1997 Gene Kozin Initial version (based on wanpipe.h). *****************************************************************************/ +#include + +#if LINUX_VERSION_CODE >= 0x020100 +#define LINUX_2_1 +#endif + #ifndef _ROUTER_H #define _ROUTER_H @@ -54,6 +68,10 @@ ROUTER_USER_MAX = (ROUTER_IOCTL<<8)+31 }; +/* identifiers for displaying proc file data for dual port adapters */ +#define PROC_DATA_PORT_0 0x8000 /* the data is for port 0 */ +#define PROC_DATA_PORT_1 0x8001 /* the data is for port 1 */ + /* NLPID for packet encapsulation (ISO/IEC TR 9577) */ #define NLPID_IP 0xCC /* Internet Protocol Datagram */ #define NLPID_SNAP 0x80 /* IEEE Subnetwork Access Protocol */ @@ -66,12 +84,14 @@ #define WAN_IFNAME_SZ 15 /* max length of the interface name */ #define WAN_DRVNAME_SZ 15 /* max length of the link driver name */ #define WAN_ADDRESS_SZ 31 /* max length of the WAN media address */ +#define USED_BY_FIELD 8 /* max length of the used by field */ /* Defines for UDP PACKET TYPE */ #define UDP_PTPIPE_TYPE 0x01 #define UDP_FPIPE_TYPE 0x02 -#define UDP_DRVSTATS_TYPE 0x03 -#define UDP_INVALID_TYPE 0x04 +#define UDP_CPIPE_TYPE 0x03 +#define UDP_DRVSTATS_TYPE 0x04 +#define UDP_INVALID_TYPE 0x05 /* Command return code */ #define CMD_OK 0 /* normal firmware return code */ @@ -129,7 +149,7 @@ unsigned n392; /* error threshold counter */ unsigned n393; /* monitored events counter */ unsigned dlci_num; /* number of DLCs (access node) */ - unsigned dlci[100]; /* List of all DLCIs */ + unsigned dlci[100]; /* List of all DLCIs */ } wan_fr_conf_t; /*---------------------------------------------------------------------------- @@ -149,9 +169,27 @@ unsigned auth_retry; /* max. retry */ unsigned auth_options; /* authentication opt. */ unsigned ip_options; /* IP options */ + char authenticator; /* AUTHENTICATOR or not */ + char ip_mode; /* Static/Host/Peer */ } wan_ppp_conf_t; /*---------------------------------------------------------------------------- + * CHDLC-specific link-level configuration. + */ +typedef struct wan_chdlc_conf +{ + unsigned char ignore_dcd; /* Protocol options: */ + unsigned char ignore_cts; /* Ignore these to determine */ + unsigned char ignore_keepalive; /* link status (Yes or No) */ + unsigned char hdlc_streaming; /* hdlc_streaming mode (Y/N) */ + unsigned keepalive_tx_tmr; /* transmit keepalive timer */ + unsigned keepalive_rx_tmr; /* receive keepalive timer */ + unsigned keepalive_err_margin; /* keepalive_error_tolerance */ + unsigned slarp_timer; /* SLARP request timer */ +} wan_chdlc_conf_t; + + +/*---------------------------------------------------------------------------- * WAN device configuration. Passed to ROUTER_SETUP IOCTL. */ typedef struct wandev_conf @@ -164,18 +202,21 @@ unsigned msize; /* dual-port memory size */ int irq; /* interrupt request level */ int dma; /* DMA request level */ + char S514_CPU_no[1]; /* S514 PCI adapter CPU number ('A' or 'B') */ + unsigned PCI_slot_no; /* S514 PCI adapter slot number */ + char comm_port; /* Communication Port (PRI=0, SEC=1) */ unsigned bps; /* data transfer rate */ unsigned mtu; /* maximum transmit unit size */ unsigned udp_port; /* UDP port for management */ unsigned char ttl; /* Time To Live for UDP security */ + unsigned char ft1; /* FT1 Configurator Option */ char interface; /* RS-232/V.35, etc. */ char clocking; /* external/internal */ char line_coding; /* NRZ/NRZI/FM0/FM1, etc. */ char station; /* DTE/DCE, primary/secondary, etc. */ char connection; /* permanent/switched/on-demand */ + char read_mode; /* read mode: Polling or interrupt */ unsigned hw_opt[4]; /* other hardware options */ - unsigned char enable_IPX; /* Enable or Disable IPX */ - unsigned long network_number; /* Network Number for IPX */ unsigned reserved[4]; /****** arbitrary data ***************/ unsigned data_size; /* data buffer size */ @@ -185,6 +226,7 @@ wan_x25_conf_t x25; /* X.25 configuration */ wan_ppp_conf_t ppp; /* PPP configuration */ wan_fr_conf_t fr; /* frame relay configuration */ + wan_chdlc_conf_t chdlc; /* Cisco HDLC configuration */ } u; } wandev_conf_t; @@ -192,6 +234,9 @@ #define WANCONFIG_X25 101 /* X.25 link */ #define WANCONFIG_FR 102 /* frame relay link */ #define WANCONFIG_PPP 103 /* synchronous PPP link */ +#define WANCONFIG_CHDLC 104 /* Cisco HDLC Link */ +#define WANCONFIG_BSC 105 /* BiSync Streaming */ +#define WANCONFIG_HDLC 106 /* HDLC Support */ /* * Configuration options defines. @@ -234,9 +279,29 @@ #define WANOPT_ONDEMAND 2 /* activate DTR only before sending */ /* frame relay in-channel signalling */ -#define WANOPT_FR_ANSI 0 /* ANSI T1.617 Annex D */ -#define WANOPT_FR_Q933 1 /* ITU Q.933A */ -#define WANOPT_FR_LMI 2 /* LMI */ +#define WANOPT_FR_ANSI 1 /* ANSI T1.617 Annex D */ +#define WANOPT_FR_Q933 2 /* ITU Q.933A */ +#define WANOPT_FR_LMI 3 /* LMI */ + +/* PPP IP Mode Options */ +#define WANOPT_PPP_STATIC 0 +#define WANOPT_PPP_HOST 1 +#define WANOPT_PPP_PEER 2 + +/* CHDLC Protocol Options */ +/* DF Commmented out for now. + +#define WANOPT_CHDLC_NO_DCD IGNORE_DCD_FOR_LINK_STAT +#define WANOPT_CHDLC_NO_CTS IGNORE_CTS_FOR_LINK_STAT +#define WANOPT_CHDLC_NO_KEEPALIVE IGNORE_KPALV_FOR_LINK_STAT +*/ + +/* Port options */ +#define WANOPT_PRI 0 +#define WANOPT_SEC 1 +/* read mode */ +#define WANOPT_INTR 0 +#define WANOPT_POLL 1 /*---------------------------------------------------------------------------- * WAN Link Status Info (for ROUTER_STAT IOCTL). @@ -278,8 +343,9 @@ WAN_DISCONNECTED, /* link/channel is disconnected */ WAN_CONNECTING, /* connection is in progress */ WAN_CONNECTED, /* link/channel is operational */ - WAN_DISCONNECTING, /* disconnection is in progress */ - WAN_LIMIT /* for verification only */ + WAN_LIMIT, /* for verification only */ + WAN_DUALPORT, /* for Dual Port cards */ + WAN_DISCONNECTING /* link/channel is disconnecting */ }; /* 'modem_status' masks */ @@ -297,16 +363,38 @@ unsigned config_id; /* configuration identifier */ char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */ char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */ + char usedby[USED_BY_FIELD]; /* used by API or WANPIPE */ unsigned idle_timeout; /* sec, before disconnecting */ unsigned hold_timeout; /* sec, before re-connecting */ unsigned cir; /* Committed Information Rate fwd,bwd*/ unsigned bc; /* Committed Burst Size fwd, bwd */ unsigned be; /* Excess Burst Size fwd, bwd */ + unsigned char enable_IPX; /* Enable or Disable IPX */ + unsigned char inarp; /* Send Inverse ARP requests Y/N */ + unsigned inarp_interval; /* sec, between InARP requests */ + unsigned long network_number; /* Network Number for IPX */ char mc; /* Multicast on or off */ char local_addr[WAN_ADDRESS_SZ+1];/* local media address, ASCIIZ */ unsigned char port; /* board port */ unsigned char protocol; /* prococol used in this channel (TCPOX25 or X25) */ - int reserved[8]; /* reserved for future extensions */ + char pap; /* PAP enabled or disabled */ + char chap; /* CHAP enabled or disabled */ + unsigned char userid[511]; /* List of User Id */ + unsigned char passwd[511]; /* List of passwords */ + unsigned char sysname[31]; /* Name of the system */ + unsigned char ignore_dcd; /* Protocol options: */ + unsigned char ignore_cts; /* Ignore these to determine */ + unsigned char ignore_keepalive; /* link status (Yes or No) */ + unsigned char hdlc_streaming; /* Hdlc streaming mode (Y/N) */ + unsigned keepalive_tx_tmr; /* transmit keepalive timer */ + unsigned keepalive_rx_tmr; /* receive keepalive timer */ + unsigned keepalive_err_margin; /* keepalive_error_tolerance */ + unsigned slarp_timer; /* SLARP request timer */ + unsigned char ttl; /* Time To Live for UDP security */ + char interface; /* RS-232/V.35, etc. */ + char clocking; /* external/internal */ + unsigned bps; /* data transfer rate */ + unsigned mtu; /* maximum transmit unit size */ } wanif_conf_t; #ifdef __KERNEL__ @@ -316,7 +404,6 @@ #include /* proc filesystem pragmatics */ #include /* in_aton(), in_ntoa() prototypes */ #include /* support for network drivers */ - /*---------------------------------------------------------------------------- * WAN device data space. */ @@ -325,9 +412,12 @@ unsigned magic; /* magic number */ char* name; /* -> WAN device name (ASCIIZ) */ void* private; /* -> driver private data */ + unsigned config_id; /* Configuration ID */ /****** hardware configuration ******/ unsigned ioport; /* adapter I/O port base #1 */ - void * maddr; /* dual-port memory address */ + char S514_cpu_no[1]; /* PCI CPU Number */ + unsigned char S514_slot_no; /* PCI Slot Number */ + unsigned long maddr; /* dual-port memory address */ unsigned msize; /* dual-port memory size */ int irq; /* interrupt request level */ int dma; /* DMA request level */ @@ -341,24 +431,31 @@ char line_coding; /* NRZ/NRZI/FM0/FM1, etc. */ char station; /* DTE/DCE, primary/secondary, etc. */ char connection; /* permanent/switched/on-demand */ + char signalling; /* Signalling RS232 or V35 */ + char read_mode; /* read mode: Polling or interrupt */ + char new_if_cnt; /* Number of interfaces per wanpipe */ + char del_if_cnt; /* Number of times del_if() gets called */ + unsigned char piggyback; /* Piggibacking a port */ unsigned hw_opt[4]; /* other hardware options */ - unsigned char enable_IPX; /* Enable or Disable IPX */ - unsigned long network_number; /* Network Number for IPX */ /****** status and statistics *******/ char state; /* device state */ - unsigned modem_status; /* modem status */ + char api_status; /* device api status */ +#ifdef LINUX_2_1 + struct net_device_stats stats; /* interface statistics */ +#else struct enet_statistics stats; /* interface statistics */ +#endif unsigned reserved[16]; /* reserved for future use */ unsigned critical; /* critical section flag */ /****** device management methods ***/ - int (*setup) (struct wan_device* wandev, wandev_conf_t* conf); - int (*shutdown) (struct wan_device* wandev); - int (*update) (struct wan_device* wandev); - int (*ioctl) (struct wan_device* wandev, unsigned cmd, + int (*setup) (struct wan_device *wandev, wandev_conf_t *conf); + int (*shutdown) (struct wan_device *wandev); + int (*update) (struct wan_device *wandev); + int (*ioctl) (struct wan_device *wandev, unsigned cmd, unsigned long arg); - int (*new_if) (struct wan_device* wandev, struct net_device* dev, - wanif_conf_t* conf); - int (*del_if) (struct wan_device* wandev, struct net_device* dev); + int (*new_if) (struct wan_device *wandev, struct net_device *dev, + wanif_conf_t *conf); + int (*del_if) (struct wan_device *wandev, struct net_device *dev); /****** maintained by the router ****/ struct wan_device* next; /* -> next device */ struct net_device* dev; /* list of network interfaces */ @@ -367,23 +464,20 @@ } wan_device_t; /* Public functions available for device drivers */ -extern int register_wan_device(wan_device_t* wandev); -extern int unregister_wan_device(char* name); -unsigned short wanrouter_type_trans(struct sk_buff* skb, struct net_device* dev); -int wanrouter_encapsulate(struct sk_buff* skb, struct net_device* dev); +extern int register_wan_device(wan_device_t *wandev); +extern int unregister_wan_device(char *name); +unsigned short wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev); +int wanrouter_encapsulate(struct sk_buff *skb, struct net_device *dev); /* Proc interface functions. These must not be called by the drivers! */ -extern int wanrouter_proc_init (void); -extern void wanrouter_proc_cleanup (void); -extern int wanrouter_proc_add (wan_device_t* wandev); -extern int wanrouter_proc_delete (wan_device_t* wandev); -extern int wanrouter_ioctl( - struct inode* inode, struct file* file, - unsigned int cmd, unsigned long arg) -; +extern int wanrouter_proc_init(void); +extern void wanrouter_proc_cleanup(void); +extern int wanrouter_proc_add(wan_device_t *wandev); +extern int wanrouter_proc_delete(wan_device_t *wandev); +extern int wanrouter_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); /* Public Data */ -extern wan_device_t* router_devlist; /* list of registered devices */ +extern wan_device_t *router_devlist; /* list of registered devices */ #endif /* __KERNEL__ */ #endif /* _ROUTER_H */ diff -ur --new-file old/linux/include/linux/zorro.h new/linux/include/linux/zorro.h --- old/linux/include/linux/zorro.h Thu Feb 25 19:02:12 1999 +++ new/linux/include/linux/zorro.h Wed Jan 26 21:45:21 2000 @@ -1,7 +1,7 @@ /* * linux/zorro.h -- Amiga AutoConfig (Zorro) Bus Definitions * - * Copyright (C) 1995-1998 Geert Uytterhoeven + * Copyright (C) 1995-2000 Geert Uytterhoeven * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive @@ -39,6 +39,9 @@ typedef __u32 zorro_id; +#define ZORRO_WILDCARD (0xffffffff) /* not official */ + + #define ZORRO_MANUF_PACIFIC_PERIPHERALS 0x00D3 #define ZORRO_PROD_PACIFIC_PERIPHERALS_SE_2000_A500 ZORRO_ID(PACIFIC_PERIPHERALS, 0x00, 0) #define ZORRO_PROD_PACIFIC_PERIPHERALS_SCSI ZORRO_ID(PACIFIC_PERIPHERALS, 0x0A, 0) @@ -694,8 +697,19 @@ #ifdef __KERNEL__ +#include + +struct zorro_dev { + struct ExpansionRom rom; + zorro_id id; + u16 slotaddr; + u16 slotsize; + char name[48]; + struct resource resource; +}; + extern unsigned int zorro_num_autocon; /* # of autoconfig devices found */ -extern struct ConfigDev zorro_autocon[ZORRO_NUM_AUTO]; +extern struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO]; /* @@ -705,10 +719,18 @@ extern void zorro_init(void); extern void zorro_proc_init(void); -extern unsigned int zorro_find(zorro_id id, unsigned int part, unsigned int index); -extern const struct ConfigDev *zorro_get_board(unsigned int key); -extern void zorro_config_board(unsigned int key, unsigned int part); -extern void zorro_unconfig_board(unsigned int key, unsigned int part); +extern struct zorro_dev *zorro_find_device(zorro_id id, + struct zorro_dev *from); + +#define zorro_request_device(z, name) \ + request_mem_region((z)->resource.start, \ + (z)->resource.end-(z)->resource.start+1, (name)) +#define zorro_check_device(z) \ + check_mem_region((z)->resource.start, \ + (z)->resource.end-(z)->resource.start+1) +#define zorro_release_device(z) \ + release_mem_region((z)->resource.start, \ + (z)->resource.end-(z)->resource.start+1) /* diff -ur --new-file old/linux/include/net/dst.h new/linux/include/net/dst.h --- old/linux/include/net/dst.h Fri Jan 21 01:06:21 2000 +++ new/linux/include/net/dst.h Fri Jan 28 17:01:54 2000 @@ -29,10 +29,13 @@ struct dst_entry *next; atomic_t __refcnt; /* client references */ int __use; - struct net_device *dev; + struct net_device *dev; int obsolete; + int flags; +#define DST_HOST 1 unsigned long lastuse; unsigned long expires; + unsigned mxlock; unsigned pmtu; unsigned window; @@ -41,6 +44,7 @@ unsigned ssthresh; unsigned cwnd; unsigned advmss; + unsigned long rate_last; /* rate limiting for ICMP */ unsigned long rate_tokens; diff -ur --new-file old/linux/include/net/ip.h new/linux/include/net/ip.h --- old/linux/include/net/ip.h Fri Jan 21 01:07:01 2000 +++ new/linux/include/net/ip.h Fri Jan 28 17:02:33 2000 @@ -84,7 +84,7 @@ * Functions provided by ip.c */ -extern void ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, +extern int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, u32 saddr, u32 daddr, struct ip_options *opt); extern int ip_rcv(struct sk_buff *skb, struct net_device *dev, diff -ur --new-file old/linux/include/net/route.h new/linux/include/net/route.h --- old/linux/include/net/route.h Fri Jan 21 01:06:56 2000 +++ new/linux/include/net/route.h Fri Jan 28 17:02:32 2000 @@ -92,8 +92,7 @@ __u32 i_packets; }; -extern struct ip_rt_acct ip_rt_acct[256]; -extern rwlock_t ip_rt_acct_lock; +extern struct ip_rt_acct *ip_rt_acct; extern void ip_rt_init(void); extern void ip_rt_redirect(u32 old_gw, u32 dst, u32 new_gw, diff -ur --new-file old/linux/include/net/snmp.h new/linux/include/net/snmp.h --- old/linux/include/net/snmp.h Sun Jan 9 06:36:20 2000 +++ new/linux/include/net/snmp.h Sat Jan 22 20:54:57 2000 @@ -182,7 +182,24 @@ unsigned long OfoPruned; unsigned long OutOfWindowIcmps; unsigned long LockDroppedIcmps; - unsigned long __pad[32-9]; + unsigned long TimeWaited; + unsigned long TimeWaitRecycled; + unsigned long TimeWaitKilled; + unsigned long PAWSPassiveRejected; + unsigned long PAWSActiveRejected; + unsigned long PAWSEstabRejected; + unsigned long DelayedACKs; + unsigned long DelayedACKLocked; + unsigned long DelayedACKLost; + unsigned long ListenOverflows; + unsigned long ListenDrops; + unsigned long TCPPrequeued; + unsigned long TCPDirectCopyFromBacklog; + unsigned long TCPDirectCopyFromPrequeue; + unsigned long TCPPrequeueDropped; + unsigned long TCPHPHits; + unsigned long TCPHPHitsToUser; + unsigned long __pad[32-26]; }; #define SNMP_INC_STATS(mib, field) ((mib)[2*smp_processor_id()+!in_interrupt()].field++) diff -ur --new-file old/linux/include/net/sock.h new/linux/include/net/sock.h --- old/linux/include/net/sock.h Fri Jan 21 01:06:41 2000 +++ new/linux/include/net/sock.h Fri Jan 28 17:02:06 2000 @@ -96,7 +96,6 @@ #include #include -#define MIN_WRITE_SPACE 2048 /* The AF_UNIX specific socket options */ struct unix_opt { @@ -229,41 +228,66 @@ __u32 snd_nxt; /* Next sequence we send */ __u32 snd_una; /* First byte we want an ack for */ - __u32 rcv_tstamp; /* timestamp of last received packet */ - __u32 lrcvtime; /* timestamp of last received data packet*/ - __u32 srtt; /* smothed round trip time << 3 */ + __u32 snd_sml; /* Last byte of the most recently transmitted small packet */ + __u32 rcv_tstamp; /* timestamp of last received ACK (for keepalives) */ + __u32 lsndtime; /* timestamp of last sent data packet (for restart window) */ - __u32 ato; /* delayed ack timeout */ - __u32 snd_wl1; /* Sequence for window update */ + /* Delayed ACK control data */ + struct { + __u8 pending; /* ACK is pending */ + __u8 quick; /* Scheduled number of quick acks */ + __u8 pingpong; /* The session is interactive */ + __u8 blocked; /* Delayed ACK was blocked by socket lock*/ + __u32 ato; /* Predicted tick of soft clock */ + __u32 lrcvtime; /* timestamp of last received data packet*/ + __u16 last_seg_size; /* Size of last incoming segment */ + __u16 rcv_mss; /* MSS used for delayed ACK decisions */ + } ack; + /* Data for direct copy to user */ + struct { + struct sk_buff_head prequeue; + int memory; + struct task_struct *task; + struct iovec *iov; + int len; + } ucopy; + + __u32 snd_wl1; /* Sequence for window update */ __u32 snd_wl2; /* Ack sequence for update */ __u32 snd_wnd; /* The window we expect to receive */ - __u32 max_window; + __u32 max_window; /* Maximal window ever seen from peer */ __u32 pmtu_cookie; /* Last pmtu seen by socket */ __u16 mss_cache; /* Cached effective mss, not including SACKS */ __u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ - __u16 ext_header_len; /* Dave, do you allow mw to use this hole? 8) --ANK */ - __u8 pending; /* pending events */ + __u16 ext_header_len; /* Network protocol overhead (IP/IPv6 options) */ + __u8 dup_acks; /* Consequetive duplicate acks seen from other end */ __u8 retransmits; - __u32 last_ack_sent; /* last ack we sent */ - __u32 backoff; /* backoff */ + __u16 __empty1; + __u8 defer_accept; + +/* RTT measurement */ + __u8 backoff; /* backoff */ + __u32 srtt; /* smothed round trip time << 3 */ __u32 mdev; /* medium deviation */ - __u32 snd_cwnd; /* Sending congestion window */ __u32 rto; /* retransmit timeout */ __u32 packets_out; /* Packets which are "in flight" */ __u32 fackets_out; /* Non-retrans SACK'd packets */ __u32 retrans_out; /* Fast-retransmitted packets out */ __u32 high_seq; /* snd_nxt at onset of congestion */ + /* * Slow start and congestion control (see also Nagle, and Karn & Partridge) */ __u32 snd_ssthresh; /* Slow start size threshold */ + __u32 snd_cwnd; /* Sending congestion window */ __u16 snd_cwnd_cnt; /* Linear increase counter */ __u16 snd_cwnd_clamp; /* Do not allow snd_cwnd to grow above this */ - __u8 dup_acks; /* Consequetive duplicate acks seen from other end */ - __u8 delayed_acks; + + __u8 nonagle; /* Disable Nagle algorithm? */ + __u8 syn_retries; /* num of allowed syn retries */ __u16 user_mss; /* mss requested by user in ioctl */ /* Two commonly used timers in both sender and receiver paths. */ @@ -294,34 +318,49 @@ __u8 snd_wscale; /* Window scaling received from sender */ __u8 rcv_wscale; /* Window scaling to send to receiver */ __u8 rexmt_done; /* Retransmitted up to send head? */ + __u8 keepalive_probes; /* num of allowed keep alive probes */ + +/* PAWS/RTTM data */ __u32 rcv_tsval; /* Time stamp value */ __u32 rcv_tsecr; /* Time stamp echo reply */ __u32 ts_recent; /* Time stamp to echo next */ long ts_recent_stamp;/* Time we stored ts_recent (for aging) */ - int num_sacks; /* Number of SACK blocks */ + __u32 last_ack_sent; /* last ack we sent (RTTM/PAWS) */ + +/* SACKs data */ struct tcp_sack_block selective_acks[4]; /* The SACKS themselves*/ struct timer_list probe_timer; /* Probes */ - __u32 window_clamp; /* XXX Document this... -DaveM */ - __u32 probes_out; /* unanswered 0 window probes */ + __u32 window_clamp; /* Maximal window to advertise */ + __u8 probes_out; /* unanswered 0 window probes */ + __u8 num_sacks; /* Number of SACK blocks */ + __u16 advmss; /* Advertised MSS */ + + __u32 syn_stamp; __u32 syn_seq; __u32 fin_seq; __u32 urg_seq; __u32 urg_data; - __u32 last_seg_size; /* Size of last incoming segment */ - __u32 rcv_mss; /* MSS used for delayed ACK decisions */ + /* The syn_wait_lock is necessary only to avoid tcp_get_info having + * to grab the main lock sock while browsing the listening hash + * (otherwise it's deadlock prone). + * This lock is acquired in read mode only from tcp_get_info() and + * it's acquired in write mode _only_ from code that is actively + * changing the syn_wait_queue. All readers that are holding + * the master sock lock don't need to grab this lock in read mode + * too as the syn_wait_queue writes are always protected from + * the main sock lock. + */ + rwlock_t syn_wait_lock; + struct tcp_listen_opt *listen_opt; + struct open_request *accept_queue; /* Established children */ - struct open_request *syn_wait_queue; - struct open_request **syn_wait_last; + int write_pending; /* A write to socket waits to start. */ - int syn_backlog; /* Backlog of received SYNs */ - int write_pending; - unsigned int keepalive_time; /* time before keep alive takes place */ unsigned int keepalive_intvl; /* time interval between keep alive probes */ - unsigned char keepalive_probes; /* num of allowed keep alive probes */ - unsigned char syn_retries; /* num of allowed syn retries */ + int linger2; }; @@ -411,7 +450,7 @@ unsigned short family; /* Address family */ unsigned char reuse, /* SO_REUSEADDR setting */ - nonagle; /* Disable Nagle algorithm? */ + __unused; atomic_t refcnt; /* Reference count */ socket_lock_t lock; /* Synchronizer... */ @@ -498,6 +537,9 @@ unsigned char localroute; /* Route locally only */ unsigned char protocol; struct ucred peercred; + int rcvlowat; + long rcvtimeo; + long sndtimeo; #ifdef CONFIG_FILTER /* Socket Filtering Instructions */ @@ -557,7 +599,7 @@ struct timer_list timer; /* This is the sock cleanup timer. */ struct timeval stamp; - /* Identd */ + /* Identd and reporting IO signals */ struct socket *socket; /* RPC layer private data */ @@ -599,12 +641,6 @@ int (*disconnect)(struct sock *sk, int flags); struct sock * (*accept) (struct sock *sk, int flags, int *err); - void (*retransmit)(struct sock *sk, int all); - void (*write_wakeup)(struct sock *sk); - void (*read_wakeup)(struct sock *sk); - - unsigned int (*poll)(struct file * file, struct socket *sock, - struct poll_table_struct *wait); int (*ioctl)(struct sock *sk, int cmd, unsigned long arg); @@ -632,8 +668,6 @@ void (*unhash)(struct sock *sk); int (*get_port)(struct sock *sk, unsigned short snum); - unsigned short max_header; - unsigned long retransmits; char name[32]; struct { @@ -672,6 +706,9 @@ * While locked, BH processing will add new packets to * the backlog queue. This queue is processed by the * owner of the socket lock right before it is released. + * + * Since ~2.3.5 it is also exclusive sleep lock serializing + * accesses from user process context. */ extern void __lock_sock(struct sock *sk); extern void __release_sock(struct sock *sk); @@ -682,11 +719,12 @@ (__sk)->lock.users = 1; \ spin_unlock_bh(&((__sk)->lock.slock)); \ } while(0) + #define release_sock(__sk) \ do { spin_lock_bh(&((__sk)->lock.slock)); \ - (__sk)->lock.users = 0; \ if ((__sk)->backlog.tail != NULL) \ __release_sock(__sk); \ + (__sk)->lock.users = 0; \ wake_up(&((__sk)->lock.wq)); \ spin_unlock_bh(&((__sk)->lock.slock)); \ } while(0) @@ -788,9 +826,6 @@ * Default socket callbacks and setup code */ -extern void sock_def_callback1(struct sock *); -extern void sock_def_callback2(struct sock *, int); -extern void sock_def_callback3(struct sock *); extern void sock_def_destruct(struct sock *); /* Initialise core socket variables */ @@ -888,6 +923,34 @@ sk_free(sk); } +/* Detach socket from process context. + * Announce socket dead, detach it from wait queue and inode. + * Note that parent inode held reference count on this struct sock, + * we do not release it in this function, because protocol + * probably wants some additional cleanups or even continuing + * to work with this socket (TCP). + * + * NOTE: When softnet goes in replace _irq with _bh! + */ +extern __inline__ void sock_orphan(struct sock *sk) +{ + write_lock_irq(&sk->callback_lock); + sk->dead = 1; + sk->socket = NULL; + sk->sleep = NULL; + write_unlock_irq(&sk->callback_lock); +} + +extern __inline__ void sock_graft(struct sock *sk, struct socket *parent) +{ + write_lock_irq(&sk->callback_lock); + sk->sleep = &parent->wait; + parent->sk = sk; + sk->socket = parent; + write_unlock_irq(&sk->callback_lock); +} + + extern __inline__ struct dst_entry * __sk_dst_get(struct sock *sk) { @@ -1071,13 +1134,18 @@ return amt; } +#define SOCK_MIN_SNDBUF 2048 +#define SOCK_MIN_RCVBUF 128 +/* Must be less or equal SOCK_MIN_SNDBUF */ +#define SOCK_MIN_WRITE_SPACE SOCK_MIN_SNDBUF + /* * Default write policy as shown to user space via poll/select/SIGIO * Kernel internally doesn't use the MIN_WRITE_SPACE threshold. */ extern __inline__ int sock_writeable(struct sock *sk) { - return sock_wspace(sk) >= MIN_WRITE_SPACE; + return sock_wspace(sk) >= SOCK_MIN_WRITE_SPACE; } extern __inline__ int gfp_any(void) @@ -1085,6 +1153,20 @@ return in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; } +extern __inline__ long sock_rcvtimeo(struct sock *sk, int noblock) +{ + return noblock ? 0 : sk->rcvtimeo; +} + +extern __inline__ long sock_sndtimeo(struct sock *sk, int noblock) +{ + return noblock ? 0 : sk->sndtimeo; +} + +extern __inline__ int sock_rcvlowat(struct sock *sk, int waitall, int len) +{ + return waitall ? len : min(sk->rcvlowat, len); +} /* * Enable debug/info messages @@ -1116,5 +1198,8 @@ remove_wait_queue((sk)->sleep, &wait); \ lock_sock(sk); \ } + +extern __u32 sysctl_wmem_max; +extern __u32 sysctl_rmem_max; #endif /* _SOCK_H */ diff -ur --new-file old/linux/include/net/tcp.h new/linux/include/net/tcp.h --- old/linux/include/net/tcp.h Fri Jan 21 01:07:08 2000 +++ new/linux/include/net/tcp.h Fri Jan 28 17:02:41 2000 @@ -19,6 +19,7 @@ #define _TCP_H #define TCP_DEBUG 1 +#undef TCP_FORMAL_WINDOW #include #include @@ -130,27 +131,27 @@ struct sock *bind_next; struct sock **bind_pprev; unsigned char state, - zapped; + substate; /* "zapped" is replaced with "substate" */ __u16 sport; unsigned short family; unsigned char reuse, - nonagle; + rcv_wscale; /* It is also TW bucket specific */ atomic_t refcnt; /* And these are ours. */ int hashent; + int timeout; __u32 rcv_nxt; __u32 snd_nxt; + __u32 rcv_wnd; + __u32 syn_seq; __u32 ts_recent; long ts_recent_stamp; + unsigned long ttd; struct tcp_bind_bucket *tb; struct tcp_tw_bucket *next_death; struct tcp_tw_bucket **pprev_death; - int death_slot; -#ifdef CONFIG_TCP_TW_RECYCLE - unsigned long ttd; - int rto; -#endif + #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) struct in6_addr v6_daddr; struct in6_addr v6_rcv_saddr; @@ -169,10 +170,11 @@ } } -extern int tcp_tw_death_row_slot; +extern atomic_t tcp_orphan_count; +extern int tcp_tw_count; +extern void tcp_time_wait(struct sock *sk, int state, int timeo); extern void tcp_timewait_kill(struct tcp_tw_bucket *tw); -extern void tcp_tw_schedule(struct tcp_tw_bucket *tw); -extern void tcp_tw_reschedule(struct tcp_tw_bucket *tw); +extern void tcp_tw_schedule(struct tcp_tw_bucket *tw, int timeo); extern void tcp_tw_deschedule(struct tcp_tw_bucket *tw); @@ -224,67 +226,81 @@ return tcp_lhashfn(sk->num); } -/* Note, that it is > than ipv6 header */ -#define NETHDR_SIZE (sizeof(struct iphdr) + 40) - -/* - * 40 is maximal IP options size - * 20 is the maximum TCP options size we can currently construct on a SYN. - * 40 is the maximum possible TCP options size. - */ - -#define MAX_SYN_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + 20 + MAX_HEADER + 15) -#define MAX_FIN_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15) -#define BASE_ACK_SIZE (NETHDR_SIZE + MAX_HEADER + 15) -#define MAX_ACK_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15) -#define MAX_RESET_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15) -#define MAX_TCPHEADER_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + 20 + MAX_HEADER + 15) +#define MAX_TCP_HEADER (128 + MAX_HEADER) /* * Never offer a window over 32767 without using window scaling. Some * poor stacks do signed 16bit maths! */ -#define MAX_WINDOW 32767 -#define MAX_DELAY_ACK 2 +#define MAX_TCP_WINDOW 32767 + +/* Minimal accepted MSS. It is (60+60+8) - (20+20). */ +#define TCP_MIN_MSS 88 + +/* Minimal RCV_MSS. */ +#define TCP_MIN_RCVMSS 536 /* * How much of the receive buffer do we advertize * (the rest is reserved for headers and driver packet overhead) * Use a power of 2. */ -#define WINDOW_ADVERTISE_DIVISOR 2 +#define TCP_WINDOW_ADVERTISE_DIVISOR 2 /* urg_data states */ -#define URG_VALID 0x0100 -#define URG_NOTYET 0x0200 -#define URG_READ 0x0400 +#define TCP_URG_VALID 0x0100 +#define TCP_URG_NOTYET 0x0200 +#define TCP_URG_READ 0x0400 -#define TCP_RETR1 7 /* +#define TCP_RETR1 3 /* * This is how many retries it does before it * tries to figure out if the gateway is - * down. + * down. Minimal RFC value is 3; it corresponds + * to ~3sec-8min depending on RTO. */ #define TCP_RETR2 15 /* * This should take at least * 90 minutes to time out. + * RFC1122 says that the limit is 100 sec. + * 15 is ~13-30min depending on RTO. */ -#define TCP_TIMEOUT_LEN (15*60*HZ) /* should be about 15 mins */ -#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to successfully - * close the socket, about 60 seconds */ -#define TCP_FIN_TIMEOUT (3*60*HZ) /* BSD style FIN_WAIT2 deadlock breaker */ - -#define TCP_ACK_TIME (3*HZ) /* time to delay before sending an ACK */ -#define TCP_WRITE_TIME (30*HZ) /* initial time to wait for an ACK, - * after last transmit */ -#define TCP_TIMEOUT_INIT (3*HZ) /* RFC 1122 initial timeout value */ -#define TCP_SYN_RETRIES 10 /* number of times to retry opening a - * connection (TCP_RETR2-....) */ -#define TCP_PROBEWAIT_LEN (1*HZ)/* time to wait between probes when - * I've got something to write and - * there is no window */ -#define TCP_KEEPALIVE_TIME (120*60*HZ) /* two hours */ +#define TCP_SYN_RETRIES 5 /* number of times to retry active opening a + * connection: ~180sec is RFC minumum */ + +#define TCP_SYNACK_RETRIES 5 /* number of times to retry passive opening a + * connection: ~180sec is RFC minumum */ + + +#define TCP_ORPHAN_RETRIES 7 /* number of times to retry on an orphaned + * socket. 7 is ~50sec-16min. + */ + + +#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT + * state, about 60 seconds */ +#define TCP_FIN_TIMEOUT TCP_TIMEWAIT_LEN + /* BSD style FIN_WAIT2 deadlock breaker. + * It used to be 3min, new value is 60sec, + * to combine FIN-WAIT-2 timeout with + * TIME-WAIT timer. + */ + +#define TCP_DELACK_MAX (HZ/2) /* maximal time to delay before sending an ACK */ +#define TCP_DELACK_MIN (2) /* minimal time to delay before sending an ACK, + * 2 scheduler ticks, not depending on HZ */ +#define TCP_ATO_MAX ((TCP_DELACK_MAX*4)/5) /* ATO producing TCP_DELACK_MAX */ +#define TCP_ATO_MIN 2 +#define TCP_RTO_MAX (120*HZ) +#define TCP_RTO_MIN (HZ/5) +#define TCP_TIMEOUT_INIT (3*HZ) /* RFC 1122 initial RTO value */ + +#define TCP_RESOURCE_PROBE_INTERVAL (HZ/2) /* Maximal interval between probes + * for local resources. + */ + +#define TCP_KEEPALIVE_TIME (120*60*HZ) /* two hours */ #define TCP_KEEPALIVE_PROBES 9 /* Max of 9 keepalive probes */ #define TCP_KEEPALIVE_INTVL (75*HZ) @@ -293,14 +309,39 @@ #define MAX_TCP_KEEPCNT 127 #define MAX_TCP_SYNCNT 127 -#define TCP_SYNACK_PERIOD (HZ/2) /* How often to run the synack slow timer */ -#define TCP_QUICK_TRIES 8 /* How often we try to retransmit, until - * we tell the link layer that it is something - * wrong (e.g. that it can expire redirects) */ - /* TIME_WAIT reaping mechanism. */ #define TCP_TWKILL_SLOTS 8 /* Please keep this a power of 2. */ -#define TCP_TWKILL_PERIOD ((HZ*60)/TCP_TWKILL_SLOTS) +#define TCP_TWKILL_PERIOD (TCP_TIMEWAIT_LEN/TCP_TWKILL_SLOTS) + +#define TCP_SYNQ_INTERVAL (HZ/5) /* Period of SYNACK timer */ +#define TCP_SYNQ_HSIZE 64 /* Size of SYNACK hash table */ + +#define TCP_PAWS_24DAYS (60 * 60 * 24 * 24) +#define TCP_PAWS_MSL 60 /* Per-host timestamps are invalidated + * after this time. It should be equal + * (or greater than) TCP_TIMEWAIT_LEN + * to provide reliability equal to one + * provided by timewait state. + */ +#define TCP_PAWS_WINDOW 1 /* Replay window for per-host + * timestamps. It must be less than + * minimal timewait lifetime. + */ + +#define TCP_TW_RECYCLE_SLOTS_LOG 5 +#define TCP_TW_RECYCLE_SLOTS (1< 4sec, it is "slow" path, no recycling is required, + so that we select tick to get range about 4 seconds. + */ + +#if HZ == 100 +#define TCP_TW_RECYCLE_TICK (7+2-TCP_TW_RECYCLE_SLOTS_LOG) +#elif HZ == 1024 +#define TCP_TW_RECYCLE_TICK (10+2-TCP_TW_RECYCLE_SLOTS_LOG) +#else +#error HZ != 100 && HZ != 1024. +#endif /* * TCP option @@ -331,23 +372,40 @@ #define TCPOLEN_SACK_BASE_ALIGNED 4 #define TCPOLEN_SACK_PERBLOCK 8 -#define TIME_WRITE 1 /* Not yet used */ -#define TIME_RETRANS 2 /* Retransmit timer */ -#define TIME_DACK 3 /* Delayed ack timer */ -#define TIME_PROBE0 4 -#define TIME_KEEPOPEN 5 +#define TCP_TIME_RETRANS 1 /* Retransmit timer */ +#define TCP_TIME_DACK 2 /* Delayed ack timer */ +#define TCP_TIME_PROBE0 3 /* Zero window probe timer */ +#define TCP_TIME_KEEPOPEN 4 /* Keepalive timer */ /* sysctl variables for tcp */ +extern int sysctl_max_syn_backlog; +extern int sysctl_tcp_timestamps; +extern int sysctl_tcp_window_scaling; +extern int sysctl_tcp_sack; +extern int sysctl_tcp_fin_timeout; +extern int sysctl_tcp_tw_recycle; extern int sysctl_tcp_keepalive_time; extern int sysctl_tcp_keepalive_probes; extern int sysctl_tcp_keepalive_intvl; extern int sysctl_tcp_syn_retries; +extern int sysctl_tcp_synack_retries; +extern int sysctl_tcp_retries1; +extern int sysctl_tcp_retries2; +extern int sysctl_tcp_orphan_retries; +extern int sysctl_tcp_syncookies; +extern int sysctl_tcp_retrans_collapse; +extern int sysctl_tcp_stdurg; +extern int sysctl_tcp_rfc1337; +extern int sysctl_tcp_tw_recycle; +extern int sysctl_tcp_abort_on_overflow; +extern int sysctl_tcp_max_orphans; +extern int sysctl_tcp_max_tw_buckets; struct open_request; struct or_calltable { int family; - void (*rtx_syn_ack) (struct sock *sk, struct open_request *req); + int (*rtx_syn_ack) (struct sock *sk, struct open_request *req, struct dst_entry*); void (*send_ack) (struct sk_buff *skb, struct open_request *req); void (*destructor) (struct open_request *req); void (*send_reset) (struct sk_buff *skb); @@ -376,12 +434,14 @@ __u16 rmt_port; __u16 mss; __u8 retrans; - __u8 __pad; - unsigned snd_wscale : 4, + __u8 index; + __u16 snd_wscale : 4, rcv_wscale : 4, tstamp_ok : 1, sack_ok : 1, - wscale_ok : 1; + wscale_ok : 1, + ecn_ok : 1, + acked : 1; /* The following two fields can be easily recomputed I think -AK */ __u32 window_clamp; /* window clamp at creation time */ __u32 rcv_wnd; /* rcv_wnd offered first time */ @@ -400,8 +460,14 @@ /* SLAB cache for open requests. */ extern kmem_cache_t *tcp_openreq_cachep; -#define tcp_openreq_alloc() kmem_cache_alloc(tcp_openreq_cachep, SLAB_ATOMIC) -#define tcp_openreq_free(req) kmem_cache_free(tcp_openreq_cachep, req) +#define tcp_openreq_alloc() kmem_cache_alloc(tcp_openreq_cachep, SLAB_ATOMIC) +#define tcp_openreq_fastfree(req) kmem_cache_free(tcp_openreq_cachep, req) + +extern __inline__ void tcp_openreq_free(struct open_request *req) +{ + req->class->destructor(req); + tcp_openreq_fastfree(req); +} #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) #define TCP_INET_FAMILY(fam) ((fam) == AF_INET) @@ -441,9 +507,9 @@ int (*hash_connecting) (struct sock *sk); - __u16 net_header_len; - + int (*remember_stamp) (struct sock *sk); + __u16 net_header_len; int (*setsockopt) (struct sock *sk, int level, @@ -506,7 +572,11 @@ extern int tcp_v4_rcv(struct sk_buff *skb, unsigned short len); -extern int tcp_do_sendmsg(struct sock *sk, struct msghdr *msg); +extern int tcp_v4_remember_stamp(struct sock *sk); + +extern int tcp_v4_tw_remember_stamp(struct tcp_tw_bucket *tw); + +extern int tcp_sendmsg(struct sock *sk, struct msghdr *msg, int size); extern int tcp_ioctl(struct sock *sk, int cmd, @@ -522,6 +592,23 @@ struct tcphdr *th, unsigned len); +static __inline__ void tcp_dec_quickack_mode(struct tcp_opt *tp) +{ + if (tp->ack.quick && --tp->ack.quick == 0 && !tp->ack.pingpong) { + /* Leaving quickack mode we deflate ATO to give peer + * a time to adapt to new worse(!) RTO. It is not required + * in pingpong mode, when ACKs were delayed in any case. + */ + tp->ack.ato = TCP_ATO_MIN; + } +} + +static __inline__ void tcp_delack_init(struct tcp_opt *tp) +{ + memset(&tp->ack, 0, sizeof(tp->ack)); +} + + enum tcp_tw_status { TCP_TW_SUCCESS = 0, @@ -530,6 +617,7 @@ TCP_TW_SYN = 3 }; + extern enum tcp_tw_status tcp_timewait_state_process(struct tcp_tw_bucket *tw, struct sk_buff *skb, struct tcphdr *th, @@ -537,7 +625,10 @@ extern struct sock * tcp_check_req(struct sock *sk,struct sk_buff *skb, struct open_request *req, - struct open_request *prev); + struct open_request **prev); +extern int tcp_child_process(struct sock *parent, + struct sock *child, + struct sk_buff *skb); extern void tcp_close(struct sock *sk, long timeout); @@ -557,6 +648,8 @@ int len, int nonblock, int flags, int *addr_len); +extern int tcp_listen_start(struct sock *sk); + extern void tcp_parse_options(struct sock *sk, struct tcphdr *th, struct tcp_opt *tp, int no_fancy); @@ -614,9 +707,7 @@ /* tcp_output.c */ -extern void tcp_read_wakeup(struct sock *); -extern void tcp_write_xmit(struct sock *); -extern void tcp_time_wait(struct sock *); +extern int tcp_write_xmit(struct sock *); extern int tcp_retransmit_skb(struct sock *, struct sk_buff *); extern void tcp_fack_retransmit(struct sock *); extern void tcp_xmit_retransmit_queue(struct sock *); @@ -624,46 +715,22 @@ extern void tcp_send_probe0(struct sock *); extern void tcp_send_partial(struct sock *); -extern void tcp_write_wakeup(struct sock *); +extern int tcp_write_wakeup(struct sock *); extern void tcp_send_fin(struct sock *sk); extern void tcp_send_active_reset(struct sock *sk, int priority); extern int tcp_send_synack(struct sock *); -extern void tcp_transmit_skb(struct sock *, struct sk_buff *); -extern void tcp_send_skb(struct sock *, struct sk_buff *, int force_queue); +extern int tcp_transmit_skb(struct sock *, struct sk_buff *); +extern void tcp_send_skb(struct sock *, struct sk_buff *, int force_queue, unsigned mss_now); extern void tcp_send_ack(struct sock *sk); -extern void tcp_send_delayed_ack(struct sock *sk, int max_timeout); +extern void tcp_send_delayed_ack(struct sock *sk); /* tcp_timer.c */ extern void tcp_reset_xmit_timer(struct sock *, int, unsigned long); extern void tcp_init_xmit_timers(struct sock *); extern void tcp_clear_xmit_timers(struct sock *); -extern void tcp_retransmit_timer(unsigned long); -extern void tcp_delack_timer(unsigned long); -extern void tcp_probe_timer(unsigned long); - extern void tcp_delete_keepalive_timer (struct sock *); extern void tcp_reset_keepalive_timer (struct sock *, unsigned long); -extern void tcp_keepalive_timer (unsigned long); - -/* - * TCP slow timer - */ -extern struct timer_list tcp_slow_timer; - -struct tcp_sl_timer { - atomic_t count; - unsigned long period; - unsigned long last; - void (*handler) (unsigned long); -}; - -#define TCP_SLT_SYNACK 0 -#define TCP_SLT_TWKILL 1 -#define TCP_SLT_MAX 2 - -extern struct tcp_sl_timer tcp_slt_array[TCP_SLT_MAX]; - extern int tcp_sync_mss(struct sock *sk, u32 pmtu); /* Compute the current effective MSS, taking SACKs and IP options, @@ -673,7 +740,7 @@ static __inline__ unsigned int tcp_current_mss(struct sock *sk) { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - struct dst_entry *dst = sk->dst_cache; + struct dst_entry *dst = __sk_dst_get(sk); int mss_now = tp->mss_cache; if (dst && dst->pmtu != tp->pmtu_cookie) @@ -682,7 +749,7 @@ if(tp->sack_ok && tp->num_sacks) mss_now -= (TCPOLEN_SACK_BASE_ALIGNED + (tp->num_sacks * TCPOLEN_SACK_PERBLOCK)); - return mss_now > 8 ? mss_now : 8; + return mss_now; } /* Initialize RCV_MSS value. @@ -704,9 +771,24 @@ else mss = tp->mss_cache; - tp->rcv_mss = max(min(mss, 536), 8); + tp->ack.rcv_mss = max(min(mss, TCP_MIN_RCVMSS), TCP_MIN_MSS); +} + +static __inline__ void __tcp_fast_path_on(struct tcp_opt *tp, u32 snd_wnd) +{ + tp->pred_flags = htonl((tp->tcp_header_len << 26) | + ntohl(TCP_FLAG_ACK) | + snd_wnd); +} + +static __inline__ void tcp_fast_path_on(struct tcp_opt *tp) +{ + __tcp_fast_path_on(tp, tp->snd_wnd>>tp->snd_wscale); } + + + /* Compute the actual receive window we are currently advertising. * Rcv_nxt can be after the window if our peer push more data * than the offered window. @@ -751,23 +833,26 @@ } /* RFC1323 scaling applied */ - return new_win >> tp->rcv_wscale; -} + new_win >>= tp->rcv_wscale; -/* See if we can advertise non-zero, and if so how much we - * can increase our advertisement. If it becomes more than - * twice what we are talking about right now, return true. - */ -extern __inline__ int tcp_raise_window(struct sock *sk) -{ - struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - u32 cur_win = tcp_receive_window(tp); - u32 new_win = __tcp_select_window(sk); +#ifdef TCP_FORMAL_WINDOW + if (new_win == 0) { + /* If we advertise zero window, disable fast path. */ + tp->pred_flags = 0; + } else if (cur_win == 0 && tp->pred_flags == 0 && + skb_queue_len(&tp->out_of_order_queue) == 0 && + !tp->urg_data) { + /* If we open zero window, enable fast path. + Without this it will be open by the first data packet, + it is too late to merge checksumming to copy. + */ + tcp_fast_path_on(tp); + } +#endif - return (new_win && (new_win > (cur_win << 1))); + return new_win; } - /* TCP timestamps are only 32-bits, this causes a slight * complication on 64-bit systems since we store a snapshot * of jiffies in the buffer control blocks below. We decidely @@ -804,6 +889,8 @@ #define TCPCB_FLAG_PSH 0x08 #define TCPCB_FLAG_ACK 0x10 #define TCPCB_FLAG_URG 0x20 +#define TCPCB_FLAG_ECE 0x40 +#define TCPCB_FLAG_CWR 0x80 __u8 sacked; /* State flags for SACK/FACK. */ #define TCPCB_SACKED_ACKED 0x01 /* SKB ACK'd by a SACK block */ @@ -860,13 +947,91 @@ return max(min(FlightSize, tp->snd_cwnd) >> 1, 2); } +/* Set slow start threshould and cwnd not falling to slow start */ +extern __inline__ void __tcp_enter_cong_avoid(struct tcp_opt *tp) +{ + tp->snd_ssthresh = tcp_recalc_ssthresh(tp); + if (tp->snd_ssthresh > tp->snd_cwnd_clamp) + tp->snd_ssthresh = tp->snd_cwnd_clamp; + tp->snd_cwnd = tp->snd_ssthresh; + tp->snd_cwnd_cnt = 0; + tp->high_seq = tp->snd_nxt; +} + +extern __inline__ void tcp_enter_cong_avoid(struct tcp_opt *tp) +{ + if (!tp->high_seq || after(tp->snd_nxt, tp->high_seq)) + __tcp_enter_cong_avoid(tp); +} + + +/* Increase initial CWND conservatively, i.e. only if estimated + RTT is low enough. It is not quite correct, we should use + POWER i.e. RTT*BANDWIDTH, but we still cannot estimate this. + + Numbers are taken from RFC1414. + */ +static __inline__ __u32 tcp_init_cwnd(struct tcp_opt *tp) +{ + __u32 cwnd; + + if (!tp->srtt || tp->srtt > ((HZ/50)<<3) || tp->mss_cache > 1460) + cwnd = 2; + else if (tp->mss_cache > 1095) + cwnd = 3; + else + cwnd = 4; + + return min(cwnd, tp->snd_cwnd_clamp); +} + + +static __inline__ int tcp_minshall_check(struct tcp_opt *tp) +{ + return after(tp->snd_sml,tp->snd_una) && + !after(tp->snd_sml, tp->snd_nxt); +} + +static __inline__ void tcp_minshall_update(struct tcp_opt *tp, int mss, int len) +{ + if (len < mss) + tp->snd_sml = tp->snd_nxt; +} + +/* Return 0, if packet can be sent now without violation Nagle's rules: + 1. It is full sized. + 2. Or it contains FIN or URG. + 3. Or TCP_NODELAY was set. + 4. Or TCP_CORK is not set, and all sent packets are ACKed. + With Minshall's modification: all sent small packets are ACKed. + */ + +static __inline__ int tcp_nagle_check(struct tcp_opt *tp, struct sk_buff *skb, unsigned mss_now) +{ + return (skb->len < mss_now && + !(TCP_SKB_CB(skb)->flags & (TCPCB_FLAG_URG|TCPCB_FLAG_FIN)) && + (tp->nonagle == 2 || + (!tp->nonagle && + tp->packets_out && + tcp_minshall_check(tp)))); +} + /* This checks if the data bearing packet SKB (usually tp->send_head) * should be put on the wire right now. */ -static __inline__ int tcp_snd_test(struct sock *sk, struct sk_buff *skb) +static __inline__ int tcp_snd_test(struct tcp_opt *tp, struct sk_buff *skb, + unsigned cur_mss, int tail) { - struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - int nagle_check = 1; + /* + * Reset CWND after idle period longer RTO to "restart window". + * It is "side" effect of the function, which is _not_ good + * from viewpoint of clarity. But we have to make it before + * checking congestion window below. Alternative is to prepend + * all the calls with this test. + */ + if (tp->packets_out==0 && + (s32)(tcp_time_stamp - tp->lsndtime) > tp->rto) + tp->snd_cwnd = min(tp->snd_cwnd, tcp_init_cwnd(tp)); /* RFC 1122 - section 4.2.3.4 * @@ -876,97 +1041,126 @@ * b) There are packets in flight and we have a small segment * [SWS avoidance and Nagle algorithm] * (part of SWS is done on packetization) + * Minshall version sounds: there are no _small_ + * segments in flight. (tcp_nagle_check) * c) We are retransmiting [Nagle] * d) We have too many packets 'in flight' * * Don't use the nagle rule for urgent data (or * for the final FIN -DaveM). + * + * Also, Nagle rule does not apply to frames, which + * sit in the middle of queue (they have no chances + * to get new data) and if room at tail of skb is + * not enough to save something seriously (<32 for now). */ - if ((sk->nonagle == 2 && (skb->len < tp->mss_cache)) || - (!sk->nonagle && - skb->len < (tp->mss_cache >> 1) && - tp->packets_out && - !(TCP_SKB_CB(skb)->flags & (TCPCB_FLAG_URG|TCPCB_FLAG_FIN)))) - nagle_check = 0; - - /* - * Reset CWND after idle period longer rto. Actually, it would - * be better to save last send time, but VJ in SIGCOMM'88 proposes - * to use keepalive timestamp. Well, it is not good, certainly, - * because SMTP is still broken, but it is better than nothing yet. - */ - if (tp->packets_out==0 && (s32)(tcp_time_stamp - tp->rcv_tstamp) > tp->rto) - tp->snd_cwnd = min(tp->snd_cwnd, 2); /* Don't be strict about the congestion window for the * final FIN frame. -DaveM */ - return (nagle_check && + return ((!tail || !tcp_nagle_check(tp, skb, cur_mss) || + skb_tailroom(skb) < 32) && ((tcp_packets_in_flight(tp) < tp->snd_cwnd) || (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) && !after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) && tp->retransmits == 0); } +static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_opt *tp) +{ + if (!tp->packets_out && !tp->probe_timer.prev) + tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, tp->rto); +} + +static __inline__ int tcp_skb_is_last(struct sock *sk, struct sk_buff *skb) +{ + return (skb->next == (struct sk_buff*)&sk->write_queue); +} + /* Push out any pending frames which were held back due to * TCP_CORK or attempt at coalescing tiny packets. * The socket must be locked by the caller. */ -static __inline__ void tcp_push_pending_frames(struct sock *sk, struct tcp_opt *tp) -{ - if(tp->send_head) { - if(tcp_snd_test(sk, tp->send_head)) - tcp_write_xmit(sk); - else if(tp->packets_out == 0 && !tp->pending) { - /* We held off on this in tcp_send_skb() */ - tp->pending = TIME_PROBE0; - tcp_reset_xmit_timer(sk, TIME_PROBE0, tp->rto); - } +static __inline__ void __tcp_push_pending_frames(struct sock *sk, + struct tcp_opt *tp, + unsigned cur_mss) +{ + struct sk_buff *skb = tp->send_head; + + if (skb) { + if (!tcp_snd_test(tp, skb, cur_mss, tcp_skb_is_last(sk, skb)) || + tcp_write_xmit(sk)) + tcp_check_probe_timer(sk, tp); } } -/* This tells the input processing path that an ACK should go out - * right now. - */ -#define tcp_enter_quickack_mode(__tp) ((__tp)->ato |= (1<<31)) -#define tcp_exit_quickack_mode(__tp) ((__tp)->ato &= ~(1<<31)) -#define tcp_in_quickack_mode(__tp) (((__tp)->ato & (1 << 31)) != 0) +static __inline__ void tcp_push_pending_frames(struct sock *sk, + struct tcp_opt *tp) +{ + __tcp_push_pending_frames(sk, tp, tcp_current_mss(sk)); +} + +extern void tcp_destroy_sock(struct sock *sk); + /* - * List all states of a TCP socket that can be viewed as a "connected" - * state. This now includes TCP_SYN_RECV, although I am not yet fully - * convinced that this is the solution for the 'getpeername(2)' - * problem. Thanks to Stephen A. Wood -FvK + * Calculate(/check) TCP checksum */ +static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len, + unsigned long saddr, unsigned long daddr, + unsigned long base) +{ + return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base); +} -extern __inline const int tcp_connected(const int state) +static __inline__ int __tcp_checksum_complete(struct sk_buff *skb) { - return ((1 << state) & - (TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_FIN_WAIT1| - TCPF_FIN_WAIT2|TCPF_SYN_RECV)); + return (unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum)); } -extern __inline const int tcp_established(const int state) +static __inline__ int tcp_checksum_complete(struct sk_buff *skb) { - return ((1 << state) & - (TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_FIN_WAIT1| - TCPF_FIN_WAIT2)); + return skb->ip_summed != CHECKSUM_UNNECESSARY && + __tcp_checksum_complete(skb); } -extern void tcp_destroy_sock(struct sock *sk); +/* Prequeue for VJ style copy to user, combined with checksumming. */ +static __inline__ void tcp_prequeue_init(struct tcp_opt *tp) +{ + tp->ucopy.task = NULL; + tp->ucopy.len = 0; + tp->ucopy.memory = 0; + skb_queue_head_init(&tp->ucopy.prequeue); +} -/* - * Calculate(/check) TCP checksum +/* Packet is added to VJ-style prequeue for processing in process + * context, if a reader task is waiting. Apparently, this exciting + * idea (VJ's mail "Re: query about TCP header on tcp-ip" of 07 Sep 93) + * failed somewhere. Latency? Burstiness? Well, at least now we will + * see, why it failed. 8)8) --ANK */ -static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len, - unsigned long saddr, unsigned long daddr, - unsigned long base) +static __inline__ int tcp_prequeue(struct sock *sk, struct sk_buff *skb) { - return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base); + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + + if (tp->ucopy.task) { + if ((tp->ucopy.memory += skb->truesize) <= (sk->rcvbuf<<1)) { + __skb_queue_tail(&tp->ucopy.prequeue, skb); + if (skb_queue_len(&tp->ucopy.prequeue) == 1) + wake_up_interruptible(sk->sleep); + } else { + NET_INC_STATS_BH(TCPPrequeueDropped); + tp->ucopy.memory -= skb->truesize; + kfree_skb(skb); + } + return 1; + } + return 0; } + #undef STATE_TRACE #ifdef STATE_TRACE @@ -1007,9 +1201,12 @@ static __inline__ void tcp_done(struct sock *sk) { + tcp_set_state(sk, TCP_CLOSE); + tcp_clear_xmit_timers(sk); + sk->shutdown = SHUTDOWN_MASK; - if (!sk->dead) + if (!sk->dead) sk->state_change(sk); else tcp_destroy_sock(sk); @@ -1106,7 +1303,7 @@ * our initial window offering to 32k. There should also * be a sysctl option to stop being nice. */ - (*rcv_wnd) = min(space, MAX_WINDOW); + (*rcv_wnd) = min(space, MAX_TCP_WINDOW); (*rcv_wscale) = 0; if (wscale_ok) { /* See RFC1323 for an explanation of the limit to 14 */ @@ -1123,52 +1320,127 @@ extern __inline__ int tcp_space(struct sock *sk) { return (sk->rcvbuf - atomic_read(&sk->rmem_alloc)) / - WINDOW_ADVERTISE_DIVISOR; + TCP_WINDOW_ADVERTISE_DIVISOR; } extern __inline__ int tcp_full_space( struct sock *sk) { - return sk->rcvbuf / WINDOW_ADVERTISE_DIVISOR; + return sk->rcvbuf / TCP_WINDOW_ADVERTISE_DIVISOR; +} + +extern __inline__ void tcp_init_buffer_space(struct sock *sk) +{ + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int rcvbuf = tp->advmss+MAX_TCP_HEADER+16+sizeof(struct sk_buff); + int sndbuf = tp->mss_clamp+MAX_TCP_HEADER+16+sizeof(struct sk_buff); + + if (sk->rcvbuf < 3*rcvbuf) + sk->rcvbuf = min (3*rcvbuf, sysctl_rmem_max); + if (sk->sndbuf < 3*sndbuf) + sk->sndbuf = min (3*sndbuf, sysctl_wmem_max); } -extern __inline__ void tcp_synq_unlink(struct tcp_opt *tp, struct open_request *req, struct open_request *prev) +extern __inline__ void tcp_acceptq_removed(struct sock *sk) { - if(!req->dl_next) - tp->syn_wait_last = (struct open_request **)prev; - prev->dl_next = req->dl_next; + sk->ack_backlog--; } -extern __inline__ void tcp_synq_queue(struct tcp_opt *tp, struct open_request *req) -{ - req->dl_next = NULL; - *tp->syn_wait_last = req; - tp->syn_wait_last = &req->dl_next; +extern __inline__ void tcp_acceptq_added(struct sock *sk) +{ + sk->ack_backlog++; } -extern __inline__ void tcp_synq_init(struct tcp_opt *tp) +extern __inline__ int tcp_acceptq_is_full(struct sock *sk) { - tp->syn_wait_queue = NULL; - tp->syn_wait_last = &tp->syn_wait_queue; + return sk->ack_backlog > sk->max_ack_backlog; } -extern void __tcp_inc_slow_timer(struct tcp_sl_timer *slt); -extern __inline__ void tcp_inc_slow_timer(int timer) +extern __inline__ void tcp_acceptq_queue(struct sock *sk, struct open_request *req, + struct sock *child) { - struct tcp_sl_timer *slt = &tcp_slt_array[timer]; - - if (atomic_read(&slt->count) == 0) - { - __tcp_inc_slow_timer(slt); - } + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - atomic_inc(&slt->count); + req->sk = child; + tcp_acceptq_added(sk); + + req->dl_next = tp->accept_queue; + tp->accept_queue = req; } -extern __inline__ void tcp_dec_slow_timer(int timer) +struct tcp_listen_opt +{ + u8 max_qlen_log; /* log_2 of maximal queued SYNs */ + int qlen; + int qlen_young; + int clock_hand; + struct open_request *syn_table[TCP_SYNQ_HSIZE]; +}; + +extern __inline__ void +tcp_synq_removed(struct sock *sk, struct open_request *req) { - struct tcp_sl_timer *slt = &tcp_slt_array[timer]; + struct tcp_listen_opt *lopt = sk->tp_pinfo.af_tcp.listen_opt; + + if (--lopt->qlen == 0) + tcp_delete_keepalive_timer(sk); + if (req->retrans == 0) + lopt->qlen_young--; +} - atomic_dec(&slt->count); +extern __inline__ void tcp_synq_added(struct sock *sk) +{ + struct tcp_listen_opt *lopt = sk->tp_pinfo.af_tcp.listen_opt; + + if (lopt->qlen++ == 0) + tcp_reset_keepalive_timer(sk, TCP_TIMEOUT_INIT); + lopt->qlen_young++; +} + +extern __inline__ int tcp_synq_len(struct sock *sk) +{ + return sk->tp_pinfo.af_tcp.listen_opt->qlen; +} + +extern __inline__ int tcp_synq_young(struct sock *sk) +{ + return sk->tp_pinfo.af_tcp.listen_opt->qlen_young; +} + +extern __inline__ int tcp_synq_is_full(struct sock *sk) +{ + return tcp_synq_len(sk)>>sk->tp_pinfo.af_tcp.listen_opt->max_qlen_log; +} + +extern __inline__ void tcp_synq_unlink(struct tcp_opt *tp, struct open_request *req, + struct open_request **prev) +{ + write_lock(&tp->syn_wait_lock); + *prev = req->dl_next; + write_unlock(&tp->syn_wait_lock); +} + +extern __inline__ void tcp_synq_drop(struct sock *sk, struct open_request *req, + struct open_request **prev) +{ + tcp_synq_unlink(&sk->tp_pinfo.af_tcp, req, prev); + tcp_synq_removed(sk, req); + tcp_openreq_free(req); +} + +static __inline__ void tcp_openreq_init(struct open_request *req, + struct tcp_opt *tp, + struct sk_buff *skb) +{ + req->rcv_wnd = 0; /* So that tcp_send_synack() knows! */ + req->rcv_isn = TCP_SKB_CB(skb)->seq; + req->mss = tp->mss_clamp; + req->ts_recent = tp->saw_tstamp ? tp->rcv_tsval : 0; + req->tstamp_ok = tp->tstamp_ok; + req->sack_ok = tp->sack_ok; + req->snd_wscale = tp->snd_wscale; + req->wscale_ok = tp->wscale_ok; + req->acked = 0; + req->rmt_port = skb->h.th->source; } extern const char timer_bug_msg[]; @@ -1179,13 +1451,14 @@ struct timer_list *timer; switch (what) { - case TIME_RETRANS: + case TCP_TIME_RETRANS: timer = &tp->retransmit_timer; break; - case TIME_DACK: + case TCP_TIME_DACK: + tp->ack.blocked = 0; timer = &tp->delack_timer; break; - case TIME_PROBE0: + case TCP_TIME_PROBE0: timer = &tp->probe_timer; break; default: @@ -1199,7 +1472,7 @@ spin_unlock_bh(&sk->timer_lock); } -/* This function does not return reliable answer. You is only as advice. +/* This function does not return reliable answer. Use it only as advice. */ static inline int tcp_timer_is_set(struct sock *sk, int what) @@ -1208,13 +1481,13 @@ int ret; switch (what) { - case TIME_RETRANS: + case TCP_TIME_RETRANS: ret = tp->retransmit_timer.prev != NULL; break; - case TIME_DACK: + case TCP_TIME_DACK: ret = tp->delack_timer.prev != NULL; break; - case TIME_PROBE0: + case TCP_TIME_PROBE0: ret = tp->probe_timer.prev != NULL; break; default: @@ -1248,18 +1521,46 @@ static inline int keepalive_intvl_when(struct tcp_opt *tp) { - if (tp->keepalive_intvl) - return tp->keepalive_intvl; - else - return sysctl_tcp_keepalive_intvl; + return tp->keepalive_intvl ? : sysctl_tcp_keepalive_intvl; } static inline int keepalive_time_when(struct tcp_opt *tp) { - if (tp->keepalive_time) - return tp->keepalive_time; - else - return sysctl_tcp_keepalive_time; + return tp->keepalive_time ? : sysctl_tcp_keepalive_time; } + +static inline int tcp_fin_time(struct tcp_opt *tp) +{ + int fin_timeout = tp->linger2 ? : sysctl_tcp_fin_timeout; + + if (fin_timeout < (tp->rto<<2) - (tp->rto>>1)) + fin_timeout = (tp->rto<<2) - (tp->rto>>1); + + return fin_timeout; +} + +#if 0 /* TCP_DEBUG */ +#define TCP_CHECK_TIMER(sk) \ +do { struct tcp_opt *__tp = &sk->tp_pinfo.af_tcp; \ + if (sk->state != TCP_CLOSE) { \ + if (__tp->packets_out) { \ + if (!tcp_timer_is_set(sk, TCP_TIME_RETRANS) && !timer_is_running(&__tp->retransmit_timer) && net_ratelimit()) \ + printk(KERN_DEBUG "sk=%p RETRANS" __FUNCTION__ "(%d) %d\n", sk, __LINE__, sk->state); \ + } else if (__tp->send_head) { \ + if (!tcp_timer_is_set(sk, TCP_TIME_PROBE0) && !timer_is_running(&__tp->probe_timer) && net_ratelimit()) \ + printk(KERN_DEBUG "sk=%p PROBE0" __FUNCTION__ "(%d) %d\n", sk, __LINE__, sk->state); \ + } \ + if (__tp->ack.pending) { \ + if (!tcp_timer_is_set(sk, TCP_TIME_DACK) && !timer_is_running(&__tp->delack_timer) && net_ratelimit()) \ + printk(KERN_DEBUG "sk=%p DACK" __FUNCTION__ "(%d) %d\n", sk, __LINE__, sk->state); \ + } \ + if (__tp->packets_out > skb_queue_len(&sk->write_queue) || \ + (__tp->send_head && skb_queue_len(&sk->write_queue) == 0)) { \ + printk(KERN_DEBUG "sk=%p QUEUE" __FUNCTION__ "(%d) %d %d %d %p\n", sk, __LINE__, sk->state, __tp->packets_out, skb_queue_len(&sk->write_queue), __tp->send_head); \ + } \ + } } while (0) +#else +#define TCP_CHECK_TIMER(sk) do { } while (0); +#endif #endif /* _TCP_H */ diff -ur --new-file old/linux/ipc/shm.c new/linux/ipc/shm.c --- old/linux/ipc/shm.c Wed Jan 12 04:18:38 2000 +++ new/linux/ipc/shm.c Mon Jan 24 20:04:37 2000 @@ -584,15 +584,10 @@ */ static struct vm_operations_struct shm_vm_ops = { - shm_open, /* open - callback for a new vm-area open */ - shm_close, /* close - callback for when the vm-area is released */ - NULL, /* no need to sync pages at unmap */ - NULL, /* protect */ - NULL, /* sync */ - NULL, /* advise */ - shm_nopage, /* nopage */ - NULL, /* wppage */ - shm_swapout /* swapout */ + open: shm_open, /* open - callback for a new vm-area open */ + close: shm_close, /* close - callback for when the vm-area is released */ + nopage: shm_nopage, + swapout: shm_swapout, }; /* Insert shmd into the list shp->attaches */ diff -ur --new-file old/linux/kernel/dma.c new/linux/kernel/dma.c --- old/linux/kernel/dma.c Wed Sep 8 20:42:15 1999 +++ new/linux/kernel/dma.c Wed Jan 26 22:29:39 2000 @@ -16,6 +16,7 @@ #include #include + /* A note on resource allocation: * @@ -35,6 +36,12 @@ spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED; +/* + * If our port doesn't define this it has no PC like DMA + */ + +#ifdef MAX_DMA_CHANNELS + /* Channel n is busy iff dma_chan_busy[n].lock != 0. * DMA0 used to be reserved for DRAM refresh, but apparently not any more... @@ -100,3 +107,22 @@ } } /* free_dma */ + +#else + +int request_dma(unsigned int dmanr, const char *device_id) +{ + return -EINVAL; +} + +int free_dma(unsigned int dmanr) +{ + return -EINVAL; +} + +int get_dma_list(char *buf) +{ + strcpy(buf, "No DMA\n"); + return 7; +} +#endif diff -ur --new-file old/linux/kernel/exit.c new/linux/kernel/exit.c --- old/linux/kernel/exit.c Mon Nov 8 19:19:19 1999 +++ new/linux/kernel/exit.c Tue Jan 25 19:43:39 2000 @@ -416,9 +416,6 @@ tsk->exit_code = code; exit_notify(); task_unlock(tsk); -#ifdef DEBUG_PROC_TREE - audit_ptree(); -#endif if (tsk->exec_domain && tsk->exec_domain->module) __MOD_DEC_USE_COUNT(tsk->exec_domain->module); if (tsk->binfmt && tsk->binfmt->module) @@ -508,9 +505,6 @@ notify_parent(p, SIGCHLD); } else release(p); -#ifdef DEBUG_PROC_TREE - audit_ptree(); -#endif goto end_wait4; default: continue; diff -ur --new-file old/linux/kernel/ksyms.c new/linux/kernel/ksyms.c --- old/linux/kernel/ksyms.c Wed Jan 19 03:54:21 2000 +++ new/linux/kernel/ksyms.c Wed Jan 26 21:43:03 2000 @@ -183,7 +183,6 @@ EXPORT_SYMBOL(ll_rw_block); EXPORT_SYMBOL(__wait_on_buffer); EXPORT_SYMBOL(___wait_on_page); -EXPORT_SYMBOL(add_blkdev_randomness); EXPORT_SYMBOL(block_read_full_page); EXPORT_SYMBOL(block_write_full_page); EXPORT_SYMBOL(block_write_partial_page); @@ -270,7 +269,6 @@ EXPORT_SYMBOL(init_buffer); EXPORT_SYMBOL(refile_buffer); EXPORT_SYMBOL(max_sectors); -EXPORT_SYMBOL(max_segments); EXPORT_SYMBOL(max_readahead); EXPORT_SYMBOL(file_moveto); @@ -432,11 +430,14 @@ EXPORT_SYMBOL(__up); EXPORT_SYMBOL(brw_page); +#ifdef CONFIG_UID16 +EXPORT_SYMBOL(overflowuid); +EXPORT_SYMBOL(overflowgid); +#endif EXPORT_SYMBOL(fs_overflowuid); EXPORT_SYMBOL(fs_overflowgid); /* all busmice */ -EXPORT_SYMBOL(add_mouse_randomness); EXPORT_SYMBOL(fasync_helper); #ifdef CONFIG_BLK_DEV_MD diff -ur --new-file old/linux/kernel/sched.c new/linux/kernel/sched.c --- old/linux/kernel/sched.c Thu Jan 20 18:51:42 2000 +++ new/linux/kernel/sched.c Tue Jan 25 00:11:30 2000 @@ -477,7 +477,7 @@ goto move_rr_last; move_rr_back: - switch (prev->state) { + switch (prev->state & ~TASK_EXCLUSIVE) { case TASK_INTERRUPTIBLE: if (signal_pending(prev)) { prev->state = TASK_RUNNING; diff -ur --new-file old/linux/kernel/signal.c new/linux/kernel/signal.c --- old/linux/kernel/signal.c Thu Jan 20 19:48:35 2000 +++ new/linux/kernel/signal.c Fri Jan 21 18:48:31 2000 @@ -12,7 +12,6 @@ #include #include #include -#include #include @@ -166,7 +165,6 @@ info->si_code = 0; info->si_pid = 0; info->si_uid = 0; - SET_SIGINFO_UID16(info->si_uid16, 0); } if (reset) @@ -325,7 +323,6 @@ q->info.si_code = SI_USER; q->info.si_pid = current->pid; q->info.si_uid = current->uid; - SET_SIGINFO_UID16(q->info.si_uid16, current->uid); break; case 1: q->info.si_signo = sig; @@ -333,7 +330,6 @@ q->info.si_code = SI_KERNEL; q->info.si_pid = 0; q->info.si_uid = 0; - SET_SIGINFO_UID16(q->info.si_uid16, 0); break; default: q->info = *info; @@ -783,7 +779,6 @@ info.si_code = SI_USER; info.si_pid = current->pid; info.si_uid = current->uid; - SET_SIGINFO_UID16(info.si_uid16, current->uid); return kill_something_info(sig, &info, pid); } diff -ur --new-file old/linux/kernel/sys.c new/linux/kernel/sys.c --- old/linux/kernel/sys.c Tue Jan 18 07:22:52 2000 +++ new/linux/kernel/sys.c Thu Jan 27 15:32:14 2000 @@ -821,21 +821,16 @@ return 1; } -/* - * This should really be a blocking read-write lock - * rather than a semaphore. Anybody want to implement - * one? - */ -DECLARE_MUTEX(uts_sem); +DECLARE_RWSEM(uts_sem); asmlinkage long sys_newuname(struct new_utsname * name) { int errno = 0; - down(&uts_sem); + down_read(&uts_sem); if (copy_to_user(name,&system_utsname,sizeof *name)) errno = -EFAULT; - up(&uts_sem); + up_read(&uts_sem); return errno; } @@ -847,13 +842,13 @@ return -EPERM; if (len < 0 || len > __NEW_UTS_LEN) return -EINVAL; - down(&uts_sem); + down_write(&uts_sem); errno = -EFAULT; if (!copy_from_user(system_utsname.nodename, name, len)) { system_utsname.nodename[len] = 0; errno = 0; } - up(&uts_sem); + up_write(&uts_sem); return errno; } @@ -863,14 +858,14 @@ if (len < 0) return -EINVAL; - down(&uts_sem); + down_read(&uts_sem); i = 1 + strlen(system_utsname.nodename); if (i > len) i = len; errno = 0; if (copy_to_user(name, system_utsname.nodename, i)) errno = -EFAULT; - up(&uts_sem); + up_read(&uts_sem); return errno; } @@ -887,13 +882,13 @@ if (len < 0 || len > __NEW_UTS_LEN) return -EINVAL; - down(&uts_sem); + down_write(&uts_sem); errno = -EFAULT; if (!copy_from_user(system_utsname.domainname, name, len)) { errno = 0; system_utsname.domainname[len] = 0; } - up(&uts_sem); + up_write(&uts_sem); return errno; } diff -ur --new-file old/linux/kernel/sysctl.c new/linux/kernel/sysctl.c --- old/linux/kernel/sysctl.c Sun Jan 16 07:08:28 2000 +++ new/linux/kernel/sysctl.c Thu Jan 27 15:32:14 2000 @@ -43,7 +43,7 @@ extern int max_threads; extern int nr_queued_signals, max_queued_signals; -/* this is needed for the proc_dointvec_minmax for overflow UID and GID */ +/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ static int maxolduid = 65535; static int minolduid = 0; @@ -722,9 +722,16 @@ void *buffer, size_t *lenp) { int r; - down(&uts_sem); - r=proc_dostring(table,write,filp,buffer,lenp); - up(&uts_sem); + + if (!write) { + down_read(&uts_sem); + r=proc_dostring(table,0,filp,buffer,lenp); + up_read(&uts_sem); + } else { + down_write(&uts_sem); + r=proc_dostring(table,1,filp,buffer,lenp); + up_write(&uts_sem); + } return r; } diff -ur --new-file old/linux/lib/vsprintf.c new/linux/lib/vsprintf.c --- old/linux/lib/vsprintf.c Tue Nov 9 02:03:01 1999 +++ new/linux/lib/vsprintf.c Wed Jan 26 21:29:12 2000 @@ -152,6 +152,7 @@ number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ /* 'z' support added 23/7/1999 S.H. */ + /* 'z' changed to 'Z' --davidm 1/25/99 */ for (str=buf ; *fmt ; ++fmt) { @@ -203,7 +204,7 @@ /* get the conversion qualifier */ qualifier = -1; - if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='z') { + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { qualifier = *fmt; ++fmt; } @@ -252,7 +253,7 @@ if (qualifier == 'l') { long * ip = va_arg(args, long *); *ip = (str - buf); - } else if (qualifier == 'z') { + } else if (qualifier == 'Z') { size_t * ip = va_arg(args, size_t *); *ip = (str - buf); } else { @@ -296,7 +297,7 @@ num = va_arg(args, unsigned long); if (flags & SIGN) num = (signed long) num; - } else if (qualifier == 'z') { + } else if (qualifier == 'Z') { num = va_arg(args, size_t); } else if (qualifier == 'h') { num = (unsigned short) va_arg(args, int); diff -ur --new-file old/linux/mm/filemap.c new/linux/mm/filemap.c --- old/linux/mm/filemap.c Tue Jan 11 20:38:55 2000 +++ new/linux/mm/filemap.c Mon Jan 24 20:04:37 2000 @@ -1627,15 +1627,10 @@ * backing-store for swapping.. */ static struct vm_operations_struct file_shared_mmap = { - NULL, /* no special open */ - NULL, /* no special close */ - filemap_unmap, /* unmap - we need to sync the pages */ - NULL, /* no special protect */ - filemap_sync, /* sync */ - NULL, /* advise */ - filemap_nopage, /* nopage */ - NULL, /* wppage */ - filemap_swapout /* swapout */ + unmap: filemap_unmap, /* unmap - we need to sync the pages */ + sync: filemap_sync, + nopage: filemap_nopage, + swapout: filemap_swapout, }; /* @@ -1645,15 +1640,7 @@ * know they can't ever get write permissions..) */ static struct vm_operations_struct file_private_mmap = { - NULL, /* open */ - NULL, /* close */ - NULL, /* unmap */ - NULL, /* protect */ - NULL, /* sync */ - NULL, /* advise */ - filemap_nopage, /* nopage */ - NULL, /* wppage */ - NULL /* swapout */ + nopage: filemap_nopage, }; /* This is used for a general mmap of a disk file */ diff -ur --new-file old/linux/mm/page_alloc.c new/linux/mm/page_alloc.c --- old/linux/mm/page_alloc.c Fri Jan 7 01:21:23 2000 +++ new/linux/mm/page_alloc.c Wed Jan 26 22:19:15 2000 @@ -6,6 +6,7 @@ * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 * Reshaped it to be a zoned allocator, Ingo Molnar, Red Hat, 1999 * Discontiguous memory support, Kanoj Sarcar, SGI, Nov 1999 + * Zone balancing, Kanoj Sarcar, SGI, Jan 2000 */ #include @@ -28,6 +29,7 @@ LIST_HEAD(lru_cache); static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" }; +static int zone_balance_ratio[MAX_NR_ZONES] = { 128, 128, 128 }; /* * Free_page() adds the page to the free lists. This is optimized for @@ -197,18 +199,32 @@ #define ZONE_BALANCED(zone) \ (((zone)->free_pages > (zone)->pages_low) && (!(zone)->low_on_memory)) +static inline unsigned long classfree(zone_t *zone) +{ + unsigned long free = 0; + zone_t *z = zone->zone_pgdat->node_zones; + + while (z != zone) { + free += z->free_pages; + z++; + } + free += zone->free_pages; + return(free); +} + static inline int zone_balance_memory (zone_t *zone, int gfp_mask) { int freed; + unsigned long free = classfree(zone); - if (zone->free_pages >= zone->pages_low) { + if (free >= zone->pages_low) { if (!zone->low_on_memory) return 1; /* * Simple hysteresis: exit 'low memory mode' if * the upper limit has been reached: */ - if (zone->free_pages >= zone->pages_high) { + if (free >= zone->pages_high) { zone->low_on_memory = 0; return 1; } @@ -220,18 +236,14 @@ * state machine, but do not try to free pages * ourselves. */ - if (!(gfp_mask & __GFP_WAIT)) - return 1; - - current->flags |= PF_MEMALLOC; freed = try_to_free_pages(gfp_mask, zone); - current->flags &= ~PF_MEMALLOC; - if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH))) + if (!freed && !(gfp_mask & __GFP_HIGH)) return 0; return 1; } +#if 0 /* * We are still balancing memory in a global way: */ @@ -260,17 +272,13 @@ * state machine, but do not try to free pages * ourselves. */ - if (!(gfp_mask & __GFP_WAIT)) - return 1; - - current->flags |= PF_MEMALLOC; freed = try_to_free_pages(gfp_mask, zone); - current->flags &= ~PF_MEMALLOC; - if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH))) + if (!freed && !(gfp_mask & __GFP_HIGH)) return 0; return 1; } +#endif /* * This is the 'heart' of the zoned buddy allocator: @@ -340,7 +348,7 @@ * The main chunk of the balancing code is in this offline branch: */ balance: - if (!balance_memory(z, gfp_mask)) + if (!zone_balance_memory(z, gfp_mask)) goto nopage; goto ready; } @@ -513,6 +521,7 @@ unsigned long i, j; unsigned long map_size; unsigned int totalpages, offset; + unsigned int cumulative = 0; totalpages = 0; for (i = 0; i < MAX_NR_ZONES; i++) { @@ -565,7 +574,7 @@ offset = lmem_map - mem_map; for (j = 0; j < MAX_NR_ZONES; j++) { zone_t *zone = pgdat->node_zones + j; - unsigned long mask = -1; + unsigned long mask; unsigned long size; size = zones_size[j]; @@ -579,13 +588,11 @@ continue; zone->offset = offset; - /* - * It's unnecessery to balance the high memory zone - */ - if (j != ZONE_HIGHMEM) { - zone->pages_low = freepages.low; - zone->pages_high = freepages.high; - } + cumulative += size; + mask = (cumulative / zone_balance_ratio[j]); + if (mask < 1) mask = 1; + zone->pages_low = mask*2; + zone->pages_high = mask*3; zone->low_on_memory = 0; for (i = 0; i < size; i++) { @@ -598,6 +605,7 @@ } offset += size; + mask = -1; for (i = 0; i < MAX_ORDER; i++) { unsigned long bitmap_size; @@ -618,3 +626,16 @@ { free_area_init_core(0, NODE_DATA(0), &mem_map, zones_size, 0); } + +static int __init setup_mem_frac(char *str) +{ + int j = 0; + + while (get_option(&str, &zone_balance_ratio[j++]) == 2); + printk("setup_mem_frac: "); + for (j = 0; j < MAX_NR_ZONES; j++) printk("%d ", zone_balance_ratio[j]); + printk("\n"); + return 1; +} + +__setup("memfrac=", setup_mem_frac); diff -ur --new-file old/linux/mm/vmscan.c new/linux/mm/vmscan.c --- old/linux/mm/vmscan.c Thu Jan 13 22:31:30 2000 +++ new/linux/mm/vmscan.c Wed Jan 26 22:23:24 2000 @@ -33,7 +33,7 @@ * using a process that no longer actually exists (it might * have died while we slept). */ -static int try_to_swap_out(struct vm_area_struct* vma, unsigned long address, pte_t * page_table, int gfp_mask, zone_t *zone) +static int try_to_swap_out(struct vm_area_struct* vma, unsigned long address, pte_t * page_table, int gfp_mask) { pte_t pte; swp_entry_t entry; @@ -58,9 +58,7 @@ goto out_failed; } - if (PageReserved(page) - || PageLocked(page) - || (zone && (!memclass(page->zone, zone)))) + if (PageReserved(page) || PageLocked(page)) goto out_failed; /* @@ -195,7 +193,7 @@ * (C) 1993 Kai Petzke, wpp@marie.physik.tu-berlin.de */ -static inline int swap_out_pmd(struct vm_area_struct * vma, pmd_t *dir, unsigned long address, unsigned long end, int gfp_mask, zone_t *zone) +static inline int swap_out_pmd(struct vm_area_struct * vma, pmd_t *dir, unsigned long address, unsigned long end, int gfp_mask) { pte_t * pte; unsigned long pmd_end; @@ -217,7 +215,7 @@ do { int result; vma->vm_mm->swap_address = address + PAGE_SIZE; - result = try_to_swap_out(vma, address, pte, gfp_mask, zone); + result = try_to_swap_out(vma, address, pte, gfp_mask); if (result) return result; address += PAGE_SIZE; @@ -226,7 +224,7 @@ return 0; } -static inline int swap_out_pgd(struct vm_area_struct * vma, pgd_t *dir, unsigned long address, unsigned long end, int gfp_mask, zone_t *zone) +static inline int swap_out_pgd(struct vm_area_struct * vma, pgd_t *dir, unsigned long address, unsigned long end, int gfp_mask) { pmd_t * pmd; unsigned long pgd_end; @@ -246,7 +244,7 @@ end = pgd_end; do { - int result = swap_out_pmd(vma, pmd, address, end, gfp_mask, zone); + int result = swap_out_pmd(vma, pmd, address, end, gfp_mask); if (result) return result; address = (address + PMD_SIZE) & PMD_MASK; @@ -255,7 +253,7 @@ return 0; } -static int swap_out_vma(struct vm_area_struct * vma, unsigned long address, int gfp_mask, zone_t *zone) +static int swap_out_vma(struct vm_area_struct * vma, unsigned long address, int gfp_mask) { pgd_t *pgdir; unsigned long end; @@ -270,7 +268,7 @@ if (address >= end) BUG(); do { - int result = swap_out_pgd(vma, pgdir, address, end, gfp_mask, zone); + int result = swap_out_pgd(vma, pgdir, address, end, gfp_mask); if (result) return result; address = (address + PGDIR_SIZE) & PGDIR_MASK; @@ -279,7 +277,7 @@ return 0; } -static int swap_out_mm(struct mm_struct * mm, int gfp_mask, zone_t *zone) +static int swap_out_mm(struct mm_struct * mm, int gfp_mask) { unsigned long address; struct vm_area_struct* vma; @@ -300,7 +298,7 @@ address = vma->vm_start; for (;;) { - int result = swap_out_vma(vma, address, gfp_mask, zone); + int result = swap_out_vma(vma, address, gfp_mask); if (result) return result; vma = vma->vm_next; @@ -322,7 +320,7 @@ * N.B. This function returns only 0 or 1. Return values != 1 from * the lower level routines result in continued processing. */ -static int swap_out(unsigned int priority, int gfp_mask, zone_t *zone) +static int swap_out(unsigned int priority, int gfp_mask) { struct task_struct * p; int counter; @@ -383,7 +381,7 @@ int ret; atomic_inc(&best->mm_count); - ret = swap_out_mm(best, gfp_mask, zone); + ret = swap_out_mm(best, gfp_mask); mmdrop(best); if (!ret) @@ -424,16 +422,18 @@ goto done; } - /* don't be too light against the d/i cache since - shrink_mmap() almost never fail when there's - really plenty of memory free. */ - count -= shrink_dcache_memory(priority, gfp_mask, zone); - count -= shrink_icache_memory(priority, gfp_mask, zone); - if (count <= 0) - goto done; /* Try to get rid of some shared memory pages.. */ if (gfp_mask & __GFP_IO) { + /* + * don't be too light against the d/i cache since + * shrink_mmap() almost never fail when there's + * really plenty of memory free. + */ + count -= shrink_dcache_memory(priority, gfp_mask, zone); + count -= shrink_icache_memory(priority, gfp_mask, zone); + if (count <= 0) + goto done; while (shm_swap(priority, gfp_mask, zone)) { if (!--count) goto done; @@ -441,7 +441,7 @@ } /* Then, try to page stuff out.. */ - while (swap_out(priority, gfp_mask, zone)) { + while (swap_out(priority, gfp_mask)) { if (!--count) goto done; } @@ -534,8 +534,11 @@ int retval = 1; wake_up_process(kswapd_process); - if (gfp_mask & __GFP_WAIT) + if (gfp_mask & __GFP_WAIT) { + current->flags |= PF_MEMALLOC; retval = do_try_to_free_pages(gfp_mask, zone); + current->flags &= ~PF_MEMALLOC; + } return retval; } diff -ur --new-file old/linux/net/atm/common.c new/linux/net/atm/common.c --- old/linux/net/atm/common.c Mon Jan 31 16:04:08 2000 +++ new/linux/net/atm/common.c Mon Jan 31 16:05:41 2000 @@ -476,13 +476,13 @@ vcc = ATM_SD(sock); switch (cmd) { - case TIOCOUTQ: + case SIOCOUTQ: if (sock->state != SS_CONNECTED || !(vcc->flags & ATM_VF_READY)) return -EINVAL; return put_user(vcc->sk->sndbuf- atomic_read(&vcc->tx_inuse)-ATM_PDU_OVHD, (int *) arg) ? -EFAULT : 0; - case TIOCINQ: + case SIOCINQ: { struct sk_buff *skb; diff -ur --new-file old/linux/net/atm/signaling.c new/linux/net/atm/signaling.c --- old/linux/net/atm/signaling.c Mon Jan 31 16:04:09 2000 +++ new/linux/net/atm/signaling.c Mon Jan 31 16:05:42 2000 @@ -162,7 +162,7 @@ while (!(skb = alloc_skb(sizeof(struct atmsvc_msg),GFP_KERNEL))) schedule(); msg = (struct atmsvc_msg *) skb_put(skb,sizeof(struct atmsvc_msg)); - memset(msg,0,sizeof(msg)); + memset(msg,0,sizeof(*msg)); msg->type = type; *(struct atm_vcc **) &msg->vcc = vcc; *(struct atm_vcc **) &msg->listen_vcc = listen_vcc; diff -ur --new-file old/linux/net/atm/svc.c new/linux/net/atm/svc.c --- old/linux/net/atm/svc.c Wed Sep 8 20:14:32 1999 +++ new/linux/net/atm/svc.c Mon Jan 31 16:05:42 2000 @@ -1,6 +1,6 @@ /* net/atm/svc.c - ATM SVC sockets */ -/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ #include @@ -253,6 +253,7 @@ new_vcc->qos = msg->qos; new_vcc->flags |= ATM_VF_HASQOS; new_vcc->remote = msg->svc; + new_vcc->local = msg->local; new_vcc->sap = msg->sap; error = atm_connect(newsock,msg->pvc.sap_addr.itf, msg->pvc.sap_addr.vpi,msg->pvc.sap_addr.vci); diff -ur --new-file old/linux/net/ax25/af_ax25.c new/linux/net/ax25/af_ax25.c --- old/linux/net/ax25/af_ax25.c Thu Jan 20 19:48:35 2000 +++ new/linux/net/ax25/af_ax25.c Tue Jan 25 20:41:10 2000 @@ -1313,7 +1313,7 @@ int lv; int addr_len = msg->msg_namelen; - if (msg->msg_flags & ~MSG_DONTWAIT) + if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR)) return -EINVAL; if (sk->zapped) diff -ur --new-file old/linux/net/core/datagram.c new/linux/net/core/datagram.c --- old/linux/net/core/datagram.c Tue Dec 14 07:47:05 1999 +++ new/linux/net/core/datagram.c Sat Jan 22 20:54:57 2000 @@ -60,14 +60,14 @@ * Wait for a packet.. */ -static int wait_for_packet(struct sock * sk, int *err) +static int wait_for_packet(struct sock * sk, int *err, long *timeo_p) { int error; DECLARE_WAITQUEUE(wait, current); - __set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(sk->sleep, &wait); + __set_current_state(TASK_INTERRUPTIBLE|TASK_EXCLUSIVE); + add_wait_queue_exclusive(sk->sleep, &wait); /* Socket errors? */ error = sock_error(sk); @@ -91,7 +91,7 @@ if (signal_pending(current)) goto out; - schedule(); + *timeo_p = schedule_timeout(*timeo_p); ready: current->state = TASK_RUNNING; @@ -132,12 +132,15 @@ { int error; struct sk_buff *skb; + long timeo; /* Caller is allowed not to check sk->err before skb_recv_datagram() */ error = sock_error(sk); if (error) goto no_packet; + timeo = sock_rcvtimeo(sk, noblock); + do { /* Again only user level code calls this function, so nothing interrupt level will suddenly eat the receive_queue. @@ -162,10 +165,10 @@ /* User doesn't want to wait */ error = -EAGAIN; - if (noblock) + if (!timeo) goto no_packet; - } while (wait_for_packet(sk, err) == 0); + } while (wait_for_packet(sk, err, &timeo) == 0); return NULL; @@ -225,11 +228,11 @@ /* exceptional events? */ if (sk->err || !skb_queue_empty(&sk->error_queue)) mask |= POLLERR; - if (sk->shutdown & RCV_SHUTDOWN) + if (sk->shutdown == SHUTDOWN_MASK) mask |= POLLHUP; /* readable? */ - if (!skb_queue_empty(&sk->receive_queue)) + if (!skb_queue_empty(&sk->receive_queue) || (sk->shutdown&RCV_SHUTDOWN)) mask |= POLLIN | POLLRDNORM; /* Connection-based need to check for termination and startup */ diff -ur --new-file old/linux/net/core/iovec.c new/linux/net/core/iovec.c --- old/linux/net/core/iovec.c Sun Jan 9 06:36:20 2000 +++ new/linux/net/core/iovec.c Sat Jan 22 20:54:57 2000 @@ -104,6 +104,11 @@ /* Copy and checkum skb to user iovec. Caller _must_ check that skb will fit to this iovec. + + Returns: 0 - success. + -EINVAL - checksum failure. + -EFAULT - fault during copy. Beware, in this case iovec can be + modified! */ int copy_and_csum_toiovec(struct iovec *iov, struct sk_buff *skb, int hlen) @@ -111,7 +116,7 @@ unsigned int csum; int chunk = skb->len - hlen; - /* Skip filled elements. Pretty silly, look at mecpy_toiove, though 8) */ + /* Skip filled elements. Pretty silly, look at memcpy_toiovec, though 8) */ while (iov->iov_len == 0) iov++; @@ -119,7 +124,7 @@ if ((unsigned short)csum_fold(csum_partial(skb->h.raw, chunk+hlen, skb->csum))) goto csum_error; if (memcpy_toiovec(iov, skb->h.raw + hlen, chunk)) - goto csum_error; + goto fault; } else { int err = 0; csum = csum_partial(skb->h.raw, hlen, skb->csum); @@ -133,6 +138,9 @@ return 0; csum_error: + return -EINVAL; + +fault: return -EFAULT; } diff -ur --new-file old/linux/net/core/skbuff.c new/linux/net/core/skbuff.c --- old/linux/net/core/skbuff.c Mon Jan 3 21:01:31 2000 +++ new/linux/net/core/skbuff.c Sat Jan 22 20:54:57 2000 @@ -4,7 +4,7 @@ * Authors: Alan Cox * Florian La Roche * - * Version: $Id: skbuff.c,v 1.63 2000/01/02 09:15:17 davem Exp $ + * Version: $Id: skbuff.c,v 1.64 2000/01/16 05:11:03 davem Exp $ * * Fixes: * Alan Cox : Fixed the worst of the load balancer bugs. @@ -61,10 +61,6 @@ #include #include -#ifdef CONFIG_ATM -#include -#endif - /* * Resource tracking variables */ @@ -165,10 +161,6 @@ skb->is_clone = 0; skb->cloned = 0; -#ifdef CONFIG_ATM - ATM_SKB(skb)->iovcnt = 0; -#endif - atomic_set(&skb->users, 1); atomic_set(skb_datarefp(skb), 1); return skb; @@ -206,6 +198,9 @@ skb->nf_debug = 0; #endif #endif +#ifdef CONFIG_NET_SCHED + skb->tc_index = 0; +#endif memset(skb->cb, 0, sizeof(skb->cb)); skb->priority = 0; } @@ -307,6 +302,9 @@ #ifdef CONFIG_NETFILTER_DEBUG new->nf_debug=old->nf_debug; #endif +#endif +#ifdef CONFIG_NET_SCHED + new->tc_index = old->tc_index; #endif } diff -ur --new-file old/linux/net/core/sock.c new/linux/net/core/sock.c --- old/linux/net/core/sock.c Thu Dec 23 04:55:38 1999 +++ new/linux/net/core/sock.c Sat Jan 22 20:54:57 2000 @@ -7,7 +7,7 @@ * handler for protocols to use and generic option handler. * * - * Version: $Id: sock.c,v 1.87 1999/11/23 08:56:59 davem Exp $ + * Version: $Id: sock.c,v 1.89 2000/01/18 08:24:13 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -140,6 +140,23 @@ /* Maximal space eaten by iovec or ancilliary data plus some space */ int sysctl_optmem_max = sizeof(unsigned long)*(2*UIO_MAXIOV + 512); +static int sock_set_timeout(long *timeo_p, char *optval, int optlen) +{ + struct timeval tv; + + if (optlen < sizeof(tv)) + return -EINVAL; + if (copy_from_user(&tv, optval, sizeof(tv))) + return -EFAULT; + + *timeo_p = MAX_SCHEDULE_TIMEOUT; + if (tv.tv_sec == 0 && tv.tv_usec == 0) + return 0; + if (tv.tv_sec < (MAX_SCHEDULE_TIMEOUT/HZ - 1)) + *timeo_p = tv.tv_sec*HZ + (tv.tv_usec+(1000000/HZ-1))/(1000000/HZ); + return 0; +} + /* * This is meant for all protocols to use and covers goings on * at the socket level. Everything here is generic. @@ -214,7 +231,7 @@ if (val > sysctl_wmem_max) val = sysctl_wmem_max; - sk->sndbuf = max(val*2,2048); + sk->sndbuf = max(val*2,SOCK_MIN_SNDBUF); /* * Wake up sending tasks if we @@ -233,7 +250,7 @@ val = sysctl_rmem_max; /* FIXME: is this lower bound the right one? */ - sk->rcvbuf = max(val*2,256); + sk->rcvbuf = max(val*2,SOCK_MIN_RCVBUF); break; case SO_KEEPALIVE: @@ -266,16 +283,19 @@ ret = -EINVAL; /* 1003.1g */ break; } - if (copy_from_user(&ling,optval,sizeof(ling))) - { + if (copy_from_user(&ling,optval,sizeof(ling))) { ret = -EFAULT; break; } - if(ling.l_onoff==0) + if(ling.l_onoff==0) { sk->linger=0; - else - { - sk->lingertime=ling.l_linger; + } else { +#if (BITS_PER_LONG == 32) + if (ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ) + sk->lingertime=MAX_SCHEDULE_TIMEOUT; + else +#endif + sk->lingertime=ling.l_linger*HZ; sk->linger=1; } break; @@ -287,8 +307,21 @@ case SO_PASSCRED: sock->passcred = valbool; break; - - + + case SO_RCVLOWAT: + if (val < 0) + val = INT_MAX; + sk->rcvlowat = val ? : 1; + break; + + case SO_RCVTIMEO: + ret = sock_set_timeout(&sk->rcvtimeo, optval, optlen); + break; + + case SO_SNDTIMEO: + ret = sock_set_timeout(&sk->sndtimeo, optval, optlen); + break; + #ifdef CONFIG_NETDEVICES case SO_BINDTODEVICE: { @@ -446,7 +479,7 @@ case SO_LINGER: lv=sizeof(v.ling); v.ling.l_onoff=sk->linger; - v.ling.l_linger=sk->lingertime; + v.ling.l_linger=sk->lingertime/HZ; break; case SO_BSDCOMPAT: @@ -454,13 +487,31 @@ break; case SO_RCVTIMEO: + lv=sizeof(struct timeval); + if (sk->rcvtimeo == MAX_SCHEDULE_TIMEOUT) { + v.tm.tv_sec = 0; + v.tm.tv_usec = 0; + } else { + v.tm.tv_sec = sk->rcvtimeo/HZ; + v.tm.tv_usec = ((sk->rcvtimeo%HZ)*1000)/HZ; + } + break; + case SO_SNDTIMEO: lv=sizeof(struct timeval); - v.tm.tv_sec=0; - v.tm.tv_usec=0; + if (sk->sndtimeo == MAX_SCHEDULE_TIMEOUT) { + v.tm.tv_sec = 0; + v.tm.tv_usec = 0; + } else { + v.tm.tv_sec = sk->sndtimeo/HZ; + v.tm.tv_usec = ((sk->sndtimeo%HZ)*1000)/HZ; + } break; case SO_RCVLOWAT: + v.val = sk->rcvlowat; + break; + case SO_SNDLOWAT: v.val=1; break; @@ -663,7 +714,7 @@ /* It is almost wait_for_tcp_memory minus release_sock/lock_sock. I think, these locks should be removed for datagram sockets. */ -static void sock_wait_for_wmem(struct sock * sk) +static long sock_wait_for_wmem(struct sock * sk, long timeo) { DECLARE_WAITQUEUE(wait, current); @@ -679,10 +730,11 @@ break; if (sk->err) break; - schedule(); + timeo = schedule_timeout(timeo); } __set_current_state(TASK_RUNNING); remove_wait_queue(sk->sleep, &wait); + return timeo; } @@ -695,6 +747,9 @@ { int err; struct sk_buff *skb; + long timeo; + + timeo = sock_sndtimeo(sk, noblock); while (1) { unsigned long try_size = size; @@ -736,12 +791,12 @@ sk->socket->flags |= SO_NOSPACE; err = -EAGAIN; - if (noblock) + if (!timeo) goto failure; err = -ERESTARTSYS; if (signal_pending(current)) goto failure; - sock_wait_for_wmem(sk); + timeo = sock_wait_for_wmem(sk, timeo); } return skb; @@ -771,13 +826,21 @@ void __release_sock(struct sock *sk) { struct sk_buff *skb = sk->backlog.head; + do { - struct sk_buff *next = skb->next; - skb->next = NULL; - sk->backlog_rcv(sk, skb); - skb = next; - } while(skb != NULL); - sk->backlog.head = sk->backlog.tail = NULL; + sk->backlog.head = sk->backlog.tail = NULL; + bh_unlock_sock(sk); + + do { + struct sk_buff *next = skb->next; + + skb->next = NULL; + sk->backlog_rcv(sk, skb); + skb = next; + } while (skb != NULL); + + bh_lock_sock(sk); + } while((skb = sk->backlog.head) != NULL); } /* @@ -1004,7 +1067,7 @@ { read_lock(&sk->callback_lock); if(!sk->dead) - wake_up_interruptible(sk->sleep); + wake_up_interruptible_all(sk->sleep); read_unlock(&sk->callback_lock); } @@ -1087,6 +1150,9 @@ sk->peercred.pid = 0; sk->peercred.uid = -1; sk->peercred.gid = -1; + sk->rcvlowat = 1; + sk->rcvtimeo = MAX_SCHEDULE_TIMEOUT; + sk->sndtimeo = MAX_SCHEDULE_TIMEOUT; atomic_set(&sk->refcnt, 1); } diff -ur --new-file old/linux/net/ethernet/eth.c new/linux/net/ethernet/eth.c --- old/linux/net/ethernet/eth.c Fri Sep 3 23:17:43 1999 +++ new/linux/net/ethernet/eth.c Sat Jan 22 20:54:57 2000 @@ -207,7 +207,7 @@ * seems to set IFF_PROMISC. */ - else if(dev->flags&(IFF_PROMISC/*|IFF_ALLMULTI*/)) + else if(1 /*dev->flags&IFF_PROMISC*/) { if(memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN)) skb->pkt_type=PACKET_OTHERHOST; @@ -265,7 +265,8 @@ memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len); } -#ifndef CONFIG_IP_ROUTER +#if 0 /*ndef CONFIG_IP_ROUTER*/ +/* This one is only slowdown with checksumming in user process context. --ANK */ /* * Copy from an ethernet device memory space to an sk_buff while checksumming if IP @@ -298,7 +299,7 @@ if ((ip_length <= length) && (ip_length > 7)) length=ip_length; - dest->csum=csum_partial_copy(src+sizeof(struct iphdr)+ETH_HLEN,dest->data+sizeof(struct iphdr)+ETH_HLEN,length,base); + dest->csum=csum_partial_copy_nocheck(src+sizeof(struct iphdr)+ETH_HLEN,dest->data+sizeof(struct iphdr)+ETH_HLEN,length,base); dest->ip_summed=1; } diff -ur --new-file old/linux/net/ipv4/af_inet.c new/linux/net/ipv4/af_inet.c --- old/linux/net/ipv4/af_inet.c Sun Jan 9 06:36:20 2000 +++ new/linux/net/ipv4/af_inet.c Sat Jan 22 20:54:57 2000 @@ -5,7 +5,7 @@ * * PF_INET protocol family socket handler. * - * Version: $Id: af_inet.c,v 1.101 2000/01/09 02:19:38 davem Exp $ + * Version: $Id: af_inet.c,v 1.104 2000/01/18 08:24:14 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -117,7 +117,9 @@ struct linux_mib net_statistics[NR_CPUS*2]; +#ifdef INET_REFCNT_DEBUG atomic_t inet_sock_nr; +#endif extern int raw_get_info(char *, char **, off_t, int); extern int snmp_get_info(char *, char **, off_t, int); @@ -159,8 +161,8 @@ if (sk->protinfo.af_inet.opt) kfree(sk->protinfo.af_inet.opt); dst_release(sk->dst_cache); - atomic_dec(&inet_sock_nr); #ifdef INET_REFCNT_DEBUG + atomic_dec(&inet_sock_nr); printk(KERN_DEBUG "INET socket %p released, %d are still alive\n", sk, atomic_read(&inet_sock_nr)); #endif } @@ -171,32 +173,28 @@ sk->prot->destroy(sk); /* Observation: when inet_sock_release is called, processes have - no access to socket. But net still has. - Step one, detach it from networking: - - A. Remove from hash tables. + * no access to socket. But net still has. + * Step one, detach it from networking: + * + * A. Remove from hash tables. */ sk->prot->unhash(sk); /* In this point socket cannot receive new packets, - but it is possible that some packets are in flight - because some CPU runs receiver and did hash table lookup - before we unhashed socket. They will achieve receive queue - and will be purged by socket destructor. - - Also we still have packets pending on receive - queue and probably, our own packets waiting in device queues. - sock_destroy will drain receive queue, but transmitted - packets will delay socket destruction until the last reference - will be released. + * but it is possible that some packets are in flight + * because some CPU runs receiver and did hash table lookup + * before we unhashed socket. They will achieve receive queue + * and will be purged by socket destructor. + * + * Also we still have packets pending on receive + * queue and probably, our own packets waiting in device queues. + * sock_destroy will drain receive queue, but transmitted + * packets will delay socket destruction until the last reference + * will be released. */ - write_lock_irq(&sk->callback_lock); - sk->dead=1; - sk->socket = NULL; - sk->sleep = NULL; - write_unlock_irq(&sk->callback_lock); + sock_orphan(sk); #ifdef INET_REFCNT_DEBUG if (atomic_read(&sk->refcnt) != 1) { @@ -222,8 +220,7 @@ char *optval, int optlen) { struct sock *sk=sock->sk; - if (sk->prot->setsockopt==NULL) - return -EOPNOTSUPP; + return sk->prot->setsockopt(sk,level,optname,optval,optlen); } @@ -239,8 +236,7 @@ char *optval, int *optlen) { struct sock *sk=sock->sk; - if (sk->prot->getsockopt==NULL) - return -EOPNOTSUPP; + return sk->prot->getsockopt(sk,level,optname,optval,optlen); } @@ -264,14 +260,6 @@ return 0; } -/* Listening INET sockets never sleep to wait for memory, so - * it is completely silly to wake them up on queue space - * available events. So we hook them up to this dummy callback. - */ -static void inet_listen_write_space(struct sock *sk) -{ -} - /* * Move a socket into listening state. */ @@ -282,12 +270,13 @@ unsigned char old_state; int err; + lock_sock(sk); + + err = -EINVAL; if (sock->state != SS_UNCONNECTED || sock->type != SOCK_STREAM) - return -EINVAL; + goto out; - lock_sock(sk); old_state = sk->state; - err = -EINVAL; if (!((1<state = TCP_LISTEN; - sk->ack_backlog = 0; - if (sk->num == 0) { - if (sk->prot->get_port(sk, 0) != 0) { - sk->state = old_state; - err = -EAGAIN; - goto out; - } - sk->sport = htons(sk->num); - } else { - /* Not nice, but the simplest solution however */ - if (sk->prev) - ((struct tcp_bind_bucket*)sk->prev)->fastreuse = 0; - } - - sk_dst_reset(sk); - sk->prot->hash(sk); - sk->socket->flags |= SO_ACCEPTCON; - sk->write_space = inet_listen_write_space; + err = tcp_listen_start(sk); + if (err) + goto out; } sk->max_ack_backlog = backlog; err = 0; @@ -345,10 +318,6 @@ if (protocol && protocol != IPPROTO_TCP) goto free_and_noproto; protocol = IPPROTO_TCP; - if (ipv4_config.no_pmtu_disc) - sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT; - else - sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT; prot = &tcp_prot; sock->ops = &inet_stream_ops; break; @@ -359,7 +328,6 @@ goto free_and_noproto; protocol = IPPROTO_UDP; sk->no_check = UDP_CSUM_DEFAULT; - sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT; prot=&udp_prot; sock->ops = &inet_dgram_ops; break; @@ -370,7 +338,6 @@ goto free_and_noproto; prot = &raw_prot; sk->reuse = 1; - sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT; sk->num = protocol; sock->ops = &inet_dgram_ops; if (protocol == IPPROTO_RAW) @@ -380,23 +347,22 @@ goto free_and_badtype; } + if (ipv4_config.no_pmtu_disc) + sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT; + else + sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT; + sock_init_data(sock,sk); sk->destruct = inet_sock_destruct; - sk->zapped=0; -#ifdef CONFIG_TCP_NAGLE_OFF - sk->nonagle = 1; -#endif + sk->zapped = 0; sk->family = PF_INET; sk->protocol = protocol; sk->prot = prot; sk->backlog_rcv = prot->backlog_rcv; - sk->timer.data = (unsigned long)sk; - sk->timer.function = &tcp_keepalive_timer; - sk->protinfo.af_inet.ttl=sysctl_ip_default_ttl; sk->protinfo.af_inet.mc_loop=1; @@ -404,7 +370,9 @@ sk->protinfo.af_inet.mc_index=0; sk->protinfo.af_inet.mc_list=NULL; +#ifdef INET_REFCNT_DEBUG atomic_inc(&inet_sock_nr); +#endif if (sk->num) { /* It assumes that any protocol which allows @@ -469,11 +437,8 @@ * linger.. */ timeout = 0; - if (sk->linger && !(current->flags & PF_EXITING)) { - timeout = HZ * sk->lingertime; - if (!timeout) - timeout = MAX_SCHEDULE_TIMEOUT; - } + if (sk->linger && !(current->flags & PF_EXITING)) + timeout = sk->lingertime; sock->sk = NULL; sk->prot->close(sk, timeout); } @@ -496,10 +461,6 @@ return -EINVAL; chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr); - if (addr->sin_addr.s_addr != 0 && chk_addr_ret != RTN_LOCAL && - chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) { - return -EADDRNOTAVAIL; /* Source address MUST be ours! */ - } snum = ntohs(addr->sin_port); if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) @@ -555,25 +516,29 @@ return sk->prot->connect(sk, (struct sockaddr *)uaddr, addr_len); } -static void inet_wait_for_connect(struct sock *sk) +static long inet_wait_for_connect(struct sock *sk, long timeo) { DECLARE_WAITQUEUE(wait, current); __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(sk->sleep, &wait); + /* Basic assumption: if someone sets sk->err, he _must_ + * change state of the socket from TCP_SYN_*. + * Connect() does not allow to get error notifications + * without closing the socket. + */ while ((1<state)&(TCPF_SYN_SENT|TCPF_SYN_RECV)) { - if (signal_pending(current)) - break; - if (sk->err) - break; release_sock(sk); - schedule(); + timeo = schedule_timeout(timeo); lock_sock(sk); + if (signal_pending(current) || !timeo) + break; set_current_state(TASK_INTERRUPTIBLE); } __set_current_state(TASK_RUNNING); remove_wait_queue(sk->sleep, &wait); + return timeo; } /* @@ -586,16 +551,16 @@ { struct sock *sk=sock->sk; int err; + long timeo; + + lock_sock(sk); if (uaddr->sa_family == AF_UNSPEC) { - lock_sock(sk); err = sk->prot->disconnect(sk, flags); sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED; - release_sock(sk); - return err; + goto out; } - lock_sock(sk); switch (sock->state) { default: err = -EINVAL; @@ -604,40 +569,58 @@ err = -EISCONN; goto out; case SS_CONNECTING: - if (tcp_established(sk->state)) { - sock->state = SS_CONNECTED; - err = 0; - goto out; - } - if (sk->err) - goto sock_error; err = -EALREADY; - if (flags & O_NONBLOCK) - goto out; + /* Fall out of switch with err, set for this state */ break; case SS_UNCONNECTED: + err = -EISCONN; + if (sk->state != TCP_CLOSE) + goto out; + + err = -EAGAIN; + if (sk->num == 0) { + if (sk->prot->get_port(sk, 0) != 0) + goto out; + sk->sport = htons(sk->num); + } + err = sk->prot->connect(sk, uaddr, addr_len); if (err < 0) goto out; + sock->state = SS_CONNECTING; - } - if (sk->state > TCP_FIN_WAIT2) - goto sock_error; + /* Just entered SS_CONNECTING state; the only + * difference is that return value in non-blocking + * case is EINPROGRESS, rather than EALREADY. + */ + err = -EINPROGRESS; + break; + } - err = -EINPROGRESS; - if (!tcp_established(sk->state) && (flags & O_NONBLOCK)) - goto out; + timeo = sock_sndtimeo(sk, flags&O_NONBLOCK); if ((1<state)&(TCPF_SYN_SENT|TCPF_SYN_RECV)) { - inet_wait_for_connect(sk); + /* Error code is set above */ + if (!timeo || !inet_wait_for_connect(sk, timeo)) + goto out; + err = -ERESTARTSYS; if (signal_pending(current)) goto out; } - if (sk->err && !tcp_established(sk->state)) - goto sock_error; + /* Connection was closed by RST, timeout, ICMP error + * or another process disconnected us. + */ + if (sk->state == TCP_CLOSE) + goto sock_error; + + /* sk->err may be not zero now, if RECVERR was ordered by user + * and error was received after socket entered established state. + * Hence, it is handled normally after connect() return successfully. + */ + sock->state = SS_CONNECTED; err = 0; out: @@ -647,11 +630,9 @@ sock_error: err = sock_error(sk) ? : -ECONNABORTED; sock->state = SS_UNCONNECTED; - if (sk->prot->disconnect(sk, O_NONBLOCK)) + if (sk->prot->disconnect(sk, flags)) sock->state = SS_DISCONNECTING; - release_sock(sk); - - return err; + goto out; } /* @@ -671,11 +652,7 @@ BUG_TRAP((1<state)&(TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_CLOSE)); - write_lock_irq(&sk2->callback_lock); - sk2->sleep = &newsock->wait; - newsock->sk = sk2; - sk2->socket = newsock; - write_unlock_irq(&sk2->callback_lock); + sock_graft(sk2, newsock); newsock->state = SS_CONNECTED; release_sock(sk2); @@ -749,7 +726,7 @@ int inet_shutdown(struct socket *sock, int how) { struct sock *sk = sock->sk; - int err; + int err = 0; /* This should really check to make sure * the socket is a TCP socket. (WHY AC...) @@ -759,35 +736,45 @@ 2->3 */ if ((how & ~SHUTDOWN_MASK) || how==0) /* MAXINT->0 */ return -EINVAL; - if (!sk) - return -ENOTCONN; lock_sock(sk); - if (sock->state == SS_CONNECTING && tcp_established(sk->state)) - sock->state = SS_CONNECTED; - err = -ENOTCONN; - if (!tcp_connected(sk->state)) - goto out; - sk->shutdown |= how; - if (sk->prot->shutdown) - sk->prot->shutdown(sk, how); + if (sock->state == SS_CONNECTING) { + if ((1<state)&(TCPF_SYN_SENT|TCPF_SYN_RECV|TCPF_CLOSE)) + sock->state = SS_DISCONNECTING; + else + sock->state = SS_CONNECTED; + } + + switch (sk->state) { + default: + sk->shutdown |= how; + if (sk->prot->shutdown) + sk->prot->shutdown(sk, how); + break; + case TCP_CLOSE: + err = -ENOTCONN; + break; + + /* Remaining two branches are temporary solution for missing + * close() in multithreaded environment. It is _not_ a good idea, + * but we have no choice until close() is repaired at VFS level. + */ + case TCP_LISTEN: + if (!(how & RCV_SHUTDOWN)) + break; + /* Fall through */ + case TCP_SYN_SENT: + err = sk->prot->disconnect(sk, O_NONBLOCK); + sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED; + break; + } + /* Wake up anyone sleeping in poll. */ sk->state_change(sk); - err = 0; -out: release_sock(sk); return err; } -unsigned int inet_poll(struct file * file, struct socket *sock, poll_table *wait) -{ - struct sock *sk = sock->sk; - - if (sk->prot->poll == NULL) - return(0); - return sk->prot->poll(file, sock, wait); -} - /* * ioctl() calls you can issue on an INET socket. Most of these are * device configuration and stuff and very rarely used. Some ioctls @@ -909,7 +896,7 @@ sock_no_socketpair, inet_accept, inet_getname, - inet_poll, + tcp_poll, inet_ioctl, inet_listen, inet_shutdown, diff -ur --new-file old/linux/net/ipv4/arp.c new/linux/net/ipv4/arp.c --- old/linux/net/ipv4/arp.c Thu Dec 23 04:55:38 1999 +++ new/linux/net/ipv4/arp.c Sat Jan 22 20:54:57 2000 @@ -1,6 +1,6 @@ /* linux/net/inet/arp.c * - * Version: $Id: arp.c,v 1.83 1999/12/15 22:39:03 davem Exp $ + * Version: $Id: arp.c,v 1.84 2000/01/18 08:24:14 davem Exp $ * * Copyright (C) 1994 by Florian La Roche * @@ -487,7 +487,9 @@ /* * Fill the device header for the ARP frame */ - dev->hard_header(skb,dev,ptype,dest_hw,src_hw,skb->len); + if (dev->hard_header && + dev->hard_header(skb,dev,ptype,dest_hw,src_hw,skb->len) < 0) + goto out; /* * Fill out the arp protocol part. @@ -552,6 +554,10 @@ skb->dev = dev; dev_queue_xmit(skb); + return; + +out: + kfree_skb(skb); } static void parp_redo(struct sk_buff *skb) diff -ur --new-file old/linux/net/ipv4/ip_input.c new/linux/net/ipv4/ip_input.c --- old/linux/net/ipv4/ip_input.c Sun Jan 9 06:36:20 2000 +++ new/linux/net/ipv4/ip_input.c Sat Jan 22 20:54:57 2000 @@ -5,7 +5,7 @@ * * The Internet Protocol (IP) module. * - * Version: $Id: ip_input.c,v 1.44 2000/01/09 02:19:30 davem Exp $ + * Version: $Id: ip_input.c,v 1.45 2000/01/16 05:11:22 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -317,13 +317,12 @@ #ifdef CONFIG_NET_CLS_ROUTE if (skb->dst->tclassid) { + struct ip_rt_acct *st = ip_rt_acct + 256*smp_processor_id(); u32 idx = skb->dst->tclassid; - write_lock(&ip_rt_acct_lock); - ip_rt_acct[idx&0xFF].o_packets++; - ip_rt_acct[idx&0xFF].o_bytes+=skb->len; - ip_rt_acct[(idx>>16)&0xFF].i_packets++; - ip_rt_acct[(idx>>16)&0xFF].i_bytes+=skb->len; - write_unlock(&ip_rt_acct_lock); + st[idx&0xFF].o_packets++; + st[idx&0xFF].o_bytes+=skb->len; + st[(idx>>16)&0xFF].i_packets++; + st[(idx>>16)&0xFF].i_bytes+=skb->len; } #endif diff -ur --new-file old/linux/net/ipv4/ip_output.c new/linux/net/ipv4/ip_output.c --- old/linux/net/ipv4/ip_output.c Sun Jan 9 06:36:20 2000 +++ new/linux/net/ipv4/ip_output.c Sat Jan 22 20:54:57 2000 @@ -5,7 +5,7 @@ * * The Internet Protocol (IP) output module. * - * Version: $Id: ip_output.c,v 1.77 2000/01/09 02:19:31 davem Exp $ + * Version: $Id: ip_output.c,v 1.78 2000/01/16 05:11:22 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -149,8 +149,8 @@ /* * Add an ip header to a skbuff and send it out. */ -void ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, - u32 saddr, u32 daddr, struct ip_options *opt) +int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, + u32 saddr, u32 daddr, struct ip_options *opt) { struct rtable *rt = (struct rtable *)skb->dst; struct iphdr *iph; @@ -182,8 +182,8 @@ ip_send_check(iph); /* Send it out. */ - NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, - output_maybe_reroute); + return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, + output_maybe_reroute); } static inline int ip_finish_output2(struct sk_buff *skb) @@ -257,7 +257,7 @@ { struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); if (newskb) - NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, newskb, NULL, + NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL, newskb->dev, ip_dev_loopback_xmit); } diff -ur --new-file old/linux/net/ipv4/ip_sockglue.c new/linux/net/ipv4/ip_sockglue.c --- old/linux/net/ipv4/ip_sockglue.c Sun Jan 9 06:36:20 2000 +++ new/linux/net/ipv4/ip_sockglue.c Sat Jan 22 20:54:57 2000 @@ -5,7 +5,7 @@ * * The IP to API glue. * - * Version: $Id: ip_sockglue.c,v 1.46 2000/01/09 02:19:32 davem Exp $ + * Version: $Id: ip_sockglue.c,v 1.47 2000/01/16 05:11:23 davem Exp $ * * Authors: see ip.c * @@ -415,7 +415,7 @@ struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) if (sk->family == PF_INET || - ((tcp_connected(sk->state) || sk->state == TCP_SYN_SENT) + (!((1<state)&(TCPF_LISTEN|TCPF_CLOSE)) && sk->daddr != LOOPBACK4_IPV6)) { #endif if (opt) diff -ur --new-file old/linux/net/ipv4/ipconfig.c new/linux/net/ipv4/ipconfig.c --- old/linux/net/ipv4/ipconfig.c Sun Jan 9 06:36:20 2000 +++ new/linux/net/ipv4/ipconfig.c Wed Jan 26 22:29:39 2000 @@ -534,7 +534,14 @@ /* Construct BOOTP header */ b->op = BOOTP_REQUEST; - b->htype = dev->type; + if (dev->type < 256) /* check for false types */ + b->htype = dev->type; + else if (dev->type == ARPHRD_IEEE802_TR) /* fix for token ring */ + b->htype = ARPHRD_IEEE802; + else { + printk("Unknown ARP type 0x%04x for device %s\n", dev->type, dev->name); + b->htype = dev->type; /* can cause undefined behavior */ + } b->hlen = dev->addr_len; memcpy(b->hw_addr, dev->dev_addr, dev->addr_len); b->secs = htons(jiffies / HZ); diff -ur --new-file old/linux/net/ipv4/proc.c new/linux/net/ipv4/proc.c --- old/linux/net/ipv4/proc.c Sun Jan 9 06:36:20 2000 +++ new/linux/net/ipv4/proc.c Sat Jan 22 20:54:57 2000 @@ -7,7 +7,7 @@ * PROC file system. It is mainly used for debugging and * statistics. * - * Version: $Id: proc.c,v 1.38 2000/01/09 02:19:30 davem Exp $ + * Version: $Id: proc.c,v 1.41 2000/01/21 23:45:57 davem Exp $ * * Authors: Fred N. van Kempen, * Gerald J. Heim, @@ -71,8 +71,9 @@ int len = socket_get_info(buffer,start,offset,length); - len += sprintf(buffer+len,"TCP: inuse %d\n", - fold_prot_inuse(&tcp_prot)); + len += sprintf(buffer+len,"TCP: inuse %d orphan %d tw %d\n", + fold_prot_inuse(&tcp_prot), + atomic_read(&tcp_orphan_count), tcp_tw_count); len += sprintf(buffer+len,"UDP: inuse %d\n", fold_prot_inuse(&udp_prot)); len += sprintf(buffer+len,"RAW: inuse %d\n", @@ -163,7 +164,14 @@ len = sprintf(buffer, "TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed" " EmbryonicRsts PruneCalled RcvPruned OfoPruned" - " OutOfWindowIcmps LockDroppedIcmps\n" + " OutOfWindowIcmps LockDroppedIcmps" + " TW TWRecycled TWKilled" + " PAWSPassive PAWSActive PAWSEstab" + " DelayedACKs DelayedACKLocked DelayedACKLost" + " ListenOverflows ListenDrops" + " TCPPrequeued TCPDirectCopyFromBacklog" + " TCPDirectCopyFromPrequeue TCPPrequeueDropped" + " TCPHPHits TCPHPHitsToUser\n" "TcpExt:"); for (i=0; i * Fred N. van Kempen, @@ -648,10 +648,6 @@ udp_connect, /* connect */ udp_disconnect, /* disconnect */ NULL, /* accept */ - NULL, /* retransmit */ - NULL, /* write_wakeup */ - NULL, /* read_wakeup */ - datagram_poll, /* poll */ #ifdef CONFIG_IP_MROUTE ipmr_ioctl, /* ioctl */ #else @@ -669,7 +665,5 @@ raw_v4_hash, /* hash */ raw_v4_unhash, /* unhash */ NULL, /* get_port */ - 128, /* max_header */ - 0, /* retransmits */ "RAW", /* name */ }; diff -ur --new-file old/linux/net/ipv4/route.c new/linux/net/ipv4/route.c --- old/linux/net/ipv4/route.c Thu Jan 20 19:48:35 2000 +++ new/linux/net/ipv4/route.c Sat Jan 22 20:54:57 2000 @@ -5,7 +5,7 @@ * * ROUTE - implementation of the IP router. * - * Version: $Id: route.c,v 1.78 2000/01/13 00:06:58 davem Exp $ + * Version: $Id: route.c,v 1.80 2000/01/21 06:37:27 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -1178,6 +1178,7 @@ rth->u.dst.output= ip_rt_bug; atomic_set(&rth->u.dst.__refcnt, 1); + rth->u.dst.flags= DST_HOST; rth->key.dst = daddr; rth->rt_dst = daddr; rth->key.tos = tos; @@ -1385,6 +1386,7 @@ goto e_nobufs; atomic_set(&rth->u.dst.__refcnt, 1); + rth->u.dst.flags= DST_HOST; rth->key.dst = daddr; rth->rt_dst = daddr; rth->key.tos = tos; @@ -1462,6 +1464,7 @@ rth->u.dst.output= ip_rt_bug; atomic_set(&rth->u.dst.__refcnt, 1); + rth->u.dst.flags= DST_HOST; rth->key.dst = daddr; rth->rt_dst = daddr; rth->key.tos = tos; @@ -1815,6 +1818,7 @@ goto e_nobufs; atomic_set(&rth->u.dst.__refcnt, 1); + rth->u.dst.flags= DST_HOST; rth->key.dst = daddr; rth->key.tos = tos; rth->key.src = saddr; @@ -2208,8 +2212,7 @@ #endif #ifdef CONFIG_NET_CLS_ROUTE -struct ip_rt_acct ip_rt_acct[256]; -rwlock_t ip_rt_acct_lock = RW_LOCK_UNLOCKED; +struct ip_rt_acct *ip_rt_acct; #ifdef CONFIG_PROC_FS static int ip_rt_acct_read(char *buffer, char **start, off_t offset, @@ -2217,14 +2220,34 @@ { *start=buffer; - if (offset + length > sizeof(ip_rt_acct)) { - length = sizeof(ip_rt_acct) - offset; + if ((offset&3) || (length&3)) + return -EIO; + + if (offset + length >= sizeof(struct ip_rt_acct)*256) { + length = sizeof(struct ip_rt_acct)*256 - offset; *eof = 1; } if (length > 0) { - read_lock_bh(&ip_rt_acct_lock); - memcpy(buffer, ((u8*)&ip_rt_acct)+offset, length); - read_unlock_bh(&ip_rt_acct_lock); + u32 *dst = (u32*)buffer; + u32 *src = (u32*)(((u8*)ip_rt_acct) + offset); + + memcpy(dst, src, length); + +#ifdef __SMP__ + if (smp_num_cpus > 1) { + int i; + int cnt = length/4; + + for (i=1; itp_pinfo.af_tcp; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct sock *child; - /* Oops! It was missing, syn_recv_sock decreases it. */ - tp->syn_backlog++; + child = tp->af_specific->syn_recv_sock(sk, skb, req, dst); + if (child) + tcp_acceptq_queue(sk, req, child); + else + tcp_openreq_free(req); - sk = tp->af_specific->syn_recv_sock(sk, skb, req, dst); - if (sk) { - req->sk = sk; - - /* Queue up for accept() */ - tcp_synq_queue(tp, req); - } else { - tp->syn_backlog--; - req->class->destructor(req); - tcp_openreq_free(req); - } - return sk; + return child; } struct sock * @@ -171,9 +164,9 @@ } } } - + req->snd_wscale = req->rcv_wscale = req->tstamp_ok = 0; - req->wscale_ok = 0; + req->wscale_ok = req->sack_ok = 0; req->expires = 0UL; req->retrans = 0; @@ -189,8 +182,8 @@ req->af.v4_req.loc_addr, sk->protinfo.af_inet.tos | RTO_CONN, 0)) { - tcp_openreq_free(req); - return NULL; + tcp_openreq_free(req); + return NULL; } /* Try to redo what tcp_v4_send_synack did. */ @@ -198,6 +191,7 @@ tcp_select_initial_window(tcp_full_space(sk),req->mss, &req->rcv_wnd, &req->window_clamp, 0, &rcv_wscale); + /* BTW win scale with syncookies is 0 by definition */ req->rcv_wscale = rcv_wscale; return get_cookie_sock(sk, skb, req, &rt->u.dst); diff -ur --new-file old/linux/net/ipv4/sysctl_net_ipv4.c new/linux/net/ipv4/sysctl_net_ipv4.c --- old/linux/net/ipv4/sysctl_net_ipv4.c Sun Jan 9 06:36:20 2000 +++ new/linux/net/ipv4/sysctl_net_ipv4.c Sat Jan 22 20:54:57 2000 @@ -1,7 +1,7 @@ /* * sysctl_net_ipv4.c: sysctl interface to net IPV4 subsystem. * - * $Id: sysctl_net_ipv4.c,v 1.42 2000/01/09 02:19:37 davem Exp $ + * $Id: sysctl_net_ipv4.c,v 1.43 2000/01/16 05:11:27 davem Exp $ * * Begun April 1, 1996, Mike Shaver. * Added /proc/sys/net/ipv4 directory entry (empty =) ). [MS] @@ -41,26 +41,6 @@ /* From ip_output.c */ extern int sysctl_ip_dynaddr; -/* From ip_masq.c */ -extern int sysctl_ip_masq_debug; - -extern int sysctl_tcp_timestamps; -extern int sysctl_tcp_window_scaling; -extern int sysctl_tcp_sack; -extern int sysctl_tcp_retrans_collapse; -extern int sysctl_tcp_keepalive_time; -extern int sysctl_tcp_keepalive_probes; -extern int sysctl_tcp_retries1; -extern int sysctl_tcp_retries2; -extern int sysctl_tcp_fin_timeout; -extern int sysctl_tcp_syncookies; -extern int sysctl_tcp_syn_retries; -extern int sysctl_tcp_stdurg; -extern int sysctl_tcp_rfc1337; -extern int sysctl_tcp_syn_taildrop; -extern int sysctl_max_syn_backlog; -extern int sysctl_tcp_tw_recycle; - /* From icmp.c */ extern int sysctl_icmp_destunreach_time; extern int sysctl_icmp_timeexceed_time; @@ -142,6 +122,12 @@ &proc_dointvec}, {NET_IPV4_TCP_SYN_RETRIES, "tcp_syn_retries", &sysctl_tcp_syn_retries, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_TCP_SYNACK_RETRIES, "tcp_synack_retries", + &sysctl_tcp_synack_retries, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_TCP_MAX_ORPHANS, "tcp_max_orphans", + &sysctl_tcp_max_orphans, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_TCP_MAX_TW_BUCKETS, "tcp_max_tw_buckets", + &sysctl_tcp_max_tw_buckets, sizeof(int), 0644, NULL, &proc_dointvec}, {NET_IPV4_IPFRAG_HIGH_THRESH, "ipfrag_high_thresh", &sysctl_ipfrag_high_thresh, sizeof(int), 0644, NULL, &proc_dointvec}, {NET_IPV4_IPFRAG_LOW_THRESH, "ipfrag_low_thresh", @@ -172,10 +158,10 @@ {NET_TCP_SYNCOOKIES, "tcp_syncookies", &sysctl_tcp_syncookies, sizeof(int), 0644, NULL, &proc_dointvec}, #endif -#ifdef CONFIG_TCP_TW_RECYCLE {NET_TCP_TW_RECYCLE, "tcp_tw_recycle", &sysctl_tcp_tw_recycle, sizeof(int), 0644, NULL, &proc_dointvec}, -#endif + {NET_TCP_ABORT_ON_OVERFLOW, "tcp_abort_on_overflow", + &sysctl_tcp_abort_on_overflow, sizeof(int), 0644, NULL, &proc_dointvec}, {NET_TCP_STDURG, "tcp_stdurg", &sysctl_tcp_stdurg, sizeof(int), 0644, NULL, &proc_dointvec}, {NET_TCP_RFC1337, "tcp_rfc1337", &sysctl_tcp_rfc1337, @@ -221,6 +207,8 @@ {NET_IPV4_INET_PEER_GC_MAXTIME, "inet_peer_gc_maxtime", &inet_peer_gc_maxtime, sizeof(int), 0644, NULL, &proc_dointvec_jiffies, &sysctl_jiffies}, + {NET_TCP_ORPHAN_RETRIES, "tcp_orphan_retries", + &sysctl_tcp_orphan_retries, sizeof(int), 0644, NULL, &proc_dointvec}, {0} }; diff -ur --new-file old/linux/net/ipv4/tcp.c new/linux/net/ipv4/tcp.c --- old/linux/net/ipv4/tcp.c Sun Jan 9 06:36:21 2000 +++ new/linux/net/ipv4/tcp.c Tue Jan 25 19:26:04 2000 @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp.c,v 1.153 2000/01/09 02:19:33 davem Exp $ + * Version: $Id: tcp.c,v 1.160 2000/01/24 18:40:32 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -202,6 +202,8 @@ * Eric Schenk : Fix fast close down bug with * shutdown() followed by close(). * Andi Kleen : Make poll agree with SIGIO + * Salvatore Sanfilippo : Support SO_LINGER with linger == 1 and + * lingertime == 0 (RFC 793 ABORT Call) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -432,113 +434,14 @@ kmem_cache_t *tcp_bucket_cachep; kmem_cache_t *tcp_timewait_cachep; -/* - * Find someone to 'accept'. Must be called with - * the listening socket locked. - */ - -static struct open_request *tcp_find_established(struct tcp_opt *tp, - struct open_request **prevp) -{ - struct open_request *req = tp->syn_wait_queue; - struct open_request *prev = (struct open_request *)&tp->syn_wait_queue; - while(req) { - if (req->sk) { - if((1 << req->sk->state) & - ~(TCPF_SYN_SENT|TCPF_SYN_RECV)) - break; - } - prev = req; - req = req->dl_next; - } - *prevp = prev; - return req; -} - -/* - * Walk down the receive queue counting readable data. - * - * Must be called with the socket lock held. - */ - -static int tcp_readable(struct sock *sk) -{ - unsigned long counted; - unsigned long amount; - struct sk_buff *skb; - int sum; - - SOCK_DEBUG(sk, "tcp_readable: %p - ",sk); - - skb = skb_peek(&sk->receive_queue); - if (skb == NULL) { - SOCK_DEBUG(sk, "empty\n"); - return(0); - } - - counted = sk->tp_pinfo.af_tcp.copied_seq; /* Where we are at the moment */ - amount = 0; - - /* Do until a push or until we are out of data. */ - do { - /* Found a hole so stops here. */ - if (before(counted, TCP_SKB_CB(skb)->seq)) /* should not happen */ - break; - - /* Length - header but start from where we are up to - * avoid overlaps. - */ - sum = skb->len - (counted - TCP_SKB_CB(skb)->seq); - if (sum >= 0) { - /* Add it up, move on. */ - amount += sum; - counted += sum; - if (skb->h.th->syn) - counted++; - } - - /* Don't count urg data ... but do it in the right place! - * Consider: "old_data (ptr is here) URG PUSH data" - * The old code would stop at the first push because - * it counted the urg (amount==1) and then does amount-- - * *after* the loop. This means tcp_readable() always - * returned zero if any URG PUSH was in the queue, even - * though there was normal data available. If we subtract - * the urg data right here, we even get it to work for more - * than one URG PUSH skb without normal data. - * This means that poll() finally works now with urg data - * in the queue. Note that rlogin was never affected - * because it doesn't use poll(); it uses two processes - * and a blocking read(). And the queue scan in tcp_read() - * was correct. Mike - */ - - /* Don't count urg data. */ - if (skb->h.th->urg) - amount--; -#if 0 - if (amount && skb->h.th->psh) break; -#endif - skb = skb->next; - } while(skb != (struct sk_buff *)&sk->receive_queue); - - SOCK_DEBUG(sk, "got %lu bytes.\n",amount); - return(amount); -} +atomic_t tcp_orphan_count = ATOMIC_INIT(0); /* * LISTEN is a special case for poll.. */ -static unsigned int tcp_listen_poll(struct sock *sk, poll_table *wait) +static __inline__ unsigned int tcp_listen_poll(struct sock *sk, poll_table *wait) { - struct open_request *req, *dummy; - - lock_sock(sk); - req = tcp_find_established(&sk->tp_pinfo.af_tcp, &dummy); - release_sock(sk); - if (req) - return POLLIN | POLLRDNORM; - return 0; + return sk->tp_pinfo.af_tcp.accept_queue ? (POLLIN | POLLRDNORM) : 0; } /* @@ -585,9 +488,25 @@ * if you don't tell them that something has hung up! * * Check-me. + * + * Check number 1. POLLHUP is _UNMASKABLE_ event (see UNIX98 and + * our fs/select.c). It means that after we received EOF, + * poll always returns immediately, making impossible poll() on write() + * in state CLOSE_WAIT. One solution is evident --- to set POLLHUP + * if and only if shutdown has been made in both directions. + * Actually, it is interesting to look how Solaris and DUX + * solve this dilemma. I would prefer, if PULLHUP were maskable, + * then we could set it on SND_SHUTDOWN. BTW examples given + * in Stevens' books assume exactly this behaviour, it explains + * why PULLHUP is incompatible with POLLOUT. --ANK + * + * NOTE. Check for TCP_CLOSE is added. The goal is to prevent + * blocking on fresh not-connected or disconnected socket. --ANK */ - if (sk->shutdown & RCV_SHUTDOWN) + if (sk->shutdown == SHUTDOWN_MASK || sk->state == TCP_CLOSE) mask |= POLLHUP; + if (sk->shutdown & RCV_SHUTDOWN) + mask |= POLLIN | POLLRDNORM; /* Connected? */ if ((1 << sk->state) & ~(TCPF_SYN_SENT|TCPF_SYN_RECV)) { @@ -605,7 +524,7 @@ } } - if (tp->urg_data & URG_VALID) + if (tp->urg_data & TCP_URG_VALID) mask |= POLLPRI; } return mask; @@ -631,32 +550,48 @@ read_unlock(&sk->callback_lock); } +/* Listening TCP sockets never sleep to wait for memory, so + * it is completely silly to wake them up on queue space + * available events. So we hook them up to this dummy callback. + */ +static void tcp_listen_write_space(struct sock *sk) +{ +} int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); int answ; switch(cmd) { - case TIOCINQ: -#ifdef FIXME /* FIXME: */ - case FIONREAD: -#endif + case SIOCINQ: if (sk->state == TCP_LISTEN) return(-EINVAL); + lock_sock(sk); - answ = tcp_readable(sk); + if ((1<state) & (TCPF_SYN_SENT|TCPF_SYN_RECV)) + answ = 0; + else if (sk->urginline || !tp->urg_data || + before(tp->urg_seq,tp->copied_seq) || + !before(tp->urg_seq,tp->rcv_nxt)) + answ = tp->rcv_nxt - tp->copied_seq; + else + answ = tp->urg_seq - tp->copied_seq; release_sock(sk); break; case SIOCATMARK: { - struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); answ = tp->urg_data && tp->urg_seq == tp->copied_seq; break; } - case TIOCOUTQ: + case SIOCOUTQ: if (sk->state == TCP_LISTEN) return(-EINVAL); - answ = sock_wspace(sk); + + if ((1<state) & (TCPF_SYN_SENT|TCPF_SYN_RECV)) + answ = 0; + else + answ = tp->write_seq - tp->snd_una; break; default: return(-ENOIOCTLCMD); @@ -665,12 +600,131 @@ return put_user(answ, (int *)arg); } + +int tcp_listen_start(struct sock *sk) +{ + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct tcp_listen_opt *lopt; + + sk->max_ack_backlog = 0; + sk->ack_backlog = 0; + tp->accept_queue = NULL; + tp->syn_wait_lock = RW_LOCK_UNLOCKED; + + lopt = kmalloc(sizeof(struct tcp_listen_opt), GFP_KERNEL); + if (!lopt) + return -ENOMEM; + + memset(lopt, 0, sizeof(struct tcp_listen_opt)); + for (lopt->max_qlen_log = 6; ; lopt->max_qlen_log++) + if ((1<max_qlen_log) >= sysctl_max_syn_backlog) + break; + + write_lock_bh(&tp->syn_wait_lock); + tp->listen_opt = lopt; + write_unlock_bh(&tp->syn_wait_lock); + + sk->state = TCP_LISTEN; + if (sk->num == 0) { + if (sk->prot->get_port(sk, 0) != 0) { + sk->state = TCP_CLOSE; + write_lock_bh(&tp->syn_wait_lock); + tp->listen_opt = NULL; + write_unlock_bh(&tp->syn_wait_lock); + kfree(lopt); + return -EAGAIN; + } + sk->sport = htons(sk->num); + } else { + if (sk->prev) + ((struct tcp_bind_bucket*)sk->prev)->fastreuse = 0; + } + + sk_dst_reset(sk); + sk->prot->hash(sk); + sk->socket->flags |= SO_ACCEPTCON; + sk->write_space = tcp_listen_write_space; + + return 0; +} + +/* + * This routine closes sockets which have been at least partially + * opened, but not yet accepted. + */ + +static void tcp_listen_stop (struct sock *sk) +{ + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct tcp_listen_opt *lopt = tp->listen_opt; + struct open_request *acc_req = tp->accept_queue; + struct open_request *req; + int i; + + tcp_delete_keepalive_timer(sk); + + /* make all the listen_opt local to us */ + write_lock_bh(&tp->syn_wait_lock); + tp->listen_opt =NULL; + write_unlock_bh(&tp->syn_wait_lock); + tp->accept_queue = NULL; + + if (lopt->qlen) { + for (i=0; isyn_table[i]) != NULL) { + lopt->syn_table[i] = req->dl_next; + lopt->qlen--; + tcp_openreq_free(req); + + /* Following specs, it would be better either to send FIN + * (and enter FIN-WAIT-1, it is normal close) + * or to send active reset (abort). + * Certainly, it is pretty dangerous while synflood, but it is + * bad justification for our negligence 8) + * To be honest, we are not able to make either + * of the variants now. --ANK + */ + } + } + } + BUG_TRAP(lopt->qlen == 0); + + kfree(lopt); + + while ((req=acc_req) != NULL) { + struct sock *child = req->sk; + + acc_req = req->dl_next; + + local_bh_disable(); + bh_lock_sock(child); + BUG_TRAP(child->lock.users==0); + sock_hold(child); + + tcp_disconnect(child, O_NONBLOCK); + + sock_orphan(child); + + atomic_inc(&tcp_orphan_count); + + tcp_destroy_sock(child); + + bh_unlock_sock(child); + local_bh_enable(); + sock_put(child); + + tcp_acceptq_removed(sk); + tcp_openreq_fastfree(req); + } + BUG_TRAP(sk->ack_backlog == 0); +} + /* * Wait for a socket to get into the connected state * * Note: Must be called with the socket locked. */ -static int wait_for_tcp_connect(struct sock * sk, int flags) +static int wait_for_tcp_connect(struct sock * sk, int flags, long *timeo_p) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -684,7 +738,7 @@ send_sig(SIGPIPE, tsk, 0); return -EPIPE; } - if(flags & MSG_DONTWAIT) + if(!*timeo_p) return -EAGAIN; if(signal_pending(tsk)) return -ERESTARTSYS; @@ -694,7 +748,7 @@ sk->tp_pinfo.af_tcp.write_pending++; release_sock(sk); - schedule(); + *timeo_p = schedule_timeout(*timeo_p); lock_sock(sk); __set_task_state(tsk, TASK_RUNNING); @@ -712,7 +766,7 @@ /* * Wait for more memory for a socket */ -static void wait_for_tcp_memory(struct sock * sk) +static long wait_for_tcp_memory(struct sock * sk, long timeo) { if (!tcp_memory_free(sk)) { DECLARE_WAITQUEUE(wait, current); @@ -732,12 +786,13 @@ break; release_sock(sk); if (!tcp_memory_free(sk)) - schedule(); + timeo = schedule_timeout(timeo); lock_sock(sk); } current->state = TASK_RUNNING; remove_wait_queue(sk->sleep, &wait); } + return timeo; } /* When all user supplied data has been queued set the PSH bit */ @@ -746,11 +801,9 @@ /* * This routine copies from a user buffer into a socket, * and starts the transmit system. - * - * Note: must be called with the socket locked. */ -int tcp_do_sendmsg(struct sock *sk, struct msghdr *msg) +int tcp_sendmsg(struct sock *sk, struct msghdr *msg, int size) { struct iovec *iov; struct tcp_opt *tp; @@ -758,15 +811,22 @@ int iovlen, flags; int mss_now; int err, copied; + long timeo; err = 0; tp = &(sk->tp_pinfo.af_tcp); - /* Wait for a connection to finish. */ + lock_sock(sk); + TCP_CHECK_TIMER(sk); + flags = msg->msg_flags; + + timeo = sock_sndtimeo(sk, flags&MSG_DONTWAIT); + + /* Wait for a connection to finish. */ if ((1 << sk->state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) - if((err = wait_for_tcp_connect(sk, flags)) != 0) - goto out; + if((err = wait_for_tcp_connect(sk, flags, &timeo)) != 0) + goto out_unlock; /* This should be in poll */ sk->socket->flags &= ~SO_NOSPACE; /* clear SIGIO XXX */ @@ -777,7 +837,7 @@ iovlen = msg->msg_iovlen; iov = msg->msg_iov; copied = 0; - + while(--iovlen >= 0) { int seglen=iov->iov_len; unsigned char * from=iov->iov_base; @@ -785,7 +845,7 @@ iov++; while(seglen > 0) { - int copy, tmp, queue_it, psh; + int copy, tmp, queue_it; if (err) goto do_fault2; @@ -811,8 +871,7 @@ * welcome. */ if (skb_tailroom(skb) > 0 && - (mss_now - copy) > 0 && - tp->snd_nxt < TCP_SKB_CB(skb)->end_seq) { + (mss_now - copy) > 0) { int last_byte_was_odd = (copy % 4); copy = mss_now - copy; @@ -855,34 +914,17 @@ } } - /* We also need to worry about the window. If - * window < 1/2 the maximum window we've seen - * from this host, don't use it. This is - * sender side silly window prevention, as - * specified in RFC1122. (Note that this is - * different than earlier versions of SWS - * prevention, e.g. RFC813.). What we - * actually do is use the whole MSS. Since - * the results in the right edge of the packet - * being outside the window, it will be queued - * for later rather than sent. + /* A chunk was here doing something strange + * with psh etc. It is deleted, because it was + * evident non-sense. --ANK */ - psh = 0; - copy = tp->snd_wnd - (tp->snd_nxt - tp->snd_una); - if(copy > (tp->max_window >> 1)) { - copy = min(copy, mss_now); - psh = 1; - } else { - copy = mss_now; - } - if(copy > seglen) - copy = seglen; + + copy = min(seglen, mss_now); /* Determine how large of a buffer to allocate. */ - tmp = MAX_HEADER + sk->prot->max_header; - if (copy < min(mss_now, tp->max_window >> 1) && - !(flags & MSG_OOB)) { - tmp += min(mss_now, tp->max_window); + tmp = MAX_TCP_HEADER + 15; + if (copy < mss_now && !(flags & MSG_OOB)) { + tmp += mss_now; /* What is happening here is that we want to * tack on later members of the users iovec @@ -901,7 +943,7 @@ /* If we didn't get any memory, we need to sleep. */ if (skb == NULL) { sk->socket->flags |= SO_NOSPACE; - if (flags&MSG_DONTWAIT) { + if (!timeo) { err = -EAGAIN; goto do_interrupted; } @@ -909,8 +951,8 @@ err = -ERESTARTSYS; goto do_interrupted; } - tcp_push_pending_frames(sk, tp); - wait_for_tcp_memory(sk); + __tcp_push_pending_frames(sk, tp, mss_now); + timeo = wait_for_tcp_memory(sk, timeo); /* If SACK's were formed or PMTU events happened, * we must find out about it. @@ -923,7 +965,7 @@ /* Prepare control bits for TCP header creation engine. */ TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | - ((PSH_NEEDED || psh) ? + ((PSH_NEEDED) ? TCPCB_FLAG_PSH : 0)); TCP_SKB_CB(skb)->sacked = 0; if (flags & MSG_OOB) { @@ -936,7 +978,7 @@ * TCP+IP+DEV headers are SKB_PUSH()'d beneath. * Reserve header space and checksum the data. */ - skb_reserve(skb, MAX_HEADER + sk->prot->max_header); + skb_reserve(skb, MAX_TCP_HEADER); skb->csum = csum_and_copy_from_user(from, skb_put(skb, copy), copy, 0, &err); @@ -950,7 +992,7 @@ TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + copy; /* This advances tp->write_seq for us. */ - tcp_send_skb(sk, skb, queue_it); + tcp_send_skb(sk, skb, queue_it, mss_now); } } sk->err = 0; @@ -981,63 +1023,39 @@ do_fault2: err = -EFAULT; out: - tcp_push_pending_frames(sk, tp); + __tcp_push_pending_frames(sk, tp, mss_now); + TCP_CHECK_TIMER(sk); +out_unlock: + release_sock(sk); return err; } #undef PSH_NEEDED /* - * Send an ack if one is backlogged at this point. Ought to merge - * this with tcp_send_ack(). - * This is called for delayed acks also. - */ - -void tcp_read_wakeup(struct sock *sk) -{ - /* If we're closed, don't send an ack, or we'll get a RST - * from the closed destination. - */ - if (sk->state != TCP_CLOSE) - tcp_send_ack(sk); -} - -/* * Handle reading urgent data. BSD has very simple semantics for * this, no blocking and very strange errors 8) */ -static int tcp_recv_urg(struct sock * sk, int nonblock, +static int tcp_recv_urg(struct sock * sk, long timeo, struct msghdr *msg, int len, int flags, int *addr_len) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); /* No URG data to read. */ - if (sk->urginline || !tp->urg_data || tp->urg_data == URG_READ) + if (sk->urginline || !tp->urg_data || tp->urg_data == TCP_URG_READ) return -EINVAL; /* Yes this is right ! */ if (sk->done) return -ENOTCONN; - if (sk->state == TCP_CLOSE || (sk->shutdown & RCV_SHUTDOWN)) { - sk->done = 1; - return 0; - } - - if (tp->urg_data & URG_VALID) { + if (tp->urg_data & TCP_URG_VALID) { int err = 0; char c = tp->urg_data; if (!(flags & MSG_PEEK)) - tp->urg_data = URG_READ; - - if(msg->msg_name) - tp->af_specific->addr2sockaddr(sk, (struct sockaddr *) - msg->msg_name); - - if(addr_len) - *addr_len = tp->af_specific->sockaddr_len; + tp->urg_data = TCP_URG_READ; /* Read urgent data. */ msg->msg_flags|=MSG_OOB; @@ -1051,6 +1069,10 @@ return err ? -EFAULT : len; } + /* Do not set sk->done, it is set only by normal data receive */ + if (sk->state == TCP_CLOSE || (sk->shutdown & RCV_SHUTDOWN)) + return 0; + /* Fixed the recv(..., MSG_OOB) behaviour. BSD docs and * the available implementations agree in this case: * this call should never block, independent of the @@ -1069,6 +1091,8 @@ static inline void tcp_eat_skb(struct sock *sk, struct sk_buff * skb) { __skb_unlink(skb, &sk->receive_queue); + BUG_TRAP(atomic_read(&skb->users) == 1); + /* Well, if I missed something then punishment will be terrible oops. */ __kfree_skb(skb); } @@ -1080,22 +1104,34 @@ */ static void cleanup_rbuf(struct sock *sk, int copied) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); struct sk_buff *skb; + int time_to_ack; /* NOTE! The socket must be locked, so that we don't get * a messed-up receive queue. */ while ((skb=skb_peek(&sk->receive_queue)) != NULL) { - if (!skb->used || atomic_read(&skb->users) > 1) + if (!skb->used) break; tcp_eat_skb(sk, skb); } + /* Delayed ACKs frequently hit locked sockets during bulk receive. */ + time_to_ack = tp->ack.blocked && tp->ack.pending; +#if 1/*def CONFIG_TCP_MORE_COARSE_ACKS*/ + if (tp->ack.pending && + (tp->rcv_nxt - tp->rcv_wup) > tp->ack.rcv_mss) + time_to_ack = 1; +#endif + /* We send an ACK if we can now advertise a non-zero window * which has been raised "significantly". + * + * Even if window raised up to infinity, do not send window open ACK + * in states, where we will not receive more. It is useless. */ - if(copied > 0) { - struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + if(copied > 0 && !time_to_ack && !(sk->shutdown&RCV_SHUTDOWN)) { __u32 rcv_window_now = tcp_receive_window(tp); __u32 new_window = __tcp_select_window(sk); @@ -1106,16 +1142,20 @@ * which don't advertize a larger window. */ if((new_window && (new_window >= rcv_window_now * 2)) && - ((rcv_window_now + tp->mss_cache) <= tp->window_clamp)) - tcp_read_wakeup(sk); + ((rcv_window_now + tp->ack.rcv_mss) <= tp->window_clamp)) + time_to_ack = 1; } + if (time_to_ack) + tcp_send_ack(sk); } /* Now socket state including sk->err is changed only under lock, - hence we should check only pending signals. + * hence we may omit checks after joining wait queue. + * We check receive queue before schedule() only as optimization; + * it is very likely that release_sock() added new data. */ -static void tcp_data_wait(struct sock *sk) +static long tcp_data_wait(struct sock *sk, long timeo) { DECLARE_WAITQUEUE(wait, current); @@ -1127,17 +1167,39 @@ release_sock(sk); if (skb_queue_empty(&sk->receive_queue)) - schedule(); + timeo = schedule_timeout(timeo); lock_sock(sk); sk->socket->flags &= ~SO_WAITDATA; remove_wait_queue(sk->sleep, &wait); __set_current_state(TASK_RUNNING); + return timeo; +} + +static void tcp_prequeue_process(struct sock *sk) +{ + struct sk_buff *skb; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + net_statistics[smp_processor_id()*2+1].TCPPrequeued += skb_queue_len(&tp->ucopy.prequeue); + + /* RX process wants to run with disabled BHs, though it is not necessary */ + local_bh_disable(); + while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) + sk->backlog_rcv(sk, skb); + local_bh_enable(); + + /* Clear memory counter. */ + tp->ucopy.memory = 0; } /* * This routine copies from a sock struct into the user buffer. + * + * Technical note: in 2.3 we work on _locked_ socket, so that + * tricks with *seq access order and skb->users are not required. + * Probably, code can be easily improved even more. */ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, @@ -1146,13 +1208,18 @@ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); int copied = 0; u32 peek_seq; - volatile u32 *seq; /* So gcc doesn't overoptimise */ + u32 *seq; unsigned long used; int err; - int target = 1; /* Read at least this many bytes */ + int target; /* Read at least this many bytes */ + long timeo; + struct task_struct *user_recv = NULL; lock_sock(sk); + TCP_CHECK_TIMER(sk); + + if (sk->err) goto out_err; @@ -1160,24 +1227,20 @@ if (sk->state == TCP_LISTEN) goto out; + timeo = sock_rcvtimeo(sk, nonblock); + /* Urgent data needs to be handled specially. */ if (flags & MSG_OOB) goto recv_urg; - /* Copying sequence to update. This is volatile to handle - * the multi-reader case neatly (memcpy_to/fromfs might be - * inline and thus not flush cached variables otherwise). - */ - peek_seq = tp->copied_seq; seq = &tp->copied_seq; - if (flags & MSG_PEEK) + if (flags & MSG_PEEK) { + peek_seq = tp->copied_seq; seq = &peek_seq; + } - /* Handle the POSIX bogosity MSG_WAITALL. */ - if (flags & MSG_WAITALL) - target=len; + target = sock_rcvlowat(sk, flags & MSG_WAITALL, len); - /* * BUG BUG BUG * This violates 1003.1g compliance. We must wait for @@ -1200,7 +1263,7 @@ if (copied) break; copied = -ERESTARTSYS; - if (nonblock) + if (!timeo) copied = -EAGAIN; break; } @@ -1232,47 +1295,128 @@ skb = skb->next; } while (skb != (struct sk_buff *)&sk->receive_queue); - if (copied >= target) + /* Well, if we have backlog, try to process it now yet. */ + + if (copied >= target && sk->backlog.tail == NULL) break; - if (sk->err && !(flags&MSG_PEEK)) { - if (!copied) + if (copied) { + if (sk->err || + sk->state == TCP_CLOSE || + (sk->shutdown & RCV_SHUTDOWN) || + !timeo) + break; + } else { + if (sk->err) { copied = sock_error(sk); - break; - } + break; + } - if (sk->shutdown & RCV_SHUTDOWN) { - sk->done = 1; - break; - } + if (sk->done) { + copied = -ENOTCONN; + break; + } - if (sk->state == TCP_CLOSE) { - if (!sk->done) { - sk->done = 1; + if (sk->state == TCP_CLOSE) { + if (!(flags&MSG_PEEK)) + sk->done = 1; break; } - if (!copied) - copied = -ENOTCONN; - break; - } - if (nonblock) { - copied = -EAGAIN; - break; + if (sk->shutdown & RCV_SHUTDOWN) + break; + + if (!timeo) { + copied = -EAGAIN; + break; + } } cleanup_rbuf(sk, copied); - tcp_data_wait(sk); + + if (tp->ucopy.task == user_recv) { + /* Install new reader */ + if (user_recv == NULL && !(flags&MSG_PEEK)) { + user_recv = current; + tp->ucopy.task = user_recv; + tp->ucopy.iov = msg->msg_iov; + } + + tp->ucopy.len = len; + + BUG_TRAP(tp->copied_seq == tp->rcv_nxt); + + /* Ugly... If prequeue is not empty, we have to + * process it before releasing socket, otherwise + * order will be broken at second iteration. + * More elegant solution is required!!! + * + * Look: we have the following (pseudo)queues: + * + * 1. packets in flight + * 2. backlog + * 3. prequeue + * 4. receive_queue + * + * Each queue can be processed only if the next ones + * are empty. At this point we have empty receive_queue. + * But prequeue _can_ be not empty after second iteration, + * when we jumped to start of loop because backlog + * processing added something to receive_queue. + * We cannot release_sock(), because backlog contains + * packets arrived _after_ prequeued ones. + * + * Shortly, algorithm is clear --- to process all + * the queues in order. We could make it more directly, + * requeueing packets from backlog to prequeue, if + * is not empty. It is more elegant, but eats cycles, + * unfortunately. + */ + if (skb_queue_len(&tp->ucopy.prequeue)) + goto do_prequeue; + + /* __ Set realtime policy in scheduler __ */ + } + + if (copied >= target) { + /* Do not sleep, just process backlog. */ + release_sock(sk); + lock_sock(sk); + } else { + timeo = tcp_data_wait(sk, timeo); + } + + if (user_recv) { + int chunk; + + /* __ Restore normal policy in scheduler __ */ + + if ((chunk = len - tp->ucopy.len) != 0) { + net_statistics[smp_processor_id()*2+1].TCPDirectCopyFromBacklog += chunk; + len -= chunk; + copied += chunk; + } + + if (tp->rcv_nxt == tp->copied_seq && + skb_queue_len(&tp->ucopy.prequeue)) { +do_prequeue: + tcp_prequeue_process(sk); + + if ((chunk = len - tp->ucopy.len) != 0) { + net_statistics[smp_processor_id()*2+1].TCPDirectCopyFromPrequeue += chunk; + len -= chunk; + copied += chunk; + } + } +#if 1/*def CONFIG_TCP_MORE_COARSE_ACKS*/ + if (tp->ack.pending && + (tp->rcv_nxt - tp->rcv_wup) > tp->ack.rcv_mss) + tcp_send_ack(sk); +#endif + } continue; found_ok_skb: - /* Lock the buffer. We can be fairly relaxed as - * an interrupt will never steal a buffer we are - * using unless I've missed something serious in - * tcp_data. - */ - atomic_inc(&skb->users); - /* Ok so how much can we use? */ used = skb->len - offset; if (len < used) @@ -1293,36 +1437,28 @@ } } - /* Copy it - We _MUST_ update *seq first so that we - * don't ever double read when we have dual readers - */ - *seq += used; - - /* This memcpy_toiovec can sleep. If it sleeps and we - * do a second read it relies on the skb->users to avoid - * a crash when cleanup_rbuf() gets called. - */ err = memcpy_toiovec(msg->msg_iov, ((unsigned char *)skb->h.th) + skb->h.th->doff*4 + offset, used); if (err) { /* Exception. Bailout! */ - atomic_dec(&skb->users); - copied = -EFAULT; + if (!copied) + copied = -EFAULT; break; } + *seq += used; copied += used; len -= used; - /* We now will not sleep again until we are finished - * with skb. Sorry if you are doing the SMP port - * but you'll just have to fix it neatly ;) - * - * Very funny Alan... -DaveM - */ - atomic_dec(&skb->users); - - if (after(tp->copied_seq,tp->urg_seq)) + if (after(tp->copied_seq,tp->urg_seq)) { tp->urg_data = 0; + if (skb_queue_len(&tp->out_of_order_queue) == 0 +#ifdef TCP_FORMAL_WINDOW + && tcp_receive_window(tp) +#endif + ) { + tcp_fast_path_on(tp); + } + } if (used + offset < skb->len) continue; @@ -1334,8 +1470,30 @@ if (flags & MSG_PEEK) continue; skb->used = 1; - if (atomic_read(&skb->users) == 1) - tcp_eat_skb(sk, skb); + tcp_eat_skb(sk, skb); + +#ifdef CONFIG_TCP_LESS_COARSE_ACKS + /* Possible improvement. When sender is faster than receiver, + * traffic looks like: fill window ... wait for window open ... + * fill window. We lose at least one rtt, because call + * cleanup_rbuf only once. Probably, if "len" was large + * we should insert several intermediate cleanup_rbuf(s). + * + * F.e.: + */ + do { + u32 full_space = min(tp->window_clamp, tcp_full_space(sk)); + + /* Try to ACK, if total buffer length is larger + than maximal window and if rcv_window has + chances to increase twice. It will result + to exponentially decreased ACKing during + read to huge (usually, mmapped) buffer. + */ + if (len >= full_space && tp->rcv_wnd <= full_space/2) + cleanup_rbuf(sk, copied); + } while (0); +#endif continue; found_fin_ok: @@ -1345,19 +1503,36 @@ /* All is done. */ skb->used = 1; - sk->shutdown |= RCV_SHUTDOWN; break; } - if (copied >= 0 && msg->msg_name) - tp->af_specific->addr2sockaddr(sk, (struct sockaddr *) - msg->msg_name); + if (user_recv) { + if (skb_queue_len(&tp->ucopy.prequeue)) { + int chunk; + + tp->ucopy.len = copied > 0 ? len : 0; + + tcp_prequeue_process(sk); + + if (copied > 0 && (chunk = len - tp->ucopy.len) != 0) { + net_statistics[smp_processor_id()*2+1].TCPDirectCopyFromPrequeue += chunk; + len -= chunk; + copied += chunk; + } + } + + tp->ucopy.task = NULL; + tp->ucopy.len = 0; + } - if(addr_len) - *addr_len = tp->af_specific->sockaddr_len; + /* According to UNIX98, msg_name/msg_namelen are ignored + * on connected socket. I was just happy when found this 8) --ANK + */ /* Clean up data we have read: This will do ACK frames. */ cleanup_rbuf(sk, copied); + + TCP_CHECK_TIMER(sk); release_sock(sk); return copied; @@ -1365,24 +1540,16 @@ err = sock_error(sk); out: + TCP_CHECK_TIMER(sk); release_sock(sk); return err; recv_urg: - err = tcp_recv_urg(sk, nonblock, msg, len, flags, addr_len); + err = tcp_recv_urg(sk, timeo, msg, len, flags, addr_len); goto out; } /* - * Check whether to renew the timer. - */ -static inline void tcp_check_fin_timer(struct sock *sk) -{ - if (sk->state == TCP_FIN_WAIT2) - tcp_reset_keepalive_timer(sk, sysctl_tcp_fin_timeout); -} - -/* * State processing on a close. This implements the state shift for * sending our FIN frame. Note that we only send a FIN for some * states. A shutdown() may have already sent the FIN, or we may be @@ -1405,24 +1572,13 @@ /* TCP_CLOSING */ TCP_CLOSING, }; -static int tcp_close_state(struct sock *sk, int dead) +static int tcp_close_state(struct sock *sk) { int next = (int) new_state[sk->state]; int ns = (next & TCP_STATE_MASK); tcp_set_state(sk, ns); - /* This is a (useful) BSD violating of the RFC. There is a - * problem with TCP as specified in that the other end could - * keep a socket open forever with no application left this end. - * We use a 3 minute timeout (about the same as BSD) then kill - * our end. If they send after that then tough - BUT: long enough - * that we won't make the old 4*rto = almost no time - whoops - * reset mistake. - */ - if (dead) - tcp_check_fin_timer(sk); - return (next & TCP_ACTION_FIN); } @@ -1443,9 +1599,8 @@ /* If we've already sent a FIN, or it's a closed state, skip this. */ if ((1 << sk->state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT|TCPF_SYN_RECV|TCPF_CLOSE_WAIT)) { - /* Clear out any half completed packets. FIN if needed. */ - if (tcp_close_state(sk,0)) + if (tcp_close_state(sk)) tcp_send_fin(sk); } } @@ -1460,40 +1615,6 @@ return ((1 << sk->state) & (TCPF_FIN_WAIT1|TCPF_CLOSING|TCPF_LAST_ACK)); } -/* - * This routine closes sockets which have been at least partially - * opened, but not yet accepted. Currently it is only called by - * tcp_close. - */ - -static void tcp_close_pending (struct sock *sk) -{ - struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - struct open_request *req = tp->syn_wait_queue; - - while(req) { - struct open_request *iter; - - if (req->sk) - tcp_close(req->sk, 0); - - iter = req; - req = req->dl_next; - - if (iter->sk) { - sk->ack_backlog--; - } else { - tcp_dec_slow_timer(TCP_SLT_SYNACK); - tp->syn_backlog--; - } - (*iter->class->destructor)(iter); - tcp_openreq_free(iter); - } - BUG_TRAP(tp->syn_backlog == 0); - BUG_TRAP(sk->ack_backlog == 0); - tcp_synq_init(tp); -} - static __inline__ void tcp_kill_sk_queues(struct sock *sk) { /* First the read buffer. */ @@ -1528,6 +1649,14 @@ /* It it has not 0 sk->num, it must be bound */ BUG_TRAP(!sk->num || sk->prev!=NULL); +#ifdef TCP_DEBUG + if (sk->zapped) { + printk("TCP: double destroy sk=%p\n", sk); + sock_hold(sk); + } + sk->zapped = 1; +#endif + sk->prot->destroy(sk); tcp_kill_sk_queues(sk); @@ -1538,6 +1667,7 @@ } #endif + atomic_dec(&tcp_orphan_count); sock_put(sk); } @@ -1547,17 +1677,17 @@ int data_was_unread = 0; lock_sock(sk); + sk->shutdown = SHUTDOWN_MASK; + if(sk->state == TCP_LISTEN) { tcp_set_state(sk, TCP_CLOSE); /* Special case. */ - tcp_close_pending(sk); + tcp_listen_stop(sk); goto adjudge_to_death; } - sk->shutdown = SHUTDOWN_MASK; - /* We need to flush the recv. buffs. We do this only on the * descriptor close, not protocol-sourced closes, because the * reader process may not have drained the data yet! @@ -1581,10 +1711,35 @@ /* Unread data was tossed, zap the connection. */ tcp_set_state(sk, TCP_CLOSE); tcp_send_active_reset(sk, GFP_KERNEL); - } else if (tcp_close_state(sk,1)) { + } else if (sk->linger && sk->lingertime==0) { + /* Check zero linger _after_ checking for unread data. */ + sk->prot->disconnect(sk, 0); + } else if (tcp_close_state(sk)) { /* We FIN if the application ate all the data before * zapping the connection. */ + + /* RED-PEN. Formally speaking, we have broken TCP state + * machine. State transitions: + * + * TCP_ESTABLISHED -> TCP_FIN_WAIT1 + * TCP_SYN_RECV -> TCP_FIN_WAIT1 (forget it, it's impossible) + * TCP_CLOSE_WAIT -> TCP_LAST_ACK + * + * are legal only when FIN has been sent (i.e. in window), + * rather than queued out of window. Purists blame. + * + * F.e. "RFC state" is ESTABLISHED, + * if Linux state is FIN-WAIT-1, but FIN is still not sent. + * + * The visible declinations are that sometimes + * we enter time-wait state, when it is not required really + * (harmless), do not send active resets, when they are + * required by specs (TCP_ESTABLISHED, TCP_CLOSE_WAIT, when + * they look as CLOSING or LAST_ACK for Linux) + * Probably, I missed some more holelets. + * --ANK + */ tcp_send_fin(sk); } @@ -1594,26 +1749,19 @@ add_wait_queue(sk->sleep, &wait); - while (1) { + do { set_current_state(TASK_INTERRUPTIBLE); if (!closing(sk)) break; release_sock(sk); timeout = schedule_timeout(timeout); lock_sock(sk); - if (!signal_pending(tsk) || timeout) - break; - } + } while (!signal_pending(tsk) && timeout); tsk->state = TASK_RUNNING; remove_wait_queue(sk->sleep, &wait); } - /* Now that the socket is dead, if we are in the FIN_WAIT2 state - * we may need to set up a timer. - */ - tcp_check_fin_timer(sk); - adjudge_to_death: /* It is the last release_sock in its life. It will remove backlog. */ release_sock(sk); @@ -1627,23 +1775,67 @@ BUG_TRAP(sk->lock.users==0); sock_hold(sk); + sock_orphan(sk); + + /* This is a (useful) BSD violating of the RFC. There is a + * problem with TCP as specified in that the other end could + * keep a socket open forever with no application left this end. + * We use a 3 minute timeout (about the same as BSD) then kill + * our end. If they send after that then tough - BUT: long enough + * that we won't make the old 4*rto = almost no time - whoops + * reset mistake. + * + * Nope, it was not mistake. It is really desired behaviour + * f.e. on http servers, when such sockets are useless, but + * consume significant resources. Let's do it with special + * linger2 option. --ANK + */ - /* Announce socket dead, detach it from wait queue and inode. */ - write_lock_irq(&sk->callback_lock); - sk->dead = 1; - sk->socket = NULL; - sk->sleep = NULL; - write_unlock_irq(&sk->callback_lock); + if (sk->state == TCP_FIN_WAIT2) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + if (tp->linger2 < 0) { + tcp_set_state(sk, TCP_CLOSE); + tcp_send_active_reset(sk, GFP_ATOMIC); + } else { + int tmo = tcp_fin_time(tp); + + if (tmo > TCP_TIMEWAIT_LEN) { + tcp_reset_keepalive_timer(sk, tcp_fin_time(tp)); + } else { + atomic_inc(&tcp_orphan_count); + tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); + goto out; + } + } + } + if (sk->state != TCP_CLOSE && + atomic_read(&tcp_orphan_count) > sysctl_tcp_max_orphans) { + if (net_ratelimit()) + printk(KERN_INFO "TCP: too many of orphaned sockets\n"); + tcp_set_state(sk, TCP_CLOSE); + tcp_send_active_reset(sk, GFP_ATOMIC); + } + atomic_inc(&tcp_orphan_count); if (sk->state == TCP_CLOSE) tcp_destroy_sock(sk); /* Otherwise, socket is reprieved until protocol close. */ +out: bh_unlock_sock(sk); local_bh_enable(); sock_put(sk); } +/* These states need RST on ABORT according to RFC793 */ + +extern __inline__ int tcp_need_reset(int state) +{ + return ((1 << state) & + (TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_FIN_WAIT1| + TCPF_FIN_WAIT2|TCPF_SYN_RECV)); +} + int tcp_disconnect(struct sock *sk, int flags) { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; @@ -1656,9 +1848,14 @@ /* ABORT function of RFC793 */ if (old_state == TCP_LISTEN) { - tcp_close_pending(sk); - } else if (tcp_connected(old_state)) { - tcp_send_active_reset(sk, GFP_KERNEL); + tcp_listen_stop(sk); + } else if (tcp_need_reset(old_state) || + (tp->snd_nxt != tp->write_seq && + (1<err = ECONNRESET; } else if (old_state == TCP_SYN_SENT) sk->err = ECONNRESET; @@ -1677,26 +1874,25 @@ memset(&sk->net_pinfo.af_inet6.rcv_saddr, 0, 16); #endif - sk->zapped = 0; sk->shutdown = 0; sk->done = 0; sk->write_space = tcp_write_space; tp->srtt = 0; -#ifdef CONFIG_TCP_TW_RECYCLE - if ((tp->write_seq += 2) == 0) - tp->write_seq = 1; -#else - tp->write_seq = 0; -#endif - tp->ato = 0; + if (sysctl_tcp_tw_recycle) { + if ((tp->write_seq += 2) == 0) + tp->write_seq = 1; + } else { + tp->write_seq = 0; + } tp->backoff = 0; tp->snd_cwnd = 2; tp->probes_out = 0; + tp->packets_out = 0; tp->high_seq = 0; tp->snd_ssthresh = 0x7fffffff; tp->snd_cwnd_cnt = 0; tp->dup_acks = 0; - tp->delayed_acks = 0; + tcp_delack_init(tp); tp->send_head = tp->retrans_head = NULL; tp->saw_tstamp = 0; __sk_dst_reset(sk); @@ -1712,11 +1908,10 @@ * conditions. This must be called with the socket locked, * and without the kernel lock held. */ -static struct open_request * wait_for_connect(struct sock * sk, - struct open_request **pprev) +static int wait_for_connect(struct sock * sk, long timeo) { DECLARE_WAITQUEUE(wait, current); - struct open_request *req; + int err; /* * True wake-one mechanism for incoming connections: only @@ -1736,17 +1931,25 @@ for (;;) { current->state = TASK_EXCLUSIVE | TASK_INTERRUPTIBLE; release_sock(sk); - schedule(); + if (sk->tp_pinfo.af_tcp.accept_queue == NULL) + timeo = schedule_timeout(timeo); lock_sock(sk); - req = tcp_find_established(&(sk->tp_pinfo.af_tcp), pprev); - if (req) + err = 0; + if (sk->tp_pinfo.af_tcp.accept_queue) break; + err = -EINVAL; + if (sk->state != TCP_LISTEN) + break; + err = -ERESTARTSYS; if (signal_pending(current)) break; + err = -EAGAIN; + if (!timeo) + break; } current->state = TASK_RUNNING; remove_wait_queue(sk->sleep, &wait); - return req; + return err; } /* @@ -1758,9 +1961,10 @@ struct sock *tcp_accept(struct sock *sk, int flags, int *err) { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - struct open_request *req, *prev; + struct open_request *req; struct sock *newsk; int error; + long timeo; lock_sock(sk); @@ -1771,25 +1975,27 @@ if (sk->state != TCP_LISTEN) goto out; + timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); + /* Find already established connection */ - req = tcp_find_established(tp, &prev); - if (!req) { + if (!tp->accept_queue) { /* If this is a non blocking socket don't sleep */ error = -EAGAIN; - if (flags & O_NONBLOCK) + if (!timeo) goto out; - error = -ERESTARTSYS; - req = wait_for_connect(sk, &prev); - if (!req) + error = wait_for_connect(sk, timeo); + if (error) goto out; } - tcp_synq_unlink(tp, req, prev); - newsk = req->sk; - req->class->destructor(req); - tcp_openreq_free(req); - sk->ack_backlog--; + req = tp->accept_queue; + tp->accept_queue = req->dl_next; + + newsk = req->sk; + tcp_acceptq_removed(sk); + tcp_openreq_fastfree(req); + BUG_TRAP(newsk->state != TCP_SYN_RECV); release_sock(sk); return newsk; @@ -1828,7 +2034,7 @@ * the point when this call is done we typically don't yet know * which interface is going to be used */ - if(val < 1 || val > MAX_WINDOW) { + if(val < 8 || val > MAX_TCP_WINDOW) { err = -EINVAL; break; } @@ -1839,11 +2045,11 @@ /* You cannot try to use this and TCP_CORK in * tandem, so let the user know. */ - if (sk->nonagle == 2) { + if (tp->nonagle == 2) { err = -EINVAL; break; } - sk->nonagle = (val == 0) ? 0 : 1; + tp->nonagle = (val == 0) ? 0 : 1; break; case TCP_CORK: @@ -1858,14 +2064,14 @@ * You cannot try to use TCP_NODELAY and this mechanism * at the same time, so let the user know. */ - if (sk->nonagle == 1) { + if (tp->nonagle == 1) { err = -EINVAL; break; } if (val != 0) { - sk->nonagle = 2; + tp->nonagle = 2; } else { - sk->nonagle = 0; + tp->nonagle = 0; tcp_push_pending_frames(sk, tp); } @@ -1905,6 +2111,38 @@ tp->syn_retries = val; break; + case TCP_LINGER2: + if (val < 0) + tp->linger2 = -1; + else if (val > sysctl_tcp_fin_timeout/HZ) + tp->linger2 = 0; + else + tp->linger2 = val*HZ; + break; + + case TCP_DEFER_ACCEPT: + tp->defer_accept = 0; + if (val > 0) { + /* Translate value in seconds to number of retransmits */ + while (val > ((TCP_TIMEOUT_INIT/HZ)<defer_accept)) + tp->defer_accept++; + tp->defer_accept++; + } + break; + + case TCP_WINDOW_CLAMP: + if (val==0) { + if (sk->state != TCP_CLOSE) { + err = -EINVAL; + break; + } + tp->window_clamp = 0; + } else { + tp->window_clamp = valuser_mss; + val = tp->mss_cache; + if (val == 0 && ((1<state)&(TCPF_CLOSE|TCPF_LISTEN))) + val = tp->user_mss; break; case TCP_NODELAY: - val = (sk->nonagle == 1); + val = (tp->nonagle == 1); break; case TCP_CORK: - val = (sk->nonagle == 2); + val = (tp->nonagle == 2); break; case TCP_KEEPIDLE: - if (tp->keepalive_time) - val = tp->keepalive_time / HZ; - else - val = sysctl_tcp_keepalive_time / HZ; + val = (tp->keepalive_time ? : sysctl_tcp_keepalive_time)/HZ; break; case TCP_KEEPINTVL: - if (tp->keepalive_intvl) - val = tp->keepalive_intvl / HZ; - else - val = sysctl_tcp_keepalive_intvl / HZ; + val = (tp->keepalive_intvl ? : sysctl_tcp_keepalive_intvl)/HZ; break; case TCP_KEEPCNT: - if (tp->keepalive_probes) - val = tp->keepalive_probes; - else - val = sysctl_tcp_keepalive_probes; + val = tp->keepalive_probes ? : sysctl_tcp_keepalive_probes; break; case TCP_SYNCNT: - if (tp->syn_retries) - val = tp->syn_retries; - else - val = sysctl_tcp_syn_retries; + val = tp->syn_retries ? : sysctl_tcp_syn_retries; + break; + case TCP_LINGER2: + val = tp->linger2; + if (val > 0) + val = (val ? : sysctl_tcp_fin_timeout)/HZ; + break; + case TCP_DEFER_ACCEPT: + val = tp->defer_accept == 0 ? 0 : (TCP_TIMEOUT_INIT<<(tp->defer_accept-1)); + break; + case TCP_WINDOW_CLAMP: + val = tp->window_clamp; break; default: return -ENOPROTOOPT; @@ -2049,11 +2288,20 @@ tcp_bhash[i].chain = NULL; } + /* Try to be a bit smarter and adjust defaults depending + * on available memory. + */ if (order > 4) { sysctl_local_port_range[0] = 32768; sysctl_local_port_range[1] = 61000; + sysctl_tcp_max_tw_buckets = 180000; + sysctl_tcp_max_orphans = 4096<<(order-4); + sysctl_max_syn_backlog = 1024; } else if (order < 3) { sysctl_local_port_range[0] = 1024*(3-order); + sysctl_tcp_max_tw_buckets >>= (3-order); + sysctl_tcp_max_orphans >>= (3-order); + sysctl_max_syn_backlog = 128; } tcp_port_rover = sysctl_local_port_range[0] - 1; diff -ur --new-file old/linux/net/ipv4/tcp_input.c new/linux/net/ipv4/tcp_input.c --- old/linux/net/ipv4/tcp_input.c Sun Jan 9 06:36:21 2000 +++ new/linux/net/ipv4/tcp_input.c Tue Jan 25 19:26:04 2000 @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_input.c,v 1.177 2000/01/09 02:19:39 davem Exp $ + * Version: $Id: tcp_input.c,v 1.183 2000/01/24 18:40:33 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -70,9 +70,6 @@ #define SYNC_INIT 1 #endif -extern int sysctl_tcp_fin_timeout; -extern int sysctl_tcp_keepalive_time; - /* These are on by default so the code paths get tested. * For the final 2.2 this may be undone at our discretion. -DaveM */ @@ -83,10 +80,108 @@ int sysctl_tcp_syncookies = SYNC_INIT; int sysctl_tcp_stdurg; int sysctl_tcp_rfc1337; -int sysctl_tcp_tw_recycle; +int sysctl_tcp_tw_recycle = 1; +int sysctl_tcp_abort_on_overflow = 0; +int sysctl_tcp_max_orphans = NR_FILE; +int sysctl_tcp_max_tw_buckets = NR_FILE*2; static int prune_queue(struct sock *sk); +/* + * Adapt the MSS value used to make delayed ack decision to the + * real world. + * + * The constant 536 hasn't any good meaning. In IPv4 world + * MTU may be smaller, though it contradicts to RFC1122, which + * states that MSS must be at least 536. + * We use the constant to do not ACK each second + * packet in a stream of tiny size packets. + * It means that super-low mtu links will be aggressively delacked. + * Seems, it is even good. If they have so low mtu, they are weirdly + * slow. + * + * AK: BTW it may be useful to add an option to lock the rcv_mss. + * this way the beowulf people wouldn't need ugly patches to get the + * ack frequencies they want and it would be an elegant way to tune delack. + */ +static __inline__ void tcp_measure_rcv_mss(struct tcp_opt *tp, struct sk_buff *skb) +{ + unsigned int len, lss; + + lss = tp->ack.last_seg_size; + tp->ack.last_seg_size = 0; + + /* skb->len may jitter because of SACKs, even if peer + * sends good full-sized frames. + */ + len = skb->len; + if (len >= tp->ack.rcv_mss) { + tp->ack.rcv_mss = len; + } else { + /* Otherwise, we make more careful check taking into account, + * that SACKs block is variable. + * + * "len" is invariant segment length, including TCP header. + */ + len = skb->tail - skb->h.raw; + if (len >= TCP_MIN_RCVMSS + sizeof(struct tcphdr)) { + /* Subtract also invariant (if peer is RFC compliant), + * tcp header plus fixed timestamp option length. + * Resulting "len" is MSS free of SACK jitter. + */ + len -= tp->tcp_header_len; + if (len == lss) + tp->ack.rcv_mss = len; + tp->ack.last_seg_size = len; + } + +#if 0 + /* Tiny-grams with PSH set artifically deflate our + * ato measurement. + * + * Mmm... I copied this test from tcp_remember_ack(), but + * I did not understand this. Is it to speedup nagling sender? + * It does not because classic (non-Minshall) sender nagles + * guided by not-acked frames not depending on size. + * And it does not help NODELAY sender, because latency + * is too high in any case. The only result is timer trashing + * and redundant ACKs. Grr... Seems, I missed something. --ANK + * + * Let me to comment out this yet... TCP should work + * perfectly without this. --ANK + */ + if (len < (tp->ack.rcv_mss >> 1) && skb->h.th->psh) + tp->ack.ato = TCP_ATO_MIN; +#endif + } +} + + +static __inline__ void tcp_enter_quickack_mode(struct tcp_opt *tp) +{ + unsigned quickacks = tcp_receive_window(tp)/(2*tp->ack.rcv_mss); + + tp->ack.quick = max(min(quickacks, 127), 1); + + if (!tp->tstamp_ok && tp->ack.quick>2) { + /* Quick ACKs are _dangerous_, if RTTM is not used. + * See comment in tcp_init_metrics(). We still help + * them to overcome the most difficult, initial + * phase of slow start. + */ + tp->ack.quick = 2; + } +} + +/* Send ACKs quickly, if "quick" count is not ehausted + * and the session is not interactive. + */ + +static __inline__ int tcp_in_quickack_mode(struct tcp_opt *tp) +{ + return (tp->ack.quick && !tp->ack.pingpong); +} + /* There is something which you must keep in mind when you analyze the * behavior of the tp->ato delayed ack timeout interval. When a * connection starts up, we want to ack as quickly as possible. The @@ -97,53 +192,52 @@ * each ACK we send, he increments snd_cwnd and transmits more of his * queue. -DaveM */ -static void tcp_delack_estimator(struct tcp_opt *tp) +static void tcp_event_data_recv(struct tcp_opt *tp, struct sk_buff *skb) { - if(tp->ato == 0) { - tp->lrcvtime = tcp_time_stamp; + u32 now; - /* Help sender leave slow start quickly, - * and also makes sure we do not take this - * branch ever again for this connection. + tcp_measure_rcv_mss(tp, skb); + + tp->ack.pending = 1; + + now = tcp_time_stamp; + + if (!tp->ack.ato) { + /* The _first_ data packet received, initialize + * delayed ACK engine. */ - tp->ato = 1; + + /* Help sender leave slow start quickly. */ tcp_enter_quickack_mode(tp); + + /* Pingpong is off, session is not interactive by default */ + tp->ack.pingpong = 0; + + /* ATO is minimal */ + tp->ack.ato = TCP_ATO_MIN; } else { - int m = tcp_time_stamp - tp->lrcvtime; + int m = now - tp->ack.lrcvtime; - tp->lrcvtime = tcp_time_stamp; - if(m <= 0) - m = 1; - if(m > tp->rto) - tp->ato = tp->rto; - else { - /* This funny shift makes sure we - * clear the "quick ack mode" bit. - */ - tp->ato = ((tp->ato << 1) >> 2) + m; + if (m > TCP_ATO_MAX/2) { + /* Do not touch ATO, if interval is out of bounds. + * It will be deflated by delack timer, if our peer + * really sends too rarely. + */ + if (m > tp->rto) { + /* Too long gap. Apparently sender falled to + * restart window, so that we send ACKs quickly. + */ + tcp_enter_quickack_mode(tp); + } + } else { + if (m <= 0) + m = TCP_ATO_MIN/2; + tp->ack.ato = (tp->ack.ato >> 1) + m; } } + tp->ack.lrcvtime = now; } -/* - * Remember to send an ACK later. - */ -static __inline__ void tcp_remember_ack(struct tcp_opt *tp, struct tcphdr *th, - struct sk_buff *skb) -{ - tp->delayed_acks++; - - /* Tiny-grams with PSH set artifically deflate our - * ato measurement, but with a lower bound. - */ - if(th->psh && (skb->len < (tp->rcv_mss >> 1))) { - /* Preserve the quickack state. */ - if((tp->ato & 0x7fffffff) > HZ/50) - tp->ato = ((tp->ato & 0x80000000) | - (HZ/50)); - } -} - /* Called to compute a smoothed rtt estimate. The data fed to this * routine either comes from timestamps, or from segments that were * known _not_ to have been retransmitted [see Karn/Partridge @@ -209,10 +303,10 @@ */ static __inline__ void tcp_bound_rto(struct tcp_opt *tp) { - if (tp->rto > 120*HZ) - tp->rto = 120*HZ; - if (tp->rto < HZ/5) - tp->rto = HZ/5; + if (tp->rto < TCP_RTO_MIN) + tp->rto = TCP_RTO_MIN; + else if (tp->rto > TCP_RTO_MAX) + tp->rto = TCP_RTO_MAX; } /* Save metrics learned by this TCP session. @@ -224,7 +318,9 @@ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); struct dst_entry *dst = __sk_dst_get(sk); - if (dst) { + dst_confirm(dst); + + if (dst && (dst->flags&DST_HOST)) { int m; if (tp->backoff || !tp->srtt) { @@ -237,8 +333,6 @@ return; } - dst_confirm(dst); - m = dst->rtt - tp->srtt; /* If newly calculated rtt larger than stored one, @@ -308,10 +402,18 @@ dst_confirm(dst); + if (dst->mxlock&(1<snd_cwnd_clamp = dst->cwnd; + if (dst->ssthresh) { + tp->snd_ssthresh = dst->ssthresh; + if (tp->snd_ssthresh > tp->snd_cwnd_clamp) + tp->snd_ssthresh = tp->snd_cwnd_clamp; + } + if (dst->rtt == 0) goto reset; - if (!tp->srtt || !tp->saw_tstamp) + if (!tp->srtt && dst->rtt < (TCP_TIMEOUT_INIT<<3)) goto reset; /* Initial rtt is determined from SYN,SYN-ACK. @@ -334,14 +436,9 @@ tp->mdev = dst->rttvar; tcp_set_rto(tp); tcp_bound_rto(tp); - - if (dst->mxlock&(1<snd_cwnd_clamp = dst->cwnd; - if (dst->ssthresh) { - tp->snd_ssthresh = dst->ssthresh; - if (tp->snd_ssthresh > tp->snd_cwnd_clamp) - tp->snd_ssthresh = tp->snd_cwnd_clamp; - } + if (tp->rto < TCP_TIMEOUT_INIT && !tp->saw_tstamp) + goto reset; + tp->snd_cwnd = tcp_init_cwnd(tp); return; @@ -357,9 +454,6 @@ } } -#define PAWS_24DAYS (60 * 60 * 24 * 24) - - /* WARNING: this must not be called if tp->saw_tstamp was false. */ extern __inline__ void tcp_replace_ts_recent(struct sock *sk, struct tcp_opt *tp, u32 seq) @@ -374,7 +468,7 @@ */ if((s32)(tp->rcv_tsval - tp->ts_recent) >= 0 || - xtime.tv_sec >= tp->ts_recent_stamp + PAWS_24DAYS) { + xtime.tv_sec >= tp->ts_recent_stamp + TCP_PAWS_24DAYS) { tp->ts_recent = tp->rcv_tsval; tp->ts_recent_stamp = xtime.tv_sec; } @@ -384,7 +478,7 @@ extern __inline__ int tcp_paws_discard(struct tcp_opt *tp, struct sk_buff *skb) { return ((s32)(tp->rcv_tsval - tp->ts_recent) < 0 && - xtime.tv_sec < tp->ts_recent_stamp + PAWS_24DAYS + xtime.tv_sec < tp->ts_recent_stamp + TCP_PAWS_24DAYS /* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM @@ -411,8 +505,13 @@ static int __tcp_sequence(struct tcp_opt *tp, u32 seq, u32 end_seq) { u32 end_window = tp->rcv_wup + tp->rcv_wnd; +#ifdef TCP_FORMAL_WINDOW + u32 rcv_wnd = tcp_receive_window(tp); +#else + u32 rcv_wnd = tp->rcv_wnd; +#endif - if (tp->rcv_wnd && + if (rcv_wnd && after(end_seq, tp->rcv_nxt) && before(seq, end_window)) return 1; @@ -424,8 +523,13 @@ /* This functions checks to see if the tcp header is actually acceptable. */ extern __inline__ int tcp_sequence(struct tcp_opt *tp, u32 seq, u32 end_seq) { +#ifdef TCP_FORMAL_WINDOW + u32 rcv_wnd = tcp_receive_window(tp); +#else + u32 rcv_wnd = tp->rcv_wnd; +#endif if (seq == tp->rcv_nxt) - return (tp->rcv_wnd || (end_seq == seq)); + return (rcv_wnd || (end_seq == seq)); return __tcp_sequence(tp, seq, end_seq); } @@ -433,8 +537,6 @@ /* When we get a reset we do this. */ static void tcp_reset(struct sock *sk) { - sk->zapped = 1; - /* We want the right error as BSD sees it (and indeed as we do). */ switch (sk->state) { case TCP_SYN_SENT: @@ -447,9 +549,8 @@ return; default: sk->err = ECONNRESET; - }; - tcp_set_state(sk, TCP_CLOSE); - tcp_clear_xmit_timers(sk); + } + tcp_done(sk); } @@ -658,17 +759,18 @@ if (tp->high_seq == 0 || after(ack, tp->high_seq)) { tp->dup_acks++; if ((tp->fackets_out > 3) || (tp->dup_acks == 3)) { - tp->snd_ssthresh = tcp_recalc_ssthresh(tp); - if (tp->snd_ssthresh > tp->snd_cwnd_clamp) - tp->snd_ssthresh = tp->snd_cwnd_clamp; - tp->snd_cwnd = (tp->snd_ssthresh + 3); - tp->high_seq = tp->snd_nxt; + __tcp_enter_cong_avoid(tp); + /* ... and account for 3 ACKs, which are + * already received to this time. + */ + tp->snd_cwnd += 3; + if(!tp->fackets_out) tcp_retransmit_skb(sk, skb_peek(&sk->write_queue)); else tcp_fack_retransmit(sk); - tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); } } else if (++tp->dup_acks > 3) { /* 2. Each time another duplicate ACK arrives, increment @@ -733,7 +835,7 @@ if (ack != tp->snd_una && before(ack, tp->high_seq)) { tcp_retransmit_skb(sk, skb_peek(&sk->write_queue)); - tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); } } else { /* FACK style, fill any remaining holes in @@ -752,7 +854,8 @@ { if (tp->snd_cwnd <= tp->snd_ssthresh) { /* In "safe" area, increase. */ - tp->snd_cwnd++; + if (tp->snd_cwnd < tp->snd_cwnd_clamp) + tp->snd_cwnd++; } else { /* In dangerous area, increase slowly. * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd @@ -826,23 +929,23 @@ { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - /* Our probe was answered. */ - tp->probes_out = 0; - /* Was it a usable window open? */ - /* should always be non-null */ - if (tp->send_head != NULL && - !before (ack + tp->snd_wnd, TCP_SKB_CB(tp->send_head)->end_seq)) { - tp->backoff = 0; - tp->pending = 0; - tcp_clear_xmit_timer(sk, TIME_PROBE0); - } else { - tcp_reset_xmit_timer(sk, TIME_PROBE0, - min(tp->rto << tp->backoff, 120*HZ)); + if (tp->send_head != NULL) { + if (!after(TCP_SKB_CB(tp->send_head)->end_seq, ack + tp->snd_wnd)) { + tp->backoff = 0; + tcp_clear_xmit_timer(sk, TCP_TIME_PROBE0); + /* If packets_out==0, socket must be waked up by + * subsequent tcp_data_snd_check(). This function is + * not for random using! + */ + } else if (!tp->packets_out) { + tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, + min(tp->rto << tp->backoff, TCP_RTO_MAX)); + } } } - + /* Should we open up the congestion window? */ static __inline__ int should_advance_cwnd(struct tcp_opt *tp, int flag) { @@ -914,18 +1017,30 @@ { struct sk_buff *skb = skb_peek(&sk->write_queue); +#ifdef TCP_DEBUG + /* It occured in 2.3, because of racy timers. Namely, + * retransmit timer did not check packets_out and retransmitted + * send_head sometimes and, hence, messed all the write_queue. + * Now it is impossible, I bet. --ANK + */ + if (skb == NULL) { + printk("Sucks! packets_out=%d, sk=%p, %d\n", tp->packets_out, sk, sk->state); + return; + } +#endif + /* Some data was ACK'd, if still retransmitting (due to a * timeout), resend more of the retransmit queue. The * congestion window is handled properly by that code. */ if (tp->retransmits) { tcp_xmit_retransmit_queue(sk); - tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); } else { __u32 when = tp->rto - (tcp_time_stamp - TCP_SKB_CB(skb)->when); if ((__s32)when < 0) when = 1; - tcp_reset_xmit_timer(sk, TIME_RETRANS, when); + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, when); } } @@ -938,13 +1053,8 @@ u32 seq = 0; u32 seq_rtt = 0; - if(sk->zapped) - return(1); /* Dead, can't ack any more so why bother */ - - if (tp->pending == TIME_KEEPOPEN) - tp->probes_out = 0; - - tp->rcv_tstamp = tcp_time_stamp; + if(sk->state == TCP_CLOSE) + return 1; /* Dead, can't ack any more so why bother */ /* If the ack is newer than sent or older than previous acks * then we can probably ignore it. @@ -953,10 +1063,8 @@ goto uninteresting_ack; /* If there is data set flag 1 */ - if (len != th->doff*4) { + if (len != th->doff*4) flag |= FLAG_DATA; - tcp_delack_estimator(tp); - } /* Update our send window. */ @@ -970,31 +1078,53 @@ if ((tp->snd_wl2 != ack) || (nwin > tp->snd_wnd)) { flag |= FLAG_WIN_UPDATE; - tp->snd_wnd = nwin; + if (tp->snd_wnd != nwin) { + tp->snd_wnd = nwin; + + /* Note, it is the only place, where + * fast path is recovered for sending TCP. + */ + if (skb_queue_len(&tp->out_of_order_queue) == 0 && +#ifdef TCP_FORMAL_WINDOW + tcp_receive_window(tp) && +#endif + !tp->urg_data) + tcp_fast_path_on(tp); + + if (nwin > tp->max_window) { + tp->max_window = nwin; + tcp_sync_mss(sk, tp->pmtu_cookie); + } + } tp->snd_wl1 = ack_seq; tp->snd_wl2 = ack; - - if (nwin > tp->max_window) - tp->max_window = nwin; } } + /* BEWARE! From this place and until return from this function + * snd_nxt and snd_wnd are out of sync. All the routines, called + * from here must get "ack" as argument or they should not depend + * on right edge of window. It is _UGLY_. It cries to be fixed. --ANK + */ + /* We passed data and got it acked, remove any soft error * log. Something worked... */ sk->err_soft = 0; + tp->probes_out = 0; + tp->rcv_tstamp = tcp_time_stamp; + + /* See if we can take anything off of the retransmit queue. */ + flag |= tcp_clean_rtx_queue(sk, ack, &seq, &seq_rtt); /* If this ack opens up a zero window, clear backoff. It was * being used to time the probes, and is probably far higher than * it needs to be for normal retransmission. */ - if (tp->pending == TIME_PROBE0) + if (tcp_timer_is_set(sk, TCP_TIME_PROBE0)) tcp_ack_probe(sk, ack); - /* See if we can take anything off of the retransmit queue. */ - flag |= tcp_clean_rtx_queue(sk, ack, &seq, &seq_rtt); - /* We must do this here, before code below clears out important * state contained in tp->fackets_out and tp->retransmits. -DaveM */ @@ -1036,7 +1166,7 @@ if (flag & FLAG_DATA_ACKED) tcp_ack_packets_out(sk, tp); } else { - tcp_clear_xmit_timer(sk, TIME_RETRANS); + tcp_clear_xmit_timer(sk, TCP_TIME_RETRANS); } flag &= (FLAG_DATA | FLAG_WIN_UPDATE); @@ -1074,9 +1204,42 @@ return 0; } +int tcp_paws_check(struct tcp_opt *tp, int rst) +{ + if ((s32)(tp->rcv_tsval - tp->ts_recent) >= 0) + return 0; + if (xtime.tv_sec >= tp->ts_recent_stamp + TCP_PAWS_24DAYS) + return 0; + + /* RST segments are not recommended to carry timestamp, + and, if they do, it is recommended to ignore PAWS because + "their cleanup function should take precedence over timestamps." + Certainly, it is mistake. It is necessary to understand the reasons + of this constraint to relax it: if peer reboots, clock may go + out-of-sync and half-open connections will not be reset. + Actually, the problem would be not existing if all + the implementations followed draft about maintaining clock + via reboots. Linux-2.2 DOES NOT! + + However, we can relax time bounds for RST segments to MSL. + */ + if (rst && xtime.tv_sec >= tp->ts_recent_stamp + TCP_PAWS_MSL) + return 0; + return 1; +} + +static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win) +{ + if (seq == s_win) + return 1; + if (after(end_seq, s_win) && before(seq, e_win)) + return 1; + return (seq == e_win && seq == end_seq); +} + /* New-style handling of TIME_WAIT sockets. */ -/* Must be called only from BH context. */ +/* Must be called with locally disabled BHs. */ void tcp_timewait_kill(struct tcp_tw_bucket *tw) { struct tcp_ehash_bucket *ehead; @@ -1121,13 +1284,6 @@ tcp_tw_put(tw); } -/* We come here as a special case from the AF specific TCP input processing, - * and the SKB has no owner. Essentially handling this is very simple, - * we just keep silently eating rx'd packets until none show up for the - * entire timeout period. The only special cases are for BSD TIME_WAIT - * reconnects and SYN/RST bits being set in the TCP header. - */ - /* * * Main purpose of TIME-WAIT state is to close connection gracefully, * when one of ends sits in LAST-ACK or CLOSING retransmitting FIN @@ -1149,6 +1305,12 @@ * The algorithm below is based on FORMAL INTERPRETATION of RFCs. * When you compare it to RFCs, please, read section SEGMENT ARRIVES * from the very beginning. + * + * NOTE. With recycling (and later with fin-wait-2) TW bucket + * is _not_ stateless. It means, that strictly speaking we must + * spinlock it. I do not want! Well, probability of misbehaviour + * is ridiculously low and, seems, we could use some mb() tricks + * to avoid misread sequence numbers, states etc. --ANK */ enum tcp_tw_status tcp_timewait_state_process(struct tcp_tw_bucket *tw, struct sk_buff *skb, @@ -1157,7 +1319,75 @@ struct tcp_opt tp; int paws_reject = 0; - /* RFC 1122: + tp.saw_tstamp = 0; + if (th->doff > (sizeof(struct tcphdr)>>2) && tw->ts_recent_stamp) { + tcp_parse_options(NULL, th, &tp, 0); + + if (tp.saw_tstamp) { + tp.ts_recent = tw->ts_recent; + tp.ts_recent_stamp = tw->ts_recent_stamp; + paws_reject = tcp_paws_check(&tp, th->rst); + } + } + + if (tw->substate == TCP_FIN_WAIT2) { + /* Just repeat all the checks of tcp_rcv_state_process() */ + + /* Out of window, send ACK */ + if (paws_reject || + !tcp_in_window(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq, + tw->rcv_nxt, tw->rcv_nxt + tw->rcv_wnd)) + return TCP_TW_ACK; + + if (th->rst) + goto kill; + + if (th->syn && TCP_SKB_CB(skb)->seq != tw->syn_seq) + goto kill_with_rst; + + /* Dup ACK? */ + if (!after(TCP_SKB_CB(skb)->end_seq, tw->rcv_nxt)) { + tcp_tw_put(tw); + return TCP_TW_SUCCESS; + } + + /* New data or FIN. If new data arrive after half-duplex close, + * reset. + */ + if (!th->fin || TCP_SKB_CB(skb)->end_seq != tw->rcv_nxt+1) { +kill_with_rst: + tcp_tw_deschedule(tw); + tcp_timewait_kill(tw); + tcp_tw_put(tw); + return TCP_TW_RST; + } + + /* FIN arrived, enter true time-wait state. */ + tw->substate = TCP_TIME_WAIT; + tw->rcv_nxt = TCP_SKB_CB(skb)->end_seq; + if (tp.saw_tstamp) { + tw->ts_recent_stamp = xtime.tv_sec; + tw->ts_recent = tp.rcv_tsval; + } + + /* I am shamed, but failed to make it more elegant. + * Yes, it is direct reference to IP, which is impossible + * to generalize to IPv6. Taking into account that IPv6 + * do not undertsnad recycling in any case, it not + * a big problem in practice. --ANK */ + if (tw->family == AF_INET && + sysctl_tcp_tw_recycle && tw->ts_recent_stamp && + tcp_v4_tw_remember_stamp(tw)) + tcp_tw_schedule(tw, tw->timeout); + else + tcp_tw_schedule(tw, TCP_TIMEWAIT_LEN); + return TCP_TW_ACK; + } + + /* + * Now real TIME-WAIT state. + * + * RFC 1122: * "When a connection is [...] on TIME-WAIT state [...] * [a TCP] MAY accept a new SYN from the remote TCP to * reopen the connection directly, if it: @@ -1171,47 +1401,31 @@ * to be an old duplicate". */ - tp.saw_tstamp = 0; - if (th->doff > (sizeof(struct tcphdr)>>2) && tw->ts_recent_stamp) { - tcp_parse_options(NULL, th, &tp, 0); - - paws_reject = tp.saw_tstamp && - ((s32)(tp.rcv_tsval - tw->ts_recent) < 0 && - xtime.tv_sec < tw->ts_recent_stamp + PAWS_24DAYS); - } - if (!paws_reject && (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq && TCP_SKB_CB(skb)->seq == tw->rcv_nxt)) { /* In window segment, it may be only reset or bare ack. */ if (th->rst) { -#ifdef CONFIG_TCP_TW_RECYCLE - /* When recycling, always follow rfc1337, - * but mark bucket as ready to recycling immediately. - */ - if (sysctl_tcp_tw_recycle) { - /* May kill it now. */ - tw->rto = 0; - tw->ttd = jiffies; - } else -#endif /* This is TIME_WAIT assasination, in two flavors. * Oh well... nobody has a sufficient solution to this * protocol bug yet. */ - if(sysctl_tcp_rfc1337 == 0) { + if (sysctl_tcp_rfc1337 == 0) { +kill: tcp_tw_deschedule(tw); tcp_timewait_kill(tw); + tcp_tw_put(tw); + return TCP_TW_SUCCESS; } - } else { - tcp_tw_reschedule(tw); } + tcp_tw_schedule(tw, TCP_TIMEWAIT_LEN); if (tp.saw_tstamp) { tw->ts_recent = tp.rcv_tsval; tw->ts_recent_stamp = xtime.tv_sec; } + tcp_tw_put(tw); return TCP_TW_SUCCESS; } @@ -1235,7 +1449,7 @@ if (th->syn && !th->rst && !th->ack && !paws_reject && (after(TCP_SKB_CB(skb)->seq, tw->rcv_nxt) || - (tp.saw_tstamp && tw->ts_recent != tp.rcv_tsval))) { + (tp.saw_tstamp && (s32)(tw->ts_recent - tp.rcv_tsval) < 0))) { u32 isn = tw->snd_nxt + 2; if (isn == 0) isn++; @@ -1243,20 +1457,18 @@ return TCP_TW_SYN; } + if (paws_reject) + NET_INC_STATS_BH(PAWSEstabRejected); + if(!th->rst) { /* In this case we must reset the TIMEWAIT timer. - - If it is ACKless SYN it may be both old duplicate - and new good SYN with random sequence number ack) { - tcp_tw_reschedule(tw); -#ifdef CONFIG_TCP_TW_RECYCLE - tw->rto = min(120*HZ, tw->rto<<1); - tw->ttd = jiffies + tw->rto; -#endif - } + * + * If it is ACKless SYN it may be both old duplicate + * and new good SYN with random sequence number ack) + tcp_tw_schedule(tw, TCP_TIMEWAIT_LEN); /* Send ACK. Note, we do not put the bucket, * it will be released by caller. @@ -1267,8 +1479,8 @@ return TCP_TW_SUCCESS; } -/* Enter the time wait state. This is always called from BH - * context. Essentially we whip up a timewait bucket, copy the +/* Enter the time wait state. This is called with locally disabled BH. + * Essentially we whip up a timewait bucket, copy the * relevant info into it from the SK, and mess with hash chains * and list linkage. */ @@ -1286,6 +1498,7 @@ sk->next->pprev = sk->pprev; *sk->pprev = sk->next; sk->pprev = NULL; + sock_prot_dec_use(sk->prot); } /* Step 2: Hash TW into TIMEWAIT half of established hash table. */ @@ -1312,41 +1525,49 @@ tw->tb->owners = (struct sock*)tw; tw->bind_pprev = &tw->tb->owners; spin_unlock(&bhead->lock); - - /* Step 4: Un-charge protocol socket in-use count. */ - sock_prot_dec_use(sk->prot); } /* - * Move a socket to time-wait. + * Move a socket to time-wait or dead fin-wait-2 state. */ -void tcp_time_wait(struct sock *sk) +void tcp_time_wait(struct sock *sk, int state, int timeo) { - struct tcp_tw_bucket *tw; + struct tcp_tw_bucket *tw = NULL; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int recycle_ok = 0; + + if (sysctl_tcp_tw_recycle && tp->ts_recent_stamp) + recycle_ok = tp->af_specific->remember_stamp(sk); + + if (tcp_tw_count < sysctl_tcp_max_tw_buckets) + tw = kmem_cache_alloc(tcp_timewait_cachep, SLAB_ATOMIC); - tw = kmem_cache_alloc(tcp_timewait_cachep, SLAB_ATOMIC); if(tw != NULL) { + int rto = (tp->rto<<2) - (tp->rto>>1); + /* Give us an identity. */ tw->daddr = sk->daddr; tw->rcv_saddr = sk->rcv_saddr; tw->bound_dev_if= sk->bound_dev_if; tw->num = sk->num; tw->state = TCP_TIME_WAIT; + tw->substate = state; tw->sport = sk->sport; tw->dport = sk->dport; tw->family = sk->family; tw->reuse = sk->reuse; - tw->hashent = sk->hashent; - tw->rcv_nxt = sk->tp_pinfo.af_tcp.rcv_nxt; - tw->snd_nxt = sk->tp_pinfo.af_tcp.snd_nxt; - tw->ts_recent = sk->tp_pinfo.af_tcp.ts_recent; - tw->ts_recent_stamp= sk->tp_pinfo.af_tcp.ts_recent_stamp; -#ifdef CONFIG_TCP_TW_RECYCLE - tw->rto = sk->tp_pinfo.af_tcp.rto; - tw->ttd = jiffies + 2*tw->rto; -#endif + tw->rcv_wscale = tp->rcv_wscale; atomic_set(&tw->refcnt, 0); + tw->hashent = sk->hashent; + tw->rcv_nxt = tp->rcv_nxt; + tw->snd_nxt = tp->snd_nxt; + tw->rcv_wnd = tcp_receive_window(tp); + tw->syn_seq = tp->syn_seq; + tw->ts_recent = tp->ts_recent; + tw->ts_recent_stamp= tp->ts_recent_stamp; + tw->pprev_death = NULL; + #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) if(tw->family == PF_INET6) { memcpy(&tw->v6_daddr, @@ -1361,22 +1582,28 @@ __tcp_tw_hashdance(sk, tw); /* Get the TIME_WAIT timeout firing. */ - tcp_tw_schedule(tw); + if (timeo < rto) + timeo = rto; - /* CLOSE the SK. */ - if(sk->state == TCP_ESTABLISHED) - tcp_statistics[smp_processor_id()*2].TcpCurrEstab--; - sk->state = TCP_CLOSE; + if (recycle_ok) { + tw->timeout = rto; + } else { + tw->timeout = TCP_TIMEWAIT_LEN; + if (state == TCP_TIME_WAIT) + timeo = TCP_TIMEWAIT_LEN; + } + + tcp_tw_schedule(tw, timeo); } else { - /* Sorry, we're out of memory, just CLOSE this + /* Sorry, if we're out of memory, just CLOSE this * socket up. We've got bigger problems than * non-graceful socket closings. */ - tcp_set_state(sk, TCP_CLOSE); + if (net_ratelimit()) + printk(KERN_INFO "TCP: time wait bucket table overflow\n"); } tcp_update_metrics(sk); - tcp_clear_xmit_timers(sk); tcp_done(sk); } @@ -1397,10 +1624,13 @@ static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th) { - sk->tp_pinfo.af_tcp.fin_seq = TCP_SKB_CB(skb)->end_seq; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + tp->fin_seq = TCP_SKB_CB(skb)->end_seq; tcp_send_ack(sk); + sk->shutdown |= RCV_SHUTDOWN; + switch(sk->state) { case TCP_SYN_RECV: case TCP_ESTABLISHED: @@ -1427,7 +1657,7 @@ break; case TCP_FIN_WAIT2: /* Received a FIN -- send ACK and enter TIME_WAIT. */ - tcp_time_wait(sk); + tcp_time_wait(sk, TCP_TIME_WAIT, 0); break; default: /* Only TCP_LISTEN and TCP_CLOSE are left, in these @@ -1435,9 +1665,17 @@ */ printk("tcp_fin: Impossible, sk->state=%d\n", sk->state); break; - } + }; + + /* It _is_ possible, that we have something out-of-order _after_ FIN. + * Probably, we should reset in this case. For now drop them. + */ + __skb_queue_purge(&tp->out_of_order_queue); + if (tp->sack_ok) + tp->num_sacks = 0; + if (!sk->dead) { - wake_up_interruptible(sk->sleep); + sk->state_change(sk); sock_wake_async(sk->socket, 1, POLL_HUP); } } @@ -1622,6 +1860,7 @@ sp->end_seq = TCP_SKB_CB(new_skb)->end_seq; } + /* This one checks to see if we can put data from the * out_of_order queue into the receive_queue. */ @@ -1658,6 +1897,7 @@ { struct sk_buff *skb1; struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int eaten = 0; /* Queue data for delivery to the user. * Packets in sequence go to the receive queue. @@ -1665,33 +1905,68 @@ */ if (TCP_SKB_CB(skb)->seq == tp->rcv_nxt) { /* Ok. In sequence. */ - queue_and_out: + if (tp->ucopy.task == current && + tp->copied_seq == tp->rcv_nxt && + tp->ucopy.len && + sk->lock.users && + !tp->urg_data) { + int chunk = min(skb->len, tp->ucopy.len); + + local_bh_enable(); + if (memcpy_toiovec(tp->ucopy.iov, skb->data, chunk)) { + sk->err = EFAULT; + sk->error_report(sk); + } + local_bh_disable(); + tp->ucopy.len -= chunk; + tp->copied_seq += chunk; + eaten = (chunk == skb->len && !skb->h.th->fin); + } + + if (!eaten) { +queue_and_out: + skb_set_owner_r(skb, sk); + __skb_queue_tail(&sk->receive_queue, skb); + } dst_confirm(sk->dst_cache); - __skb_queue_tail(&sk->receive_queue, skb); tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; - if(skb->h.th->fin) { + if(skb->len) + tcp_event_data_recv(tp, skb); + if(skb->h.th->fin) tcp_fin(skb, sk, skb->h.th); - } else { - tcp_remember_ack(tp, skb->h.th, skb); - } + /* This may have eaten into a SACK block. */ if(tp->sack_ok && tp->num_sacks) tcp_sack_remove_skb(tp, skb); tcp_ofo_queue(sk); /* Turn on fast path. */ - if (skb_queue_len(&tp->out_of_order_queue) == 0) - tp->pred_flags = htonl(((tp->tcp_header_len >> 2) << 28) | - ntohl(TCP_FLAG_ACK) | - tp->snd_wnd); + if (skb_queue_len(&tp->out_of_order_queue) == 0 && +#ifdef TCP_FORMAL_WINDOW + tcp_receive_window(tp) && +#endif + !tp->urg_data) + tcp_fast_path_on(tp); + + if (eaten) + kfree_skb(skb); + + if (!sk->dead) { + wake_up_interruptible(sk->sleep); + sock_wake_async(sk->socket,1, POLL_IN); + } return; } - + /* An old packet, either a retransmit or some packet got lost. */ if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) { - /* A retransmit, 2nd most common case. Force an imediate ack. */ - SOCK_DEBUG(sk, "retransmit received: seq %X\n", TCP_SKB_CB(skb)->seq); + /* A retransmit, 2nd most common case. Force an imediate ack. + * + * It is impossible, seq is checked by top level. + */ + NETDEBUG(printk("retransmit in tcp_data_queue: seq %X\n", TCP_SKB_CB(skb)->seq)); tcp_enter_quickack_mode(tp); + tp->ack.pending = 1; kfree_skb(skb); return; } @@ -1706,15 +1981,17 @@ } /* Ok. This is an out_of_order segment, force an ack. */ - tp->delayed_acks++; - tcp_enter_quickack_mode(tp); + tp->ack.pending = 1; /* Disable header prediction. */ tp->pred_flags = 0; + SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n", tp->rcv_nxt, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq); + skb_set_owner_r(skb, sk); + if (skb_peek(&tp->out_of_order_queue) == NULL) { /* Initial out of order segment, build 1 SACK. */ if(tp->sack_ok) { @@ -1758,6 +2035,7 @@ } } } + return; } @@ -1767,7 +2045,7 @@ * room, then we will just have to discard the packet. */ -static int tcp_data(struct sk_buff *skb, struct sock *sk, unsigned int len) +static void tcp_data(struct sk_buff *skb, struct sock *sk, unsigned int len) { struct tcphdr *th; struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); @@ -1777,11 +2055,11 @@ skb_trim(skb, len - (th->doff*4)); if (skb->len == 0 && !th->fin) - return(0); + goto drop; /* * If our receive queue has grown past its limits shrink it. - * Make sure to do this before moving snd_nxt, otherwise + * Make sure to do this before moving rcv_nxt, otherwise * data might be acked for that we don't have enough room. */ if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf) { @@ -1789,7 +2067,7 @@ /* Still not enough room. That can happen when * skb->true_size differs significantly from skb->len. */ - return 0; + goto drop; } } @@ -1799,29 +2077,20 @@ printk(KERN_DEBUG "*** tcp.c:tcp_data bug acked < copied\n"); tp->rcv_nxt = tp->copied_seq; } + return; - /* Above, tcp_data_queue() increments delayed_acks appropriately. - * Now tell the user we may have some data. - */ - if (!sk->dead) { - wake_up_interruptible(sk->sleep); - sock_wake_async(sk->socket,1, POLL_IN); - } - return(1); +drop: + kfree_skb(skb); } static void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - if (!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) && - tcp_packets_in_flight(tp) < tp->snd_cwnd) { - /* Put more data onto the wire. */ - tcp_write_xmit(sk); - } else if (tp->packets_out == 0 && !tp->pending) { - /* Start probing the receivers window. */ - tcp_reset_xmit_timer(sk, TIME_PROBE0, tp->rto); - } + if (after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) || + tcp_packets_in_flight(tp) >= tp->snd_cwnd || + tcp_write_xmit(sk)) + tcp_check_probe_timer(sk, tp); } static __inline__ void tcp_data_snd_check(struct sock *sk) @@ -1832,57 +2101,6 @@ __tcp_data_snd_check(sk, skb); } -/* - * Adapt the MSS value used to make delayed ack decision to the - * real world. - * - * The constant 536 hasn't any good meaning. In IPv4 world - * MTU may be smaller, though it contradicts to RFC1122, which - * states that MSS must be at least 536. - * We use the constant to do not ACK each second - * packet in a stream of tiny size packets. - * It means that super-low mtu links will be aggressively delacked. - * Seems, it is even good. If they have so low mtu, they are weirdly - * slow. - * - * AK: BTW it may be useful to add an option to lock the rcv_mss. - * this way the beowulf people wouldn't need ugly patches to get the - * ack frequencies they want and it would be an elegant way to tune delack. - */ -static __inline__ void tcp_measure_rcv_mss(struct sock *sk, struct sk_buff *skb) -{ - struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - unsigned int len, lss; - - lss = tp->last_seg_size; - tp->last_seg_size = 0; - - /* skb->len may jitter because of SACKs, even if peer - * sends good full-sized frames. - */ - len = skb->len; - if (len >= tp->rcv_mss) { - tp->rcv_mss = len; - } else { - /* Otherwise, we make more careful check taking into account, - * that SACKs block is variable. - * - * "len" is invariant segment length, including TCP header. - */ - len = skb->tail - skb->h.raw; - if (len >= 536 + sizeof(struct tcphdr)) { - /* Subtract also invariant (if peer is RFC compliant), - * tcp header plus fixed timestamp option length. - * Resulting "len" is MSS free of SACK jitter. - */ - len -= tp->tcp_header_len; - if (len == lss) - tp->rcv_mss = len; - tp->last_seg_size = len; - } - } -} - /* * Check if sending an ack is needed. */ @@ -1904,26 +2122,25 @@ * start in an expediant manner. */ - /* Two full frames received or... */ - if (((tp->rcv_nxt - tp->rcv_wup) >= tp->rcv_mss * MAX_DELAY_ACK) || - /* We will update the window "significantly" or... */ - tcp_raise_window(sk) || - /* We entered "quick ACK" mode or... */ + /* More than one full frame received or... */ + if (((tp->rcv_nxt - tp->rcv_wup) > tp->ack.rcv_mss) || + /* We ACK each frame or... */ tcp_in_quickack_mode(tp) || - /* We have out of order data */ - (ofo_possible && (skb_peek(&tp->out_of_order_queue) != NULL))) { + /* We have out of order data or */ + (ofo_possible && + skb_peek(&tp->out_of_order_queue) != NULL)) { /* Then ack it now */ tcp_send_ack(sk); } else { /* Else, send delayed ack. */ - tcp_send_delayed_ack(sk, HZ/2); + tcp_send_delayed_ack(sk); } } static __inline__ void tcp_ack_snd_check(struct sock *sk) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - if (tp->delayed_acks == 0) { + if (tp->ack.pending == 0) { /* We sent a data segment already. */ return; } @@ -1975,7 +2192,7 @@ */ if (tp->urg_seq == tp->copied_seq) tp->copied_seq++; /* Move the copied sequence on correctly */ - tp->urg_data = URG_NOTYET; + tp->urg_data = TCP_URG_NOTYET; tp->urg_seq = ptr; /* Disable header prediction. */ @@ -1992,12 +2209,12 @@ tcp_check_urg(sk,th); /* Do we wait for any urgent data? - normally not... */ - if (tp->urg_data == URG_NOTYET) { + if (tp->urg_data == TCP_URG_NOTYET) { u32 ptr = tp->urg_seq - ntohl(th->seq) + (th->doff*4); /* Is the urgent pointer pointing into this packet? */ if (ptr < len) { - tp->urg_data = URG_VALID | *(ptr + (unsigned char *) th); + tp->urg_data = TCP_URG_VALID | *(ptr + (unsigned char *) th); if (!sk->dead) sk->data_ready(sk,0); } @@ -2014,7 +2231,8 @@ static int prune_queue(struct sock *sk) { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - struct sk_buff * skb; + struct sk_buff *skb; + int pruned = 0; SOCK_DEBUG(sk, "prune_queue: c=%x\n", tp->copied_seq); @@ -2024,7 +2242,9 @@ skb = __skb_dequeue_tail(&tp->out_of_order_queue); if(skb != NULL) { /* Free it all. */ - do { net_statistics[smp_processor_id()*2].OfoPruned += skb->len; + do { + pruned += skb->len; + net_statistics[smp_processor_id()*2].OfoPruned += skb->len; kfree_skb(skb); skb = __skb_dequeue_tail(&tp->out_of_order_queue); } while(skb != NULL); @@ -2059,13 +2279,47 @@ * if we are really having our buffer space abused we stop accepting * new receive data. * + * 8) The arguments are interesting, but I even cannot imagine + * what kind of arguments could force us to drop NICE, ALREADY + * RECEIVED DATA only to get one more packet? --ANK + * * FIXME: it should recompute SACK state and only remove enough * buffers to get into bounds again. The current scheme loses - * badly sometimes on links with large RTT, especially when - * the driver has high overhead per skb. - * (increasing the rcvbuf is not enough because it inflates the - * the window too, disabling flow control effectively) -AK + * badly sometimes on links with large RTT, especially when + * the driver has high overhead per skb. + * (increasing the rcvbuf is not enough because it inflates the + * the window too, disabling flow control effectively) -AK + * + * Mmm... Why not to scale it seprately then? Just replace + * / WINDOW_ADVERTISE_DIVISOR with >> sk->window_advertise_scale + * and adjust it dynamically, when TCP window flow control + * fails? -ANK */ + + /* F.e. one possible tactics is: */ + do { + u32 new_clamp = (tp->rcv_nxt-tp->copied_seq) + pruned; + + /* This guy is not a good guy. I bet, he martirized cats, + * when was child and grew up to finished sadist. Clamp him! + */ + if (new_clamp > 3*tp->ack.rcv_mss) + new_clamp -= tp->ack.rcv_mss; + else + new_clamp = 2*tp->ack.rcv_mss; + tp->window_clamp = min(tp->window_clamp, new_clamp); + } while (0); + /* Though it should be made earlier, when we are still not + * congested. This header prediction logic sucks + * without true implementation of VJ algorithm. + * I am really anxious. How was it possible to combine + * header prediction and sending ACKs outside of recvmsg() context? + * They _are_ incompatible. We should not advance window so + * brainlessly and we should not advertise so huge window from the very + * beginning. BTW window "prediction" does not speedup anything! + * SIlly, silly, silly. + */ + if(atomic_read(&sk->rmem_alloc) < (sk->rcvbuf << 1)) return 0; @@ -2073,6 +2327,57 @@ return -1; } +static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen) +{ + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int chunk = skb->len - hlen; + int err; + + local_bh_enable(); + if (skb->ip_summed==CHECKSUM_UNNECESSARY) + err = memcpy_toiovec(tp->ucopy.iov, skb->h.raw + hlen, chunk); + else + err = copy_and_csum_toiovec(tp->ucopy.iov, skb, hlen); + + if (!err) { +update: + tp->ucopy.len -= chunk; + tp->copied_seq += chunk; + local_bh_disable(); + return 0; + } + + if (err == -EFAULT) { + sk->err = EFAULT; + sk->error_report(sk); + goto update; + } + + local_bh_disable(); + return err; +} + +static int __tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb) +{ + int result; + + if (sk->lock.users) { + local_bh_enable(); + result = __tcp_checksum_complete(skb); + local_bh_disable(); + } else { + result = __tcp_checksum_complete(skb); + } + return result; +} + +static __inline__ int +tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb) +{ + return skb->ip_summed != CHECKSUM_UNNECESSARY && + __tcp_checksum_complete_user(sk, skb); +} + /* * TCP receive function for the ESTABLISHED state. * @@ -2080,7 +2385,33 @@ * disabled when: * - A zero window was announced from us - zero window probing * is only handled properly in the slow path. - * - Out of order segments arrived. + * [ NOTE: actually, it was made incorrectly and nobody ever noticed + * this! Reason is clear: 1. Correct senders do not send + * to zero window. 2. Even if a sender sends to zero window, + * nothing terrible occurs. + * + * For now I cleaned this and fast path is really always disabled, + * when window is zero, but I would be more happy to remove these + * checks. Code will be only cleaner and _faster_. --ANK + * + * Later note. I've just found that slow path also accepts + * out of window segments, look at tcp_sequence(). So... + * it is the last argument: I repair all and comment out + * repaired code by TCP_FORMAL_WINDOW. + * [ I remember one rhyme from a chidren's book. (I apologize, + * the trasnlation is not rhymed 8)): people in one (jewish) village + * decided to build sauna, but divided to two parties. + * The first one insisted that battens should not be dubbed, + * another objected that foots will suffer of splinters, + * the first fended that dubbed wet battens are too slippy + * and people will fall and it is much more serious! + * Certaiinly, all they went to rabbi. + * After some thinking, he judged: "Do not be lazy! + * Certainly, dub the battens! But put them by dubbed surface down." + * ] + * ] + * + * - Out of order segments arrived. * - Urgent data is expected. * - There is no buffer space left * - Unexpected TCP flags/window values/header lengths are received @@ -2088,7 +2419,7 @@ * - Data is sent in both directions. Fast path only supports pure senders * or pure receivers (this means either the sequence number or the ack * value must stay constant) - * - Unexpected TCP option. + * - Unexpected TCP option. * * When these conditions are not satisfied it drops into a standard * receive procedure patterned after RFC793 to handle all cases. @@ -2116,7 +2447,6 @@ * We do checksum and copy also but from device to kernel. */ - /* RED-PEN. Using static variables to pass function arguments * cannot be good idea... */ @@ -2133,13 +2463,12 @@ if ((tcp_flag_word(th) & ~(TCP_RESERVED_BITS|TCP_FLAG_PSH)) == tp->pred_flags && TCP_SKB_CB(skb)->seq == tp->rcv_nxt) { - int tcp_header_len = th->doff*4; + int tcp_header_len = tp->tcp_header_len; - /* Timestamp header prediction */ - - /* Non-standard header f.e. SACKs -> slow path */ - if (tcp_header_len != tp->tcp_header_len) - goto slow_path; + /* Timestamp header prediction: tcp_header_len + * is automatically equal to th->doff*4 due to pred_flags + * match. + */ /* Check timestamp */ if (tcp_header_len == sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) { @@ -2161,8 +2490,8 @@ goto slow_path; /* Predicted packet is in window by definition. - seq == rcv_nxt and last_ack_sent <= rcv_nxt. - Hence, check seq<=last_ack_sent reduces to: + * seq == rcv_nxt and last_ack_sent <= rcv_nxt. + * Hence, check seq<=last_ack_sent reduces to: */ if (tp->rcv_nxt == tp->last_ack_sent) { tp->ts_recent = tp->rcv_tsval; @@ -2173,6 +2502,9 @@ if (len <= tcp_header_len) { /* Bulk data transfer: sender */ if (len == tcp_header_len) { + /* We know that such packets are checksummed + * on entry. + */ tcp_ack(sk, th, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->ack_seq, len); kfree_skb(skb); @@ -2182,19 +2514,42 @@ TCP_INC_STATS_BH(TcpInErrs); goto discard; } - } else if (TCP_SKB_CB(skb)->ack_seq == tp->snd_una && - atomic_read(&sk->rmem_alloc) <= sk->rcvbuf) { - /* Bulk data transfer: receiver */ - __skb_pull(skb,tcp_header_len); - - /* Is it possible to simplify this? */ - tcp_measure_rcv_mss(sk, skb); - - /* DO NOT notify forward progress here. - * It saves dozen of CPU instructions in fast path. --ANK - * And where is it signaled then ? -AK - */ - __skb_queue_tail(&sk->receive_queue, skb); + } else if (TCP_SKB_CB(skb)->ack_seq == tp->snd_una) { + int eaten = 0; + + if (tp->ucopy.task == current && + tp->copied_seq == tp->rcv_nxt && + len - tcp_header_len <= tp->ucopy.len && + sk->lock.users) { + eaten = 1; + + NET_INC_STATS_BH(TCPHPHitsToUser); + + if (tcp_copy_to_iovec(sk, skb, tcp_header_len)) + goto csum_error; + + __skb_pull(skb,tcp_header_len); + } else { + if (tcp_checksum_complete_user(sk, skb)) + goto csum_error; + + if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf) + goto step5; + + NET_INC_STATS_BH(TCPHPHits); + + /* Bulk data transfer: receiver */ + __skb_pull(skb,tcp_header_len); + + /* DO NOT notify forward progress here. + * It saves dozen of CPU instructions in fast path. --ANK + * And where is it signaled then ? -AK + * Nowhere. 8) --ANK + */ + __skb_queue_tail(&sk->receive_queue, skb); + skb_set_owner_r(skb, sk); + } + tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; /* FIN bit check is not done since if FIN is set in @@ -2202,27 +2557,43 @@ */ wake_up_interruptible(sk->sleep); sock_wake_async(sk->socket,1, POLL_IN); - tcp_delack_estimator(tp); - tcp_remember_ack(tp, th, skb); + tcp_event_data_recv(tp, skb); +#if 1/*def CONFIG_TCP_MORE_COARSE_ACKS*/ + if (eaten) { + if (tcp_in_quickack_mode(tp)) { + tcp_send_ack(sk); + } else { + tcp_send_delayed_ack(sk); + } + } else +#endif __tcp_ack_snd_check(sk, 0); + + if (eaten) + kfree_skb(skb); return 0; } /* Packet is in sequence, flags are trivial; - * only ACK is strange or we are tough on memory. - * Jump to step 5. + * only ACK is strange. Jump to step 5. */ + if (tcp_checksum_complete_user(sk, skb)) + goto csum_error; goto step5; } slow_path: + if (tcp_checksum_complete_user(sk, skb)) + goto csum_error; + /* * RFC1323: H1. Apply PAWS check first. */ if (tcp_fast_parse_options(sk, th, tp) && tp->saw_tstamp && tcp_paws_discard(tp, skb)) { if (!th->rst) { + NET_INC_STATS_BH(PAWSEstabRejected); tcp_send_ack(sk); goto discard; } @@ -2251,7 +2622,9 @@ TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq, tp->rcv_wup, tp->rcv_wnd); } + tcp_enter_quickack_mode(tp); tcp_send_ack(sk); + NET_INC_STATS_BH(DelayedACKLost); goto discard; } @@ -2279,11 +2652,8 @@ /* Process urgent data. */ tcp_urg(sk, th, len); - { /* step 7: process the segment text */ - int queued = tcp_data(skb, sk, len); - - tcp_measure_rcv_mss(sk, skb); + tcp_data(skb, sk, len); /* Be careful, tcp_data() may have put this into TIME_WAIT. */ if(sk->state != TCP_CLOSE) { @@ -2291,12 +2661,13 @@ tcp_ack_snd_check(sk); } - if (!queued) { - discard: - kfree_skb(skb); - } - } + return 0; + +csum_error: + TCP_INC_STATS_BH(TcpInErrs); +discard: + kfree_skb(skb); return 0; } @@ -2328,6 +2699,7 @@ newsk->dport = req->rmt_port; sock_lock_init(newsk); + bh_lock_sock(newsk); atomic_set(&newsk->rmem_alloc, 0); skb_queue_head_init(&newsk->receive_queue); @@ -2351,22 +2723,27 @@ newtp->rcv_nxt = req->rcv_isn + 1; newtp->snd_nxt = req->snt_isn + 1; newtp->snd_una = req->snt_isn + 1; - newtp->srtt = 0; - newtp->ato = 0; + newtp->snd_sml = req->snt_isn + 1; + + tcp_delack_init(newtp); + if (skb->len >= 536) + newtp->ack.last_seg_size = skb->len; + + tcp_prequeue_init(newtp); + newtp->snd_wl1 = req->rcv_isn; newtp->snd_wl2 = req->snt_isn; - /* RFC1323: The window in SYN & SYN/ACK segments - * is never scaled. - */ - newtp->snd_wnd = ntohs(skb->h.th->window); - - newtp->max_window = newtp->snd_wnd; - newtp->pending = 0; newtp->retransmits = 0; - newtp->last_ack_sent = req->rcv_isn + 1; newtp->backoff = 0; + newtp->srtt = 0; newtp->mdev = TCP_TIMEOUT_INIT; + newtp->rto = TCP_TIMEOUT_INIT; + + newtp->packets_out = 0; + newtp->fackets_out = 0; + newtp->retrans_out = 0; + newtp->snd_ssthresh = 0x7fffffff; /* So many TCP implementations out there (incorrectly) count the * initial SYN frame in their delayed-ACK and congestion control @@ -2374,22 +2751,11 @@ * efficiently to them. -DaveM */ newtp->snd_cwnd = 2; - - newtp->rto = TCP_TIMEOUT_INIT; - newtp->packets_out = 0; - newtp->fackets_out = 0; - newtp->retrans_out = 0; - newtp->high_seq = 0; - newtp->snd_ssthresh = 0x7fffffff; newtp->snd_cwnd_cnt = 0; + newtp->high_seq = 0; + newtp->dup_acks = 0; - newtp->delayed_acks = 0; - init_timer(&newtp->retransmit_timer); - newtp->retransmit_timer.function = &tcp_retransmit_timer; - newtp->retransmit_timer.data = (unsigned long) newsk; - init_timer(&newtp->delack_timer); - newtp->delack_timer.function = &tcp_delack_timer; - newtp->delack_timer.data = (unsigned long) newsk; + tcp_init_xmit_timers(newsk); skb_queue_head_init(&newtp->out_of_order_queue); newtp->send_head = newtp->retrans_head = NULL; newtp->rcv_wup = req->rcv_isn + 1; @@ -2397,31 +2763,25 @@ newtp->copied_seq = req->rcv_isn + 1; newtp->saw_tstamp = 0; + newtp->last_ack_sent = req->rcv_isn + 1; - init_timer(&newtp->probe_timer); - newtp->probe_timer.function = &tcp_probe_timer; - newtp->probe_timer.data = (unsigned long) newsk; newtp->probes_out = 0; newtp->syn_seq = req->rcv_isn; newtp->fin_seq = req->rcv_isn; newtp->urg_data = 0; - tcp_synq_init(newtp); - newtp->syn_backlog = 0; - if (skb->len >= 536) - newtp->last_seg_size = skb->len; + newtp->listen_opt = NULL; + newtp->accept_queue = NULL; + /* Deinitialize syn_wait_lock to trap illegal accesses. */ + memset(&newtp->syn_wait_lock, 0, sizeof(newtp->syn_wait_lock)); /* Back to base struct sock members. */ newsk->err = 0; - newsk->ack_backlog = 0; - newsk->max_ack_backlog = SOMAXCONN; newsk->priority = 0; atomic_set(&newsk->refcnt, 1); +#ifdef INET_REFCNT_DEBUG atomic_inc(&inet_sock_nr); +#endif - spin_lock_init(&sk->timer_lock); - init_timer(&newsk->timer); - newsk->timer.function = &tcp_keepalive_timer; - newsk->timer.data = (unsigned long) newsk; if (newsk->keepopen) tcp_reset_keepalive_timer(newsk, keepalive_time_when(newtp)); newsk->socket = NULL; @@ -2440,6 +2800,9 @@ newtp->snd_wscale = newtp->rcv_wscale = 0; newtp->window_clamp = min(newtp->window_clamp,65535); } + newtp->snd_wnd = ntohs(skb->h.th->window) << newtp->snd_wscale; + newtp->max_window = newtp->snd_wnd; + if (newtp->tstamp_ok) { newtp->ts_recent = req->ts_recent; newtp->ts_recent_stamp = xtime.tv_sec; @@ -2453,16 +2816,6 @@ return newsk; } -static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win) -{ - if (seq == s_win) - return 1; - if (after(end_seq, s_win) && before(seq, e_win)) - return 1; - return (seq == e_win && seq == end_seq); -} - - /* * Process an incoming packet for SYN_RECV sockets represented * as an open_request. @@ -2470,30 +2823,28 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb, struct open_request *req, - struct open_request *prev) + struct open_request **prev) { struct tcphdr *th = skb->h.th; struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); u32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); int paws_reject = 0; struct tcp_opt ttp; - - /* If socket has already been created, process - packet in its context. - - We fall here only due to race, when packets were enqueued - to backlog of listening socket. - */ - if (req->sk) - return req->sk; + struct sock *child; ttp.saw_tstamp = 0; if (th->doff > (sizeof(struct tcphdr)>>2)) { - tcp_parse_options(NULL, th, &ttp, 0); - paws_reject = ttp.saw_tstamp && - (s32)(ttp.rcv_tsval - req->ts_recent) < 0; + if (ttp.saw_tstamp) { + ttp.ts_recent = req->ts_recent; + /* We do not store true stamp, but it is not required, + * it can be estimated (approximately) + * from another data. + */ + ttp.ts_recent_stamp = xtime.tv_sec - ((TCP_TIMEOUT_INIT/HZ)<retrans); + paws_reject = tcp_paws_check(&ttp, th->rst); + } } /* Check for pure retransmited SYN. */ @@ -2517,7 +2868,7 @@ * Enforce "SYN-ACK" according to figure 8, figure 6 * of RFC793, fixed by RFC1122. */ - req->class->rtx_syn_ack(sk, req); + req->class->rtx_syn_ack(sk, req, NULL); return NULL; } @@ -2544,6 +2895,8 @@ /* Out of window: send ACK and drop. */ if (!(flg & TCP_FLAG_RST)) req->class->send_ack(skb, req); + if (paws_reject) + NET_INC_STATS_BH(PAWSEstabRejected); return NULL; } @@ -2572,35 +2925,78 @@ /* Invalid ACK: reset will be sent by listening socket */ if (TCP_SKB_CB(skb)->ack_seq != req->snt_isn+1) return sk; - - /* OK, ACK is valid, create big socket and - feed this segment to it. It will repeat all - the tests. THIS SEGMENT MUST MOVE SOCKET TO - ESTABLISHED STATE. If it will be dropped after - socket is created, wait for troubles. + /* Also, it would be not so bad idea to check rcv_tsecr, which + * is essentially ACK extension and too early or too late values + * should cause reset in unsynchronized states. */ - sk = tp->af_specific->syn_recv_sock(sk, skb, req, NULL); - if (sk == NULL) + + /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */ + if (tp->defer_accept && TCP_SKB_CB(skb)->end_seq == req->rcv_isn+1) { + req->acked = 1; return NULL; + } - tcp_dec_slow_timer(TCP_SLT_SYNACK); - req->sk = sk; - return sk; + /* OK, ACK is valid, create big socket and + * feed this segment to it. It will repeat all + * the tests. THIS SEGMENT MUST MOVE SOCKET TO + * ESTABLISHED STATE. If it will be dropped after + * socket is created, wait for troubles. + */ + child = tp->af_specific->syn_recv_sock(sk, skb, req, NULL); + if (child == NULL) + goto listen_overflow; -embryonic_reset: tcp_synq_unlink(tp, req, prev); - tp->syn_backlog--; - tcp_dec_slow_timer(TCP_SLT_SYNACK); + tcp_synq_removed(sk, req); + tcp_acceptq_queue(sk, req, child); + return child; + +listen_overflow: + if (!sysctl_tcp_abort_on_overflow) { + req->acked = 1; + return NULL; + } + +embryonic_reset: NET_INC_STATS_BH(EmbryonicRsts); if (!(flg & TCP_FLAG_RST)) req->class->send_reset(skb); - req->class->destructor(req); - tcp_openreq_free(req); + tcp_synq_drop(sk, req, prev); return NULL; } +/* + * Queue segment on the new socket if the new socket is active, + * otherwise we just shortcircuit this and continue with + * the new socket. + */ + +int tcp_child_process(struct sock *parent, struct sock *child, + struct sk_buff *skb) +{ + int ret = 0; + int state = child->state; + + if (child->lock.users == 0) { + ret = tcp_rcv_state_process(child, skb, skb->h.th, skb->len); + + /* Wakeup parent, send SIGIO */ + if (state == TCP_SYN_RECV && child->state != state) + parent->data_ready(parent, 0); + } else { + /* Alas, it is possible again, because we do lookup + * in main socket hash table and lock on listening + * socket does not protect us more. + */ + sk_add_backlog(child, skb); + } + + bh_unlock_sock(child); + return ret; +} + static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, struct tcphdr *th, unsigned len) { @@ -2608,25 +3004,6 @@ tcp_parse_options(sk, th, tp, 0); -#ifdef CONFIG_TCP_TW_RECYCLE - if (tp->ts_recent_stamp && tp->saw_tstamp && !th->rst && - (s32)(tp->rcv_tsval - tp->ts_recent) < 0 && - xtime.tv_sec < tp->ts_recent_stamp + PAWS_24DAYS) { - /* Old duplicate segment. We remember last - ts_recent from this host in timewait bucket. - - Actually, we could implement per host cache - to truncate timewait state after RTO. Paranoidal arguments - of rfc1337 are not enough to close this nice possibility. - */ - if (net_ratelimit()) - printk(KERN_DEBUG "TCP: tw recycle, PAWS worked. Good.\n"); - if (th->ack) - return 1; - goto discard; - } -#endif - if (th->ack) { /* rfc793: * "If the state is SYN-SENT then @@ -2646,10 +3023,36 @@ * We do not send data with SYN, so that RFC-correct * test reduces to: */ - if (sk->zapped || - TCP_SKB_CB(skb)->ack_seq != tp->snd_nxt) + if (TCP_SKB_CB(skb)->ack_seq != tp->snd_nxt) return 1; + /* Check not from any RFC, but it is evident consequence + * of combining PAWS and usual SYN-SENT logic: ACK _is_ + * checked in SYN-SENT unlike another states, hence + * echoed tstamp must be checked too. + */ + if (tp->saw_tstamp) { + if (tp->rcv_tsecr == 0) { + /* Workaround for bug in linux-2.1 and early + * 2.2 kernels. Let's pretend that we did not + * see such timestamp to avoid bogus rtt value, + * calculated by tcp_ack(). + */ + tp->saw_tstamp = 0; + + /* But do not forget to store peer's timestamp! */ + if (th->syn) { + tp->ts_recent = tp->rcv_tsval; + tp->ts_recent_stamp = xtime.tv_sec; + } + } else if ((__s32)(tp->rcv_tsecr - tcp_time_stamp) > 0 || + (__s32)(tp->rcv_tsecr - tp->syn_stamp) < 0) { + NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "TCP: synsent reject.\n")); + NET_INC_STATS_BH(PAWSActiveRejected); + return 1; + } + } + /* Now ACK is acceptable. * * "If the RST bit is set @@ -2689,18 +3092,13 @@ * because tcp_ack check is too weak for SYN-SENT) * causes moving socket to invalid semi-SYN-SENT, * semi-ESTABLISHED state and connection hangs. - * - * There exist buggy stacks, which really send - * such ACKs: f.e. 202.226.91.94 (okigate.oki.co.jp) - * Actually, if this host did not try to get something - * from ftp.inr.ac.ru I'd never find this bug 8) - * * --ANK (990514) * - * I was wrong, I apologize. Bare ACK is valid. + * Bare ACK is valid, however. * Actually, RFC793 requires to send such ACK * in reply to any out of window packet. - * It is wrong, but Linux also does it sometimes. + * It is wrong, but Linux also send such + * useless ACKs sometimes. * --ANK (990724) */ @@ -2717,7 +3115,7 @@ /* RFC1323: The window in SYN & SYN/ACK segments is * never scaled. */ - tp->snd_wnd = htons(th->window); + tp->snd_wnd = ntohs(th->window); tp->snd_wl1 = TCP_SKB_CB(skb)->seq; tp->snd_wl2 = TCP_SKB_CB(skb)->ack_seq; tp->fin_seq = TCP_SKB_CB(skb)->seq; @@ -2742,26 +3140,35 @@ tcp_initialize_rcv_mss(sk); tcp_init_metrics(sk); + if (sk->keepopen) + tcp_reset_keepalive_timer(sk, keepalive_time_when(tp)); + + tp->copied_seq = tp->rcv_nxt; + __tcp_fast_path_on(tp, tp->snd_wnd); + + if(!sk->dead) { + sk->state_change(sk); + sock_wake_async(sk->socket, 0, POLL_OUT); + } + if (tp->write_pending) { /* Save one ACK. Data will be ready after * several ticks, if write_pending is set. * - * How to make this correctly? - */ - tp->delayed_acks++; - if (tp->ato == 0) - tp->ato = tp->rto; - tcp_send_delayed_ack(sk, tp->rto); + * It may be deleted, but with this feature tcpdumps + * look so _wonderfully_ clever, that I was not able + * to stand against the temptation 8) --ANK + */ + tp->ack.pending = 1; + tp->ack.lrcvtime = tcp_time_stamp; + tcp_enter_quickack_mode(tp); + tp->ack.pingpong = 1; + tp->ack.ato = TCP_ATO_MIN; + tcp_reset_xmit_timer(sk, TCP_TIME_DACK, TCP_DELACK_MIN); + goto discard; } else { tcp_send_ack(sk); } - - tp->copied_seq = tp->rcv_nxt; - - if(!sk->dead) { - wake_up_interruptible(sk->sleep); - sock_wake_async(sk->socket, 0, POLL_OUT); - } return -1; } @@ -2777,6 +3184,10 @@ goto discard; } + /* PAWS check. */ + if (tp->ts_recent_stamp && tp->saw_tstamp && tcp_paws_check(tp, 0)) + goto discard; + if (th->syn) { /* We see SYN without ACK. It is attempt of * simultaneous connect with crossed SYNs. @@ -2800,8 +3211,9 @@ /* RFC1323: The window in SYN & SYN/ACK segments is * never scaled. */ - tp->snd_wnd = htons(th->window); + tp->snd_wnd = ntohs(th->window); tp->snd_wl1 = TCP_SKB_CB(skb)->seq; + tp->max_window = tp->snd_wnd; tcp_sync_mss(sk, tp->pmtu_cookie); tcp_initialize_rcv_mss(sk); @@ -2960,6 +3372,8 @@ #endif ) { if (!th->rst) { + NET_INC_STATS_BH(DelayedACKLost); + tcp_enter_quickack_mode(tp); tcp_send_ack(sk); } goto discard; @@ -3011,28 +3425,29 @@ tp->copied_seq = tp->rcv_nxt; /* Note, that this wakeup is only for marginal - crossed SYN case. Passively open sockets - are not waked up, because sk->sleep == NULL - and sk->socket == NULL. + * crossed SYN case. Passively open sockets + * are not waked up, because sk->sleep == NULL + * and sk->socket == NULL. */ - if (!sk->dead && sk->sleep) { - wake_up_interruptible(sk->sleep); + if (!sk->dead) { + sk->state_change(sk); sock_wake_async(sk->socket,0,POLL_OUT); } tp->snd_una = TCP_SKB_CB(skb)->ack_seq; - tp->snd_wnd = htons(th->window) << tp->snd_wscale; + tp->snd_wnd = ntohs(th->window) << tp->snd_wscale; tp->snd_wl1 = TCP_SKB_CB(skb)->seq; tp->snd_wl2 = TCP_SKB_CB(skb)->ack_seq; /* tcp_ack considers this ACK as duplicate - * and does not calculate rtt. It is wrong. + * and does not calculate rtt. * Fix it at least with timestamps. */ if (tp->saw_tstamp && !tp->srtt) tcp_ack_saw_tstamp(sk, tp, 0, 0, FLAG_SYN_ACKED); tcp_init_metrics(sk); + tcp_fast_path_on(tp); } else { SOCK_DEBUG(sk, "bad ack\n"); return 1; @@ -3041,26 +3456,50 @@ case TCP_FIN_WAIT1: if (tp->snd_una == tp->write_seq) { - sk->shutdown |= SEND_SHUTDOWN; tcp_set_state(sk, TCP_FIN_WAIT2); - if (!sk->dead) - sk->state_change(sk); - else - tcp_reset_keepalive_timer(sk, sysctl_tcp_fin_timeout); + sk->shutdown |= SEND_SHUTDOWN; dst_confirm(sk->dst_cache); + + if (!sk->dead) { + /* Wake up lingering close() */ + sk->state_change(sk); + } else { + int tmo; + + if (tp->linger2 < 0 || + after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt)) { + tcp_done(sk); + return 1; + } + + tmo = tcp_fin_time(tp); + if (tmo > TCP_TIMEWAIT_LEN) { + tcp_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN); + } else if (th->fin || sk->lock.users) { + /* Bad case. We could lose such FIN otherwise. + * It is not a big problem, but it looks confusing + * and not so rare event. We still can lose it now, + * if it spins in bh_lock_sock(), but it is really + * marginal case. + */ + tcp_reset_keepalive_timer(sk, tmo); + } else { + tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); + goto discard; + } + } } break; - case TCP_CLOSING: + case TCP_CLOSING: if (tp->snd_una == tp->write_seq) { - tcp_time_wait(sk); + tcp_time_wait(sk, TCP_TIME_WAIT, 0); goto discard; } break; case TCP_LAST_ACK: if (tp->snd_una == tp->write_seq) { - tcp_set_state(sk,TCP_CLOSE); tcp_update_metrics(sk); tcp_done(sk); goto discard; @@ -3080,27 +3519,22 @@ case TCP_CLOSING: if (!before(TCP_SKB_CB(skb)->seq, tp->fin_seq)) break; - case TCP_FIN_WAIT1: case TCP_FIN_WAIT2: /* RFC 793 says to queue data in these states, * RFC 1122 says we MUST send a reset. * BSD 4.4 also does reset. */ - if ((sk->shutdown & RCV_SHUTDOWN) && sk->dead) { + if (sk->shutdown & RCV_SHUTDOWN) { if (after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt)) { tcp_reset(sk); return 1; } } - + /* Fall through */ case TCP_ESTABLISHED: - queued = tcp_data(skb, sk, len); - - /* This must be after tcp_data() does the skb_pull() to - * remove the header size from skb->len. - */ - tcp_measure_rcv_mss(sk, skb); + tcp_data(skb, sk, len); + queued = 1; break; } diff -ur --new-file old/linux/net/ipv4/tcp_ipv4.c new/linux/net/ipv4/tcp_ipv4.c --- old/linux/net/ipv4/tcp_ipv4.c Thu Jan 20 19:48:35 2000 +++ new/linux/net/ipv4/tcp_ipv4.c Sat Jan 22 20:54:57 2000 @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_ipv4.c,v 1.194 2000/01/09 02:19:41 davem Exp $ + * Version: $Id: tcp_ipv4.c,v 1.197 2000/01/21 06:37:28 davem Exp $ * * IPv4 specific functions * @@ -52,7 +52,6 @@ #include #include #include -#include #include #include @@ -61,15 +60,9 @@ #include #include +#include -extern int sysctl_tcp_timestamps; -extern int sysctl_tcp_window_scaling; -extern int sysctl_tcp_sack; -extern int sysctl_tcp_syncookies; -extern int sysctl_tcp_tw_recycle; extern int sysctl_ip_dynaddr; -extern __u32 sysctl_wmem_max; -extern __u32 sysctl_rmem_max; /* Check TCP sequence numbers in ICMP packets. */ #define ICMP_MIN_LENGTH 8 @@ -319,89 +312,13 @@ local_bh_enable(); } -#ifdef CONFIG_TCP_TW_RECYCLE -/* - Very stupid pseudo-"algoritm". If the approach will be successful - (and it will!), we have to make it more reasonable. - Now it eats lots of CPU, when we are tough on ports. - - Apparently, it should be hash table indexed by daddr/dport. - - How does it work? We allow to truncate time-wait state, if: - 1. PAWS works on it. - 2. timewait bucket did not receive data for timeout: - - initially timeout := 2*RTO, so that if our ACK to first - transmitted peer's FIN is lost, we will see first retransmit. - - if we receive anything, the timout is increased exponentially - to follow normal TCP backoff pattern. - It is important that minimal RTO (HZ/5) > minimal timestamp - step (1ms). - 3. When creating new socket, we inherit sequence number - and ts_recent of time-wait bucket, increasinf them a bit. - - These two conditions guarantee, that data will not be corrupted - both by retransmitted and by delayed segments. They do not guarantee - that peer will leave LAST-ACK/CLOSING state gracefully, it will be - reset sometimes, namely, when more than two our ACKs to its FINs are lost. - This reset is harmless and even good. +/* This lock without TASK_EXCLUSIVE is good on UP and it can be very bad on SMP. + * Look, when several writers sleep and reader wakes them up, all but one + * immediately hit write lock and grab all the cpus. Exclusive sleep solves + * this, _but_ remember, it adds useless work on UP machines (wake up each + * exclusive lock release). It should be ifdefed really. */ -int tcp_v4_tw_recycle(struct sock *sk, u32 daddr, u16 dport) -{ - static int tw_rover; - - struct tcp_tw_bucket *tw; - struct tcp_bind_hashbucket *head; - struct tcp_bind_bucket *tb; - - int low = sysctl_local_port_range[0]; - int high = sysctl_local_port_range[1]; - unsigned long now = jiffies; - int i, rover; - - rover = tw_rover; - - local_bh_disable(); - for (i=0; ilock); - for (tb = head->chain; tb; tb = tb->next) { - tw = (struct tcp_tw_bucket*)tb->owners; - - if (tw->state != TCP_TIME_WAIT || - tw->dport != dport || - tw->daddr != daddr || - tw->rcv_saddr != sk->rcv_saddr || - tb->port < low || - tb->port >= high || - !TCP_INET_FAMILY(tw->family) || - tw->ts_recent_stamp == 0 || - (long)(now - tw->ttd) <= 0) - continue; - tw_rover = rover; - goto hit; - } - spin_unlock(&head->lock); - } - local_bh_enable(); - tw_rover = rover; - return -EAGAIN; - -hit: - sk->num = tw->num; - if ((sk->bind_next = tb->owners) != NULL) - tb->owners->bind_pprev = &sk->bind_next; - tb->owners = sk; - sk->bind_pprev = &tb->owners; - sk->prev = (struct sock *) tb; - spin_unlock_bh(&head->lock); - return 0; -} -#endif - - void tcp_listen_wlock(void) { write_lock(&tcp_lhash_lock); @@ -409,9 +326,9 @@ if (atomic_read(&tcp_lhash_users)) { DECLARE_WAITQUEUE(wait, current); - add_wait_queue(&tcp_lhash_wait, &wait); + add_wait_queue_exclusive(&tcp_lhash_wait, &wait); for (;;) { - set_current_state(TASK_UNINTERRUPTIBLE); + set_current_state(TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE); if (atomic_read(&tcp_lhash_users) == 0) break; write_unlock_bh(&tcp_lhash_lock); @@ -445,6 +362,8 @@ sk->pprev = skp; sock_prot_inc_use(sk->prot); write_unlock(lock); + if (sk->state == TCP_LISTEN) + wake_up(&tcp_lhash_wait); } static void tcp_v4_hash(struct sock *sk) @@ -478,6 +397,8 @@ sock_prot_dec_use(sk->prot); } write_unlock_bh(lock); + if (sk->state == TCP_LISTEN) + wake_up(&tcp_lhash_wait); } /* Don't inline this cruft. Here are some nice properties to @@ -546,8 +467,9 @@ * * Local BH must be disabled here. */ -static inline struct sock *__tcp_v4_lookup(u32 saddr, u16 sport, - u32 daddr, u16 hnum, int dif) + +static inline struct sock *__tcp_v4_lookup_established(u32 saddr, u16 sport, + u32 daddr, u16 hnum, int dif) { struct tcp_ehash_bucket *head; TCP_V4_ADDR_COOKIE(acookie, saddr, daddr) @@ -572,7 +494,7 @@ goto hit; read_unlock(&head->lock); - return tcp_v4_lookup_listener(daddr, hnum, dif); + return NULL; hit: sock_hold(sk); @@ -580,6 +502,19 @@ return sk; } +static inline struct sock *__tcp_v4_lookup(u32 saddr, u16 sport, + u32 daddr, u16 hnum, int dif) +{ + struct sock *sk; + + sk = __tcp_v4_lookup_established(saddr, sport, daddr, hnum, dif); + + if (sk) + return sk; + + return tcp_v4_lookup_listener(daddr, hnum, dif); +} + __inline__ struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif) { struct sock *sk; @@ -609,21 +544,16 @@ int hash = tcp_hashfn(daddr, sk->num, saddr, sk->dport); struct tcp_ehash_bucket *head = &tcp_ehash[hash]; struct sock *sk2, **skp; -#ifdef CONFIG_TCP_TW_RECYCLE struct tcp_tw_bucket *tw; -#endif write_lock_bh(&head->lock); /* Check TIME-WAIT sockets first. */ for(skp = &(head + tcp_ehash_size)->chain; (sk2=*skp) != NULL; skp = &sk2->next) { -#ifdef CONFIG_TCP_TW_RECYCLE tw = (struct tcp_tw_bucket*)sk2; -#endif if(TCP_IPV4_MATCH(sk2, acookie, saddr, daddr, ports, dif)) { -#ifdef CONFIG_TCP_TW_RECYCLE struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); /* With PAWS, it is safe from the viewpoint @@ -631,12 +561,17 @@ is safe provided sequence spaces do not overlap i.e. at data rates <= 80Mbit/sec. - Actually, the idea is close to VJ's (rfc1332) - one, only timestamp cache is held not per host, + Actually, the idea is close to VJ's one, + only timestamp cache is held not per host, but per port pair and TW bucket is used as state holder. + + If TW bucket has been already destroyed we + fall back to VJ's scheme and use initial + timestamp retrieved from peer table. */ - if (sysctl_tcp_tw_recycle && tw->ts_recent_stamp) { + if (tw->substate == TCP_TIME_WAIT && + sysctl_tcp_tw_recycle && tw->ts_recent_stamp) { if ((tp->write_seq = tw->snd_nxt + 2) == 0) tp->write_seq = 1; tp->ts_recent = tw->ts_recent; @@ -645,13 +580,10 @@ skp = &head->chain; goto unique; } else -#endif - goto not_unique; + goto not_unique; } } -#ifdef CONFIG_TCP_TW_RECYCLE tw = NULL; -#endif /* And established part... */ for(skp = &head->chain; (sk2=*skp)!=NULL; skp = &sk2->next) { @@ -659,9 +591,7 @@ goto not_unique; } -#ifdef CONFIG_TCP_TW_RECYCLE unique: -#endif BUG_TRAP(sk->pprev==NULL); if ((sk->next = *skp) != NULL) (*skp)->pprev = &sk->next; @@ -671,17 +601,17 @@ sock_prot_inc_use(sk->prot); write_unlock_bh(&head->lock); -#ifdef CONFIG_TCP_TW_RECYCLE if (tw) { /* Silly. Should hash-dance instead... */ local_bh_disable(); tcp_tw_deschedule(tw); tcp_timewait_kill(tw); + NET_INC_STATS_BH(TimeWaitRecycled); local_bh_enable(); tcp_tw_put(tw); } -#endif + return 0; not_unique: @@ -727,9 +657,6 @@ int tmp; int err; - if (sk->state != TCP_CLOSE) - return(-EISCONN); - if (addr_len < sizeof(struct sockaddr_in)) return(-EINVAL); @@ -759,8 +686,7 @@ daddr = rt->rt_dst; err = -ENOBUFS; - buff = sock_wmalloc(sk, (MAX_HEADER + sk->prot->max_header), - 0, GFP_KERNEL); + buff = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 0, GFP_KERNEL); if (buff == NULL) goto failure; @@ -769,27 +695,28 @@ sk->saddr = rt->rt_src; sk->rcv_saddr = sk->saddr; - if (!sk->num) { - if (sk->prot->get_port(sk, 0) -#ifdef CONFIG_TCP_TW_RECYCLE - && (!sysctl_tcp_tw_recycle || - tcp_v4_tw_recycle(sk, daddr, usin->sin_port)) -#endif - ) { - kfree_skb(buff); - err = -EAGAIN; - goto failure; - } - sk->sport = htons(sk->num); - } -#ifdef CONFIG_TCP_TW_RECYCLE - else if (tp->ts_recent_stamp && sk->daddr != daddr) { + if (tp->ts_recent_stamp && sk->daddr != daddr) { /* Reset inherited state */ tp->ts_recent = 0; tp->ts_recent_stamp = 0; tp->write_seq = 0; } -#endif + + if (sysctl_tcp_tw_recycle && + !tp->ts_recent_stamp && + rt->rt_dst == daddr) { + struct inet_peer *peer = rt_get_peer(rt); + + /* VJ's idea. We save last timestamp seen from + * the destination in peer table, when entering state TIME-WAIT + * and initialize ts_recent from it, when trying new connection. + */ + + if (peer && peer->tcp_ts_stamp + TCP_PAWS_MSL >= xtime.tv_sec) { + tp->ts_recent_stamp = peer->tcp_ts_stamp; + tp->ts_recent = peer->tcp_ts; + } + } sk->dport = usin->sin_port; sk->daddr = daddr; @@ -814,85 +741,62 @@ return err; } -static int tcp_v4_sendmsg(struct sock *sk, struct msghdr *msg, int len) +static __inline__ int tcp_v4_iif(struct sk_buff *skb) { - int retval = -EINVAL; - - lock_sock(sk); - - /* Do sanity checking for sendmsg/sendto/send. */ - if (msg->msg_flags & ~(MSG_OOB|MSG_DONTROUTE|MSG_DONTWAIT|MSG_NOSIGNAL)) - goto out; - if (msg->msg_name) { - struct sockaddr_in *addr=(struct sockaddr_in *)msg->msg_name; - - if (msg->msg_namelen < sizeof(*addr)) - goto out; - if (addr->sin_family && addr->sin_family != AF_INET) - goto out; - retval = -ENOTCONN; - if(sk->state == TCP_CLOSE) - goto out; - retval = -EISCONN; - if (addr->sin_port != sk->dport) - goto out; - if (addr->sin_addr.s_addr != sk->daddr) - goto out; - } - retval = tcp_do_sendmsg(sk, msg); - -out: - release_sock(sk); - return retval; + return ((struct rtable*)skb->dst)->rt_iif; } +static __inline__ unsigned tcp_v4_synq_hash(u32 raddr, u16 rport) +{ + unsigned h = raddr ^ rport; + h ^= h>>16; + h ^= h>>8; + return h&(TCP_SYNQ_HSIZE-1); +} -/* - * Do a linear search in the socket open_request list. - * This should be replaced with a global hash table. - */ static struct open_request *tcp_v4_search_req(struct tcp_opt *tp, struct iphdr *iph, struct tcphdr *th, - struct open_request **prevp) + struct open_request ***prevp) { - struct open_request *req, *prev; - __u16 rport = th->source; - - /* assumption: the socket is not in use. - * as we checked the user count on tcp_rcv and we're - * running from a soft interrupt. - */ - prev = (struct open_request *) (&tp->syn_wait_queue); - for (req = prev->dl_next; req; req = req->dl_next) { - if (req->af.v4_req.rmt_addr == iph->saddr && + struct tcp_listen_opt *lopt = tp->listen_opt; + struct open_request *req, **prev; + __u16 rport = th->source; + __u32 raddr = iph->saddr; + + for (prev = &lopt->syn_table[tcp_v4_synq_hash(raddr, rport)]; + (req = *prev) != NULL; + prev = &req->dl_next) { + if (req->rmt_port == rport && + req->af.v4_req.rmt_addr == raddr && req->af.v4_req.loc_addr == iph->daddr && - req->rmt_port == rport && TCP_INET_FAMILY(req->class->family)) { - if (req->sk) { - /* Weird case: connection was established - and then killed by RST before user accepted - it. This connection is dead, but we cannot - kill openreq to avoid blocking in accept(). - - accept() will collect this garbage, - but such reqs must be ignored, when talking - to network. - */ - bh_lock_sock(req->sk); - BUG_TRAP(req->sk->lock.users==0); - if (req->sk->state == TCP_CLOSE) { - bh_unlock_sock(req->sk); - prev = req; - continue; - } - } + BUG_TRAP(req->sk == NULL); *prevp = prev; return req; } - prev = req; } - return NULL; + + return NULL; +} + +static void tcp_v4_synq_add(struct sock *sk, struct open_request *req) +{ + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + struct tcp_listen_opt *lopt = tp->listen_opt; + unsigned h = tcp_v4_synq_hash(req->af.v4_req.rmt_addr, req->rmt_port); + + req->expires = jiffies + TCP_TIMEOUT_INIT; + req->retrans = 0; + req->sk = NULL; + req->index = h; + req->dl_next = lopt->syn_table[h]; + + write_lock(&tp->syn_wait_lock); + lopt->syn_table[h] = req; + write_unlock(&tp->syn_wait_lock); + + tcp_synq_added(sk); } @@ -984,7 +888,7 @@ th = (struct tcphdr*)(dp+(iph->ihl<<2)); - sk = tcp_v4_lookup(iph->daddr, th->dest, iph->saddr, th->source, skb->dev->ifindex); + sk = tcp_v4_lookup(iph->daddr, th->dest, iph->saddr, th->source, tcp_v4_iif(skb)); if (sk == NULL) { ICMP_INC_STATS_BH(IcmpInErrors); return; @@ -1001,6 +905,9 @@ if (sk->lock.users != 0) NET_INC_STATS_BH(LockDroppedIcmps); + if (sk->state == TCP_CLOSE) + goto out; + tp = &sk->tp_pinfo.af_tcp; seq = ntohl(th->seq); if (sk->state != TCP_LISTEN && !between(seq, tp->snd_una, tp->snd_nxt)) { @@ -1010,14 +917,11 @@ switch (type) { case ICMP_SOURCE_QUENCH: -#ifndef OLD_SOURCE_QUENCH /* This is deprecated */ - if (sk->lock.users == 0) { - tp->snd_ssthresh = tcp_recalc_ssthresh(tp); - tp->snd_cwnd = tp->snd_ssthresh; - tp->snd_cwnd_cnt = 0; - tp->high_seq = tp->snd_nxt; - } -#endif + /* This is deprecated, but if someone generated it, + * we have no reasons to ignore it. + */ + if (sk->lock.users == 0) + tcp_enter_cong_avoid(tp); goto out; case ICMP_PARAMETERPROB: err = EPROTO; @@ -1042,7 +946,7 @@ } switch (sk->state) { - struct open_request *req, *prev; + struct open_request *req, **prev; case TCP_LISTEN: if (sk->lock.users != 0) goto out; @@ -1060,47 +964,25 @@ if (!req) goto out; - if (req->sk) { - struct sock *nsk = req->sk; - - /* - * Already in ESTABLISHED and a big socket is created, - * set error code there. - * The error will _not_ be reported in the accept(), - * but only with the next operation on the socket after - * accept. - */ - sock_hold(nsk); - bh_unlock_sock(sk); - sock_put(sk); - sk = nsk; - - BUG_TRAP(sk->lock.users == 0); - tp = &sk->tp_pinfo.af_tcp; - if (!between(seq, tp->snd_una, tp->snd_nxt)) { - NET_INC_STATS(OutOfWindowIcmps); - goto out; - } - } else { - if (seq != req->snt_isn) { - NET_INC_STATS(OutOfWindowIcmps); - goto out; - } + /* ICMPs are not backlogged, hence we cannot get + an established socket here. + */ + BUG_TRAP(req->sk == NULL); - /* - * Still in SYN_RECV, just remove it silently. - * There is no good way to pass the error to the newly - * created socket, and POSIX does not want network - * errors returned from accept(). - */ - tp->syn_backlog--; - tcp_synq_unlink(tp, req, prev); - tcp_dec_slow_timer(TCP_SLT_SYNACK); - req->class->destructor(req); - tcp_openreq_free(req); + if (seq != req->snt_isn) { + NET_INC_STATS_BH(OutOfWindowIcmps); goto out; } - break; + + /* + * Still in SYN_RECV, just remove it silently. + * There is no good way to pass the error to the newly + * created socket, and POSIX does not want network + * errors returned from accept(). + */ + tcp_synq_drop(sk, req, prev); + goto out; + case TCP_SYN_SENT: case TCP_SYN_RECV: /* Cannot happen. It can f.e. if SYNs crossed. @@ -1110,10 +992,9 @@ if (sk->lock.users == 0) { TCP_INC_STATS_BH(TcpAttemptFails); sk->err = err; - /* Wake people up to see the error (see connect in sock.c) */ + sk->error_report(sk); - tcp_set_state(sk, TCP_CLOSE); tcp_done(sk); } else { sk->err_soft = err; @@ -1270,28 +1151,23 @@ { struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sk; - tcp_v4_send_ack(skb, tw->snd_nxt, tw->rcv_nxt, 0, tw->ts_recent); + tcp_v4_send_ack(skb, tw->snd_nxt, tw->rcv_nxt, + tw->rcv_wnd>>tw->rcv_wscale, tw->ts_recent); tcp_tw_put(tw); } static void tcp_v4_or_send_ack(struct sk_buff *skb, struct open_request *req) { - tcp_v4_send_ack(skb, req->snt_isn+1, req->rcv_isn+1, req->rcv_wnd, req->ts_recent); + tcp_v4_send_ack(skb, req->snt_isn+1, req->rcv_isn+1, req->rcv_wnd, + req->ts_recent); } -/* - * Send a SYN-ACK after having received an ACK. - * This still operates on a open_request only, not on a big - * socket. - */ -static void tcp_v4_send_synack(struct sock *sk, struct open_request *req) +static struct dst_entry* tcp_v4_route_req(struct sock *sk, struct open_request *req) { struct rtable *rt; struct ip_options *opt; - struct sk_buff * skb; - /* First, grab a route. */ opt = req->af.v4_req.opt; if(ip_route_output(&rt, ((opt && opt->srr) ? opt->faddr : @@ -1300,15 +1176,33 @@ RT_TOS(sk->protinfo.af_inet.tos) | RTO_CONN | sk->localroute, sk->bound_dev_if)) { IP_INC_STATS_BH(IpOutNoRoutes); - return; + return NULL; } - if(opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) { + if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) { ip_rt_put(rt); IP_INC_STATS_BH(IpOutNoRoutes); - return; + return NULL; } + return &rt->u.dst; +} + +/* + * Send a SYN-ACK after having received an ACK. + * This still operates on a open_request only, not on a big + * socket. + */ +static int tcp_v4_send_synack(struct sock *sk, struct open_request *req, + struct dst_entry *dst) +{ + int err = -1; + struct sk_buff * skb; - skb = tcp_make_synack(sk, &rt->u.dst, req); + /* First, grab a route. */ + if (dst == NULL && + (dst = tcp_v4_route_req(sk, req)) == NULL) + goto out; + + skb = tcp_make_synack(sk, dst, req); if (skb) { struct tcphdr *th = skb->h.th; @@ -1317,10 +1211,15 @@ req->af.v4_req.loc_addr, req->af.v4_req.rmt_addr, csum_partial((char *)th, skb->len, skb->csum)); - ip_build_and_send_pkt(skb, sk, req->af.v4_req.loc_addr, - req->af.v4_req.rmt_addr, req->af.v4_req.opt); + err = ip_build_and_send_pkt(skb, sk, req->af.v4_req.loc_addr, + req->af.v4_req.rmt_addr, req->af.v4_req.opt); + if (err == NET_XMIT_CN) + err = 0; } - ip_rt_put(rt); + +out: + dst_release(dst); + return err; } /* @@ -1328,7 +1227,7 @@ */ static void tcp_v4_or_free(struct open_request *req) { - if(!req->sk && req->af.v4_req.opt) + if (req->af.v4_req.opt) kfree_s(req->af.v4_req.opt, optlength(req->af.v4_req.opt)); } @@ -1372,8 +1271,14 @@ * It would be better to replace it with a global counter for all sockets * but then some measure against one socket starving all other sockets * would be needed. + * + * It was 128 by default. Experiments with real servers show, that + * it is absolutely not enough even at 100conn/sec. 256 cures most + * of problems. This value is adjusted to 128 for very small machines + * (<=32Mb of memory) and to 1024 on normal or better ones (>=256Mb). + * Further increasing requires to change hash table size. */ -int sysctl_max_syn_backlog = 128; +int sysctl_max_syn_backlog = 256; struct or_calltable or_ipv4 = { PF_INET, @@ -1383,9 +1288,6 @@ tcp_v4_send_reset }; -#define BACKLOG(sk) ((sk)->tp_pinfo.af_tcp.syn_backlog) /* lvalue! */ -#define BACKLOGMAX(sk) sysctl_max_syn_backlog - int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) { struct tcp_opt tp; @@ -1394,6 +1296,7 @@ __u32 saddr = skb->nh.iph->saddr; __u32 daddr = skb->nh.iph->daddr; __u32 isn = TCP_SKB_CB(skb)->when; + struct dst_entry *dst = NULL; #ifdef CONFIG_SYN_COOKIES int want_cookie = 0; #else @@ -1405,84 +1308,108 @@ (RTCF_BROADCAST|RTCF_MULTICAST)) goto drop; - /* XXX: Check against a global syn pool counter. */ - if (BACKLOG(sk) > BACKLOGMAX(sk)) { + /* TW buckets are converted to open requests without + * limitations, they conserve resources and peer is + * evidently real one. + */ + if (tcp_synq_is_full(sk) && !isn) { #ifdef CONFIG_SYN_COOKIES - if (sysctl_tcp_syncookies && !isn) { - syn_flood_warning(skb); + if (sysctl_tcp_syncookies) { want_cookie = 1; } else #endif goto drop; - } else { - if (isn == 0) - isn = tcp_v4_init_sequence(sk, skb); - BACKLOG(sk)++; } - req = tcp_openreq_alloc(); - if (req == NULL) { - goto dropbacklog; - } + /* Accept backlog is full. If we have already queued enough + * of warm entries in syn queue, drop request. It is better than + * clogging syn queue with openreqs with exponentially increasing + * timeout. + */ + if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1) + goto drop; - req->rcv_wnd = 0; /* So that tcp_send_synack() knows! */ + req = tcp_openreq_alloc(); + if (req == NULL) + goto drop; - req->rcv_isn = TCP_SKB_CB(skb)->seq; tp.tstamp_ok = tp.sack_ok = tp.wscale_ok = tp.snd_wscale = 0; - tp.mss_clamp = 536; tp.user_mss = sk->tp_pinfo.af_tcp.user_mss; tcp_parse_options(NULL, th, &tp, want_cookie); - req->mss = tp.mss_clamp; - req->ts_recent = tp.saw_tstamp ? tp.rcv_tsval : 0; - req->tstamp_ok = tp.tstamp_ok; - req->sack_ok = tp.sack_ok; - req->snd_wscale = tp.snd_wscale; - req->wscale_ok = tp.wscale_ok; - req->rmt_port = th->source; + tcp_openreq_init(req, &tp, skb); + req->af.v4_req.loc_addr = daddr; req->af.v4_req.rmt_addr = saddr; + req->af.v4_req.opt = tcp_v4_save_options(sk, skb); + req->class = &or_ipv4; - /* Note that we ignore the isn passed from the TIME_WAIT - * state here. That's the price we pay for cookies. - * - * RED-PEN. The price is high... Then we cannot kill TIME-WAIT - * and should reject connection attempt, duplicates with random - * sequence number can corrupt data. Right? - * I disabled sending cookie to request matching to a timewait - * bucket. - */ - if (want_cookie) + if (want_cookie) { +#ifdef CONFIG_SYN_COOKIES + syn_flood_warning(skb); +#endif isn = cookie_v4_init_sequence(sk, skb, &req->mss); + } else if (isn == 0) { + struct inet_peer *peer = NULL; - req->snt_isn = isn; - - req->af.v4_req.opt = tcp_v4_save_options(sk, skb); + /* VJ's idea. We save last timestamp seen + * from the destination in peer table, when entering + * state TIME-WAIT, and check against it before + * accepting new connection request. + * + * If "isn" is not zero, this request hit alive + * timewait bucket, so that all the necessary checks + * are made in the function processing timewait state. + */ + if (tp.saw_tstamp && + sysctl_tcp_tw_recycle && + (dst = tcp_v4_route_req(sk, req)) != NULL && + (peer = rt_get_peer((struct rtable*)dst)) != NULL && + peer->v4daddr == saddr) { + if (xtime.tv_sec < peer->tcp_ts_stamp + TCP_PAWS_MSL && + (s32)(peer->tcp_ts - req->ts_recent) > TCP_PAWS_WINDOW) { + NETDEBUG(printk(KERN_DEBUG "TW_REC: reject openreq %u/%u %08x/%u\n", peer->tcp_ts, req->ts_recent, saddr, ntohs(skb->h.th->source))); + NET_INC_STATS_BH(PAWSPassiveRejected); + dst_release(dst); + goto drop_and_free; + } + } + /* Kill the following clause, if you dislike this way. */ + else if (!sysctl_tcp_syncookies && + (sysctl_max_syn_backlog - tcp_synq_len(sk) + < (sysctl_max_syn_backlog>>2)) && + (!peer || !peer->tcp_ts_stamp) && + (!dst || !dst->rtt)) { + /* Without syncookies last quarter of + * backlog is filled with destinations, proven to be alive. + * It means that we continue to communicate + * to destinations, already remembered + * to the moment of synflood. + */ + NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "TCP: drop open request from %08x/%u\n", saddr, ntohs(skb->h.th->source))); + TCP_INC_STATS_BH(TcpAttemptFails); + dst_release(dst); + goto drop_and_free; + } - req->class = &or_ipv4; - req->retrans = 0; - req->sk = NULL; + isn = tcp_v4_init_sequence(sk, skb); + } + req->snt_isn = isn; - tcp_v4_send_synack(sk, req); + if (tcp_v4_send_synack(sk, req, dst)) + goto drop_and_free; if (want_cookie) { - if (req->af.v4_req.opt) - kfree(req->af.v4_req.opt); - tcp_v4_or_free(req); tcp_openreq_free(req); } else { - req->expires = jiffies + TCP_TIMEOUT_INIT; - tcp_inc_slow_timer(TCP_SLT_SYNACK); - tcp_synq_queue(&sk->tp_pinfo.af_tcp, req); + tcp_v4_synq_add(sk, req); } - return 0; -dropbacklog: - if (!want_cookie) - BACKLOG(sk)--; +drop_and_free: + tcp_openreq_free(req); drop: TCP_INC_STATS_BH(TcpAttemptFails); return 0; @@ -1497,29 +1424,20 @@ struct open_request *req, struct dst_entry *dst) { - struct ip_options *opt = req->af.v4_req.opt; struct tcp_opt *newtp; struct sock *newsk; - if (sk->ack_backlog > sk->max_ack_backlog) - goto exit; /* head drop */ - if (dst == NULL) { - struct rtable *rt; - - if (ip_route_output(&rt, - opt && opt->srr ? opt->faddr : req->af.v4_req.rmt_addr, - req->af.v4_req.loc_addr, sk->protinfo.af_inet.tos|RTO_CONN, 0)) - return NULL; - dst = &rt->u.dst; - } + if (tcp_acceptq_is_full(sk)) + goto exit_overflow; + + if (dst == NULL && + (dst = tcp_v4_route_req(sk, req)) == NULL) + goto exit; newsk = tcp_create_openreq_child(sk, req, skb); if (!newsk) goto exit; - sk->tp_pinfo.af_tcp.syn_backlog--; - sk->ack_backlog++; - newsk->dst_cache = dst; newtp = &(newsk->tp_pinfo.af_tcp); @@ -1527,7 +1445,8 @@ newsk->saddr = req->af.v4_req.loc_addr; newsk->rcv_saddr = req->af.v4_req.loc_addr; newsk->protinfo.af_inet.opt = req->af.v4_req.opt; - newsk->protinfo.af_inet.mc_index = ((struct rtable*)skb->dst)->rt_iif; + req->af.v4_req.opt = NULL; + newsk->protinfo.af_inet.mc_index = tcp_v4_iif(skb); newsk->protinfo.af_inet.mc_ttl = skb->nh.iph->ttl; newtp->ext_header_len = 0; if (newsk->protinfo.af_inet.opt) @@ -1535,28 +1454,26 @@ tcp_sync_mss(newsk, dst->pmtu); tcp_initialize_rcv_mss(newsk); + newtp->advmss = dst->advmss; - if (newsk->rcvbuf < (3 * (dst->advmss+40+MAX_HEADER+15))) - newsk->rcvbuf = min ((3 * (dst->advmss+40+MAX_HEADER+15)), sysctl_rmem_max); - if (newsk->sndbuf < (3 * (newtp->mss_clamp+40+MAX_HEADER+15))) - newsk->sndbuf = min ((3 * (newtp->mss_clamp+40+MAX_HEADER+15)), sysctl_wmem_max); + tcp_init_buffer_space(newsk); - bh_lock_sock(newsk); - __tcp_v4_hash(newsk); __tcp_inherit_port(sk, newsk); return newsk; +exit_overflow: + NET_INC_STATS_BH(ListenOverflows); exit: + NET_INC_STATS_BH(ListenDrops); dst_release(dst); return NULL; } - static struct sock *tcp_v4_hnd_req(struct sock *sk,struct sk_buff *skb) { - struct open_request *req, *prev; + struct open_request *req, **prev; struct tcphdr *th = skb->h.th; struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); @@ -1565,6 +1482,25 @@ if (req) return tcp_check_req(sk, skb, req, prev); + if (tp->accept_queue) { + struct sock *nsk; + + nsk = __tcp_v4_lookup_established(skb->nh.iph->saddr, + th->source, + skb->nh.iph->daddr, + ntohs(th->dest), + tcp_v4_iif(skb)); + + if (nsk) { + if (nsk->state != TCP_TIME_WAIT) { + bh_lock_sock(nsk); + return nsk; + } + tcp_tw_put((struct tcp_tw_bucket*)sk); + return NULL; + } + } + #ifdef CONFIG_SYN_COOKIES if (!th->rst && (th->syn || th->ack)) sk = cookie_v4_check(sk, skb, &(IPCB(skb)->opt)); @@ -1572,27 +1508,26 @@ return sk; } -static int tcp_csum_verify(struct sk_buff *skb) +static int tcp_v4_checksum_init(struct sk_buff *skb) { - switch (skb->ip_summed) { - case CHECKSUM_NONE: - skb->csum = csum_partial((char *)skb->h.th, skb->len, 0); - case CHECKSUM_HW: - if (tcp_v4_check(skb->h.th,skb->len,skb->nh.iph->saddr,skb->nh.iph->daddr,skb->csum)) { - NETDEBUG(printk(KERN_DEBUG "TCPv4 bad checksum " - "from %d.%d.%d.%d:%04x to %d.%d.%d.%d:%04x, " - "len=%d/%d\n", - NIPQUAD(skb->nh.iph->saddr), - ntohs(skb->h.th->source), - NIPQUAD(skb->nh.iph->daddr), - ntohs(skb->h.th->dest), - skb->len, - ntohs(skb->nh.iph->tot_len))); - return 1; + if (skb->ip_summed == CHECKSUM_HW) { + if (tcp_v4_check(skb->h.th,skb->len,skb->nh.iph->saddr, + skb->nh.iph->daddr,skb->csum)) { + NETDEBUG(printk(KERN_DEBUG "hw tcp v4 csum failed\n")); + return -1; } skb->ip_summed = CHECKSUM_UNNECESSARY; - default: - /* CHECKSUM_UNNECESSARY */ + } else if (skb->ip_summed != CHECKSUM_UNNECESSARY) { + if (skb->len <= 68) { + if (tcp_v4_check(skb->h.th,skb->len,skb->nh.iph->saddr, + skb->nh.iph->daddr, + csum_partial((char *)skb->h.th, skb->len, 0))) + return -1; + skb->ip_summed = CHECKSUM_UNNECESSARY; + } else { + skb->csum = ~tcp_v4_check(skb->h.th,skb->len,skb->nh.iph->saddr, + skb->nh.iph->daddr,0); + } } return 0; } @@ -1614,66 +1549,35 @@ goto discard; #endif /* CONFIG_FILTER */ - /* - * This doesn't check if the socket has enough room for the packet. - * Either process the packet _without_ queueing it and then free it, - * or do the check later. - */ - skb_set_owner_r(skb, sk); + IP_INC_STATS_BH(IpInDelivers); if (sk->state == TCP_ESTABLISHED) { /* Fast path */ - /* Ready to move deeper ... */ - if (tcp_csum_verify(skb)) - goto csum_err; + TCP_CHECK_TIMER(sk); if (tcp_rcv_established(sk, skb, skb->h.th, skb->len)) goto reset; + TCP_CHECK_TIMER(sk); return 0; - } + } - if (tcp_csum_verify(skb)) + if (tcp_checksum_complete(skb)) goto csum_err; if (sk->state == TCP_LISTEN) { - struct sock *nsk; - - nsk = tcp_v4_hnd_req(sk, skb); + struct sock *nsk = tcp_v4_hnd_req(sk, skb); if (!nsk) goto discard; - /* - * Queue it on the new socket if the new socket is active, - * otherwise we just shortcircuit this and continue with - * the new socket.. - */ if (nsk != sk) { - int ret; - int state = nsk->state; - - skb_orphan(skb); - - BUG_TRAP(nsk->lock.users == 0); - skb_set_owner_r(skb, nsk); - ret = tcp_rcv_state_process(nsk, skb, skb->h.th, skb->len); - - /* Wakeup parent, send SIGIO, if this packet changed - socket state from SYN-RECV. - - It still looks ugly, however it is much better - than miracleous double wakeup in syn_recv_sock() - and tcp_rcv_state_process(). - */ - if (state == TCP_SYN_RECV && nsk->state != state) - sk->data_ready(sk, 0); - - bh_unlock_sock(nsk); - if (ret) + if (tcp_child_process(sk, nsk, skb)) goto reset; return 0; } } - + + TCP_CHECK_TIMER(sk); if (tcp_rcv_state_process(sk, skb, skb->h.th, skb->len)) goto reset; + TCP_CHECK_TIMER(sk); return 0; reset: @@ -1716,6 +1620,9 @@ if (len < sizeof(struct tcphdr)) goto bad_packet; + if (tcp_v4_checksum_init(skb) < 0) + goto bad_packet; + TCP_SKB_CB(skb)->seq = ntohl(th->seq); TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + len - th->doff*4); @@ -1724,7 +1631,7 @@ skb->used = 0; sk = __tcp_v4_lookup(skb->nh.iph->saddr, th->source, - skb->nh.iph->daddr, ntohs(th->dest), skb->dev->ifindex); + skb->nh.iph->daddr, ntohs(th->dest), tcp_v4_iif(skb)); if (!sk) goto no_tcp_socket; @@ -1738,9 +1645,10 @@ bh_lock_sock(sk); ret = 0; - if (!sk->lock.users) - ret = tcp_v4_do_rcv(sk, skb); - else + if (!sk->lock.users) { + if (!tcp_prequeue(sk, skb)) + ret = tcp_v4_do_rcv(sk, skb); + } else sk_add_backlog(sk, skb); bh_unlock_sock(sk); @@ -1749,7 +1657,7 @@ return ret; no_tcp_socket: - if (tcp_csum_verify(skb)) { + if (tcp_checksum_complete(skb)) { bad_packet: TCP_INC_STATS_BH(TcpInErrs); } else { @@ -1766,7 +1674,7 @@ goto discard_it; do_time_wait: - if (tcp_csum_verify(skb)) { + if (tcp_checksum_complete(skb)) { TCP_INC_STATS_BH(TcpInErrs); goto discard_and_relse; } @@ -1776,7 +1684,7 @@ { struct sock *sk2; - sk2 = tcp_v4_lookup_listener(skb->nh.iph->daddr, ntohs(th->dest), skb->dev->ifindex); + sk2 = tcp_v4_lookup_listener(skb->nh.iph->daddr, ntohs(th->dest), tcp_v4_iif(skb)); if (sk2 != NULL) { tcp_tw_deschedule((struct tcp_tw_bucket *)sk); tcp_timewait_kill((struct tcp_tw_bucket *)sk); @@ -1796,36 +1704,39 @@ goto discard_it; } +/* With per-bucket locks this operation is not-atomic, so that + * this version is not worse. + */ static void __tcp_v4_rehash(struct sock *sk) { - struct tcp_ehash_bucket *oldhead = &tcp_ehash[sk->hashent]; - struct tcp_ehash_bucket *head = &tcp_ehash[(sk->hashent = tcp_sk_hashfn(sk))]; - struct sock **skp = &head->chain; - - write_lock_bh(&oldhead->lock); - if(sk->pprev) { - if(sk->next) - sk->next->pprev = sk->pprev; - *sk->pprev = sk->next; - sk->pprev = NULL; - } - write_unlock(&oldhead->lock); - write_lock(&head->lock); - if((sk->next = *skp) != NULL) - (*skp)->pprev = &sk->next; - *skp = sk; - sk->pprev = skp; - write_unlock_bh(&head->lock); + sk->prot->unhash(sk); + sk->prot->hash(sk); } int tcp_v4_rebuild_header(struct sock *sk) { - struct rtable *rt = (struct rtable *)__sk_dst_get(sk); + struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0); __u32 new_saddr; int want_rewrite = sysctl_ip_dynaddr && sk->state == TCP_SYN_SENT; - if(rt == NULL) - return 0; + if (rt == NULL) { + int err; + + u32 daddr = sk->daddr; + + if(sk->protinfo.af_inet.opt && sk->protinfo.af_inet.opt->srr) + daddr = sk->protinfo.af_inet.opt->faddr; + + err = ip_route_output(&rt, daddr, sk->saddr, + RT_TOS(sk->protinfo.af_inet.tos) | RTO_CONN | sk->localroute, + sk->bound_dev_if); + if (err) { + sk->err_soft=-err; + sk->error_report(sk); + return -1; + } + __sk_dst_set(sk, &rt->u.dst); + } /* Force route checking if want_rewrite. * The idea is good, the implementation is disguisting. @@ -1855,16 +1766,6 @@ dst_release(&new_rt->u.dst); } } - if (rt->u.dst.obsolete) { - int err; - err = ip_route_output(&rt, rt->rt_dst, rt->rt_src, rt->key.tos|RTO_CONN, rt->key.oif); - if (err) { - sk->err_soft=-err; - sk->error_report(sk); - return -1; - } - __sk_dst_set(sk, &rt->u.dst); - } return 0; @@ -1877,7 +1778,7 @@ "saddr=%08X rcv_saddr=%08X\n", ntohl(sk->saddr), ntohl(sk->rcv_saddr)); - return 0; + return -1; } if (new_saddr != sk->saddr) { @@ -1895,7 +1796,7 @@ * XXX really change the sockets identity after * XXX it has entered the hashes. -DaveM * - * Besides that, it does not check for connetion + * Besides that, it does not check for connection * uniqueness. Wait for troubles. */ __tcp_v4_rehash(sk); @@ -1913,6 +1814,63 @@ sin->sin_port = sk->dport; } +/* VJ's idea. Save last timestamp seen from this destination + * and hold it at least for normal timewait interval to use for duplicate + * segment detection in subsequent connections, before they enter synchronized + * state. + */ + +int tcp_v4_remember_stamp(struct sock *sk) +{ + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + struct rtable *rt = (struct rtable*)__sk_dst_get(sk); + struct inet_peer *peer = NULL; + int release_it = 0; + + if (rt == NULL || rt->rt_dst != sk->daddr) { + peer = inet_getpeer(sk->daddr, 1); + release_it = 1; + } else { + if (rt->peer == NULL) + rt_bind_peer(rt, 1); + peer = rt->peer; + } + + if (peer) { + if ((s32)(peer->tcp_ts - tp->ts_recent) <= 0 || + (peer->tcp_ts_stamp + TCP_PAWS_MSL < xtime.tv_sec && + peer->tcp_ts_stamp <= tp->ts_recent_stamp)) { + peer->tcp_ts_stamp = tp->ts_recent_stamp; + peer->tcp_ts = tp->ts_recent; + } + if (release_it) + inet_putpeer(peer); + return 1; + } + + return 0; +} + +int tcp_v4_tw_remember_stamp(struct tcp_tw_bucket *tw) +{ + struct inet_peer *peer = NULL; + + peer = inet_getpeer(tw->daddr, 1); + + if (peer) { + if ((s32)(peer->tcp_ts - tw->ts_recent) <= 0 || + (peer->tcp_ts_stamp + TCP_PAWS_MSL < xtime.tv_sec && + peer->tcp_ts_stamp <= tw->ts_recent_stamp)) { + peer->tcp_ts_stamp = tw->ts_recent_stamp; + peer->tcp_ts = tw->ts_recent; + } + inet_putpeer(peer); + return 1; + } + + return 0; +} + struct tcp_func ipv4_specific = { ip_queue_xmit, tcp_v4_send_check, @@ -1920,6 +1878,7 @@ tcp_v4_conn_request, tcp_v4_syn_recv_sock, tcp_v4_hash_connecting, + tcp_v4_remember_stamp, sizeof(struct iphdr), ip_setsockopt, @@ -1937,6 +1896,7 @@ skb_queue_head_init(&tp->out_of_order_queue); tcp_init_xmit_timers(sk); + tcp_prequeue_init(tp); tp->rto = TCP_TIMEOUT_INIT; tp->mdev = TCP_TIMEOUT_INIT; @@ -1951,19 +1911,14 @@ /* See draft-stevens-tcpca-spec-01 for discussion of the * initialization of these values. */ - tp->snd_cwnd_cnt = 0; tp->snd_ssthresh = 0x7fffffff; /* Infinity */ tp->snd_cwnd_clamp = ~0; tp->mss_cache = 536; sk->state = TCP_CLOSE; - sk->max_ack_backlog = SOMAXCONN; sk->write_space = tcp_write_space; - /* Init SYN queue. */ - tcp_synq_init(tp); - sk->tp_pinfo.af_tcp.af_specific = &ipv4_specific; return 0; @@ -1981,9 +1936,10 @@ /* Cleans up our, hopefuly empty, out_of_order_queue. */ __skb_queue_purge(&tp->out_of_order_queue); - /* Clean up a referenced TCP bind bucket, this only happens if a - * port is allocated for a socket, but it never fully connects. - */ + /* Clean prequeue, it must be empty really */ + __skb_queue_purge(&tp->ucopy.prequeue); + + /* Clean up a referenced TCP bind bucket. */ if(sk->prev != NULL) tcp_put_port(sk); @@ -1993,17 +1949,19 @@ /* Proc filesystem TCP sock list dumping. */ static void get_openreq(struct sock *sk, struct open_request *req, char *tmpbuf, int i) { - sprintf(tmpbuf, "%4d: %08lX:%04X %08lX:%04X" - " %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p", + int ttd = req->expires - jiffies; + + sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X" + " %02X %08X:%08X %02X:%08X %08X %5d %8d %u %d %p", i, - (long unsigned int)req->af.v4_req.loc_addr, + req->af.v4_req.loc_addr, ntohs(sk->sport), - (long unsigned int)req->af.v4_req.rmt_addr, + req->af.v4_req.rmt_addr, ntohs(req->rmt_port), TCP_SYN_RECV, 0,0, /* could print option size, but that is af dependent. */ 1, /* timers active (only the expire timer) */ - (unsigned long)(req->expires - jiffies), + ttd, req->retrans, sk->socket ? sk->socket->inode->i_uid : 0, 0, /* non standard timer */ @@ -2017,7 +1975,7 @@ { unsigned int dest, src; __u16 destp, srcp; - int timer_active, timer_active1, timer_active2; + int timer_active; unsigned long timer_expires; struct tcp_opt *tp = &sp->tp_pinfo.af_tcp; @@ -2025,15 +1983,16 @@ src = sp->rcv_saddr; destp = ntohs(sp->dport); srcp = ntohs(sp->sport); - timer_active1 = tp->retransmit_timer.prev != NULL; - timer_active2 = sp->timer.prev != NULL; timer_active = 0; timer_expires = (unsigned) -1; - if (timer_active1 && tp->retransmit_timer.expires < timer_expires) { + if (tp->retransmit_timer.prev != NULL && tp->retransmit_timer.expires < timer_expires) { timer_active = 1; timer_expires = tp->retransmit_timer.expires; + } else if (tp->probe_timer.prev != NULL && tp->probe_timer.expires < timer_expires) { + timer_active = 4; + timer_expires = tp->probe_timer.expires; } - if (timer_active2 && sp->timer.expires < timer_expires) { + if (sp->timer.prev != NULL && sp->timer.expires < timer_expires) { timer_active = 2; timer_expires = sp->timer.expires; } @@ -2041,38 +2000,37 @@ timer_expires = jiffies; sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X" - " %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p", + " %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p %u %u %u %u", i, src, srcp, dest, destp, sp->state, tp->write_seq-tp->snd_una, tp->rcv_nxt-tp->copied_seq, timer_active, timer_expires-jiffies, tp->retransmits, sp->socket ? sp->socket->inode->i_uid : 0, - 0, + tp->probes_out, sp->socket ? sp->socket->inode->i_ino : 0, - atomic_read(&sp->refcnt), sp); + atomic_read(&sp->refcnt), sp, + tp->rto, tp->ack.ato, tp->ack.quick, tp->ack.pingpong + ); } static void get_timewait_sock(struct tcp_tw_bucket *tw, char *tmpbuf, int i) { unsigned int dest, src; __u16 destp, srcp; - int slot_dist; + int ttd = tw->ttd - jiffies; + + if (ttd < 0) + ttd = 0; dest = tw->daddr; src = tw->rcv_saddr; destp = ntohs(tw->dport); srcp = ntohs(tw->sport); - slot_dist = tw->death_slot; - if(slot_dist > tcp_tw_death_row_slot) - slot_dist = (TCP_TWKILL_SLOTS - slot_dist) + tcp_tw_death_row_slot; - else - slot_dist = tcp_tw_death_row_slot - slot_dist; - sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X" " %02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p", - i, src, srcp, dest, destp, TCP_TIME_WAIT, 0, 0, - 3, slot_dist * TCP_TWKILL_PERIOD, 0, 0, 0, 0, + i, src, srcp, dest, destp, tw->substate, 0, 0, + 3, ttd, 0, 0, 0, 0, atomic_read(&tw->refcnt), tw); } @@ -2093,6 +2051,8 @@ tcp_listen_lock(); for(i = 0; i < TCP_LHTABLE_SIZE; i++) { struct sock *sk = tcp_listening_hash[i]; + struct tcp_listen_opt *lopt; + int k; for (sk = tcp_listening_hash[i]; sk; sk = sk->next, num++) { struct open_request *req; @@ -2112,25 +2072,30 @@ } skip_listen: - lock_sock(sk); - for (req = tp->syn_wait_queue; req; req = req->dl_next, num++) { - if (req->sk) - continue; - if (!TCP_INET_FAMILY(req->class->family)) - continue; - - pos += 128; - if (pos < offset) - continue; - get_openreq(sk, req, tmpbuf, num); - len += sprintf(buffer+len, "%-127s\n", tmpbuf); - if(len >= length) { - tcp_listen_unlock(); - release_sock(sk); - goto out_no_bh; + read_lock_bh(&tp->syn_wait_lock); + lopt = tp->listen_opt; + if (lopt && lopt->qlen != 0) { + for (k=0; ksyn_table[k]; req; req = req->dl_next, num++) { + if (!TCP_INET_FAMILY(req->class->family)) + continue; + + pos += 128; + if (pos < offset) + continue; + get_openreq(sk, req, tmpbuf, num); + len += sprintf(buffer+len, "%-127s\n", tmpbuf); + if(len >= length) { + read_unlock_bh(&tp->syn_wait_lock); + tcp_listen_unlock(); + goto out_no_bh; + } + } } } - release_sock(sk); + read_unlock_bh(&tp->syn_wait_lock); + + /* Completed requests are in normal socket hash table */ } } tcp_listen_unlock(); @@ -2194,27 +2159,23 @@ tcp_v4_connect, /* connect */ tcp_disconnect, /* disconnect */ tcp_accept, /* accept */ - NULL, /* retransmit */ - tcp_write_wakeup, /* write_wakeup */ - tcp_read_wakeup, /* read_wakeup */ - tcp_poll, /* poll */ tcp_ioctl, /* ioctl */ tcp_v4_init_sock, /* init */ tcp_v4_destroy_sock, /* destroy */ tcp_shutdown, /* shutdown */ tcp_setsockopt, /* setsockopt */ tcp_getsockopt, /* getsockopt */ - tcp_v4_sendmsg, /* sendmsg */ + tcp_sendmsg, /* sendmsg */ tcp_recvmsg, /* recvmsg */ NULL, /* bind */ tcp_v4_do_rcv, /* backlog_rcv */ tcp_v4_hash, /* hash */ tcp_unhash, /* unhash */ tcp_v4_get_port, /* get_port */ - 128, /* max_header */ - 0, /* retransmits */ "TCP", /* name */ }; + + void __init tcp_v4_init(struct net_proto_family *ops) { diff -ur --new-file old/linux/net/ipv4/tcp_output.c new/linux/net/ipv4/tcp_output.c --- old/linux/net/ipv4/tcp_output.c Thu Jan 13 21:03:00 2000 +++ new/linux/net/ipv4/tcp_output.c Sat Jan 22 20:54:57 2000 @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_output.c,v 1.116 2000/01/13 00:19:49 davem Exp $ + * Version: $Id: tcp_output.c,v 1.119 2000/01/19 04:06:15 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -31,6 +31,7 @@ * during syn/ack processing. * David S. Miller : Output engine completely rewritten. * Andrea Arcangeli: SYNACK carry ts_recent in tsecr. + * Cacophonix Gaul : draft-minshall-nagle-01 * */ @@ -38,75 +39,65 @@ #include -extern int sysctl_tcp_timestamps; -extern int sysctl_tcp_window_scaling; -extern int sysctl_tcp_sack; - /* People can turn this off for buggy TCP's found in printers etc. */ int sysctl_tcp_retrans_collapse = 1; -/* Get rid of any delayed acks, we sent one already.. */ -static __inline__ void clear_delayed_acks(struct sock * sk) -{ - struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - - tp->delayed_acks = 0; - if(tcp_in_quickack_mode(tp)) - tcp_exit_quickack_mode(tp); - tcp_clear_xmit_timer(sk, TIME_DACK); -} - static __inline__ void update_send_head(struct sock *sk) { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - + tp->send_head = tp->send_head->next; if (tp->send_head == (struct sk_buff *) &sk->write_queue) tp->send_head = NULL; } /* Calculate mss to advertise in SYN segment. - RFC1122, RFC1063, draft-ietf-tcpimpl-pmtud-01 state that: - - 1. It is independent of path mtu. - 2. Ideally, it is maximal possible segment size i.e. 65535-40. - 3. For IPv4 it is reasonable to calculate it from maximal MTU of - attached devices, because some buggy hosts are confused by - large MSS. - 4. We do not make 3, we advertise MSS, calculated from first - hop device mtu, but allow to raise it to ip_rt_min_advmss. - This may be overriden via information stored in routing table. - 5. Value 65535 for MSS is valid in IPv6 and means "as large as possible, - probably even Jumbo". + * RFC1122, RFC1063, draft-ietf-tcpimpl-pmtud-01 state that: + * + * 1. It is independent of path mtu. + * 2. Ideally, it is maximal possible segment size i.e. 65535-40. + * 3. For IPv4 it is reasonable to calculate it from maximal MTU of + * attached devices, because some buggy hosts are confused by + * large MSS. + * 4. We do not make 3, we advertise MSS, calculated from first + * hop device mtu, but allow to raise it to ip_rt_min_advmss. + * This may be overriden via information stored in routing table. + * 5. Value 65535 for MSS is valid in IPv6 and means "as large as possible, + * probably even Jumbo". */ static __u16 tcp_advertise_mss(struct sock *sk) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); struct dst_entry *dst = __sk_dst_get(sk); - int mss; + int mss = tp->advmss; - if (dst) { + if (dst && dst->advmss < mss) { mss = dst->advmss; - } else { - struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + tp->advmss = mss; + } - /* No dst. It is bad. Guess some reasonable value. - * Actually, this case should not be possible. - * SANITY. - */ - BUG_TRAP(dst!=NULL); + return (__u16)mss; +} - mss = tp->mss_cache; - mss += (tp->tcp_header_len - sizeof(struct tcphdr)) + - tp->ext_header_len; +static __inline__ void tcp_event_data_sent(struct tcp_opt *tp, struct sk_buff *skb) +{ + /* If we had a reply for ato after last received + * packet, enter pingpong mode. + */ + if ((u32)(tp->lsndtime - tp->ack.lrcvtime) < tp->ack.ato) + tp->ack.pingpong = 1; - /* Minimal MSS to include full set of of TCP/IP options - plus 8 bytes of data. It corresponds to mtu 128. - */ - if (mss < 88) - mss = 88; - } + tp->lsndtime = tcp_time_stamp; +} - return (__u16)mss; +static __inline__ void tcp_event_ack_sent(struct sock *sk) +{ + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + tp->last_ack_sent = tp->rcv_nxt; + tcp_dec_quickack_mode(tp); + tp->ack.pending = 0; + tcp_clear_xmit_timer(sk, TCP_TIME_DACK); } /* This routine actually transmits TCP packets queued in by @@ -120,7 +111,7 @@ * We are working here with either a clone of the original * SKB, or a fresh unique copy made by the retransmit engine. */ -void tcp_transmit_skb(struct sock *sk, struct sk_buff *skb) +int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb) { if(skb != NULL) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); @@ -128,6 +119,7 @@ int tcp_header_size = tp->tcp_header_len; struct tcphdr *th; int sysctl_flags; + int err; #define SYSCTL_FLAG_TSTAMPS 0x1 #define SYSCTL_FLAG_WSCALE 0x2 @@ -190,11 +182,29 @@ } tp->af_specific->send_check(sk, th, skb->len, skb); - clear_delayed_acks(sk); - tp->last_ack_sent = tp->rcv_nxt; + if (th->ack) + tcp_event_ack_sent(sk); + + if (skb->len != tcp_header_size) + tcp_event_data_sent(tp, skb); + TCP_INC_STATS(TcpOutSegs); - tp->af_specific->queue_xmit(skb); + + err = tp->af_specific->queue_xmit(skb); + if (err <= 0) + return err; + + tcp_enter_cong_avoid(tp); + + /* NET_XMIT_CN is special. It does not guarantee, + * that this packet is lost. It tells that device + * is about to start to drop packets or already + * drops some packets of the same priority and + * invokes us to send less aggressively. + */ + return err == NET_XMIT_CN ? 0 : err; } + return -ENOBUFS; #undef SYSCTL_FLAG_TSTAMPS #undef SYSCTL_FLAG_WSCALE #undef SYSCTL_FLAG_SACK @@ -202,32 +212,33 @@ /* This is the main buffer sending routine. We queue the buffer * and decide whether to queue or transmit now. + * + * NOTE: probe0 timer is not checked, do not forget tcp_push_pending_frames, + * otherwise socket can stall. */ -void tcp_send_skb(struct sock *sk, struct sk_buff *skb, int force_queue) +void tcp_send_skb(struct sock *sk, struct sk_buff *skb, int force_queue, unsigned cur_mss) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); /* Advance write_seq and place onto the write_queue. */ - tp->write_seq += (TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq); + tp->write_seq = TCP_SKB_CB(skb)->end_seq; __skb_queue_tail(&sk->write_queue, skb); - if (!force_queue && tp->send_head == NULL && tcp_snd_test(sk, skb)) { + if (!force_queue && tp->send_head == NULL && tcp_snd_test(tp, skb, cur_mss, 1)) { /* Send it out now. */ TCP_SKB_CB(skb)->when = tcp_time_stamp; - tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; - tp->packets_out++; - tcp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL)); - if(!tcp_timer_is_set(sk, TIME_RETRANS)) - tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); - } else { - /* Queue it, remembering where we must start sending. */ - if (tp->send_head == NULL) - tp->send_head = skb; - if (!force_queue && tp->packets_out == 0 && !tp->pending) { - tp->pending = TIME_PROBE0; - tcp_reset_xmit_timer(sk, TIME_PROBE0, tp->rto); + if (tcp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL)) == 0) { + tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; + tcp_minshall_update(tp, cur_mss, skb->len); + tp->packets_out++; + if(!tcp_timer_is_set(sk, TCP_TIME_RETRANS)) + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); + return; } } + /* Queue it, remembering where we must start sending. */ + if (tp->send_head == NULL) + tp->send_head = skb; } /* Function to create two new TCP segments. Shrinks the given segment @@ -243,13 +254,13 @@ /* Get a new skb... force flag on. */ buff = sock_wmalloc(sk, - (nsize + MAX_HEADER + sk->prot->max_header), + (nsize + MAX_TCP_HEADER + 15), 1, GFP_ATOMIC); if (buff == NULL) - return -1; /* We'll just try again later. */ + return -ENOMEM; /* We'll just try again later. */ /* Reserve space for headers. */ - skb_reserve(buff, MAX_HEADER + sk->prot->max_header); + skb_reserve(buff, MAX_TCP_HEADER); /* Correct the sequence numbers. */ TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; @@ -276,8 +287,8 @@ TCP_SKB_CB(buff)->sacked = 0; /* Copy and checksum data tail into the new buffer. */ - buff->csum = csum_partial_copy(skb->data + len, skb_put(buff, nsize), - nsize, 0); + buff->csum = csum_partial_copy_nocheck(skb->data + len, skb_put(buff, nsize), + nsize, 0); /* This takes care of the FIN sequence number too. */ TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq; @@ -288,6 +299,11 @@ /* Looks stupid, but our code really uses when of * skbs, which it never sent before. --ANK + * + * NOTE: several days after I added this, Dave repaired + * tcp_simple_retransmit() and it should not use ->when + * of never sent skbs more. I am not sure, so that + * this line remains until more careful investigation. --ANK */ TCP_SKB_CB(buff)->when = TCP_SKB_CB(skb)->when; @@ -335,20 +351,19 @@ if (mss_now > tp->mss_clamp) mss_now = tp->mss_clamp; - /* Now subtract TCP options size, not including SACKs */ - mss_now -= tp->tcp_header_len - sizeof(struct tcphdr); - /* Now subtract optional transport overhead */ mss_now -= tp->ext_header_len; - /* It we got too small (or even negative) value, - clamp it by 8 from below. Why 8 ? - Well, it could be 1 with the same success, - but if IP accepted segment of length 1, - it would love 8 even more 8) --ANK (980731) - */ - if (mss_now < 8) - mss_now = 8; + /* Then reserve room for full set of TCP options and 8 bytes of data */ + if (mss_now < 48) + mss_now = 48; + + /* Now subtract TCP options size, not including SACKs */ + mss_now -= tp->tcp_header_len - sizeof(struct tcphdr); + + /* Bound mss with half of window */ + if (tp->max_window && mss_now > (tp->max_window>>1)) + mss_now = max((tp->max_window>>1), 1); /* And store cached results */ tp->pmtu_cookie = pmtu; @@ -360,27 +375,30 @@ /* This routine writes packets to the network. It advances the * send_head. This happens as incoming acks open up the remote * window for us. + * + * Returns 1, if no segments are in flight and we have queued segments, but + * cannot send anything now because of SWS or another problem. */ -void tcp_write_xmit(struct sock *sk) +int tcp_write_xmit(struct sock *sk) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); unsigned int mss_now; - /* Account for SACKS, we may need to fragment due to this. - * It is just like the real MSS changing on us midstream. - * We also handle things correctly when the user adds some - * IP options mid-stream. Silly to do, but cover it. - */ - mss_now = tcp_current_mss(sk); - - /* If we are zapped, the bytes will have to remain here. - * In time closedown will empty the write queue and all + /* If we are closed, the bytes will have to remain here. + * In time closedown will finish, we empty the write queue and all * will be happy. */ - if(!sk->zapped) { + if(sk->state != TCP_CLOSE) { struct sk_buff *skb; int sent_pkts = 0; + /* Account for SACKS, we may need to fragment due to this. + * It is just like the real MSS changing on us midstream. + * We also handle things correctly when the user adds some + * IP options mid-stream. Silly to do, but cover it. + */ + mss_now = tcp_current_mss(sk); + /* Anything on the transmit queue that fits the window can * be added providing we are: * @@ -388,27 +406,36 @@ * b) not exceeding our congestion window. * c) not retransmitting [Nagle] */ - while((skb = tp->send_head) && tcp_snd_test(sk, skb)) { + while((skb = tp->send_head) && + tcp_snd_test(tp, skb, mss_now, tcp_skb_is_last(sk, skb))) { if (skb->len > mss_now) { if (tcp_fragment(sk, skb, mss_now)) break; } - /* Advance the send_head. This one is going out. */ - update_send_head(sk); TCP_SKB_CB(skb)->when = tcp_time_stamp; + if (tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))) + break; + /* Advance the send_head. This one is sent out. */ + update_send_head(sk); tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; + tcp_minshall_update(tp, mss_now, skb->len); tp->packets_out++; - tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)); sent_pkts = 1; } /* If we sent anything, make sure the retransmit * timer is active. */ - if (sent_pkts && !tcp_timer_is_set(sk, TIME_RETRANS)) - tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); + if (sent_pkts) { + if (!tcp_timer_is_set(sk, TCP_TIME_RETRANS)) + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); + return 0; + } + + return !tp->packets_out && tp->send_head; } + return 0; } /* This function returns the amount that we can raise the @@ -471,7 +498,7 @@ * but may be worse for the performance because of rcv_mss * fluctuations. --SAW 1998/11/1 */ - unsigned int mss = tp->rcv_mss; + unsigned int mss = tp->ack.rcv_mss; int free_space; u32 window; @@ -481,11 +508,19 @@ free_space = tp->window_clamp; if (tp->window_clamp < mss) mss = tp->window_clamp; - - if ((free_space < (tcp_full_space(sk) / 2)) && + + if ((free_space < (min((int)tp->window_clamp, tcp_full_space(sk)) / 2)) && (free_space < ((int) (mss/2)))) { window = 0; - tp->pred_flags = 0; + + /* THIS IS _VERY_ GOOD PLACE to play window clamp. + * if free_space becomes suspiciously low + * verify ratio rmem_alloc/(rcv_nxt - copied_seq), + * and if we predict that when free_space will be lower mss, + * rmem_alloc will run out of rcvbuf*2, shrink window_clamp. + * It will eliminate most of prune events! Very simple, + * it is the next thing to do. --ANK + */ } else { /* Get the largest window that is a nice multiple of mss. * Window clamp already applied above. @@ -542,9 +577,9 @@ /* Optimize, actually we could also combine next_skb->csum * to skb->csum using a single add w/carry operation too. */ - skb->csum = csum_partial_copy(next_skb->data, - skb_put(skb, next_skb_size), - next_skb_size, skb->csum); + skb->csum = csum_partial_copy_nocheck(next_skb->data, + skb_put(skb, next_skb_size), + next_skb_size, skb->csum); } /* Update sequence range on original skb. */ @@ -603,8 +638,10 @@ if (old_next_skb != skb || skb->len > mss) resend_skb = 1; old_next_skb = skb->next; - if (resend_skb != 0) - tcp_retransmit_skb(sk, skb); + if (resend_skb != 0) { + if (tcp_retransmit_skb(sk, skb)) + break; + } } } @@ -629,9 +666,21 @@ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); unsigned int cur_mss = tcp_current_mss(sk); +#ifdef TCP_DEBUG + /* It was possible this summer, that retransmit timer + * raced with its deletion and hit socket with packets_out==0. + * I fixed it, but preserved the check in the place, + * where the fault occured. --ANK + */ + if (skb == NULL) { + printk("tcp_retransmit_skb: bug, skb==NULL, caller=%p\n", NET_CALLER(sk)); + return -EFAULT; + } +#endif + if(skb->len > cur_mss) { if(tcp_fragment(sk, skb, cur_mss)) - return 1; /* We'll try again later. */ + return -ENOMEM; /* We'll try again later. */ /* New SKB created, account for it. */ tp->packets_out++; @@ -646,7 +695,7 @@ tcp_retrans_try_collapse(sk, skb, cur_mss); if(tp->af_specific->rebuild_header(sk)) - return 1; /* Routing failure or similar. */ + return -EHOSTUNREACH; /* Routing failure or similar. */ /* Some Solaris stacks overoptimize and ignore the FIN on a * retransmit when old data is attached. So strip it off @@ -673,13 +722,10 @@ else skb = skb_clone(skb, GFP_ATOMIC); - tcp_transmit_skb(sk, skb); - /* Update global TCP statistics and return success. */ - sk->prot->retransmits++; TCP_INC_STATS(TcpRetransSegs); - return 0; + return tcp_transmit_skb(sk, skb); } /* This gets called after a retransmit timeout, and the initially @@ -774,7 +820,11 @@ */ mss_now = tcp_current_mss(sk); - if((tp->send_head != NULL) && (skb->len < mss_now)) { + /* Please, find seven differences of 2.3.33 and loook + * what I broke here. 8) --ANK + */ + + if(tp->send_head != NULL) { /* tcp_write_xmit() takes care of the rest. */ TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_FIN; TCP_SKB_CB(skb)->end_seq++; @@ -783,31 +833,34 @@ /* Special case to avoid Nagle bogosity. If this * segment is the last segment, and it was queued * due to Nagle/SWS-avoidance, send it out now. + * + * Hmm... actually it overrides also congestion + * avoidance (OK for FIN) and retransmit phase + * (not OK? Added.). */ if(tp->send_head == skb && - !sk->nonagle && - skb->len < (tp->rcv_mss >> 1) && - tp->packets_out && - !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_URG)) { - update_send_head(sk); + !after(tp->write_seq, tp->snd_una + tp->snd_wnd) && + !tp->retransmits) { TCP_SKB_CB(skb)->when = tcp_time_stamp; - tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; - tp->packets_out++; - tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)); - if(!tcp_timer_is_set(sk, TIME_RETRANS)) - tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); + if (!tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))) { + update_send_head(sk); + tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; + tp->packets_out++; + if(!tcp_timer_is_set(sk, TCP_TIME_RETRANS)) + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); + } else + tcp_check_probe_timer(sk, tp); } } else { /* Socket is locked, keep trying until memory is available. */ do { skb = sock_wmalloc(sk, - (MAX_HEADER + - sk->prot->max_header), + MAX_TCP_HEADER + 15, 1, GFP_KERNEL); } while (skb == NULL); /* Reserve space for headers and prepare control bits. */ - skb_reserve(skb, MAX_HEADER + sk->prot->max_header); + skb_reserve(skb, MAX_TCP_HEADER); skb->csum = 0; TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_FIN); TCP_SKB_CB(skb)->sacked = 0; @@ -816,7 +869,8 @@ /* FIN eats a sequence byte, write_seq advanced by tcp_send_skb(). */ TCP_SKB_CB(skb)->seq = tp->write_seq; TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1; - tcp_send_skb(sk, skb, 0); + tcp_send_skb(sk, skb, 0, mss_now); + __tcp_push_pending_frames(sk, tp, mss_now); } } @@ -831,19 +885,19 @@ struct sk_buff *skb; /* NOTE: No TCP options attached and we never retransmit this. */ - skb = alloc_skb(MAX_HEADER + sk->prot->max_header, priority); + skb = alloc_skb(MAX_TCP_HEADER + 15, priority); if (!skb) return; /* Reserve space for headers and prepare control bits. */ - skb_reserve(skb, MAX_HEADER + sk->prot->max_header); + skb_reserve(skb, MAX_TCP_HEADER); skb->csum = 0; TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_RST); TCP_SKB_CB(skb)->sacked = 0; TCP_SKB_CB(skb)->urg_ptr = 0; /* Send it off. */ - TCP_SKB_CB(skb)->seq = tp->write_seq; + TCP_SKB_CB(skb)->seq = tp->snd_nxt; TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq; TCP_SKB_CB(skb)->when = tcp_time_stamp; tcp_transmit_skb(sk, skb); @@ -859,13 +913,13 @@ struct tcp_opt* tp = &(sk->tp_pinfo.af_tcp); struct sk_buff* skb; - skb = sock_wmalloc(sk, (MAX_HEADER + sk->prot->max_header), + skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC); if (skb == NULL) return -ENOMEM; /* Reserve space for headers and prepare control bits. */ - skb_reserve(skb, MAX_HEADER + sk->prot->max_header); + skb_reserve(skb, MAX_TCP_HEADER); skb->csum = 0; TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_SYN); TCP_SKB_CB(skb)->sacked = 0; @@ -877,8 +931,7 @@ __skb_queue_tail(&sk->write_queue, skb); TCP_SKB_CB(skb)->when = tcp_time_stamp; tp->packets_out++; - tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)); - return 0; + return tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)); } /* @@ -887,16 +940,17 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, struct open_request *req) { + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); struct tcphdr *th; int tcp_header_size; struct sk_buff *skb; - skb = sock_wmalloc(sk, MAX_HEADER + sk->prot->max_header, 1, GFP_ATOMIC); + skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC); if (skb == NULL) return NULL; /* Reserve space for headers. */ - skb_reserve(skb, MAX_HEADER + sk->prot->max_header); + skb_reserve(skb, MAX_TCP_HEADER); skb->dst = dst_clone(dst); @@ -919,7 +973,7 @@ if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */ __u8 rcv_wscale; /* Set this up on the first call only */ - req->window_clamp = skb->dst->window; + req->window_clamp = tp->window_clamp ? : skb->dst->window; /* tcp_full_space because it is guaranteed to be the first packet */ tcp_select_initial_window(tcp_full_space(sk), dst->advmss - (req->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), @@ -951,7 +1005,7 @@ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); /* Reserve space for headers. */ - skb_reserve(buff, MAX_HEADER + sk->prot->max_header); + skb_reserve(buff, MAX_TCP_HEADER + 15); /* We'll fix this up when we get a response from the other end. * See tcp_input.c:tcp_rcv_state_process case TCP_SYN_SENT. @@ -962,12 +1016,16 @@ /* If user gave his TCP_MAXSEG, record it to clamp */ if (tp->user_mss) tp->mss_clamp = tp->user_mss; + tp->max_window = 0; tcp_sync_mss(sk, dst->pmtu); + tcp_initialize_rcv_mss(sk); - tp->window_clamp = dst->window; + if (!tp->window_clamp) + tp->window_clamp = dst->window; + tp->advmss = dst->advmss; tcp_select_initial_window(tcp_full_space(sk), - dst->advmss - (tp->tcp_header_len - sizeof(struct tcphdr)), + tp->advmss - (tp->tcp_header_len - sizeof(struct tcphdr)), &tp->rcv_wnd, &tp->window_clamp, sysctl_tcp_window_scaling, @@ -982,10 +1040,12 @@ goto err_out; sk->err = 0; + sk->done = 0; tp->snd_wnd = 0; tp->snd_wl1 = 0; tp->snd_wl2 = tp->write_seq; tp->snd_una = tp->write_seq; + tp->snd_sml = tp->write_seq; tp->rcv_nxt = 0; tp->rcv_wup = 0; tp->copied_seq = 0; @@ -1006,13 +1066,14 @@ /* Send it off. */ TCP_SKB_CB(buff)->when = tcp_time_stamp; + tp->syn_stamp = TCP_SKB_CB(buff)->when; __skb_queue_tail(&sk->write_queue, buff); tp->packets_out++; tcp_transmit_skb(sk, skb_clone(buff, GFP_KERNEL)); TCP_INC_STATS(TcpActiveOpens); /* Timer for repeating the SYN until an answer. */ - tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); return 0; err_out: @@ -1025,16 +1086,14 @@ * to see if we should even be here. See tcp_input.c:tcp_ack_snd_check() * for details. */ -void tcp_send_delayed_ack(struct sock *sk, int max_timeout) +void tcp_send_delayed_ack(struct sock *sk) { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; unsigned long timeout; /* Stay within the limit we were given */ - timeout = (tp->ato << 1) >> 1; - if (timeout > max_timeout) - timeout = max_timeout; - timeout += jiffies; + timeout = tp->ack.ato; + timeout += jiffies + (timeout>>2); /* Use new timeout only if there wasn't a older one earlier. */ spin_lock_bh(&sk->timer_lock); @@ -1042,18 +1101,46 @@ sock_hold(sk); tp->delack_timer.expires = timeout; } else { + /* If delack timer was blocked or is about to expire, + * send ACK now. + */ + if (tp->ack.blocked || time_before_eq(tp->delack_timer.expires, jiffies+(tp->ack.ato>>2))) { + spin_unlock_bh(&sk->timer_lock); + + tcp_send_ack(sk); + __sock_put(sk); + return; + } + if (time_before(timeout, tp->delack_timer.expires)) tp->delack_timer.expires = timeout; } add_timer(&tp->delack_timer); spin_unlock_bh(&sk->timer_lock); + +#ifdef TCP_FORMAL_WINDOW + /* Explanation. Header prediction path does not handle + * case of zero window. If we send ACK immediately, pred_flags + * are reset when sending ACK. If rcv_nxt is advanced and + * ack is not sent, than delayed ack is scheduled. + * Hence, it is the best place to check for zero window. + */ + if (tp->pred_flags) { + if (tcp_receive_window(tp) == 0) + tp->pred_flags = 0; + } else { + if (skb_queue_len(&tp->out_of_order_queue) == 0 && + !tp->urg_data) + tcp_fast_path_on(tp); + } +#endif } /* This routine sends an ack and also updates the window. */ void tcp_send_ack(struct sock *sk) { /* If we have been reset, we may not send again. */ - if(!sk->zapped) { + if(sk->state != TCP_CLOSE) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); struct sk_buff *buff; @@ -1061,29 +1148,15 @@ * tcp_transmit_skb() will set the ownership to this * sock. */ - buff = alloc_skb(MAX_HEADER + sk->prot->max_header, GFP_ATOMIC); + buff = alloc_skb(MAX_TCP_HEADER + 15, GFP_ATOMIC); if (buff == NULL) { - /* Force it to send an ack. We don't have to do this - * (ACK is unreliable) but it's much better use of - * bandwidth on slow links to send a spare ack than - * resend packets. - * - * This is the one possible way that we can delay an - * ACK and have tp->ato indicate that we are in - * quick ack mode, so clear it. It is also the only - * possible way for ato to be zero, when ACK'ing a - * SYNACK because we've taken no ATO measurement yet. - */ - if (tcp_in_quickack_mode(tp)) - tcp_exit_quickack_mode(tp); - if (!tp->ato) - tp->ato = tp->rto; - tcp_send_delayed_ack(sk, HZ/2); + tp->ack.pending = 1; + tcp_reset_xmit_timer(sk, TCP_TIME_DACK, TCP_DELACK_MAX); return; } /* Reserve space for headers and prepare control bits. */ - skb_reserve(buff, MAX_HEADER + sk->prot->max_header); + skb_reserve(buff, MAX_TCP_HEADER); buff->csum = 0; TCP_SKB_CB(buff)->flags = TCPCB_FLAG_ACK; TCP_SKB_CB(buff)->sacked = 0; @@ -1099,24 +1172,20 @@ /* This routine sends a packet with an out of date sequence * number. It assumes the other end will try to ack it. */ -void tcp_write_wakeup(struct sock *sk) +int tcp_write_wakeup(struct sock *sk) { - /* After a valid reset we can send no more. */ - if (!sk->zapped) { + if (sk->state != TCP_CLOSE) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); struct sk_buff *skb; - /* Write data can still be transmitted/retransmitted in the - * following states. If any other state is encountered, return. - * [listen/close will never occur here anyway] + /* Now this function is never called, while + * we have something not ACKed in queue. */ - if ((1 << sk->state) & - ~(TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_FIN_WAIT1| - TCPF_FIN_WAIT2|TCPF_LAST_ACK|TCPF_CLOSING)) - return; + BUG_TRAP(tp->snd_una == tp->snd_nxt); - if (before(tp->snd_nxt, tp->snd_una + tp->snd_wnd) && - ((skb = tp->send_head) != NULL)) { + if (tp->snd_wnd > (tp->snd_nxt-tp->snd_una) + && ((skb = tp->send_head) != NULL)) { + int err; unsigned long win_size; /* We are probing the opening of a window @@ -1126,24 +1195,26 @@ win_size = tp->snd_wnd - (tp->snd_nxt - tp->snd_una); if (win_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq) { if (tcp_fragment(sk, skb, win_size)) - return; /* Let a retransmit get it. */ + return -1; } - update_send_head(sk); TCP_SKB_CB(skb)->when = tcp_time_stamp; - tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; - tp->packets_out++; - tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)); - if (!tcp_timer_is_set(sk, TIME_RETRANS)) - tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); + err = tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)); + if (!err) { + update_send_head(sk); + tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; + tp->packets_out++; + if (!tcp_timer_is_set(sk, TCP_TIME_RETRANS)) + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); + } + return err; } else { /* We don't queue it, tcp_transmit_skb() sets ownership. */ - skb = alloc_skb(MAX_HEADER + sk->prot->max_header, - GFP_ATOMIC); + skb = alloc_skb(MAX_TCP_HEADER + 15, GFP_ATOMIC); if (skb == NULL) - return; + return -1; /* Reserve space for headers and set control bits. */ - skb_reserve(skb, MAX_HEADER + sk->prot->max_header); + skb_reserve(skb, MAX_TCP_HEADER); skb->csum = 0; TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK; TCP_SKB_CB(skb)->sacked = 0; @@ -1152,13 +1223,18 @@ /* Use a previous sequence. This should cause the other * end to send an ack. Don't queue or clone SKB, just * send it. + * + * RED-PEN: logically it should be snd_una-1. + * snd_nxt-1 will not be acked. snd_una==snd_nxt + * in this place however. Right? */ - TCP_SKB_CB(skb)->seq = tp->snd_nxt - 1; + TCP_SKB_CB(skb)->seq = tp->snd_una - 1; TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq; TCP_SKB_CB(skb)->when = tcp_time_stamp; - tcp_transmit_skb(sk, skb); + return tcp_transmit_skb(sk, skb); } } + return -1; } /* A window probe timeout has occurred. If window is not closed send @@ -1167,11 +1243,32 @@ void tcp_send_probe0(struct sock *sk) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int err; + + err = tcp_write_wakeup(sk); + + if (tp->packets_out || !tp->send_head) { + /* Cancel probe timer, if it is not required. */ + tp->probes_out = 0; + tp->backoff = 0; + return; + } - tcp_write_wakeup(sk); - tp->pending = TIME_PROBE0; - tp->backoff++; - tp->probes_out++; - tcp_reset_xmit_timer (sk, TIME_PROBE0, - min(tp->rto << tp->backoff, 120*HZ)); + if (err <= 0) { + tp->backoff++; + tp->probes_out++; + tcp_reset_xmit_timer (sk, TCP_TIME_PROBE0, + min(tp->rto << tp->backoff, TCP_RTO_MAX)); + } else { + /* If packet was not sent due to local congestion, + * do not backoff and do not remember probes_out. + * Let local senders to fight for local resources. + * + * Use accumulated backoff yet. + */ + if (!tp->probes_out) + tp->probes_out=1; + tcp_reset_xmit_timer (sk, TCP_TIME_PROBE0, + min(tp->rto << tp->backoff, TCP_RESOURCE_PROBE_INTERVAL)); + } } diff -ur --new-file old/linux/net/ipv4/tcp_timer.c new/linux/net/ipv4/tcp_timer.c --- old/linux/net/ipv4/tcp_timer.c Wed Sep 8 20:14:32 1999 +++ new/linux/net/ipv4/tcp_timer.c Sat Jan 22 20:54:57 2000 @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_timer.c,v 1.68 1999/09/07 02:31:43 davem Exp $ + * Version: $Id: tcp_timer.c,v 1.71 2000/01/18 08:24:19 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -23,29 +23,20 @@ #include int sysctl_tcp_syn_retries = TCP_SYN_RETRIES; +int sysctl_tcp_synack_retries = TCP_SYNACK_RETRIES; int sysctl_tcp_keepalive_time = TCP_KEEPALIVE_TIME; int sysctl_tcp_keepalive_probes = TCP_KEEPALIVE_PROBES; int sysctl_tcp_keepalive_intvl = TCP_KEEPALIVE_INTVL; int sysctl_tcp_retries1 = TCP_RETR1; int sysctl_tcp_retries2 = TCP_RETR2; +int sysctl_tcp_orphan_retries = TCP_ORPHAN_RETRIES; - -static void tcp_sltimer_handler(unsigned long); -static void tcp_syn_recv_timer(unsigned long); +static void tcp_retransmit_timer(unsigned long); +static void tcp_delack_timer(unsigned long); +static void tcp_probe_timer(unsigned long); +static void tcp_keepalive_timer (unsigned long data); static void tcp_twkill(unsigned long); -struct timer_list tcp_slow_timer = { - NULL, NULL, - 0, 0, - tcp_sltimer_handler, -}; - - -struct tcp_sl_timer tcp_slt_array[TCP_SLT_MAX] = { - {ATOMIC_INIT(0), TCP_SYNACK_PERIOD, 0, tcp_syn_recv_timer},/* SYNACK */ - {ATOMIC_INIT(0), TCP_TWKILL_PERIOD, 0, tcp_twkill} /* TWKILL */ -}; - const char timer_bug_msg[] = KERN_DEBUG "tcpbug: unknown timer value\n"; /* @@ -56,17 +47,25 @@ void tcp_init_xmit_timers(struct sock *sk) { - init_timer(&sk->tp_pinfo.af_tcp.retransmit_timer); - sk->tp_pinfo.af_tcp.retransmit_timer.function=&tcp_retransmit_timer; - sk->tp_pinfo.af_tcp.retransmit_timer.data = (unsigned long) sk; - - init_timer(&sk->tp_pinfo.af_tcp.delack_timer); - sk->tp_pinfo.af_tcp.delack_timer.function=&tcp_delack_timer; - sk->tp_pinfo.af_tcp.delack_timer.data = (unsigned long) sk; - - init_timer(&sk->tp_pinfo.af_tcp.probe_timer); - sk->tp_pinfo.af_tcp.probe_timer.function=&tcp_probe_timer; - sk->tp_pinfo.af_tcp.probe_timer.data = (unsigned long) sk; + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + + spin_lock_init(&sk->timer_lock); + + init_timer(&tp->retransmit_timer); + tp->retransmit_timer.function=&tcp_retransmit_timer; + tp->retransmit_timer.data = (unsigned long) sk; + + init_timer(&tp->delack_timer); + tp->delack_timer.function=&tcp_delack_timer; + tp->delack_timer.data = (unsigned long) sk; + + init_timer(&tp->probe_timer); + tp->probe_timer.function=&tcp_probe_timer; + tp->probe_timer.data = (unsigned long) sk; + + init_timer(&sk->timer); + sk->timer.function=&tcp_keepalive_timer; + sk->timer.data = (unsigned long) sk; } /* @@ -79,7 +78,7 @@ spin_lock_bh(&sk->timer_lock); switch (what) { - case TIME_RETRANS: + case TCP_TIME_RETRANS: /* When seting the transmit timer the probe timer * should not be set. * The delayed ack timer can be set if we are changing the @@ -89,29 +88,25 @@ __sock_put(sk); if (!tp->retransmit_timer.prev || !del_timer(&tp->retransmit_timer)) sock_hold(sk); - if (when > 120*HZ) { + if (when > TCP_RTO_MAX) { printk(KERN_DEBUG "reset_xmit_timer sk=%p when=0x%lx, caller=%p\n", sk, when, NET_CALLER(sk)); - when = 120*HZ; + when = TCP_RTO_MAX; } mod_timer(&tp->retransmit_timer, jiffies+when); break; - case TIME_DACK: + case TCP_TIME_DACK: if (!tp->delack_timer.prev || !del_timer(&tp->delack_timer)) sock_hold(sk); mod_timer(&tp->delack_timer, jiffies+when); break; - case TIME_PROBE0: + case TCP_TIME_PROBE0: if (!tp->probe_timer.prev || !del_timer(&tp->probe_timer)) sock_hold(sk); mod_timer(&tp->probe_timer, jiffies+when); break; - case TIME_WRITE: - printk(KERN_DEBUG "bug: tcp_reset_xmit_timer TIME_WRITE\n"); - break; - default: printk(KERN_DEBUG "bug: unknown timer value\n"); }; @@ -127,6 +122,7 @@ __sock_put(sk); if(tp->delack_timer.prev && del_timer(&tp->delack_timer)) __sock_put(sk); + tp->ack.blocked = 0; if(tp->probe_timer.prev && del_timer(&tp->probe_timer)) __sock_put(sk); if(sk->timer.prev && del_timer(&sk->timer)) @@ -134,39 +130,33 @@ spin_unlock_bh(&sk->timer_lock); } -static void tcp_write_err(struct sock *sk, int force) +static void tcp_write_err(struct sock *sk) { - sk->err = sk->err_soft ? sk->err_soft : ETIMEDOUT; + sk->err = sk->err_soft ? : ETIMEDOUT; sk->error_report(sk); - tcp_clear_xmit_timers(sk); - - /* Do not time wait the socket. It is timed out and, hence, - * idle for 120*HZ. "force" argument is ignored, delete - * it eventually. - */ - - /* Clean up time. */ - tcp_set_state(sk, TCP_CLOSE); tcp_done(sk); } /* A write timeout has occurred. Process the after effects. */ -static void tcp_write_timeout(struct sock *sk) +static int tcp_write_timeout(struct sock *sk) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + int retry_until; - /* Look for a 'soft' timeout. */ - if ((sk->state == TCP_ESTABLISHED && - tp->retransmits && (tp->retransmits % TCP_QUICK_TRIES) == 0) || - (sk->state != TCP_ESTABLISHED && tp->retransmits > sysctl_tcp_retries1)) { - /* NOTE. draft-ietf-tcpimpl-pmtud-01.txt requires pmtu black - hole detection. :-( - - It is place to make it. It is not made. I do not want - to make it. It is disguisting. It does not work in any - case. Let me to cite the same draft, which requires for - us to implement this: + if ((1<state)&(TCPF_SYN_SENT|TCPF_SYN_RECV)) { + if (tp->retransmits) + dst_negative_advice(&sk->dst_cache); + retry_until = tp->syn_retries ? : sysctl_tcp_syn_retries; + } else { + if (tp->retransmits >= sysctl_tcp_retries1) { + /* NOTE. draft-ietf-tcpimpl-pmtud-01.txt requires pmtu black + hole detection. :-( + + It is place to make it. It is not made. I do not want + to make it. It is disguisting. It does not work in any + case. Let me to cite the same draft, which requires for + us to implement this: "The one security concern raised by this memo is that ICMP black holes are often caused by over-zealous security administrators who block @@ -177,57 +167,70 @@ be far nicer to have all of the black holes fixed rather than fixing all of the TCP implementations." - Golden words :-). - */ + Golden words :-). + */ - dst_negative_advice(&sk->dst_cache); + dst_negative_advice(&sk->dst_cache); + } + retry_until = sysctl_tcp_retries2; + if (sk->dead) + retry_until = sysctl_tcp_orphan_retries; } - - /* Have we tried to SYN too many times (repent repent 8)) */ - if (sk->state == TCP_SYN_SENT && - ((!tp->syn_retries && tp->retransmits > sysctl_tcp_syn_retries) || - (tp->syn_retries && tp->retransmits > tp->syn_retries))) { - tcp_write_err(sk, 1); - /* Don't FIN, we got nothing back */ - } else if (tp->retransmits > sysctl_tcp_retries2) { + + if (tp->retransmits >= retry_until) { /* Has it gone just too far? */ - tcp_write_err(sk, 0); + tcp_write_err(sk); + return 1; } + return 0; } -void tcp_delack_timer(unsigned long data) +static void tcp_delack_timer(unsigned long data) { struct sock *sk = (struct sock*)data; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); bh_lock_sock(sk); if (sk->lock.users) { /* Try again later. */ - tcp_reset_xmit_timer(sk, TIME_DACK, HZ/5); + tp->ack.blocked = 1; + NET_INC_STATS_BH(DelayedACKLocked); + tcp_reset_xmit_timer(sk, TCP_TIME_DACK, TCP_DELACK_MIN); goto out_unlock; } - if(!sk->zapped && - sk->tp_pinfo.af_tcp.delayed_acks && - sk->state != TCP_CLOSE) + if (tp->ack.pending) { + /* Delayed ACK missed: inflate ATO, leave pingpong mode */ + tp->ack.ato = min(tp->ack.ato<<1, TCP_ATO_MAX); + tp->ack.pingpong = 0; tcp_send_ack(sk); + NET_INC_STATS_BH(DelayedACKs); + } + TCP_CHECK_TIMER(sk); out_unlock: bh_unlock_sock(sk); sock_put(sk); } -void tcp_probe_timer(unsigned long data) +static void tcp_probe_timer(unsigned long data) { struct sock *sk = (struct sock*)data; struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - - if(sk->zapped) - goto out; + int max_probes; bh_lock_sock(sk); if (sk->lock.users) { /* Try again later. */ - tcp_reset_xmit_timer(sk, TIME_PROBE0, HZ/5); + tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, HZ/5); + goto out_unlock; + } + + if (sk->state == TCP_CLOSE) + goto out_unlock; + + if (tp->packets_out || !tp->send_head) { + tp->probes_out = 0; goto out_unlock; } @@ -246,151 +249,251 @@ * with RFCs, only probe timer combines both retransmission timeout * and probe timeout in one bottle. --ANK */ - if (tp->probes_out > sysctl_tcp_retries2) { - tcp_write_err(sk, 0); + max_probes = sk->dead ? sysctl_tcp_orphan_retries : sysctl_tcp_retries2; + + if (tp->probes_out > max_probes) { + tcp_write_err(sk); } else { /* Only send another probe if we didn't close things up. */ tcp_send_probe0(sk); + TCP_CHECK_TIMER(sk); } out_unlock: bh_unlock_sock(sk); -out: sock_put(sk); } /* Kill off TIME_WAIT sockets once their lifetime has expired. */ -int tcp_tw_death_row_slot = 0; -static struct tcp_tw_bucket *tcp_tw_death_row[TCP_TWKILL_SLOTS] = - { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; -static spinlock_t tw_death_lock = SPIN_LOCK_UNLOCKED; +static int tcp_tw_death_row_slot = 0; +int tcp_tw_count = 0; +static struct tcp_tw_bucket *tcp_tw_death_row[TCP_TWKILL_SLOTS]; +static spinlock_t tw_death_lock = SPIN_LOCK_UNLOCKED; +static struct timer_list tcp_tw_timer = { function: tcp_twkill }; static void tcp_twkill(unsigned long data) { struct tcp_tw_bucket *tw; int killed = 0; - /* The death-row tw chains are only ever touched - * in BH context so no BH disabling (for now) is needed. + /* NOTE: compare this to previous version where lock + * was released after detaching chain. It was racy, + * because tw buckets are scheduled in not serialized context + * in 2.3 (with netfilter), and with softnet it is common, because + * soft irqs are not sequenced. */ spin_lock(&tw_death_lock); - tw = tcp_tw_death_row[tcp_tw_death_row_slot]; - tcp_tw_death_row[tcp_tw_death_row_slot] = NULL; - tcp_tw_death_row_slot = - ((tcp_tw_death_row_slot + 1) & (TCP_TWKILL_SLOTS - 1)); - spin_unlock(&tw_death_lock); - while(tw != NULL) { - struct tcp_tw_bucket *next = tw->next_death; + if (tcp_tw_count == 0) + goto out; + + while((tw = tcp_tw_death_row[tcp_tw_death_row_slot]) != NULL) { + tcp_tw_death_row[tcp_tw_death_row_slot] = tw->next_death; + tw->pprev_death = NULL; + spin_unlock(&tw_death_lock); tcp_timewait_kill(tw); tcp_tw_put(tw); + killed++; - tw = next; - } - if(killed != 0) { - struct tcp_sl_timer *slt = (struct tcp_sl_timer *)data; - atomic_sub(killed, &slt->count); + + spin_lock(&tw_death_lock); } + tcp_tw_death_row_slot = + ((tcp_tw_death_row_slot + 1) & (TCP_TWKILL_SLOTS - 1)); + + if ((tcp_tw_count -= killed) != 0) + mod_timer(&tcp_tw_timer, jiffies+TCP_TWKILL_PERIOD); + net_statistics[smp_processor_id()*2].TimeWaited += killed; +out: + spin_unlock(&tw_death_lock); } /* These are always called from BH context. See callers in * tcp_input.c to verify this. */ -void tcp_tw_schedule(struct tcp_tw_bucket *tw) -{ - struct tcp_tw_bucket **tpp; - int slot; +/* This is for handling early-kills of TIME_WAIT sockets. */ +void tcp_tw_deschedule(struct tcp_tw_bucket *tw) +{ spin_lock(&tw_death_lock); - slot = (tcp_tw_death_row_slot - 1) & (TCP_TWKILL_SLOTS - 1); - tpp = &tcp_tw_death_row[slot]; - if((tw->next_death = *tpp) != NULL) - (*tpp)->pprev_death = &tw->next_death; - *tpp = tw; - tw->pprev_death = tpp; - - tw->death_slot = slot; - atomic_inc(&tw->refcnt); + if (tw->pprev_death) { + if(tw->next_death) + tw->next_death->pprev_death = tw->pprev_death; + *tw->pprev_death = tw->next_death; + tw->pprev_death = NULL; + tcp_tw_put(tw); + if (--tcp_tw_count == 0) + del_timer(&tcp_tw_timer); + } spin_unlock(&tw_death_lock); - - tcp_inc_slow_timer(TCP_SLT_TWKILL); } -/* Happens rarely if at all, no care about scalability here. */ -void tcp_tw_reschedule(struct tcp_tw_bucket *tw) +/* Short-time timewait calendar */ + +static int tcp_twcal_hand = -1; +static int tcp_twcal_jiffie; +static void tcp_twcal_tick(unsigned long); +static struct timer_list tcp_twcal_timer = {NULL, NULL, 0, 0, tcp_twcal_tick,}; +static struct tcp_tw_bucket *tcp_twcal_row[TCP_TW_RECYCLE_SLOTS]; + +void tcp_tw_schedule(struct tcp_tw_bucket *tw, int timeo) { struct tcp_tw_bucket **tpp; int slot; + /* timeout := RTO * 3.5 + * + * 3.5 = 1+2+0.5 to wait for two retransmits. + * + * RATIONALE: if FIN arrived and we entered TIME-WAIT state, + * our ACK acking that FIN can be lost. If N subsequent retransmitted + * FINs (or previous seqments) are lost (probability of such event + * is p^(N+1), where p is probability to lose single packet and + * time to detect the loss is about RTO*(2^N - 1) with exponential + * backoff). Normal timewait length is calculated so, that we + * waited at least for one retransmitted FIN (maximal RTO is 120sec). + * [ BTW Linux. following BSD, violates this requirement waiting + * only for 60sec, we should wait at least for 240 secs. + * Well, 240 consumes too much of resources 8) + * ] + * This interval is not reduced to catch old duplicate and + * responces to our wandering segments living for two MSLs. + * However, if we use PAWS to detect + * old duplicates, we can reduce the interval to bounds required + * by RTO, rather than MSL. So, if peer understands PAWS, we + * kill tw bucket after 3.5*RTO (it is important that this number + * is greater than TS tick!) and detect old duplicates with help + * of PAWS. + */ + slot = (timeo + (1<> TCP_TW_RECYCLE_TICK; + spin_lock(&tw_death_lock); + + /* Unlink it, if it was scheduled */ if (tw->pprev_death) { if(tw->next_death) tw->next_death->pprev_death = tw->pprev_death; *tw->pprev_death = tw->next_death; tw->pprev_death = NULL; + tcp_tw_count--; } else atomic_inc(&tw->refcnt); - slot = (tcp_tw_death_row_slot - 1) & (TCP_TWKILL_SLOTS - 1); - tpp = &tcp_tw_death_row[slot]; + if (slot >= TCP_TW_RECYCLE_SLOTS) { + /* Schedule to slow timer */ + if (timeo >= TCP_TIMEWAIT_LEN) { + slot = TCP_TWKILL_SLOTS-1; + } else { + slot = (timeo + TCP_TWKILL_PERIOD-1) / TCP_TWKILL_PERIOD; + if (slot >= TCP_TWKILL_SLOTS) + slot = TCP_TWKILL_SLOTS-1; + } + tw->ttd = jiffies + timeo; + slot = (tcp_tw_death_row_slot + slot) & (TCP_TWKILL_SLOTS - 1); + tpp = &tcp_tw_death_row[slot]; + } else { + tw->ttd = jiffies + (slot< (slot<next_death = *tpp) != NULL) (*tpp)->pprev_death = &tw->next_death; *tpp = tw; tw->pprev_death = tpp; - tw->death_slot = slot; + if (tcp_tw_count++ == 0) + mod_timer(&tcp_tw_timer, jiffies+TCP_TWKILL_PERIOD); spin_unlock(&tw_death_lock); - - /* Timer was incremented when we first entered the table. */ } -/* This is for handling early-kills of TIME_WAIT sockets. */ -void tcp_tw_deschedule(struct tcp_tw_bucket *tw) +void tcp_twcal_tick(unsigned long dummy) { + int n, slot; + unsigned long j; + unsigned long now = jiffies; + int killed = 0; + int adv = 0; + spin_lock(&tw_death_lock); - if (tw->pprev_death) { - if(tw->next_death) - tw->next_death->pprev_death = tw->pprev_death; - *tw->pprev_death = tw->next_death; - tw->pprev_death = NULL; - tcp_tw_put(tw); + if (tcp_twcal_hand < 0) + goto out; + + slot = tcp_twcal_hand; + j = tcp_twcal_jiffie; + + for (n=0; nnext_death; + tw->pprev_death = NULL; + + tcp_timewait_kill(tw); + tcp_tw_put(tw); + killed++; + } + } else { + if (!adv) { + adv = 1; + tcp_twcal_jiffie = j; + tcp_twcal_hand = slot; + } + + if (tcp_twcal_row[slot] != NULL) { + mod_timer(&tcp_twcal_timer, j); + goto out; + } + } + j += (1<tp_pinfo.af_tcp; - /* We are reset. We will send no more retransmits. */ - if(sk->zapped) - goto out; - bh_lock_sock(sk); if (sk->lock.users) { /* Try again later */ - tcp_reset_xmit_timer(sk, TIME_RETRANS, HZ/20); + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, HZ/20); goto out_unlock; } - /* Clear delay ack timer. */ - tcp_clear_xmit_timer(sk, TIME_DACK); + if (sk->state == TCP_CLOSE || tp->packets_out == 0) + goto out_unlock; + + BUG_TRAP(!skb_queue_empty(&sk->write_queue)); + + if (tcp_write_timeout(sk)) + goto out_unlock; /* RFC 2018, clear all 'sacked' flags in retransmission queue, * the sender may have dropped out of order frames and we must @@ -426,11 +529,19 @@ tp->snd_cwnd = 1; } - tp->retransmits++; - tp->dup_acks = 0; tp->high_seq = tp->snd_nxt; - tcp_retransmit_skb(sk, skb_peek(&sk->write_queue)); + if (tcp_retransmit_skb(sk, skb_peek(&sk->write_queue)) > 0) { + /* Retransmission failed because of local congestion, + * do not backoff. + */ + if (!tp->retransmits) + tp->retransmits=1; + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, + min(tp->rto, TCP_RESOURCE_PROBE_INTERVAL)); + TCP_CHECK_TIMER(sk); + goto out_unlock; + } /* Increase the timeout each time we retransmit. Note that * we do not increase the rtt estimate. rto is initialized @@ -448,132 +559,105 @@ * the 120 second clamps though! */ tp->backoff++; - tp->rto = min(tp->rto << 1, 120*HZ); - tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto); - - tcp_write_timeout(sk); + tp->retransmits++; + tp->rto = min(tp->rto << 1, TCP_RTO_MAX); + tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); + TCP_CHECK_TIMER(sk); out_unlock: bh_unlock_sock(sk); -out: sock_put(sk); } /* - * Slow timer for SYN-RECV sockets + * Timer for listening sockets */ -static void tcp_do_syn_queue(struct sock *sk, struct tcp_opt *tp, unsigned long now) +static void tcp_synack_timer(struct sock *sk) { - struct open_request *prev, *req; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + struct tcp_listen_opt *lopt = tp->listen_opt; + int max_retries = tp->syn_retries ? : sysctl_tcp_synack_retries; + int thresh = max_retries; + unsigned long now = jiffies; + struct open_request **reqp, *req; + int i, budget; - prev = (struct open_request *) &tp->syn_wait_queue; - for(req = tp->syn_wait_queue; req; ) { - struct open_request *next = req->dl_next; - - if (!req->sk && (long)(now - req->expires) >= 0) { - tcp_synq_unlink(tp, req, prev); - if(req->retrans >= sysctl_tcp_retries1) { - (*req->class->destructor)(req); - tcp_dec_slow_timer(TCP_SLT_SYNACK); - tp->syn_backlog--; - tcp_openreq_free(req); - if (! tp->syn_wait_queue) - break; - } else { - unsigned long timeo; - struct open_request *rp; - - (*req->class->rtx_syn_ack)(sk, req); - req->retrans++; - timeo = min((TCP_TIMEOUT_INIT << req->retrans), - (120 * HZ)); - req->expires = now + timeo; - rp = prev->dl_next; - tcp_synq_queue(tp, req); - if(rp != prev->dl_next) - prev = prev->dl_next; - } - } else - prev = req; - req = next; - } -} + if (lopt == NULL || lopt->qlen == 0) + return; -/* This now scales very nicely. -DaveM */ -static void tcp_syn_recv_timer(unsigned long data) -{ - struct sock *sk; - unsigned long now = jiffies; - int i; + /* Normally all the openreqs are young and become mature + * (i.e. converted to established socket) for first timeout. + * If synack was not acknowledged for 3 seconds, it means + * one of the following things: synack was lost, ack was lost, + * rtt is high or nobody planned to ack (i.e. synflood). + * When server is a bit loaded, queue is populated with old + * open requests, reducing effective size of queue. + * When server is well loaded, queue size reduces to zero + * after several minutes of work. It is not synflood, + * it is normal operation. The solution is pruning + * too old entries overriding normal timeout, when + * situation becomes dangerous. + * + * Essentially, we reserve half of room for young + * embrions; and abort old ones without pity, if old + * ones are about to clog our table. + */ + if (lopt->qlen>>(lopt->max_qlen_log-1)) { + int young = (lopt->qlen_young<<1); - read_lock(&tcp_lhash_lock); - for(i = 0; i < TCP_LHTABLE_SIZE; i++) { - sk = tcp_listening_hash[i]; - while(sk) { - struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - - /* TCP_LISTEN is implied. */ - bh_lock_sock(sk); - if (!sk->lock.users && tp->syn_wait_queue) - tcp_do_syn_queue(sk, tp, now); - bh_unlock_sock(sk); - sk = sk->next; + while (thresh > 2) { + if (lopt->qlen < young) + break; + thresh--; + young <<= 1; } } - read_unlock(&tcp_lhash_lock); -} -void tcp_sltimer_handler(unsigned long data) -{ - struct tcp_sl_timer *slt = tcp_slt_array; - unsigned long next = ~0UL; - unsigned long now = jiffies; - int i; + if (tp->defer_accept) + max_retries = tp->defer_accept; - for (i=0; i < TCP_SLT_MAX; i++, slt++) { - if (atomic_read(&slt->count)) { - long trigger; - - trigger = slt->period - ((long)(now - slt->last)); - - if (trigger <= 0) { - (*slt->handler)((unsigned long) slt); - slt->last = now; - trigger = slt->period; - } + budget = 2*(TCP_SYNQ_HSIZE/(TCP_TIMEOUT_INIT/TCP_SYNQ_INTERVAL)); + i = lopt->clock_hand; - /* Only reschedule if some events remain. */ - if (atomic_read(&slt->count)) - next = min(next, trigger); + do { + reqp=&lopt->syn_table[i]; + while ((req = *reqp) != NULL) { + if ((long)(now - req->expires) >= 0) { + if ((req->retrans < thresh || + (req->acked && req->retrans < max_retries)) + && !req->class->rtx_syn_ack(sk, req, NULL)) { + unsigned long timeo; + + if (req->retrans++ == 0) + lopt->qlen_young--; + timeo = min((TCP_TIMEOUT_INIT << req->retrans), + TCP_RTO_MAX); + req->expires = now + timeo; + reqp = &req->dl_next; + continue; + } + + /* Drop this request */ + write_lock(&tp->syn_wait_lock); + *reqp = req->dl_next; + write_unlock(&tp->syn_wait_lock); + lopt->qlen--; + if (req->retrans == 0) + lopt->qlen_young--; + tcp_openreq_free(req); + } + reqp = &req->dl_next; } - } - if (next != ~0UL) - mod_timer(&tcp_slow_timer, (now + next)); -} -/* __tcp_inc_slow_timer is called when an slow timer is started - * first time (slt->count was 0). There is race condition between - * timer creation and deletion and if we do not force adding timer here, - * we might lose timer. We could avoid it with global spinlock, but - * it is apparently overkill, so that we restart timer ALWAYS when - * this function is entered, it guarantees that timer will not lost. - */ + i = (i+1)&(TCP_SYNQ_HSIZE-1); -void __tcp_inc_slow_timer(struct tcp_sl_timer *slt) -{ - unsigned long now = jiffies; - unsigned long when; - - slt->last = now; + } while (--budget > 0); - when = now + slt->period; + lopt->clock_hand = i; - if (tcp_slow_timer.prev && - (long)(tcp_slow_timer.expires - when) < 0) - when = tcp_slow_timer.expires; - - mod_timer(&tcp_slow_timer, when); + if (lopt->qlen) + tcp_reset_keepalive_timer(sk, TCP_SYNQ_INTERVAL); } void tcp_delete_keepalive_timer (struct sock *sk) @@ -595,6 +679,9 @@ void tcp_set_keepalive(struct sock *sk, int val) { + if ((1<state)&(TCPF_CLOSE|TCPF_LISTEN)) + return; + if (val && !sk->keepopen) tcp_reset_keepalive_timer(sk, keepalive_time_when(&sk->tp_pinfo.af_tcp)); else if (!val) @@ -602,7 +689,7 @@ } -void tcp_keepalive_timer (unsigned long data) +static void tcp_keepalive_timer (unsigned long data) { struct sock *sk = (struct sock *) data; struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; @@ -616,14 +703,31 @@ goto out; } - if (sk->state == TCP_FIN_WAIT2 && sk->dead) + if (sk->state == TCP_LISTEN) { + tcp_synack_timer(sk); + goto out; + } + + if (sk->state == TCP_FIN_WAIT2 && sk->dead) { + if (tp->linger2 >= 0) { + int tmo = tcp_fin_time(tp) - TCP_TIMEWAIT_LEN; + + if (tmo > 0) { + tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); + goto out; + } + } + tcp_send_active_reset(sk, GFP_ATOMIC); goto death; + } - if (!sk->keepopen) + if (!sk->keepopen || sk->state == TCP_CLOSE) goto out; elapsed = keepalive_time_when(tp); - if (!((1<state) & (TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_FIN_WAIT2))) + + /* It is alive without keepalive 8) */ + if (tp->packets_out || tp->send_head) goto resched; elapsed = tcp_time_stamp - tp->rcv_tstamp; @@ -632,28 +736,30 @@ if ((!tp->keepalive_probes && tp->probes_out >= sysctl_tcp_keepalive_probes) || (tp->keepalive_probes && tp->probes_out >= tp->keepalive_probes)) { tcp_send_active_reset(sk, GFP_ATOMIC); - tcp_write_err(sk, 1); + tcp_write_err(sk); goto out; } - tp->probes_out++; - tp->pending = TIME_KEEPOPEN; - tcp_write_wakeup(sk); - elapsed = keepalive_intvl_when(tp); + if (tcp_write_wakeup(sk) <= 0) { + tp->probes_out++; + elapsed = keepalive_intvl_when(tp); + } else { + /* If keepalive was lost due to local congestion, + * try harder. + */ + elapsed = TCP_RESOURCE_PROBE_INTERVAL; + } } else { /* It is tp->rcv_tstamp + keepalive_time_when(tp) */ - if (keepalive_time_when(tp) > elapsed) - elapsed = keepalive_time_when(tp) - elapsed; - else - elapsed = 0; + elapsed = keepalive_time_when(tp) - elapsed; } + TCP_CHECK_TIMER(sk); + resched: tcp_reset_keepalive_timer (sk, elapsed); goto out; death: - tcp_set_state(sk, TCP_CLOSE); - tcp_clear_xmit_timers(sk); tcp_done(sk); out: diff -ur --new-file old/linux/net/ipv4/udp.c new/linux/net/ipv4/udp.c --- old/linux/net/ipv4/udp.c Sun Jan 9 06:36:21 2000 +++ new/linux/net/ipv4/udp.c Sat Jan 22 20:54:57 2000 @@ -5,7 +5,7 @@ * * The User Datagram Protocol (UDP). * - * Version: $Id: udp.c,v 1.77 2000/01/09 02:19:44 davem Exp $ + * Version: $Id: udp.c,v 1.79 2000/01/18 08:24:20 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -369,30 +369,15 @@ } /* - * Various people wanted BSD UDP semantics. Well they've come - * back out because they slow down response to stuff like dead - * or unreachable name servers and they screw term users something - * chronic. Oh and it violates RFC1122. So basically fix your - * client code people. - */ - - /* * RFC1122: OK. Passes ICMP errors back to application, as per - * 4.1.3.3. After the comment above, that should be no surprise. - */ - - if (!harderr && !sk->protinfo.af_inet.recverr) - goto out; - - /* - * 4.x BSD compatibility item. Break RFC1122 to - * get BSD socket semantics. + * 4.1.3.3. */ - if(sk->bsdism && sk->state!=TCP_ESTABLISHED && !sk->protinfo.af_inet.recverr) - goto out; - - if (sk->protinfo.af_inet.recverr) + if (!sk->protinfo.af_inet.recverr) { + if (!harderr || sk->state != TCP_ESTABLISHED) + goto out; + } else { ip_icmp_error(sk, skb, err, uh->dest, info, (u8*)(uh+1)); + } sk->err = err; sk->error_report(sk); out: @@ -629,15 +614,13 @@ { switch(cmd) { - case TIOCOUTQ: + case SIOCOUTQ: { - unsigned long amount; - - amount = sock_wspace(sk); + int amount = atomic_read(&sk->wmem_alloc); return put_user(amount, (int *)arg); } - case TIOCINQ: + case SIOCINQ: { struct sk_buff *skb; unsigned long amount; @@ -663,6 +646,17 @@ return(0); } +static __inline__ int __udp_checksum_complete(struct sk_buff *skb) +{ + return (unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum)); +} + +static __inline__ int udp_checksum_complete(struct sk_buff *skb) +{ + return skb->ip_summed != CHECKSUM_UNNECESSARY && + __udp_checksum_complete(skb); +} + /* * This should be easy, if there is something there we * return it, otherwise we block. @@ -699,31 +693,21 @@ msg->msg_flags |= MSG_TRUNC; } -#ifndef CONFIG_UDP_DELAY_CSUM - err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov, - copied); -#else if (skb->ip_summed==CHECKSUM_UNNECESSARY) { err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov, copied); - } else if (copied > msg->msg_iov[0].iov_len || (msg->msg_flags&MSG_TRUNC)) { - if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum))) + } else if (msg->msg_flags&MSG_TRUNC) { + if (__udp_checksum_complete(skb)) goto csum_copy_err; err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov, copied); } else { - unsigned int csum; + err = copy_and_csum_toiovec(msg->msg_iov, skb, sizeof(struct udphdr)); - err = 0; - csum = csum_partial(skb->h.raw, sizeof(struct udphdr), skb->csum); - csum = csum_and_copy_to_user((char*)&skb->h.uh[1], msg->msg_iov[0].iov_base, - copied, csum, &err); if (err) - goto out_free; - if ((unsigned short)csum_fold(csum)) goto csum_copy_err; } -#endif + if (err) goto out_free; sk->stamp=skb->stamp; @@ -744,7 +728,6 @@ out: return err; -#ifdef CONFIG_UDP_DELAY_CSUM csum_copy_err: UDP_INC_STATS_BH(UdpInErrors); @@ -768,7 +751,6 @@ * as some normal condition. */ return (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH; -#endif } int udp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) @@ -831,9 +813,9 @@ * Charge it to the socket, dropping if the queue is full. */ -#if defined(CONFIG_FILTER) && defined(CONFIG_UDP_DELAY_CSUM) +#if defined(CONFIG_FILTER) if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) { - if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum))) { + if (__udp_checksum_complete(skb)) { UDP_INC_STATS_BH(UdpInErrors); IP_INC_STATS_BH(IpInDiscards); ip_statistics[smp_processor_id()*2].IpInDelivers--; @@ -855,12 +837,6 @@ return 0; } - -static inline void udp_deliver(struct sock *sk, struct sk_buff *skb) -{ - udp_queue_rcv_skb(sk, skb); -} - /* * Multicasts and broadcasts go to each listener. * @@ -889,7 +865,7 @@ skb1 = skb_clone(skb, GFP_ATOMIC); if(skb1) - udp_deliver(sk, skb1); + udp_queue_rcv_skb(sk, skb1); sk = sknext; } while(sknext); } else @@ -898,30 +874,25 @@ return 0; } -static int udp_checksum_verify(struct sk_buff *skb, struct udphdr *uh, - unsigned short ulen, u32 saddr, u32 daddr, - int full_csum_deferred) -{ - if (!full_csum_deferred) { - if (uh->check) { - if (skb->ip_summed == CHECKSUM_HW && - udp_check(uh, ulen, saddr, daddr, skb->csum)) - return -1; - if (skb->ip_summed == CHECKSUM_NONE && - udp_check(uh, ulen, saddr, daddr, - csum_partial((char *)uh, ulen, 0))) - return -1; - } - } else { - if (uh->check == 0) - skb->ip_summed = CHECKSUM_UNNECESSARY; - else if (skb->ip_summed == CHECKSUM_HW) { - if (udp_check(uh, ulen, saddr, daddr, skb->csum)) - return -1; - skb->ip_summed = CHECKSUM_UNNECESSARY; - } else if (skb->ip_summed != CHECKSUM_UNNECESSARY) - skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0); - } +/* Initialize UDP checksum. If exited with zero value (success), + * CHECKSUM_UNNECESSARY means, that no more checks are required. + * Otherwise, csum completion requires chacksumming packet body, + * including udp header and folding it to skb->csum. + */ +static int udp_checksum_init(struct sk_buff *skb, struct udphdr *uh, + unsigned short ulen, u32 saddr, u32 daddr) +{ + if (uh->check == 0) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + } else if (skb->ip_summed == CHECKSUM_HW) { + if (udp_check(uh, ulen, saddr, daddr, skb->csum)) + return -1; + skb->ip_summed = CHECKSUM_UNNECESSARY; + } else if (skb->ip_summed != CHECKSUM_UNNECESSARY) + skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0); + /* Probably, we should checksum udp header (it should be in cache + * in any case) and data in tiny packets (< rx copybreak). + */ return 0; } @@ -961,50 +932,33 @@ } skb_trim(skb, ulen); - if(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) { - int defer; + if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0) + goto csum_error; -#ifdef CONFIG_UDP_DELAY_CSUM - defer = 1; -#else - defer = 0; -#endif - if (udp_checksum_verify(skb, uh, ulen, saddr, daddr, defer)) - goto csum_error; + if(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) return udp_v4_mcast_deliver(skb, uh, saddr, daddr); - } sk = udp_v4_lookup(saddr, uh->source, daddr, uh->dest, skb->dev->ifindex); - - if (sk == NULL) { - /* No socket. Drop packet silently, if checksum is wrong */ - if (udp_checksum_verify(skb, uh, ulen, saddr, daddr, 0)) - goto csum_error; - - UDP_INC_STATS_BH(UdpNoPorts); - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); - - /* - * Hmm. We got an UDP packet to a port to which we - * don't wanna listen. Ignore it. - */ - kfree_skb(skb); - return(0); - } - if (udp_checksum_verify(skb, uh, ulen, saddr, daddr, -#ifdef CONFIG_UDP_DELAY_CSUM - 1 -#else - (sk->no_check & UDP_CSUM_NORCV) != 0 -#endif - )) { + + if (sk != NULL) { + udp_queue_rcv_skb(sk, skb); sock_put(sk); - goto csum_error; + return 0; } - udp_deliver(sk, skb); - __sock_put(sk); - return 0; + /* No socket. Drop packet silently, if checksum is wrong */ + if (udp_checksum_complete(skb)) + goto csum_error; + + UDP_INC_STATS_BH(UdpNoPorts); + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); + + /* + * Hmm. We got an UDP packet to a port to which we + * don't wanna listen. Ignore it. + */ + kfree_skb(skb); + return(0); csum_error: /* @@ -1090,10 +1044,6 @@ udp_connect, /* connect */ udp_disconnect, /* disconnect */ NULL, /* accept */ - NULL, /* retransmit */ - NULL, /* write_wakeup */ - NULL, /* read_wakeup */ - datagram_poll, /* poll */ udp_ioctl, /* ioctl */ NULL, /* init */ NULL, /* destroy */ @@ -1107,7 +1057,5 @@ udp_v4_hash, /* hash */ udp_v4_unhash, /* unhash */ udp_v4_get_port, /* good_socknum */ - 128, /* max_header */ - 0, /* retransmits */ "UDP", /* name */ }; diff -ur --new-file old/linux/net/ipv6/addrconf.c new/linux/net/ipv6/addrconf.c --- old/linux/net/ipv6/addrconf.c Fri Jan 14 20:25:21 2000 +++ new/linux/net/ipv6/addrconf.c Sat Jan 22 20:54:58 2000 @@ -6,7 +6,7 @@ * Pedro Roque * Alexey Kuznetsov * - * $Id: addrconf.c,v 1.55 1999/12/15 22:39:40 davem Exp $ + * $Id: addrconf.c,v 1.57 2000/01/18 08:24:21 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -682,6 +682,23 @@ } return -1; } + +static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev) +{ + int err = -1; + struct inet6_ifaddr *ifp; + + read_lock_bh(&idev->lock); + for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) { + if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) { + memcpy(eui, ifp->addr.s6_addr+8, 8); + err = 0; + break; + } + } + read_unlock_bh(&idev->lock); + return err; +} #endif /* @@ -859,7 +876,8 @@ #ifdef CONFIG_IPV6_EUI64 if (pinfo->prefix_len == 64) { memcpy(&addr, &pinfo->prefix, 8); - if (ipv6_generate_eui64(addr.s6_addr + 8, dev)) { + if (ipv6_generate_eui64(addr.s6_addr + 8, dev) && + ipv6_inherit_eui64(addr.s6_addr + 8, in6_dev)) { in6_dev_put(in6_dev); return; } @@ -1519,7 +1537,7 @@ */ if (ifp->idev->cnf.forwarding == 0 && - (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) == 0 && + (dev->flags&IFF_LOOPBACK) == 0 && (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) { struct in6_addr all_routers; diff -ur --new-file old/linux/net/ipv6/af_inet6.c new/linux/net/ipv6/af_inet6.c --- old/linux/net/ipv6/af_inet6.c Thu Dec 23 04:55:38 1999 +++ new/linux/net/ipv6/af_inet6.c Sat Jan 22 20:54:58 2000 @@ -7,7 +7,7 @@ * * Adapted from linux/net/ipv4/af_inet.c * - * $Id: af_inet6.c,v 1.49 1999/12/15 22:39:43 davem Exp $ + * $Id: af_inet6.c,v 1.52 2000/01/18 08:24:21 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -85,13 +85,17 @@ extern void ipv6_sysctl_unregister(void); #endif +#ifdef INET_REFCNT_DEBUG atomic_t inet6_sock_nr; +#endif static void inet6_sock_destruct(struct sock *sk) { inet_sock_destruct(sk); +#ifdef INET_REFCNT_DEBUG atomic_dec(&inet6_sock_nr); +#endif MOD_DEC_USE_COUNT; } @@ -140,9 +144,6 @@ sk->prot = prot; sk->backlog_rcv = prot->backlog_rcv; - sk->timer.data = (unsigned long)sk; - sk->timer.function = &tcp_keepalive_timer; - sk->net_pinfo.af_inet6.hop_limit = -1; sk->net_pinfo.af_inet6.mcast_hops = -1; sk->net_pinfo.af_inet6.mc_loop = 1; @@ -158,8 +159,16 @@ sk->protinfo.af_inet.mc_index = 0; sk->protinfo.af_inet.mc_list = NULL; + if (ipv4_config.no_pmtu_disc) + sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT; + else + sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT; + + +#ifdef INET_REFCNT_DEBUG atomic_inc(&inet6_sock_nr); atomic_inc(&inet_sock_nr); +#endif MOD_INC_USE_COUNT; if (sk->type==SOCK_RAW && protocol==IPPROTO_RAW) @@ -421,7 +430,7 @@ sock_no_socketpair, /* a do nothing */ inet_accept, /* ok */ inet6_getname, - inet_poll, /* ok */ + tcp_poll, /* ok */ inet6_ioctl, /* must change */ inet_listen, /* ok */ inet_shutdown, /* ok */ diff -ur --new-file old/linux/net/ipv6/icmp.c new/linux/net/ipv6/icmp.c --- old/linux/net/ipv6/icmp.c Sun Jan 9 06:36:21 2000 +++ new/linux/net/ipv6/icmp.c Sat Jan 22 20:54:58 2000 @@ -5,7 +5,7 @@ * Authors: * Pedro Roque * - * $Id: icmp.c,v 1.25 2000/01/09 02:19:54 davem Exp $ + * $Id: icmp.c,v 1.26 2000/01/19 04:06:19 davem Exp $ * * Based on net/ipv4/icmp.c * @@ -146,19 +146,19 @@ */ if (offset) { - csum = csum_partial_copy((void *) msg->data + - offset - sizeof(struct icmp6hdr), - buff, len, msg->csum); + csum = csum_partial_copy_nocheck((void *) msg->data + + offset - sizeof(struct icmp6hdr), + buff, len, msg->csum); msg->csum = csum; return 0; } - csum = csum_partial_copy((void *) &msg->icmph, buff, - sizeof(struct icmp6hdr), msg->csum); + csum = csum_partial_copy_nocheck((void *) &msg->icmph, buff, + sizeof(struct icmp6hdr), msg->csum); - csum = csum_partial_copy((void *) msg->data, - buff + sizeof(struct icmp6hdr), - len - sizeof(struct icmp6hdr), csum); + csum = csum_partial_copy_nocheck((void *) msg->data, + buff + sizeof(struct icmp6hdr), + len - sizeof(struct icmp6hdr), csum); icmph = (struct icmp6hdr *) buff; diff -ur --new-file old/linux/net/ipv6/ip6_fib.c new/linux/net/ipv6/ip6_fib.c --- old/linux/net/ipv6/ip6_fib.c Tue Aug 31 20:23:03 1999 +++ new/linux/net/ipv6/ip6_fib.c Sat Jan 22 20:54:58 2000 @@ -5,7 +5,7 @@ * Authors: * Pedro Roque * - * $Id: ip6_fib.c,v 1.19 1999/08/31 07:04:00 davem Exp $ + * $Id: ip6_fib.c,v 1.20 2000/01/16 05:11:37 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -926,8 +926,8 @@ #if RT6_DEBUG >= 2 if (rt->u.dst.obsolete>0) { - BUG_TRAP(rt->u.dst.obsolete<=0); - return -EFAULT; + BUG_TRAP(fn==NULL || rt->u.dst.obsolete<=0); + return -ENOENT; } #endif if (fn == NULL || rt == &ip6_null_entry) diff -ur --new-file old/linux/net/ipv6/ipv6_sockglue.c new/linux/net/ipv6/ipv6_sockglue.c --- old/linux/net/ipv6/ipv6_sockglue.c Sun Jan 9 06:36:21 2000 +++ new/linux/net/ipv6/ipv6_sockglue.c Sat Jan 22 20:54:58 2000 @@ -7,7 +7,7 @@ * * Based on linux/net/ipv4/ip_sockglue.c * - * $Id: ipv6_sockglue.c,v 1.30 2000/01/09 02:19:49 davem Exp $ + * $Id: ipv6_sockglue.c,v 1.31 2000/01/16 05:11:38 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -192,7 +192,9 @@ kfree_skb(pktopt); sk->destruct = inet_sock_destruct; +#ifdef INET_REFCNT_DEBUG atomic_dec(&inet6_sock_nr); +#endif MOD_DEC_USE_COUNT; retv = 0; break; @@ -271,7 +273,7 @@ if (sk->type == SOCK_STREAM) { if (opt) { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - if ((tcp_connected(sk->state) || sk->state == TCP_SYN_SENT) + if (!((1<state)&(TCPF_LISTEN|TCPF_CLOSE)) && sk->daddr != LOOPBACK4_IPV6) { tp->ext_header_len = opt->opt_flen + opt->opt_nflen; tcp_sync_mss(sk, tp->pmtu_cookie); diff -ur --new-file old/linux/net/ipv6/mcast.c new/linux/net/ipv6/mcast.c --- old/linux/net/ipv6/mcast.c Sun Jan 9 06:36:21 2000 +++ new/linux/net/ipv6/mcast.c Sat Jan 22 20:54:58 2000 @@ -5,7 +5,7 @@ * Authors: * Pedro Roque * - * $Id: mcast.c,v 1.28 2000/01/09 02:19:50 davem Exp $ + * $Id: mcast.c,v 1.29 2000/01/18 08:24:21 davem Exp $ * * Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c * @@ -500,7 +500,8 @@ if (dev->hard_header) { unsigned char ha[MAX_ADDR_LEN]; ndisc_mc_map(snd_addr, ha, dev, 1); - dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, full_len); + if (dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, full_len) < 0) + goto out; } if (ipv6_get_lladdr(dev, &addr_buf)) { @@ -508,7 +509,7 @@ printk(KERN_DEBUG "igmp6: %s no linklocal address\n", dev->name); #endif - return; + goto out; } ip6_nd_hdr(sk, skb, dev, &addr_buf, snd_addr, NEXTHDR_HOP, payload_len); @@ -532,6 +533,10 @@ else ICMP6_INC_STATS(Icmp6OutGroupMembResponses); ICMP6_INC_STATS(Icmp6OutMsgs); + return; + +out: + kfree_skb(skb); } static void igmp6_join_group(struct ifmcaddr6 *ma) diff -ur --new-file old/linux/net/ipv6/raw.c new/linux/net/ipv6/raw.c --- old/linux/net/ipv6/raw.c Sun Jan 9 06:36:21 2000 +++ new/linux/net/ipv6/raw.c Sat Jan 22 20:54:58 2000 @@ -7,7 +7,7 @@ * * Adapted from linux/net/ipv4/raw.c * - * $Id: raw.c,v 1.31 2000/01/09 02:19:50 davem Exp $ + * $Id: raw.c,v 1.33 2000/01/18 08:24:22 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -763,10 +763,6 @@ udpv6_connect, /* connect */ udp_disconnect, /* disconnect */ NULL, /* accept */ - NULL, /* retransmit */ - NULL, /* write_wakeup */ - NULL, /* read_wakeup */ - datagram_poll, /* poll */ NULL, /* ioctl */ rawv6_init_sk, /* init */ inet6_destroy_sock, /* destroy */ @@ -780,7 +776,5 @@ raw_v6_hash, /* hash */ raw_v6_unhash, /* unhash */ NULL, /* get_port */ - 128, /* max_header */ - 0, /* retransmits */ "RAW", /* name */ }; diff -ur --new-file old/linux/net/ipv6/route.c new/linux/net/ipv6/route.c --- old/linux/net/ipv6/route.c Sun Jan 9 06:36:21 2000 +++ new/linux/net/ipv6/route.c Sat Jan 22 20:54:58 2000 @@ -5,7 +5,7 @@ * Authors: * Pedro Roque * - * $Id: route.c,v 1.44 2000/01/09 02:19:51 davem Exp $ + * $Id: route.c,v 1.45 2000/01/16 05:11:38 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -93,7 +93,7 @@ struct rt6_info ip6_null_entry = { {{NULL, ATOMIC_INIT(1), 1, &loopback_dev, - -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -ENETUNREACH, NULL, NULL, ip6_pkt_discard, ip6_pkt_discard, #ifdef CONFIG_NET_CLS_ROUTE @@ -296,6 +296,7 @@ rt->rt6i_dst.plen = 128; rt->rt6i_flags |= RTF_CACHE; + rt->u.dst.flags |= DST_HOST; #ifdef CONFIG_IPV6_SUBTREES if (rt->rt6i_src.plen && saddr) { @@ -687,6 +688,8 @@ ipv6_addr_copy(&rt->rt6i_dst.addr, &rtmsg->rtmsg_dst); rt->rt6i_dst.plen = rtmsg->rtmsg_dst_len; + if (rt->rt6i_dst.plen == 128) + rt->u.dst.flags = DST_HOST; ipv6_wash_prefix(&rt->rt6i_dst.addr, rt->rt6i_dst.plen); #ifdef CONFIG_IPV6_SUBTREES @@ -940,6 +943,7 @@ ipv6_addr_copy(&nrt->rt6i_dst.addr, dest); nrt->rt6i_dst.plen = 128; + nrt->u.dst.flags |= DST_HOST; ipv6_addr_copy(&nrt->rt6i_gateway, (struct in6_addr*)neigh->primary_key); nrt->rt6i_nexthop = neigh_clone(neigh); @@ -1025,6 +1029,7 @@ goto out; ipv6_addr_copy(&nrt->rt6i_dst.addr, daddr); nrt->rt6i_dst.plen = 128; + nrt->u.dst.flags |= DST_HOST; nrt->rt6i_nexthop = neigh_clone(rt->rt6i_nexthop); dst_set_expires(&rt->u.dst, ip6_rt_mtu_expires); nrt->rt6i_flags |= RTF_DYNAMIC|RTF_CACHE|RTF_EXPIRES; @@ -1045,7 +1050,7 @@ struct rt6_info *rt; rt = dst_alloc(&ip6_dst_ops); - + if (rt) { rt->u.dst.input = ort->u.dst.input; rt->u.dst.output = ort->u.dst.output; @@ -1193,7 +1198,8 @@ rt = dst_alloc(&ip6_dst_ops); if (rt == NULL) return -ENOMEM; - + + rt->u.dst.flags = DST_HOST; rt->u.dst.input = ip6_input; rt->u.dst.output = ip6_output; rt->rt6i_dev = dev_get_by_name("lo"); diff -ur --new-file old/linux/net/ipv6/tcp_ipv6.c new/linux/net/ipv6/tcp_ipv6.c --- old/linux/net/ipv6/tcp_ipv6.c Sun Jan 9 06:36:21 2000 +++ new/linux/net/ipv6/tcp_ipv6.c Sat Jan 22 20:54:58 2000 @@ -5,7 +5,7 @@ * Authors: * Pedro Roque * - * $Id: tcp_ipv6.c,v 1.116 2000/01/09 02:19:52 davem Exp $ + * $Id: tcp_ipv6.c,v 1.118 2000/01/18 08:24:22 davem Exp $ * * Based on: * linux/net/ipv4/tcp.c @@ -46,11 +46,6 @@ #include -extern int sysctl_max_syn_backlog; -extern int sysctl_tcp_tw_recycle; -extern __u32 sysctl_wmem_max; -extern __u32 sysctl_rmem_max; - static void tcp_v6_send_reset(struct sk_buff *skb); static void tcp_v6_or_send_ack(struct sk_buff *skb, struct open_request *req); static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, @@ -58,11 +53,6 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); static int tcp_v6_xmit(struct sk_buff *skb); -static struct open_request *tcp_v6_search_req(struct tcp_opt *tp, - struct ipv6hdr *ip6h, - struct tcphdr *th, - int iif, - struct open_request **prevp); static struct tcp_func ipv6_mapped; static struct tcp_func ipv6_specific; @@ -282,9 +272,10 @@ * * The sockhash lock must be held as a reader here. */ -static inline struct sock *__tcp_v6_lookup(struct in6_addr *saddr, u16 sport, - struct in6_addr *daddr, u16 hnum, - int dif) + +static inline struct sock *__tcp_v6_lookup_established(struct in6_addr *saddr, u16 sport, + struct in6_addr *daddr, u16 hnum, + int dif) { struct tcp_ehash_bucket *head; struct sock *sk; @@ -314,8 +305,7 @@ } } read_unlock(&head->lock); - - return tcp_v6_lookup_listener(daddr, hnum, dif); + return NULL; hit: sock_hold(sk); @@ -323,6 +313,21 @@ return sk; } + +static inline struct sock *__tcp_v6_lookup(struct in6_addr *saddr, u16 sport, + struct in6_addr *daddr, u16 hnum, + int dif) +{ + struct sock *sk; + + sk = __tcp_v6_lookup_established(saddr, sport, daddr, hnum, dif); + + if (sk) + return sk; + + return tcp_v6_lookup_listener(daddr, hnum, dif); +} + #define tcp_v6_lookup(sa, sp, da, dp, dif) \ ({ struct sock *___sk; \ local_bh_disable(); \ @@ -331,6 +336,46 @@ ___sk; \ }) + +/* + * Open request hash tables. + */ + +static __inline__ unsigned tcp_v6_synq_hash(struct in6_addr *raddr, u16 rport) +{ + unsigned h = raddr->s6_addr32[3] ^ rport; + h ^= h>>16; + h ^= h>>8; + return h&(TCP_SYNQ_HSIZE-1); +} + +static struct open_request *tcp_v6_search_req(struct tcp_opt *tp, + struct ipv6hdr *ip6h, + struct tcphdr *th, + int iif, + struct open_request ***prevp) +{ + struct tcp_listen_opt *lopt = tp->listen_opt; + struct open_request *req, **prev; + __u16 rport = th->source; + + for (prev = &lopt->syn_table[tcp_v6_synq_hash(&ip6h->saddr, rport)]; + (req = *prev) != NULL; + prev = &req->dl_next) { + if (req->rmt_port == rport && + req->class->family == AF_INET6 && + !ipv6_addr_cmp(&req->af.v6_req.rmt_addr, &ip6h->saddr) && + !ipv6_addr_cmp(&req->af.v6_req.loc_addr, &ip6h->daddr) && + (!req->af.v6_req.iif || req->af.v6_req.iif == iif)) { + BUG_TRAP(req->sk == NULL); + *prevp = prev; + return req; + } + } + + return NULL; +} + static __inline__ u16 tcp_v6_check(struct tcphdr *th, int len, struct in6_addr *saddr, struct in6_addr *daddr, @@ -375,10 +420,10 @@ !ipv6_addr_cmp(&tw->v6_daddr, saddr) && !ipv6_addr_cmp(&tw->v6_rcv_saddr, daddr) && sk2->bound_dev_if == sk->bound_dev_if) { -#ifdef CONFIG_TCP_TW_RECYCLE struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - if (sysctl_tcp_tw_recycle && tw->ts_recent_stamp) { + if (tw->substate == TCP_TIME_WAIT && + sysctl_tcp_tw_recycle && tw->ts_recent_stamp) { /* See comment in tcp_ipv4.c */ if ((tp->write_seq = tw->snd_nxt + 2) == 0) tp->write_seq = 1; @@ -388,8 +433,7 @@ skp = &head->chain; goto unique; } else -#endif - goto not_unique; + goto not_unique; } } tw = NULL; @@ -399,9 +443,7 @@ goto not_unique; } -#ifdef CONFIG_TCP_TW_RECYCLE unique: -#endif BUG_TRAP(sk->pprev==NULL); if ((sk->next = *skp) != NULL) (*skp)->pprev = &sk->next; @@ -411,17 +453,16 @@ sock_prot_inc_use(sk->prot); write_unlock_bh(&head->lock); -#ifdef CONFIG_TCP_TW_RECYCLE if (tw) { /* Silly. Should hash-dance instead... */ local_bh_disable(); tcp_tw_deschedule(tw); tcp_timewait_kill(tw); + NET_INC_STATS_BH(TimeWaitRecycled); local_bh_enable(); tcp_tw_put(tw); } -#endif return 0; not_unique: @@ -467,9 +508,6 @@ int addr_type; int err; - if (sk->state != TCP_CLOSE) - return(-EISCONN); - if (addr_len < sizeof(struct sockaddr_in6)) return(-EINVAL); @@ -501,18 +539,11 @@ if(addr_type & IPV6_ADDR_MULTICAST) return -ENETUNREACH; - /* We may need to bind the socket. */ - if (sk->num==0 && sk->prot->get_port(sk, 0)) - return -EAGAIN; - sk->sport = htons(sk->num); - -#ifdef CONFIG_TCP_TW_RECYCLE if (tp->ts_recent_stamp && ipv6_addr_cmp(&np->daddr, &usin->sin6_addr)) { tp->ts_recent = 0; tp->ts_recent_stamp = 0; tp->write_seq = 0; } -#endif ipv6_addr_copy(&np->daddr, &usin->sin6_addr); np->flow_label = fl.fl6_flowlabel; @@ -602,8 +633,7 @@ tp->mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); err = -ENOBUFS; - buff = sock_wmalloc(sk, (MAX_HEADER + sk->prot->max_header), - 0, GFP_KERNEL); + buff = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 0, GFP_KERNEL); if (buff == NULL) goto failure; @@ -629,46 +659,6 @@ return err; } -static int tcp_v6_sendmsg(struct sock *sk, struct msghdr *msg, int len) -{ - struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6; - int retval = -EINVAL; - - lock_sock(sk); - /* - * Do sanity checking for sendmsg/sendto/send - */ - - if (msg->msg_flags & ~(MSG_OOB|MSG_DONTROUTE|MSG_DONTWAIT|MSG_NOSIGNAL)) - goto out; - if (msg->msg_name) { - struct sockaddr_in6 *addr=(struct sockaddr_in6 *)msg->msg_name; - - if (msg->msg_namelen < sizeof(*addr)) - goto out; - - if (addr->sin6_family && addr->sin6_family != AF_INET6) - goto out; - retval = -ENOTCONN; - - if(sk->state == TCP_CLOSE) - goto out; - retval = -EISCONN; - if (addr->sin6_port != sk->dport) - goto out; - if (ipv6_addr_cmp(&addr->sin6_addr, &np->daddr)) - goto out; - if (np->sndflow && np->flow_label != (addr->sin6_flowinfo&IPV6_FLOWINFO_MASK)) - goto out; - } - - retval = tcp_do_sendmsg(sk, msg); - -out: - release_sock(sk); - return retval; -} - void tcp_v6_err(struct sk_buff *skb, struct ipv6hdr *hdr, struct inet6_skb_parm *opt, int type, int code, unsigned char *header, __u32 info) @@ -701,6 +691,9 @@ if (sk->lock.users) NET_INC_STATS_BH(LockDroppedIcmps); + if (sk->state == TCP_CLOSE) + goto out; + tp = &sk->tp_pinfo.af_tcp; seq = ntohl(th->seq); if (sk->state != TCP_LISTEN && !between(seq, tp->snd_una, tp->snd_nxt)) { @@ -719,7 +712,7 @@ goto out; /* icmp should have updated the destination cache entry */ - dst = sk_dst_check(sk, np->dst_cookie); + dst = __sk_dst_check(sk, np->dst_cookie); if (dst == NULL) { struct flowi fl; @@ -736,7 +729,8 @@ fl.uli_u.ports.sport = sk->sport; dst = ip6_route_output(sk, &fl); - } + } else + dst_clone(dst); if (dst->error) { sk->err_soft = -dst->error; @@ -752,7 +746,7 @@ /* Might be for an open_request */ switch (sk->state) { - struct open_request *req, *prev; + struct open_request *req, **prev; struct ipv6hdr hd; case TCP_LISTEN: if (sk->lock.users) @@ -765,35 +759,19 @@ if (!req) goto out; - if (req->sk) { - struct sock *nsk = req->sk; - - sock_hold(nsk); - bh_unlock_sock(sk); - sock_put(sk); - sk = nsk; - - BUG_TRAP(sk->lock.users==0); - - tp = &sk->tp_pinfo.af_tcp; - if (!between(seq, tp->snd_una, tp->snd_nxt)) { - NET_INC_STATS_BH(OutOfWindowIcmps); - goto out; - } - } else { - if (seq != req->snt_isn) { - NET_INC_STATS_BH(OutOfWindowIcmps); - goto out; - } + /* ICMPs are not backlogged, hence we cannot get + * an established socket here. + */ + BUG_TRAP(req->sk == NULL); - tp->syn_backlog--; - tcp_synq_unlink(tp, req, prev); - tcp_dec_slow_timer(TCP_SLT_SYNACK); - req->class->destructor(req); - tcp_openreq_free(req); + if (seq != req->snt_isn) { + NET_INC_STATS_BH(OutOfWindowIcmps); goto out; } - break; + + tcp_synq_drop(sk, req, prev); + goto out; + case TCP_SYN_SENT: case TCP_SYN_RECV: /* Cannot happen. It can, it SYNs are crossed. --ANK */ @@ -802,7 +780,6 @@ sk->err = err; sk->error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ - tcp_set_state(sk, TCP_CLOSE); tcp_done(sk); } else { sk->err_soft = err; @@ -823,12 +800,13 @@ } -static void tcp_v6_send_synack(struct sock *sk, struct open_request *req) +static int tcp_v6_send_synack(struct sock *sk, struct open_request *req, + struct dst_entry *dst) { struct sk_buff * skb; - struct dst_entry *dst; struct ipv6_txoptions *opt = NULL; struct flowi fl; + int err = -1; fl.proto = IPPROTO_TCP; fl.nl_u.ip6_u.daddr = &req->af.v6_req.rmt_addr; @@ -838,24 +816,26 @@ fl.uli_u.ports.dport = req->rmt_port; fl.uli_u.ports.sport = sk->sport; - opt = sk->net_pinfo.af_inet6.opt; - if (opt == NULL && - sk->net_pinfo.af_inet6.rxopt.bits.srcrt == 2 && - req->af.v6_req.pktopts) { - struct sk_buff *pktopts = req->af.v6_req.pktopts; - struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)pktopts->cb; - if (rxopt->srcrt) - opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt)); - } + if (dst == NULL) { + opt = sk->net_pinfo.af_inet6.opt; + if (opt == NULL && + sk->net_pinfo.af_inet6.rxopt.bits.srcrt == 2 && + req->af.v6_req.pktopts) { + struct sk_buff *pktopts = req->af.v6_req.pktopts; + struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)pktopts->cb; + if (rxopt->srcrt) + opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt)); + } - if (opt && opt->srcrt) { - struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; - fl.nl_u.ip6_u.daddr = rt0->addr; - } + if (opt && opt->srcrt) { + struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; + fl.nl_u.ip6_u.daddr = rt0->addr; + } - dst = ip6_route_output(sk, &fl); - if (dst->error) - goto done; + dst = ip6_route_output(sk, &fl); + if (dst->error) + goto done; + } skb = tcp_make_synack(sk, dst, req); if (skb) { @@ -866,21 +846,22 @@ csum_partial((char *)th, skb->len, skb->csum)); fl.nl_u.ip6_u.daddr = &req->af.v6_req.rmt_addr; - ip6_xmit(sk, skb, &fl, opt); + err = ip6_xmit(sk, skb, &fl, opt); + if (err == NET_XMIT_CN) + err = 0; } done: dst_release(dst); if (opt && opt != sk->net_pinfo.af_inet6.opt) sock_kfree_s(sk, opt, opt->tot_len); + return err; } static void tcp_v6_or_free(struct open_request *req) { - if (req->af.v6_req.pktopts) { + if (req->af.v6_req.pktopts) kfree_skb(req->af.v6_req.pktopts); - req->af.v6_req.pktopts = NULL; - } } static struct or_calltable or_ipv6 = { @@ -907,127 +888,322 @@ } -#define BACKLOG(sk) ((sk)->tp_pinfo.af_tcp.syn_backlog) /* lvalue! */ -#define BACKLOGMAX(sk) sysctl_max_syn_backlog +static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, + struct sk_buff *skb) +{ + struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6; + th->check = 0; + + th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, + csum_partial((char *)th, th->doff<<2, + skb->csum)); +} -/* FIXME: this is substantially similar to the ipv4 code. - * Can some kind of merge be done? -- erics - */ -static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) + +static void tcp_v6_send_reset(struct sk_buff *skb) { - struct tcp_opt tp; - struct open_request *req; - __u32 isn = TCP_SKB_CB(skb)->when; + struct tcphdr *th = skb->h.th, *t1; + struct sk_buff *buff; + struct flowi fl; - if (skb->protocol == __constant_htons(ETH_P_IP)) - return tcp_v4_conn_request(sk, skb); + if (th->rst) + return; - /* FIXME: do the same check for anycast */ if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) - goto drop; - - if (isn == 0) - isn = tcp_v6_init_sequence(sk,skb); + return; /* - * There are no SYN attacks on IPv6, yet... + * We need to grab some memory, and put together an RST, + * and then put it into the queue to be sent. */ - if (BACKLOG(sk) >= BACKLOGMAX(sk)) { - (void)(net_ratelimit() && - printk(KERN_INFO "droping syn ack:%d max:%d\n", - BACKLOG(sk), BACKLOGMAX(sk))); - goto drop; - } - - req = tcp_openreq_alloc(); - if (req == NULL) { - goto drop; - } - - BACKLOG(sk)++; - - req->rcv_wnd = 0; /* So that tcp_send_synack() knows! */ - req->rcv_isn = TCP_SKB_CB(skb)->seq; - req->snt_isn = isn; - tp.tstamp_ok = tp.sack_ok = tp.wscale_ok = tp.snd_wscale = 0; + buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr), GFP_ATOMIC); + if (buff == NULL) + return; - tp.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); - tp.user_mss = sk->tp_pinfo.af_tcp.user_mss; + skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr)); - tcp_parse_options(NULL, skb->h.th, &tp, 0); + t1 = (struct tcphdr *) skb_push(buff,sizeof(struct tcphdr)); - req->mss = tp.mss_clamp; - req->ts_recent = tp.saw_tstamp ? tp.rcv_tsval : 0; - req->tstamp_ok = tp.tstamp_ok; - req->sack_ok = tp.sack_ok; - req->snd_wscale = tp.snd_wscale; - req->wscale_ok = tp.wscale_ok; - req->rmt_port = skb->h.th->source; - ipv6_addr_copy(&req->af.v6_req.rmt_addr, &skb->nh.ipv6h->saddr); - ipv6_addr_copy(&req->af.v6_req.loc_addr, &skb->nh.ipv6h->daddr); - req->af.v6_req.pktopts = NULL; - if (ipv6_opt_accepted(sk, skb) || - sk->net_pinfo.af_inet6.rxopt.bits.rxinfo || - sk->net_pinfo.af_inet6.rxopt.bits.rxhlim) { - atomic_inc(&skb->users); - req->af.v6_req.pktopts = skb; + /* Swap the send and the receive. */ + memset(t1, 0, sizeof(*t1)); + t1->dest = th->source; + t1->source = th->dest; + t1->doff = sizeof(*t1)/4; + t1->rst = 1; + + if(th->ack) { + t1->seq = th->ack_seq; + } else { + t1->ack = 1; + t1->ack_seq = htonl(ntohl(th->seq) + th->syn + th->fin + + skb->len - (th->doff<<2)); } - req->af.v6_req.iif = sk->bound_dev_if; - /* So that link locals have meaning */ - if (!sk->bound_dev_if && ipv6_addr_type(&req->af.v6_req.rmt_addr)&IPV6_ADDR_LINKLOCAL) - req->af.v6_req.iif = tcp_v6_iif(skb); + buff->csum = csum_partial((char *)t1, sizeof(*t1), 0); - req->class = &or_ipv6; - req->retrans = 0; - req->sk = NULL; + fl.nl_u.ip6_u.daddr = &skb->nh.ipv6h->saddr; + fl.nl_u.ip6_u.saddr = &skb->nh.ipv6h->daddr; + fl.fl6_flowlabel = 0; - tcp_v6_send_synack(sk, req); + t1->check = csum_ipv6_magic(fl.nl_u.ip6_u.saddr, + fl.nl_u.ip6_u.daddr, + sizeof(*t1), IPPROTO_TCP, + buff->csum); - req->expires = jiffies + TCP_TIMEOUT_INIT; - tcp_inc_slow_timer(TCP_SLT_SYNACK); - tcp_synq_queue(&sk->tp_pinfo.af_tcp, req); + fl.proto = IPPROTO_TCP; + fl.oif = tcp_v6_iif(skb); + fl.uli_u.ports.dport = t1->dest; + fl.uli_u.ports.sport = t1->source; - return 0; + /* sk = NULL, but it is safe for now. RST socket required. */ + buff->dst = ip6_route_output(NULL, &fl); -drop: - TCP_INC_STATS_BH(TcpAttemptFails); - return 0; /* don't send reset */ -} + if (buff->dst->error == 0) { + ip6_xmit(NULL, buff, &fl, NULL); + TCP_INC_STATS_BH(TcpOutSegs); + TCP_INC_STATS_BH(TcpOutRsts); + return; + } -static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, - struct sk_buff *skb) -{ - struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6; - th->check = 0; - - th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, - csum_partial((char *)th, th->doff<<2, - skb->csum)); + kfree_skb(buff); } -static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, - struct open_request *req, - struct dst_entry *dst) +static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts) { - struct ipv6_pinfo *np; + struct tcphdr *th = skb->h.th, *t1; + struct sk_buff *buff; struct flowi fl; - struct tcp_opt *newtp; - struct sock *newsk; - struct ipv6_txoptions *opt; + int tot_len = sizeof(struct tcphdr); - if (skb->protocol == __constant_htons(ETH_P_IP)) { - /* - * v6 mapped - */ + buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr), GFP_ATOMIC); + if (buff == NULL) + return; - newsk = tcp_v4_syn_recv_sock(sk, skb, req, dst); + skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr)); - if (newsk == NULL) - return NULL; + if (ts) + tot_len += 3*4; - np = &newsk->net_pinfo.af_inet6; + t1 = (struct tcphdr *) skb_push(buff,tot_len); + + /* Swap the send and the receive. */ + memset(t1, 0, sizeof(*t1)); + t1->dest = th->source; + t1->source = th->dest; + t1->doff = tot_len/4; + t1->seq = htonl(seq); + t1->ack_seq = htonl(ack); + t1->ack = 1; + t1->window = htons(win); + + if (ts) { + u32 *ptr = (u32*)(t1 + 1); + *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | + (TCPOPT_NOP << 16) | + (TCPOPT_TIMESTAMP << 8) | + TCPOLEN_TIMESTAMP); + *ptr++ = htonl(tcp_time_stamp); + *ptr = htonl(ts); + } + + buff->csum = csum_partial((char *)t1, tot_len, 0); + + fl.nl_u.ip6_u.daddr = &skb->nh.ipv6h->saddr; + fl.nl_u.ip6_u.saddr = &skb->nh.ipv6h->daddr; + fl.fl6_flowlabel = 0; + + t1->check = csum_ipv6_magic(fl.nl_u.ip6_u.saddr, + fl.nl_u.ip6_u.daddr, + tot_len, IPPROTO_TCP, + buff->csum); + + fl.proto = IPPROTO_TCP; + fl.oif = tcp_v6_iif(skb); + fl.uli_u.ports.dport = t1->dest; + fl.uli_u.ports.sport = t1->source; + + buff->dst = ip6_route_output(NULL, &fl); + + if (buff->dst->error == 0) { + ip6_xmit(NULL, buff, &fl, NULL); + TCP_INC_STATS_BH(TcpOutSegs); + return; + } + + kfree_skb(buff); +} + +static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) +{ + struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sk; + + tcp_v6_send_ack(skb, tw->snd_nxt, tw->rcv_nxt, + tw->rcv_wnd>>tw->rcv_wscale, tw->ts_recent); + + tcp_tw_put(tw); +} + +static void tcp_v6_or_send_ack(struct sk_buff *skb, struct open_request *req) +{ + tcp_v6_send_ack(skb, req->snt_isn+1, req->rcv_isn+1, req->rcv_wnd, req->ts_recent); +} + + +static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) +{ + struct open_request *req, **prev; + struct tcphdr *th = skb->h.th; + struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); + + /* Find possible connection requests. */ + req = tcp_v6_search_req(tp, skb->nh.ipv6h, th, tcp_v6_iif(skb), &prev); + if (req) + return tcp_check_req(sk, skb, req, prev); + + if (tp->accept_queue) { + struct sock *nsk; + + nsk = __tcp_v6_lookup_established(&skb->nh.ipv6h->saddr, + th->source, + &skb->nh.ipv6h->daddr, + ntohs(th->dest), + tcp_v6_iif(skb)); + + if (nsk) { + if (nsk->state != TCP_TIME_WAIT) { + bh_lock_sock(nsk); + return nsk; + } + tcp_tw_put((struct tcp_tw_bucket*)sk); + return NULL; + } + } + +#if 0 /*def CONFIG_SYN_COOKIES*/ + if (!th->rst && (th->syn || th->ack)) + sk = cookie_v6_check(sk, skb, &(IPCB(skb)->opt)); +#endif + return sk; +} + +static void tcp_v6_synq_add(struct sock *sk, struct open_request *req) +{ + struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; + struct tcp_listen_opt *lopt = tp->listen_opt; + unsigned h = tcp_v6_synq_hash(&req->af.v6_req.rmt_addr, req->rmt_port); + + req->sk = NULL; + req->expires = jiffies + TCP_TIMEOUT_INIT; + req->retrans = 0; + req->index = h; + req->dl_next = lopt->syn_table[h]; + + write_lock(&tp->syn_wait_lock); + lopt->syn_table[h] = req; + write_unlock(&tp->syn_wait_lock); + + tcp_synq_added(sk); +} + + +/* FIXME: this is substantially similar to the ipv4 code. + * Can some kind of merge be done? -- erics + */ +static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) +{ + struct tcp_opt tp; + struct open_request *req = NULL; + __u32 isn = TCP_SKB_CB(skb)->when; + + if (skb->protocol == __constant_htons(ETH_P_IP)) + return tcp_v4_conn_request(sk, skb); + + /* FIXME: do the same check for anycast */ + if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) + goto drop; + + /* + * There are no SYN attacks on IPv6, yet... + */ + if (tcp_synq_is_full(sk) && !isn) { + if (net_ratelimit()) + printk(KERN_INFO "TCPv6: dropping request, synflood is possible\n"); + goto drop; + } + + if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1) + goto drop; + + req = tcp_openreq_alloc(); + if (req == NULL) + goto drop; + + tp.tstamp_ok = tp.sack_ok = tp.wscale_ok = tp.snd_wscale = 0; + tp.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); + tp.user_mss = sk->tp_pinfo.af_tcp.user_mss; + + tcp_parse_options(NULL, skb->h.th, &tp, 0); + + tcp_openreq_init(req, &tp, skb); + + req->class = &or_ipv6; + ipv6_addr_copy(&req->af.v6_req.rmt_addr, &skb->nh.ipv6h->saddr); + ipv6_addr_copy(&req->af.v6_req.loc_addr, &skb->nh.ipv6h->daddr); + req->af.v6_req.pktopts = NULL; + if (ipv6_opt_accepted(sk, skb) || + sk->net_pinfo.af_inet6.rxopt.bits.rxinfo || + sk->net_pinfo.af_inet6.rxopt.bits.rxhlim) { + atomic_inc(&skb->users); + req->af.v6_req.pktopts = skb; + } + req->af.v6_req.iif = sk->bound_dev_if; + + /* So that link locals have meaning */ + if (!sk->bound_dev_if && ipv6_addr_type(&req->af.v6_req.rmt_addr)&IPV6_ADDR_LINKLOCAL) + req->af.v6_req.iif = tcp_v6_iif(skb); + + if (isn == 0) + isn = tcp_v6_init_sequence(sk,skb); + + req->snt_isn = isn; + + if (tcp_v6_send_synack(sk, req, NULL)) + goto drop; + + tcp_v6_synq_add(sk, req); + + return 0; + +drop: + if (req) + tcp_openreq_free(req); + + TCP_INC_STATS_BH(TcpAttemptFails); + return 0; /* don't send reset */ +} + +static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, + struct open_request *req, + struct dst_entry *dst) +{ + struct ipv6_pinfo *np; + struct flowi fl; + struct tcp_opt *newtp; + struct sock *newsk; + struct ipv6_txoptions *opt; + + if (skb->protocol == __constant_htons(ETH_P_IP)) { + /* + * v6 mapped + */ + + newsk = tcp_v4_syn_recv_sock(sk, skb, req, dst); + + if (newsk == NULL) + return NULL; + + np = &newsk->net_pinfo.af_inet6; ipv6_addr_set(&np->daddr, 0, 0, __constant_htonl(0x0000FFFF), newsk->daddr); @@ -1047,7 +1223,9 @@ /* Charge newly allocated IPv6 socket. Though it is mapped, * it is IPv6 yet. */ +#ifdef INET_REFCNT_DEBUG atomic_inc(&inet6_sock_nr); +#endif MOD_INC_USE_COUNT; /* It is tricky place. Until this moment IPv4 tcp @@ -1061,8 +1239,8 @@ opt = sk->net_pinfo.af_inet6.opt; - if (sk->ack_backlog > sk->max_ack_backlog) - goto out; + if (tcp_acceptq_is_full(sk)) + goto out_overflow; if (sk->net_pinfo.af_inet6.rxopt.bits.srcrt == 2 && opt == NULL && req->af.v6_req.pktopts) { @@ -1090,15 +1268,14 @@ if (dst->error) goto out; - sk->tp_pinfo.af_tcp.syn_backlog--; - sk->ack_backlog++; - newsk = tcp_create_openreq_child(sk, req, skb); if (newsk == NULL) goto out; /* Charge newly allocated IPv6 socket */ +#ifdef INET_REFCNT_DEBUG atomic_inc(&inet6_sock_nr); +#endif MOD_INC_USE_COUNT; ip6_dst_store(newsk, dst, NULL); @@ -1124,6 +1301,8 @@ np->pktoptions = NULL; if (req->af.v6_req.pktopts) { np->pktoptions = skb_clone(req->af.v6_req.pktopts, GFP_ATOMIC); + kfree_skb(req->af.v6_req.pktopts); + req->af.v6_req.pktopts = NULL; if (np->pktoptions) skb_set_owner_r(np->pktoptions, newsk); } @@ -1149,250 +1328,49 @@ tcp_sync_mss(newsk, dst->pmtu); tcp_initialize_rcv_mss(newsk); + newtp->advmss = dst->advmss; - if (newsk->rcvbuf < (3 * (dst->advmss+60+MAX_HEADER+15))) - newsk->rcvbuf = min ((3 * (dst->advmss+60+MAX_HEADER+15)), sysctl_rmem_max); - if (newsk->sndbuf < (3 * (newtp->mss_clamp+60+MAX_HEADER+15))) - newsk->sndbuf = min ((3 * (newtp->mss_clamp+60+MAX_HEADER+15)), sysctl_wmem_max); + tcp_init_buffer_space(newsk); newsk->daddr = LOOPBACK4_IPV6; newsk->saddr = LOOPBACK4_IPV6; newsk->rcv_saddr= LOOPBACK4_IPV6; - bh_lock_sock(newsk); - __tcp_v6_hash(newsk); tcp_inherit_port(sk, newsk); return newsk; +out_overflow: + NET_INC_STATS_BH(ListenOverflows); out: + NET_INC_STATS_BH(ListenDrops); if (opt && opt != sk->net_pinfo.af_inet6.opt) sock_kfree_s(sk, opt, opt->tot_len); dst_release(dst); return NULL; } -static void tcp_v6_send_reset(struct sk_buff *skb) -{ - struct tcphdr *th = skb->h.th, *t1; - struct sk_buff *buff; - struct flowi fl; - - if (th->rst) - return; - - if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) - return; - - /* - * We need to grab some memory, and put together an RST, - * and then put it into the queue to be sent. - */ - - buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr), GFP_ATOMIC); - if (buff == NULL) - return; - - skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr)); - - t1 = (struct tcphdr *) skb_push(buff,sizeof(struct tcphdr)); - - /* Swap the send and the receive. */ - memset(t1, 0, sizeof(*t1)); - t1->dest = th->source; - t1->source = th->dest; - t1->doff = sizeof(*t1)/4; - t1->rst = 1; - - if(th->ack) { - t1->seq = th->ack_seq; - } else { - t1->ack = 1; - t1->ack_seq = htonl(ntohl(th->seq) + th->syn + th->fin - + skb->len - (th->doff<<2)); - } - - buff->csum = csum_partial((char *)t1, sizeof(*t1), 0); - - fl.nl_u.ip6_u.daddr = &skb->nh.ipv6h->saddr; - fl.nl_u.ip6_u.saddr = &skb->nh.ipv6h->daddr; - fl.fl6_flowlabel = 0; - - t1->check = csum_ipv6_magic(fl.nl_u.ip6_u.saddr, - fl.nl_u.ip6_u.daddr, - sizeof(*t1), IPPROTO_TCP, - buff->csum); - - fl.proto = IPPROTO_TCP; - fl.oif = tcp_v6_iif(skb); - fl.uli_u.ports.dport = t1->dest; - fl.uli_u.ports.sport = t1->source; - - /* sk = NULL, but it is safe for now. RST socket required. */ - buff->dst = ip6_route_output(NULL, &fl); - - if (buff->dst->error == 0) { - ip6_xmit(NULL, buff, &fl, NULL); - TCP_INC_STATS_BH(TcpOutSegs); - TCP_INC_STATS_BH(TcpOutRsts); - return; - } - - kfree_skb(buff); -} - -static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts) +static int tcp_v6_checksum_init(struct sk_buff *skb) { - struct tcphdr *th = skb->h.th, *t1; - struct sk_buff *buff; - struct flowi fl; - int tot_len = sizeof(struct tcphdr); - - buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr), GFP_ATOMIC); - if (buff == NULL) - return; - - skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr)); - - if (ts) - tot_len += 3*4; - - t1 = (struct tcphdr *) skb_push(buff,tot_len); - - /* Swap the send and the receive. */ - memset(t1, 0, sizeof(*t1)); - t1->dest = th->source; - t1->source = th->dest; - t1->doff = tot_len/4; - t1->seq = htonl(seq); - t1->ack_seq = htonl(ack); - t1->ack = 1; - t1->window = htons(win); - - if (ts) { - u32 *ptr = (u32*)(t1 + 1); - *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | - (TCPOPT_NOP << 16) | - (TCPOPT_TIMESTAMP << 8) | - TCPOLEN_TIMESTAMP); - *ptr++ = htonl(tcp_time_stamp); - *ptr = htonl(ts); - } - - buff->csum = csum_partial((char *)t1, tot_len, 0); - - fl.nl_u.ip6_u.daddr = &skb->nh.ipv6h->saddr; - fl.nl_u.ip6_u.saddr = &skb->nh.ipv6h->daddr; - fl.fl6_flowlabel = 0; - - t1->check = csum_ipv6_magic(fl.nl_u.ip6_u.saddr, - fl.nl_u.ip6_u.daddr, - tot_len, IPPROTO_TCP, - buff->csum); - - fl.proto = IPPROTO_TCP; - fl.oif = tcp_v6_iif(skb); - fl.uli_u.ports.dport = t1->dest; - fl.uli_u.ports.sport = t1->source; - - buff->dst = ip6_route_output(NULL, &fl); - - if (buff->dst->error == 0) { - ip6_xmit(NULL, buff, &fl, NULL); - TCP_INC_STATS_BH(TcpOutSegs); - return; - } - - kfree_skb(buff); -} - -static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) -{ - struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sk; - - tcp_v6_send_ack(skb, tw->snd_nxt, tw->rcv_nxt, 0, tw->ts_recent); - - tcp_tw_put(tw); -} - -static void tcp_v6_or_send_ack(struct sk_buff *skb, struct open_request *req) -{ - tcp_v6_send_ack(skb, req->snt_isn+1, req->rcv_isn+1, req->rcv_wnd, req->ts_recent); -} - -static struct open_request *tcp_v6_search_req(struct tcp_opt *tp, - struct ipv6hdr *ip6h, - struct tcphdr *th, - int iif, - struct open_request **prevp) -{ - struct open_request *req, *prev; - __u16 rport = th->source; - - /* assumption: the socket is not in use. - * as we checked the user count on tcp_rcv and we're - * running from a soft interrupt. - */ - prev = (struct open_request *) (&tp->syn_wait_queue); - for (req = prev->dl_next; req; req = req->dl_next) { - if (req->rmt_port == rport && - req->class->family == AF_INET6 && - !ipv6_addr_cmp(&req->af.v6_req.rmt_addr, &ip6h->saddr) && - !ipv6_addr_cmp(&req->af.v6_req.loc_addr, &ip6h->daddr) && - (!req->af.v6_req.iif || req->af.v6_req.iif == iif)) { - if (req->sk) { - bh_lock_sock(req->sk); - BUG_TRAP(req->sk->lock.users==0); - if (req->sk->state == TCP_CLOSE) { - bh_unlock_sock(req->sk); - prev = req; - continue; - } - } - *prevp = prev; - return req; - } - prev = req; - } - return NULL; -} - - -static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) -{ - struct open_request *req, *prev; - struct tcphdr *th = skb->h.th; - struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - - /* Find possible connection requests. */ - req = tcp_v6_search_req(tp, skb->nh.ipv6h, th, tcp_v6_iif(skb), &prev); - if (req) - return tcp_check_req(sk, skb, req, prev); - -#if 0 /*def CONFIG_SYN_COOKIES*/ - if (!th->rst && (th->syn || th->ack)) - sk = cookie_v6_check(sk, skb, &(IPCB(skb)->opt)); -#endif - return sk; -} - - -static int tcp_v6_csum_verify(struct sk_buff *skb) -{ - switch (skb->ip_summed) { - case CHECKSUM_NONE: - skb->csum = csum_partial((char *)skb->h.th, skb->len, 0); - case CHECKSUM_HW: + if (skb->ip_summed == CHECKSUM_HW) { if (tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,skb->csum)) { - printk(KERN_DEBUG "tcp v6 csum failed\n"); - return 1; + NETDEBUG(printk(KERN_DEBUG "hw tcp v6 csum failed\n")); + return -1; } skb->ip_summed = CHECKSUM_UNNECESSARY; - default: - /* CHECKSUM_UNNECESSARY */ - }; + } else if (skb->ip_summed != CHECKSUM_UNNECESSARY) { + if (skb->len <= 68) { + if (tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, + &skb->nh.ipv6h->daddr,csum_partial((char *)skb->h.th, skb->len, 0))) + return -1; + skb->ip_summed = CHECKSUM_UNNECESSARY; + } else { + skb->csum = ~tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, + &skb->nh.ipv6h->daddr,0); + } + } return 0; } @@ -1435,13 +1413,6 @@ IP6_INC_STATS_BH(Ip6InDelivers); - /* - * This doesn't check if the socket has enough room for the packet. - * Either process the packet _without_ queueing it and then free it, - * or do the check later. - */ - skb_set_owner_r(skb, sk); - /* Do Stevens' IPV6_PKTOPTIONS. Yes, guys, it is the only place in our code, where we @@ -1461,23 +1432,20 @@ } if (sk->state == TCP_ESTABLISHED) { /* Fast path */ - /* Ready to move deeper ... */ - if (tcp_v6_csum_verify(skb)) - goto csum_err; + TCP_CHECK_TIMER(sk); if (tcp_rcv_established(sk, skb, skb->h.th, skb->len)) goto reset; + TCP_CHECK_TIMER(sk); if (users) goto ipv6_pktoptions; return 0; } - if (tcp_v6_csum_verify(skb)) + if (tcp_checksum_complete(skb)) goto csum_err; if (sk->state == TCP_LISTEN) { - struct sock *nsk; - - nsk = tcp_v6_hnd_req(sk, skb); + struct sock *nsk = tcp_v6_hnd_req(sk, skb); if (!nsk) goto discard; @@ -1486,21 +1454,8 @@ * otherwise we just shortcircuit this and continue with * the new socket.. */ - if(nsk != sk) { - int ret; - int state = nsk->state; - - skb_orphan(skb); - BUG_TRAP(nsk->lock.users == 0); - skb_set_owner_r(skb, nsk); - ret = tcp_rcv_state_process(nsk, skb, skb->h.th, skb->len); - - /* Wakeup parent, send SIGIO */ - if (state == TCP_SYN_RECV && nsk->state != state) - sk->data_ready(sk, 0); - bh_unlock_sock(nsk); - - if (ret) + if(nsk != sk) { + if (tcp_child_process(sk, nsk, skb)) goto reset; if (users) kfree_skb(skb); @@ -1508,8 +1463,10 @@ } } + TCP_CHECK_TIMER(sk); if (tcp_rcv_state_process(sk, skb, skb->h.th, skb->len)) goto reset; + TCP_CHECK_TIMER(sk); if (users) goto ipv6_pktoptions; return 0; @@ -1588,6 +1545,9 @@ if (len < sizeof(struct tcphdr)) goto bad_packet; + if (tcp_v6_checksum_init(skb) < 0) + goto bad_packet; + TCP_SKB_CB(skb)->seq = ntohl(th->seq); TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + len - th->doff*4); @@ -1608,9 +1568,10 @@ bh_lock_sock(sk); ret = 0; - if (!sk->lock.users) - ret = tcp_v6_do_rcv(sk, skb); - else + if (!sk->lock.users) { + if (!tcp_prequeue(sk, skb)) + ret = tcp_v6_do_rcv(sk, skb); + } else sk_add_backlog(sk, skb); bh_unlock_sock(sk); @@ -1618,7 +1579,7 @@ return ret; no_tcp_socket: - if (tcp_v6_csum_verify(skb)) { + if (tcp_checksum_complete(skb)) { bad_packet: TCP_INC_STATS_BH(TcpInErrs); } else { @@ -1639,7 +1600,7 @@ goto discard_it; do_time_wait: - if (tcp_v6_csum_verify(skb)) { + if (tcp_checksum_complete(skb)) { TCP_INC_STATS_BH(TcpInErrs); sock_put(sk); goto discard_it; @@ -1677,7 +1638,7 @@ struct dst_entry *dst; struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6; - dst = sk_dst_check(sk, np->dst_cookie); + dst = __sk_dst_check(sk, np->dst_cookie); if (dst == NULL) { struct flowi fl; @@ -1704,12 +1665,9 @@ } ip6_dst_store(sk, dst, NULL); - return 0; } - err = dst->error; - dst_release(dst); - return err; + return 0; } static int tcp_v6_xmit(struct sk_buff *skb) @@ -1732,7 +1690,7 @@ fl.nl_u.ip6_u.daddr = rt0->addr; } - dst = sk_dst_check(sk, np->dst_cookie); + dst = __sk_dst_check(sk, np->dst_cookie); if (dst == NULL) { dst = ip6_route_output(sk, &fl); @@ -1743,11 +1701,10 @@ return -sk->err_soft; } - dst_clone(dst); ip6_dst_store(sk, dst, NULL); } - skb->dst = dst; + skb->dst = dst_clone(dst); /* Restore final destination back after routing done */ fl.nl_u.ip6_u.daddr = &np->daddr; @@ -1767,6 +1724,12 @@ sin6->sin6_flowinfo = 0; } +static int tcp_v6_remember_stamp(struct sock *sk) +{ + /* Alas, not yet... */ + return 0; +} + static struct tcp_func ipv6_specific = { tcp_v6_xmit, tcp_v6_send_check, @@ -1774,6 +1737,7 @@ tcp_v6_conn_request, tcp_v6_syn_recv_sock, tcp_v6_hash_connecting, + tcp_v6_remember_stamp, sizeof(struct ipv6hdr), ipv6_setsockopt, @@ -1793,6 +1757,7 @@ tcp_v6_conn_request, tcp_v6_syn_recv_sock, tcp_v4_hash_connecting, + tcp_v4_remember_stamp, sizeof(struct iphdr), ipv6_setsockopt, @@ -1812,6 +1777,7 @@ skb_queue_head_init(&tp->out_of_order_queue); tcp_init_xmit_timers(sk); + tcp_prequeue_init(tp); tp->rto = TCP_TIMEOUT_INIT; tp->mdev = TCP_TIMEOUT_INIT; @@ -1826,16 +1792,11 @@ /* See draft-stevens-tcpca-spec-01 for discussion of the * initialization of these values. */ - tp->snd_cwnd_cnt = 0; tp->snd_ssthresh = 0x7fffffff; tp->snd_cwnd_clamp = ~0; tp->mss_cache = 536; sk->state = TCP_CLOSE; - sk->max_ack_backlog = SOMAXCONN; - - /* Init SYN queue. */ - tcp_synq_init(tp); sk->tp_pinfo.af_tcp.af_specific = &ipv6_specific; @@ -1847,27 +1808,19 @@ static int tcp_v6_destroy_sock(struct sock *sk) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - struct sk_buff *skb; tcp_clear_xmit_timers(sk); - /* - * Cleanup up the write buffer. - */ - - while((skb = __skb_dequeue(&sk->write_queue)) != NULL) - kfree_skb(skb); + /* Cleanup up the write buffer. */ + __skb_queue_purge(&sk->write_queue); - /* - * Cleans up our, hopefuly empty, out_of_order_queue - */ + /* Cleans up our, hopefuly empty, out_of_order_queue. */ + __skb_queue_purge(&tp->out_of_order_queue); - while((skb = __skb_dequeue(&tp->out_of_order_queue)) != NULL) - kfree_skb(skb); + /* Clean prequeue, it must be empty really */ + __skb_queue_purge(&tp->ucopy.prequeue); - /* Clean up a locked TCP bind bucket, this only happens if a - * port is allocated for a socket, but it never fully connects. - */ + /* Clean up a referenced TCP bind bucket. */ if(sk->prev != NULL) tcp_put_port(sk); @@ -1878,12 +1831,16 @@ static void get_openreq6(struct sock *sk, struct open_request *req, char *tmpbuf, int i) { struct in6_addr *dest, *src; + int ttd = req->expires - jiffies; + + if (ttd < 0) + ttd = 0; src = &req->af.v6_req.loc_addr; dest = &req->af.v6_req.rmt_addr; sprintf(tmpbuf, "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " - "%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p", + "%02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p", i, src->s6_addr32[0], src->s6_addr32[1], src->s6_addr32[2], src->s6_addr32[3], @@ -1894,7 +1851,7 @@ TCP_SYN_RECV, 0,0, /* could print option size, but that is af dependent. */ 1, /* timers active (only the expire timer) */ - (unsigned long)(req->expires - jiffies), + ttd, req->retrans, sk->socket ? sk->socket->inode->i_uid : 0, 0, /* non standard timer */ @@ -1906,7 +1863,7 @@ { struct in6_addr *dest, *src; __u16 destp, srcp; - int timer_active, timer_active1, timer_active2; + int timer_active; unsigned long timer_expires; struct tcp_opt *tp = &sp->tp_pinfo.af_tcp; @@ -1914,15 +1871,16 @@ src = &sp->net_pinfo.af_inet6.rcv_saddr; destp = ntohs(sp->dport); srcp = ntohs(sp->sport); - timer_active1 = tp->retransmit_timer.prev != NULL; - timer_active2 = sp->timer.prev != NULL; timer_active = 0; timer_expires = (unsigned) -1; - if (timer_active1 && tp->retransmit_timer.expires < timer_expires) { + if (tp->retransmit_timer.prev != NULL && tp->retransmit_timer.expires < timer_expires) { timer_active = 1; timer_expires = tp->retransmit_timer.expires; + } else if (tp->probe_timer.prev != NULL && tp->probe_timer.expires < timer_expires) { + timer_active = 4; + timer_expires = tp->probe_timer.expires; } - if (timer_active2 && sp->timer.expires < timer_expires) { + if (sp->timer.prev != NULL && sp->timer.expires < timer_expires) { timer_active = 2; timer_expires = sp->timer.expires; } @@ -1931,7 +1889,7 @@ sprintf(tmpbuf, "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " - "%02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p", + "%02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p %u %u %u %u", i, src->s6_addr32[0], src->s6_addr32[1], src->s6_addr32[2], src->s6_addr32[3], srcp, @@ -1942,28 +1900,27 @@ timer_active, timer_expires-jiffies, tp->retransmits, sp->socket ? sp->socket->inode->i_uid : 0, - 0, + tp->probes_out, sp->socket ? sp->socket->inode->i_ino : 0, - atomic_read(&sp->refcnt), sp); + atomic_read(&sp->refcnt), sp, + tp->rto, tp->ack.ato, tp->ack.quick, tp->ack.pingpong + ); } static void get_timewait6_sock(struct tcp_tw_bucket *tw, char *tmpbuf, int i) { struct in6_addr *dest, *src; __u16 destp, srcp; - int slot_dist; + int ttd = tw->ttd - jiffies; + + if (ttd < 0) + ttd = 0; dest = &tw->v6_daddr; src = &tw->v6_rcv_saddr; destp = ntohs(tw->dport); srcp = ntohs(tw->sport); - slot_dist = tw->death_slot; - if(slot_dist > tcp_tw_death_row_slot) - slot_dist = (TCP_TWKILL_SLOTS - slot_dist) + tcp_tw_death_row_slot; - else - slot_dist = tcp_tw_death_row_slot - slot_dist; - sprintf(tmpbuf, "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " "%02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p", @@ -1972,8 +1929,8 @@ src->s6_addr32[2], src->s6_addr32[3], srcp, dest->s6_addr32[0], dest->s6_addr32[1], dest->s6_addr32[2], dest->s6_addr32[3], destp, - TCP_TIME_WAIT, 0, 0, - 3, slot_dist * TCP_TWKILL_PERIOD, 0, 0, 0, 0, + tw->substate, 0, 0, + 3, ttd, 0, 0, 0, 0, atomic_read(&tw->refcnt), tw); } @@ -2002,6 +1959,8 @@ tcp_listen_lock(); for(i = 0; i < TCP_LHTABLE_SIZE; i++) { struct sock *sk = tcp_listening_hash[i]; + struct tcp_listen_opt *lopt; + int k; for (sk = tcp_listening_hash[i]; sk; sk = sk->next, num++) { struct open_request *req; @@ -2019,24 +1978,29 @@ } } - lock_sock(sk); - for (req = tp->syn_wait_queue; req; req = req->dl_next, num++) { - if (req->sk) - continue; - if (req->class->family != PF_INET6) - continue; - pos += LINE_LEN+1; - if (pos < offset) - continue; - get_openreq6(sk, req, tmpbuf, num); - len += sprintf(buffer+len, LINE_FMT, tmpbuf); - if(len >= length) { - release_sock(sk); - tcp_listen_unlock(); - goto out_no_bh; + read_lock_bh(&tp->syn_wait_lock); + lopt = tp->listen_opt; + if (lopt && lopt->qlen != 0) { + for (k=0; ksyn_table[k]; req; req = req->dl_next, num++) { + if (req->class->family != PF_INET6) + continue; + pos += LINE_LEN+1; + if (pos < offset) + continue; + get_openreq6(sk, req, tmpbuf, num); + len += sprintf(buffer+len, LINE_FMT, tmpbuf); + if(len >= length) { + read_unlock_bh(&tp->syn_wait_lock); + tcp_listen_unlock(); + goto out_no_bh; + } + } } } - release_sock(sk); + read_unlock_bh(&tp->syn_wait_lock); + + /* Completed requests are in normal socket hash table */ } } tcp_listen_unlock(); @@ -2100,25 +2064,19 @@ tcp_v6_connect, /* connect */ tcp_disconnect, /* disconnect */ tcp_accept, /* accept */ - NULL, /* retransmit */ - tcp_write_wakeup, /* write_wakeup */ - tcp_read_wakeup, /* read_wakeup */ - tcp_poll, /* poll */ tcp_ioctl, /* ioctl */ tcp_v6_init_sock, /* init */ tcp_v6_destroy_sock, /* destroy */ tcp_shutdown, /* shutdown */ tcp_setsockopt, /* setsockopt */ tcp_getsockopt, /* getsockopt */ - tcp_v6_sendmsg, /* sendmsg */ + tcp_sendmsg, /* sendmsg */ tcp_recvmsg, /* recvmsg */ NULL, /* bind */ tcp_v6_do_rcv, /* backlog_rcv */ tcp_v6_hash, /* hash */ tcp_unhash, /* unhash */ tcp_v6_get_port, /* get_port */ - 128, /* max_header */ - 0, /* retransmits */ "TCPv6", /* name */ }; diff -ur --new-file old/linux/net/ipv6/udp.c new/linux/net/ipv6/udp.c --- old/linux/net/ipv6/udp.c Sun Jan 9 06:36:21 2000 +++ new/linux/net/ipv6/udp.c Sat Jan 22 20:54:58 2000 @@ -7,7 +7,7 @@ * * Based on linux/ipv4/udp.c * - * $Id: udp.c,v 1.48 2000/01/09 02:19:53 davem Exp $ + * $Id: udp.c,v 1.50 2000/01/18 08:24:24 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -366,54 +366,19 @@ msg->msg_flags |= MSG_TRUNC; } -#ifndef CONFIG_UDP_DELAY_CSUM - err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), - msg->msg_iov, copied); -#else if (skb->ip_summed==CHECKSUM_UNNECESSARY) { err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov, copied); - } else if (copied > msg->msg_iov[0].iov_len || (msg->msg_flags&MSG_TRUNC)) { - if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum))) { - /* Clear queue. */ - if (flags&MSG_PEEK) { - int clear = 0; - spin_lock_irq(&sk->receive_queue.lock); - if (skb == skb_peek(&sk->receive_queue)) { - __skb_unlink(skb, &sk->receive_queue); - clear = 1; - } - spin_unlock_irq(&sk->receive_queue.lock); - if (clear) - kfree_skb(skb); - } - - /* Error for blocking case is chosen to masquerade - as some normal condition. - */ - err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH; - udp_stats_in6.UdpInErrors++; - goto out_free; - } + } else if (msg->msg_flags&MSG_TRUNC) { + if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum))) + goto csum_copy_err; err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov, copied); } else { - unsigned int csum = csum_partial(skb->h.raw, sizeof(struct udphdr), skb->csum); - - err = 0; - csum = csum_and_copy_to_user((char*)&skb->h.uh[1], msg->msg_iov[0].iov_base, copied, csum, &err); + err = copy_and_csum_toiovec(msg->msg_iov, skb, sizeof(struct udphdr)); if (err) - goto out_free; - if ((unsigned short)csum_fold(csum)) { - /* Error for blocking case is chosen to masquerade - as some normal condition. - */ - err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH; - udp_stats_in6.UdpInErrors++; - goto out_free; - } + goto csum_copy_err; } -#endif if (err) goto out_free; @@ -447,6 +412,27 @@ skb_free_datagram(sk, skb); out: return err; + +csum_copy_err: + /* Clear queue. */ + if (flags&MSG_PEEK) { + int clear = 0; + spin_lock_irq(&sk->receive_queue.lock); + if (skb == skb_peek(&sk->receive_queue)) { + __skb_unlink(skb, &sk->receive_queue); + clear = 1; + } + spin_unlock_irq(&sk->receive_queue.lock); + if (clear) + kfree_skb(skb); + } + + /* Error for blocking case is chosen to masquerade + as some normal condition. + */ + err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH; + UDP6_INC_STATS_USER(UdpInErrors); + goto out_free; } void udpv6_err(struct sk_buff *skb, struct ipv6hdr *hdr, @@ -474,7 +460,7 @@ !sk->net_pinfo.af_inet6.recverr) goto out; - if (sk->bsdism && sk->state!=TCP_ESTABLISHED && + if (sk->state!=TCP_ESTABLISHED && !sk->net_pinfo.af_inet6.recverr) goto out; @@ -489,7 +475,7 @@ static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) { -#if defined(CONFIG_FILTER) && defined(CONFIG_UDP_DELAY_CSUM) +#if defined(CONFIG_FILTER) if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) { if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum))) { UDP6_INC_STATS_BH(UdpInErrors); @@ -621,24 +607,12 @@ skb_trim(skb, ulen); -#ifndef CONFIG_UDP_DELAY_CSUM - switch (skb->ip_summed) { - case CHECKSUM_NONE: - skb->csum = csum_partial((char*)uh, ulen, 0); - case CHECKSUM_HW: - if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) { - printk(KERN_DEBUG "IPv6: udp checksum error\n"); - goto discard; - } - }; -#else if (skb->ip_summed==CHECKSUM_HW) { if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) goto discard; skb->ip_summed = CHECKSUM_UNNECESSARY; } else if (skb->ip_summed != CHECKSUM_UNNECESSARY) skb->csum = ~csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, 0); -#endif len = ulen; @@ -651,7 +625,7 @@ } /* Unicast */ - + /* * check socket cache ... must talk to Alan about his plans * for sock caches... i'll skip this for now. @@ -660,11 +634,9 @@ sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, dev->ifindex); if (sk == NULL) { -#ifdef CONFIG_UDP_DELAY_CSUM if (skb->ip_summed != CHECKSUM_UNNECESSARY && (unsigned short)csum_fold(csum_partial((char*)uh, len, skb->csum))) goto discard; -#endif UDP6_INC_STATS_BH(UdpNoPorts); icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev); @@ -672,12 +644,6 @@ kfree_skb(skb); return(0); } - if (0/*sk->user_callback && - sk->user_callback(sk->user_data, skb) == 0*/) { - UDP6_INC_STATS_BH(UdpInDatagrams); - sock_put(sk); - return(0); - } /* deliver */ @@ -980,10 +946,6 @@ udpv6_connect, /* connect */ udp_disconnect, /* disconnect */ NULL, /* accept */ - NULL, /* retransmit */ - NULL, /* write_wakeup */ - NULL, /* read_wakeup */ - datagram_poll, /* poll */ udp_ioctl, /* ioctl */ NULL, /* init */ inet6_destroy_sock, /* destroy */ @@ -997,8 +959,6 @@ udp_v6_hash, /* hash */ udp_v6_unhash, /* unhash */ udp_v6_get_port, /* get_port */ - 128, /* max_header */ - 0, /* retransmits */ "UDP", /* name */ }; diff -ur --new-file old/linux/net/irda/af_irda.c new/linux/net/irda/af_irda.c --- old/linux/net/irda/af_irda.c Fri Jan 7 20:51:56 2000 +++ new/linux/net/irda/af_irda.c Mon Jan 24 20:04:37 2000 @@ -1522,7 +1522,7 @@ * we set writable also when the other side has shut down the * connection. This prevents stuck sockets. */ - if (sk->sndbuf - (int)atomic_read(&sk->wmem_alloc) >= MIN_WRITE_SPACE) + if (sk->sndbuf - (int)atomic_read(&sk->wmem_alloc) >= SOCK_MIN_WRITE_SPACE) mask |= POLLOUT | POLLWRNORM | POLLWRBAND; return mask; diff -ur --new-file old/linux/net/khttpd/accept.c new/linux/net/khttpd/accept.c --- old/linux/net/khttpd/accept.c Mon Aug 23 19:01:02 1999 +++ new/linux/net/khttpd/accept.c Sat Jan 22 20:54:58 2000 @@ -63,7 +63,7 @@ the allocation of a new socket. (Which doesn't seem to be used anyway) */ - if (Socket->sk->tp_pinfo.af_tcp.syn_wait_queue==NULL) + if (Socket->sk->tp_pinfo.af_tcp.accept_queue==NULL) { return 0; } diff -ur --new-file old/linux/net/khttpd/datasending.c new/linux/net/khttpd/datasending.c --- old/linux/net/khttpd/datasending.c Tue Dec 7 02:06:50 1999 +++ new/linux/net/khttpd/datasending.c Sat Jan 22 20:54:58 2000 @@ -172,7 +172,7 @@ if (CurrentRequest->sock->sk->state == TCP_ESTABLISHED || CurrentRequest->sock->sk->state == TCP_CLOSE_WAIT) { - CurrentRequest->sock->sk->nonagle = 0; + CurrentRequest->sock->sk->tp_pinfo.af_tcp.nonagle = 0; tcp_push_pending_frames(CurrentRequest->sock->sk,&(CurrentRequest->sock->sk->tp_pinfo.af_tcp)); } release_sock(CurrentRequest->sock->sk); diff -ur --new-file old/linux/net/khttpd/sockets.c new/linux/net/khttpd/sockets.c --- old/linux/net/khttpd/sockets.c Wed Aug 18 18:45:10 1999 +++ new/linux/net/khttpd/sockets.c Sat Jan 22 20:54:58 2000 @@ -68,9 +68,10 @@ (void)printk(KERN_ERR " daemon is (or was a short time ago) using port %i.\n",Port); return 0; } - + + /* Grrr... setsockopt() does this. */ sock->sk->reuse = 1; - sock->sk->nonagle = 0; + /* Wow!!! */ sock->sk->linger = 1; /* Now, start listening on the socket */ diff -ur --new-file old/linux/net/khttpd/userspace.c new/linux/net/khttpd/userspace.c --- old/linux/net/khttpd/userspace.c Wed Aug 25 23:50:35 1999 +++ new/linux/net/khttpd/userspace.c Sat Jan 22 20:54:58 2000 @@ -181,8 +181,7 @@ static int AddSocketToAcceptQueue(struct socket *sock,const int Port) { struct open_request *req; - struct sock *sk; - struct tcp_opt *tp; + struct sock *sk, *nsk; EnterFunction("AddSocketToAcceptQueue"); @@ -196,8 +195,7 @@ lock_sock(sk); - if (sk->state != TCP_LISTEN || - sk->ack_backlog > sk->max_ack_backlog) /* To many pending requests */ + if (sk->state != TCP_LISTEN || tcp_acceptq_is_full(sk)) { release_sock(sk); sock_put(sk); @@ -213,20 +211,17 @@ return -1; } - req->sk = sock->sk; + nsk = sock->sk; sock->sk = NULL; sock->state = SS_UNCONNECTED; req->class = &Dummy; - write_lock_irq(&req->sk->callback_lock); - req->sk->socket = NULL; - req->sk->sleep = NULL; - write_unlock_irq(&req->sk->callback_lock); + write_lock_irq(&nsk->callback_lock); + nsk->socket = NULL; + nsk->sleep = NULL; + write_unlock_irq(&nsk->callback_lock); - tp =&(sk->tp_pinfo.af_tcp); - sk->ack_backlog++; - - tcp_synq_queue(tp,req); + tcp_acceptq_queue(sk, req, nsk); sk->data_ready(sk, 0); diff -ur --new-file old/linux/net/khttpd/waitheaders.c new/linux/net/khttpd/waitheaders.c --- old/linux/net/khttpd/waitheaders.c Mon Aug 23 22:44:03 1999 +++ new/linux/net/khttpd/waitheaders.c Sat Jan 22 20:54:58 2000 @@ -256,7 +256,7 @@ } else /* Normal Case */ { - Request->sock->sk->nonagle = 2; /* this is TCP_CORK */ + Request->sock->sk->tp_pinfo.af_tcp.nonagle = 2; /* this is TCP_CORK */ if (Request->HTTPVER!=9) /* HTTP/0.9 doesn't allow a header */ SendHTTPHeader(Request); } diff -ur --new-file old/linux/net/netlink/af_netlink.c new/linux/net/netlink/af_netlink.c --- old/linux/net/netlink/af_netlink.c Thu Oct 28 23:34:44 1999 +++ new/linux/net/netlink/af_netlink.c Sat Jan 22 20:54:58 2000 @@ -48,9 +48,9 @@ struct netlink_opt { - pid_t pid; + u32 pid; unsigned groups; - pid_t dst_pid; + u32 dst_pid; unsigned dst_groups; unsigned long state; int (*handler)(int unit, struct sk_buff *skb); @@ -95,6 +95,12 @@ #endif } +/* This lock without TASK_EXCLUSIVE is good on UP and it is _very_ bad on SMP. + * Look, when several writers sleep and reader wakes them up, all but one + * immediately hit write lock and grab all the cpus. Exclusive sleep solves + * this, _but_ remember, it adds useless work on UP machines. + */ + static void netlink_table_grab(void) { write_lock_bh(&nl_table_lock); @@ -102,9 +108,9 @@ if (atomic_read(&nl_table_users)) { DECLARE_WAITQUEUE(wait, current); - add_wait_queue(&nl_table_wait, &wait); + add_wait_queue_exclusive(&nl_table_wait, &wait); for(;;) { - set_current_state(TASK_UNINTERRUPTIBLE); + set_current_state(TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE); if (atomic_read(&nl_table_users) == 0) break; write_unlock_bh(&nl_table_lock); @@ -120,6 +126,7 @@ static __inline__ void netlink_table_ungrab(void) { write_unlock_bh(&nl_table_lock); + wake_up(&nl_table_wait); } static __inline__ void @@ -254,14 +261,9 @@ /* OK. Socket is unlinked, and, therefore, no new packets will arrive */ - write_lock_irq(&sk->callback_lock); - sk->dead = 1; - sk->socket = NULL; + sock_orphan(sk); sock->sk = NULL; - wake_up_interruptible(sk->sleep); - sk->sleep = NULL; - wake_up_interruptible(&sk->protinfo.af_netlink->wait); - write_unlock_irq(&sk->callback_lock); + wake_up_interruptible_all(&sk->protinfo.af_netlink->wait); skb_queue_purge(&sk->write_queue); @@ -391,8 +393,11 @@ struct sock *sk; int len = skb->len; int protocol = ssk->protocol; + long timeo; DECLARE_WAITQUEUE(wait, current); + timeo = sock_sndtimeo(ssk, nonblock); + retry: sk = netlink_lookup(protocol, pid); if (sk == NULL) @@ -409,7 +414,7 @@ if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf || test_bit(0, &sk->protinfo.af_netlink->state)) { - if (nonblock) { + if (!timeo) { if (ssk->protinfo.af_netlink->pid == 0) netlink_overrun(sk); sock_put(sk); @@ -422,9 +427,8 @@ if ((atomic_read(&sk->rmem_alloc) > sk->rcvbuf || test_bit(0, &sk->protinfo.af_netlink->state)) && - !signal_pending(current) && !sk->dead) - schedule(); + timeo = schedule_timeout(timeo); __set_current_state(TASK_RUNNING); remove_wait_queue(&sk->protinfo.af_netlink->wait, &wait); @@ -553,9 +557,6 @@ if (msg->msg_flags&MSG_OOB) return -EOPNOTSUPP; - - if (msg->msg_flags&~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE)) - return -EINVAL; if (msg->msg_namelen) { if (addr->nl_family != AF_NETLINK) diff -ur --new-file old/linux/net/netrom/af_netrom.c new/linux/net/netrom/af_netrom.c --- old/linux/net/netrom/af_netrom.c Fri Nov 19 20:33:29 1999 +++ new/linux/net/netrom/af_netrom.c Tue Jan 25 20:41:10 2000 @@ -978,7 +978,7 @@ unsigned char *asmptr; int size; - if (msg->msg_flags & ~MSG_DONTWAIT) + if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR)) return -EINVAL; if (sk->zapped) diff -ur --new-file old/linux/net/netsyms.c new/linux/net/netsyms.c --- old/linux/net/netsyms.c Sun Jan 9 06:36:21 2000 +++ new/linux/net/netsyms.c Sat Jan 22 20:54:58 2000 @@ -61,7 +61,6 @@ #include #include -extern int tcp_tw_death_row_slot; extern int sysctl_local_port_range[2]; extern int tcp_port_rover; extern int udp_port_rover; @@ -277,14 +276,15 @@ EXPORT_SYMBOL(inet_stream_connect); EXPORT_SYMBOL(inet_dgram_connect); EXPORT_SYMBOL(inet_accept); -EXPORT_SYMBOL(inet_poll); EXPORT_SYMBOL(inet_listen); EXPORT_SYMBOL(inet_shutdown); EXPORT_SYMBOL(inet_setsockopt); EXPORT_SYMBOL(inet_getsockopt); EXPORT_SYMBOL(inet_sendmsg); EXPORT_SYMBOL(inet_recvmsg); +#ifdef INET_REFCNT_DEBUG EXPORT_SYMBOL(inet_sock_nr); +#endif EXPORT_SYMBOL(inet_sock_destruct); EXPORT_SYMBOL(inet_sock_release); @@ -307,7 +307,6 @@ EXPORT_SYMBOL(memcpy_fromiovecend); EXPORT_SYMBOL(csum_partial_copy_fromiovecend); EXPORT_SYMBOL(copy_and_csum_toiovec); -EXPORT_SYMBOL(tcp_keepalive_timer); EXPORT_SYMBOL(tcp_v4_lookup_listener); /* UDP/TCP exported functions for TCPv6 */ EXPORT_SYMBOL(udp_ioctl); @@ -318,7 +317,6 @@ EXPORT_SYMBOL(tcp_disconnect); EXPORT_SYMBOL(tcp_accept); EXPORT_SYMBOL(tcp_write_wakeup); -EXPORT_SYMBOL(tcp_read_wakeup); EXPORT_SYMBOL(tcp_write_space); EXPORT_SYMBOL(tcp_poll); EXPORT_SYMBOL(tcp_ioctl); @@ -328,19 +326,18 @@ EXPORT_SYMBOL(tcp_recvmsg); EXPORT_SYMBOL(tcp_send_synack); EXPORT_SYMBOL(tcp_check_req); +EXPORT_SYMBOL(tcp_child_process); EXPORT_SYMBOL(tcp_reset_xmit_timer); EXPORT_SYMBOL(tcp_parse_options); EXPORT_SYMBOL(tcp_rcv_established); EXPORT_SYMBOL(tcp_init_xmit_timers); EXPORT_SYMBOL(tcp_clear_xmit_timers); -EXPORT_SYMBOL(tcp_slt_array); -EXPORT_SYMBOL(__tcp_inc_slow_timer); EXPORT_SYMBOL(tcp_statistics); EXPORT_SYMBOL(tcp_rcv_state_process); EXPORT_SYMBOL(tcp_timewait_state_process); EXPORT_SYMBOL(tcp_timewait_cachep); EXPORT_SYMBOL(tcp_timewait_kill); -EXPORT_SYMBOL(tcp_do_sendmsg); +EXPORT_SYMBOL(tcp_sendmsg); EXPORT_SYMBOL(tcp_v4_rebuild_header); EXPORT_SYMBOL(tcp_v4_send_check); EXPORT_SYMBOL(tcp_v4_conn_request); @@ -362,8 +359,9 @@ EXPORT_SYMBOL(tcp_transmit_skb); EXPORT_SYMBOL(tcp_connect); EXPORT_SYMBOL(tcp_make_synack); -EXPORT_SYMBOL(tcp_tw_death_row_slot); EXPORT_SYMBOL(tcp_tw_deschedule); +EXPORT_SYMBOL(tcp_delete_keepalive_timer); +EXPORT_SYMBOL(tcp_reset_keepalive_timer); EXPORT_SYMBOL(sysctl_local_port_range); EXPORT_SYMBOL(tcp_port_rover); EXPORT_SYMBOL(udp_port_rover); @@ -375,7 +373,12 @@ EXPORT_SYMBOL(tcp_write_xmit); EXPORT_SYMBOL(dev_loopback_xmit); +EXPORT_SYMBOL(tcp_v4_remember_stamp); + +extern int sysctl_tcp_tw_recycle; + #ifdef CONFIG_SYSCTL +EXPORT_SYMBOL(sysctl_tcp_tw_recycle); EXPORT_SYMBOL(sysctl_max_syn_backlog); #endif @@ -489,7 +492,9 @@ EXPORT_SYMBOL(fddi_type_trans); EXPORT_SYMBOL(fddi_setup); #endif /* CONFIG_FDDI */ +#if 0 EXPORT_SYMBOL(eth_copy_and_sum); +#endif EXPORT_SYMBOL(alloc_skb); EXPORT_SYMBOL(__kfree_skb); EXPORT_SYMBOL(skb_clone); diff -ur --new-file old/linux/net/packet/af_packet.c new/linux/net/packet/af_packet.c --- old/linux/net/packet/af_packet.c Thu Dec 23 04:55:38 1999 +++ new/linux/net/packet/af_packet.c Tue Jan 25 19:26:04 2000 @@ -5,7 +5,7 @@ * * PACKET - implements raw packet sockets. * - * Version: $Id: af_packet.c,v 1.26 1999/12/20 05:20:02 davem Exp $ + * Version: $Id: af_packet.c,v 1.28 2000/01/24 23:35:59 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -789,13 +789,8 @@ * Now the socket is dead. No more input will appear. */ - write_lock_irq(&sk->callback_lock); + sock_orphan(sk); sock->sk = NULL; - sk->socket = NULL; - sk->dead = 1; - sk->sleep = NULL; - write_unlock_irq(&sk->callback_lock); - /* Purge queues */ @@ -1537,15 +1532,8 @@ } static struct vm_operations_struct packet_mmap_ops = { - packet_mm_open, /* open */ - packet_mm_close, /* close */ - NULL, /* unmap */ - NULL, /* no special protect */ - NULL, /* sync */ - NULL, /* advise */ - NULL, /* nopage */ - NULL, /* wppage */ - NULL /* swapout */ + open: packet_mm_open, + close: packet_mm_close, }; static void free_pg_vec(unsigned long *pg_vec, unsigned order, unsigned len) diff -ur --new-file old/linux/net/rose/af_rose.c new/linux/net/rose/af_rose.c --- old/linux/net/rose/af_rose.c Thu Jan 20 19:48:35 2000 +++ new/linux/net/rose/af_rose.c Tue Jan 25 20:41:10 2000 @@ -1010,7 +1010,7 @@ unsigned char *asmptr; int n, size, qbit = 0; - if (msg->msg_flags & ~MSG_DONTWAIT) + if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR)) return -EINVAL; if (sk->zapped) diff -ur --new-file old/linux/net/socket.c new/linux/net/socket.c --- old/linux/net/socket.c Tue Jan 11 23:19:17 2000 +++ new/linux/net/socket.c Wed Jan 26 18:40:08 2000 @@ -176,7 +176,10 @@ * Statistics counters of the socket lists */ -static int sockets_in_use = 0; +static union { + int counter; + char __pad[SMP_CACHE_BYTES]; +} sockets_in_use[NR_CPUS] __cacheline_aligned = {{0}}; /* * Support routines. Move socket addresses back and forth across the kernel/user @@ -261,23 +264,14 @@ goto out; } - lock_kernel(); file->f_dentry = d_alloc_root(sock->inode); if (!file->f_dentry) { - unlock_kernel(); put_filp(file); put_unused_fd(fd); fd = -ENOMEM; goto out; } - /* - * The socket maintains a reference to the inode, so we - * have to increment the count. - */ - sock->inode->i_count++; - unlock_kernel(); - file->f_op = &socket_file_ops; file->f_mode = 3; file->f_flags = O_RDWR; @@ -360,7 +354,7 @@ sock->sk = NULL; sock->file = NULL; - sockets_in_use++; + sockets_in_use[smp_processor_id()].counter++; return sock; } @@ -383,9 +377,12 @@ if (sock->fasync_list) printk(KERN_ERR "sock_release: fasync list not empty!\n"); - --sockets_in_use; /* Bookkeeping.. */ + sockets_in_use[smp_processor_id()].counter--; + if (!sock->file) { + iput(sock->inode); + return; + } sock->file=NULL; - iput(sock->inode); } int sock_sendmsg(struct socket *sock, struct msghdr *msg, int size) @@ -889,8 +886,6 @@ int err; if ((sock = sockfd_lookup(fd, &err)) != NULL) { - if ((unsigned) backlog == 0) /* BSDism */ - backlog = 1; if ((unsigned) backlog > SOMAXCONN) backlog = SOMAXCONN; err=sock->ops->listen(sock, backlog); @@ -943,6 +938,9 @@ goto out_release; } + /* File flags are inherited via accept(). It looks silly, but we + * have to be compatible with another OSes. + */ if ((err = sock_map_fd(newsock)) < 0) goto out_release; @@ -1119,7 +1117,7 @@ flags |= MSG_DONTWAIT; err=sock_recvmsg(sock, &msg, size, flags); - if(err >= 0 && addr != NULL) + if(err >= 0 && addr != NULL && msg.msg_namelen) { err2=move_addr_to_user(address, msg.msg_namelen, addr, addr_len); if(err2<0) @@ -1341,7 +1339,7 @@ goto out_freeiov; len = err; - if (uaddr != NULL) { + if (uaddr != NULL && msg_sys.msg_namelen) { err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len); if (err < 0) goto out_freeiov; @@ -1595,7 +1593,17 @@ int socket_get_info(char *buffer, char **start, off_t offset, int length) { - int len = sprintf(buffer, "sockets: used %d\n", sockets_in_use); + int len, cpu; + int counter = 0; + + for (cpu=0; cpu= len) { *start = buffer; @@ -1605,5 +1613,7 @@ len -= offset; if (len > length) len = length; + if (len < 0) + len = 0; return len; } diff -ur --new-file old/linux/net/sunrpc/xprt.c new/linux/net/sunrpc/xprt.c --- old/linux/net/sunrpc/xprt.c Thu Jan 20 19:48:35 2000 +++ new/linux/net/sunrpc/xprt.c Mon Jan 24 20:04:37 2000 @@ -816,7 +816,7 @@ do_rpciod_tcp_dispatcher(void) { struct rpc_xprt *xprt; - int result; + int result = 0; dprintk("rpciod_tcp_dispatcher: Queue Running\n"); diff -ur --new-file old/linux/net/unix/af_unix.c new/linux/net/unix/af_unix.c --- old/linux/net/unix/af_unix.c Thu Dec 23 04:55:38 1999 +++ new/linux/net/unix/af_unix.c Sat Jan 22 20:54:58 2000 @@ -8,7 +8,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * Version: $Id: af_unix.c,v 1.87 1999/12/09 00:54:25 davem Exp $ + * Version: $Id: af_unix.c,v 1.88 2000/01/18 08:24:28 davem Exp $ * * Fixes: * Linus Torvalds : Assorted bug cures. @@ -337,10 +337,7 @@ /* Clear state */ unix_state_wlock(sk); - write_lock(&sk->callback_lock); - sk->dead = 1; - sk->socket = NULL; - write_unlock(&sk->callback_lock); + sock_orphan(sk); sk->shutdown = SHUTDOWN_MASK; dentry = sk->protinfo.af_unix.dentry; sk->protinfo.af_unix.dentry=NULL; @@ -348,8 +345,7 @@ sk->state = TCP_CLOSE; unix_state_wunlock(sk); - wake_up_interruptible(sk->sleep); - wake_up_interruptible(&sk->protinfo.af_unix.peer_wait); + wake_up_interruptible_all(&sk->protinfo.af_unix.peer_wait); skpair=unix_peer(sk); @@ -360,7 +356,8 @@ if (!skb_queue_empty(&sk->receive_queue) || embrion) skpair->err = ECONNRESET; unix_state_wunlock(skpair); - sk->data_ready(skpair,0); + sk->state_change(skpair); + sock_wake_async(sk->socket,1,POLL_HUP); } sock_put(skpair); /* It may now die */ unix_peer(sk) = NULL; @@ -418,7 +415,7 @@ if (sk->state != TCP_CLOSE && sk->state != TCP_LISTEN) goto out_unlock; if (backlog > sk->max_ack_backlog) - wake_up_interruptible(&sk->protinfo.af_unix.peer_wait); + wake_up_interruptible_all(&sk->protinfo.af_unix.peer_wait); sk->max_ack_backlog=backlog; sk->state=TCP_LISTEN; sock->flags |= SO_ACCEPTCON; @@ -740,26 +737,26 @@ return err; } -static void unix_wait_for_peer(unix_socket *other) +static long unix_wait_for_peer(unix_socket *other, long timeo) { int sched; DECLARE_WAITQUEUE(wait, current); - __set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&other->protinfo.af_unix.peer_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE|TASK_EXCLUSIVE); + add_wait_queue_exclusive(&other->protinfo.af_unix.peer_wait, &wait); sched = (!other->dead && !(other->shutdown&RCV_SHUTDOWN) && - !signal_pending(current) && - skb_queue_len(&other->receive_queue) >= other->max_ack_backlog); + skb_queue_len(&other->receive_queue) > other->max_ack_backlog); unix_state_runlock(other); if (sched) - schedule(); + timeo = schedule_timeout(timeo); __set_current_state(TASK_RUNNING); remove_wait_queue(&other->protinfo.af_unix.peer_wait, &wait); + return timeo; } static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, @@ -773,6 +770,7 @@ unsigned hash; int st; int err; + long timeo; err = unix_mkname(sunaddr, addr_len, &hash); if (err < 0) @@ -783,6 +781,8 @@ (err = unix_autobind(sock)) != 0) goto out; + timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); + /* First of all allocate resources. If we will make it after state is locked, we will have to recheck all again in any case. @@ -820,12 +820,12 @@ if (other->state != TCP_LISTEN) goto out_unlock; - if (skb_queue_len(&other->receive_queue) >= other->max_ack_backlog) { + if (skb_queue_len(&other->receive_queue) > other->max_ack_backlog) { err = -EAGAIN; - if (flags & O_NONBLOCK) + if (!timeo) goto out_unlock; - unix_wait_for_peer(other); + timeo = unix_wait_for_peer(other, timeo); err = -ERESTARTSYS; if (signal_pending(current)) @@ -959,8 +959,8 @@ if (sk->state!=TCP_LISTEN) goto out; - /* If socket state is TCP_LISTEN it cannot change, - so that no locks are necessary. + /* If socket state is TCP_LISTEN it cannot change (for now...), + * so that no locks are necessary. */ skb = skb_recv_datagram(sk, 0, flags&O_NONBLOCK, &err); @@ -968,16 +968,13 @@ goto out; tsk = skb->sk; - if (skb_queue_len(&sk->receive_queue) <= sk->max_ack_backlog/2) - wake_up_interruptible(&sk->protinfo.af_unix.peer_wait); skb_free_datagram(sk, skb); + wake_up_interruptible(&sk->protinfo.af_unix.peer_wait); /* attach accepted sock to socket */ unix_state_wlock(tsk); newsock->state = SS_CONNECTED; - newsock->sk = tsk; - tsk->sleep = &newsock->wait; - tsk->socket = newsock; + sock_graft(tsk, newsock); unix_state_wunlock(tsk); return 0; @@ -1069,15 +1066,12 @@ int err; unsigned hash; struct sk_buff *skb; + long timeo; err = -EOPNOTSUPP; if (msg->msg_flags&MSG_OOB) goto out; - err = -EINVAL; - if (msg->msg_flags&~(MSG_DONTWAIT|MSG_NOSIGNAL)) - goto out; - if (msg->msg_namelen) { err = unix_mkname(sunaddr, msg->msg_namelen, &hash); if (err < 0) @@ -1095,6 +1089,7 @@ (err = unix_autobind(sock)) != 0) goto out; + skb = sock_alloc_send_skb(sk, len, 0, msg->msg_flags&MSG_DONTWAIT, &err); if (skb==NULL) goto out; @@ -1108,6 +1103,8 @@ if (err) goto out_free; + timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); + restart: if (!other) { err = -ECONNRESET; @@ -1151,20 +1148,13 @@ if (other->shutdown&RCV_SHUTDOWN) goto out_unlock; - if (0/*other->user_callback && - other->user_callback(other->user_data, skb) == 0*/) { - unix_state_runlock(other); - sock_put(other); - return len; - } - - if (skb_queue_len(&other->receive_queue) >= other->max_ack_backlog) { - if (msg->msg_flags & MSG_DONTWAIT) { + if (skb_queue_len(&other->receive_queue) > other->max_ack_backlog) { + if (!timeo) { err = -EAGAIN; goto out_unlock; } - unix_wait_for_peer(other); + timeo = unix_wait_for_peer(other, timeo); err = -ERESTARTSYS; if (signal_pending(current)) @@ -1205,10 +1195,6 @@ if (msg->msg_flags&MSG_OOB) goto out_err; - err = -EINVAL; - if (msg->msg_flags&~(MSG_DONTWAIT|MSG_NOSIGNAL)) - goto out_err; - if (msg->msg_namelen) { err = (sk->state==TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP); goto out_err; @@ -1329,8 +1315,7 @@ if (!skb) goto out; - if (skb_queue_len(&sk->receive_queue) <= sk->max_ack_backlog/2) - wake_up_interruptible(&sk->protinfo.af_unix.peer_wait); + wake_up_interruptible(&sk->protinfo.af_unix.peer_wait); if (msg->msg_name) unix_copy_addr(msg, skb->sk); @@ -1380,7 +1365,7 @@ * Sleep until data has arrive. But check for races.. */ -static void unix_stream_data_wait(unix_socket * sk) +static long unix_stream_data_wait(unix_socket * sk, long timeo) { DECLARE_WAITQUEUE(wait, current); @@ -1394,12 +1379,13 @@ if (skb_queue_len(&sk->receive_queue) || sk->err || (sk->shutdown & RCV_SHUTDOWN) || - signal_pending(current)) + signal_pending(current) || + !timeo) break; sk->socket->flags |= SO_WAITDATA; unix_state_runlock(sk); - schedule(); + timeo = schedule_timeout(timeo); unix_state_rlock(sk); sk->socket->flags &= ~SO_WAITDATA; } @@ -1407,6 +1393,7 @@ __set_current_state(TASK_RUNNING); remove_wait_queue(sk->sleep, &wait); unix_state_runlock(sk); + return timeo; } @@ -1415,12 +1402,12 @@ int flags, struct scm_cookie *scm) { struct sock *sk = sock->sk; - int noblock = flags & MSG_DONTWAIT; struct sockaddr_un *sunaddr=msg->msg_name; int copied = 0; int check_creds = 0; - int target = 1; + int target; int err = 0; + long timeo; err = -EINVAL; if (sk->state != TCP_ESTABLISHED) @@ -1430,9 +1417,8 @@ if (flags&MSG_OOB) goto out; - if (flags&MSG_WAITALL) - target = size; - + target = sock_rcvlowat(sk, flags&MSG_WAITALL, size); + timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT); msg->msg_namelen = 0; @@ -1462,11 +1448,11 @@ if (sk->shutdown & RCV_SHUTDOWN) break; err = -EAGAIN; - if (noblock) + if (!timeo) break; up(&sk->protinfo.af_unix.readsem); - unix_stream_data_wait(sk); + timeo = unix_stream_data_wait(sk, timeo); if (signal_pending(current)) { err = -ERESTARTSYS; @@ -1569,10 +1555,9 @@ unix_state_wlock(other); other->shutdown |= peer_mode; unix_state_wunlock(other); + other->state_change(other); if (peer_mode&RCV_SHUTDOWN) - other->data_ready(other,0); - else - other->state_change(other); + sock_wake_async(sk->socket,1,POLL_HUP); } if (other) sock_put(other); @@ -1589,14 +1574,11 @@ switch(cmd) { - - case TIOCOUTQ: - amount = sk->sndbuf - atomic_read(&sk->wmem_alloc); - if(amount<0) - amount=0; + case SIOCOUTQ: + amount = atomic_read(&sk->wmem_alloc); err = put_user(amount, (int *)arg); break; - case TIOCINQ: + case SIOCINQ: { struct sk_buff *skb; if (sk->state==TCP_LISTEN) { @@ -1630,11 +1612,11 @@ /* exceptional events? */ if (sk->err) mask |= POLLERR; - if (sk->shutdown & RCV_SHUTDOWN) + if (sk->shutdown == SHUTDOWN_MASK) mask |= POLLHUP; /* readable? */ - if (!skb_queue_empty(&sk->receive_queue)) + if (!skb_queue_empty(&sk->receive_queue) || (sk->shutdown&RCV_SHUTDOWN)) mask |= POLLIN | POLLRDNORM; /* Connection-based need to check for termination and startup */ diff -ur --new-file old/linux/net/wanrouter/wanmain.c new/linux/net/wanrouter/wanmain.c --- old/linux/net/wanrouter/wanmain.c Thu Aug 26 23:13:59 1999 +++ new/linux/net/wanrouter/wanmain.c Sat Jan 22 21:31:10 2000 @@ -9,15 +9,16 @@ * o Logical connection management (switched virtual circuits) * o Protocol encapsulation/decapsulation * -* Author: Gene Kozin +* Author: Gideon Hack * -* Copyright: (c) 1995-1997 Sangoma Technologies Inc. +* Copyright: (c) 1995-1999 Sangoma Technologies 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. * ============================================================================ +* Oct 01, 1999 Gideon Hack Update for s514 PCI card * Dec 27, 1996 Gene Kozin Initial version (based on Sangoma's WANPIPE) * Jan 16, 1997 Gene Kozin router_devlist made public * Jan 31, 1997 Alan Cox Hacked it about a bit for 2.1 @@ -31,8 +32,10 @@ * kernel memory and copy configuration data to * kernel space (for big firmwares) * May 19, 1999 Arnaldo Melo __init in wanrouter_init +* Jun 02, 1999 Gideon Hack Updates for Linux 2.0.X and 2.2.X kernels. *****************************************************************************/ +#include #include #include /* offsetof(), etc. */ #include /* return codes */ @@ -48,7 +51,11 @@ #include /* WAN router API definitions */ #include /* __init et al. */ -/****** Defines and Macros **************************************************/ + + +/* + * Defines and Macros + */ #ifndef min #define min(a,b) (((a)<(b))?(a):(b)) @@ -57,48 +64,49 @@ #define max(a,b) (((a)>(b))?(a):(b)) #endif -/****** Function Prototypes *************************************************/ - /* - * Kernel loadable module interface. + * Function Prototypes */ +/* + * Kernel loadable module interface. + */ #ifdef MODULE int init_module (void); void cleanup_module (void); #endif -/* +/* * WAN device IOCTL handlers */ -static int device_setup (wan_device_t* wandev, wandev_conf_t* u_conf); -static int device_stat (wan_device_t* wandev, wandev_stat_t* u_stat); -static int device_shutdown (wan_device_t* wandev); -static int device_new_if (wan_device_t* wandev, wanif_conf_t* u_conf); -static int device_del_if (wan_device_t* wandev, char* u_name); - -/* +static int device_setup(wan_device_t *wandev, wandev_conf_t *u_conf); +static int device_stat(wan_device_t *wandev, wandev_stat_t *u_stat); +static int device_shutdown(wan_device_t *wandev); +static int device_new_if(wan_device_t *wandev, wanif_conf_t *u_conf); +static int device_del_if(wan_device_t *wandev, char *u_name); + +/* * Miscellaneous */ -static wan_device_t* find_device (char* name); -static int delete_interface (wan_device_t* wandev, char* name, int forse); +static wan_device_t *find_device (char *name); +static int delete_interface (wan_device_t *wandev, char *name, int force); /* * Global Data */ static char fullname[] = "WAN Router"; -static char copyright[] = "(c) 1995-1997 Sangoma Technologies Inc."; +static char copyright[] = "(c) 1995-1999 Sangoma Technologies Inc."; static char modname[] = ROUTER_NAME; /* short module name */ -wan_device_t * router_devlist = NULL; /* list of registered devices */ -static int devcnt = 0; +wan_device_t* router_devlist = NULL; /* list of registered devices */ +static int devcnt = 0; -/* - * Organizationally Unique Identifiers for encapsulation/decapsulation +/* + * Organize Unique Identifiers for encapsulation/decapsulation */ - + static unsigned char oui_ether[] = { 0x00, 0x00, 0x00 }; #if 0 static unsigned char oui_802_2[] = { 0x00, 0x80, 0xC2 }; @@ -115,8 +123,7 @@ fullname, ROUTER_VERSION, ROUTER_RELEASE, copyright); err = wanrouter_proc_init(); if (err) - printk(KERN_ERR "%s: can't create entry in proc filesystem!\n", - modname); + printk(KERN_ERR "%s: can't create entry in proc filesystem!\n", modname); /* * Initialise compiled in boards @@ -138,14 +145,14 @@ */ /* - * Module 'insert' entry point. - * o print announcement - * o initialize static data - * o create /proc/net/router directory and static entries + * Module 'insert' entry point. + * o print announcement + * o initialize static data + * o create /proc/net/router directory and static entries * - * Return: 0 Ok + * Return: 0 Ok * < 0 error. - * Context: process + * Context: process */ int init_module (void) @@ -161,10 +168,10 @@ } /* - * Module 'remove' entry point. - * o delete /proc/net/router directory and static entries. + * Module 'remove' entry point. + * o delete /proc/net/router directory and static entries. */ - + void cleanup_module (void) { wanrouter_proc_cleanup(); @@ -173,33 +180,34 @@ #endif /* - * Kernel APIs + * Kernel APIs */ /* - * Register WAN device. - * o verify device credentials - * o create an entry for the device in the /proc/net/router directory - * o initialize internally maintained fields of the wan_device structure - * o link device data space to a singly-linked list - * o if it's the first device, then start kernel 'thread' - * o increment module use count + * Register WAN device. + * o verify device credentials + * o create an entry for the device in the /proc/net/router directory + * o initialize internally maintained fields of the wan_device structure + * o link device data space to a singly-linked list + * o if it's the first device, then start kernel 'thread' + * o increment module use count * - * Return: - * 0 Ok - * < 0 error. + * Return: + * 0 Ok + * < 0 error. * - * Context: process + * Context: process */ -int register_wan_device(wan_device_t* wandev) + +int register_wan_device(wan_device_t *wandev) { int err, namelen; if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC) || (wandev->name == NULL)) return -EINVAL; - + namelen = strlen(wandev->name); if (!namelen || (namelen > WAN_DRVNAME_SZ)) return -EINVAL; @@ -215,12 +223,10 @@ * Register /proc directory entry */ err = wanrouter_proc_add(wandev); - if (err) - { + if (err) { printk(KERN_ERR "%s: can't create /proc/net/router/%s entry!\n", - modname, wandev->name) - ; + modname, wandev->name); return err; } @@ -250,8 +256,8 @@ * Context: process */ - -int unregister_wan_device(char* name) + +int unregister_wan_device(char *name) { wan_device_t *wandev, *prev; @@ -269,8 +275,7 @@ printk(KERN_INFO "%s: unregistering WAN device %s\n", modname, name); #endif - if (wandev->state != WAN_UNCONFIGURED) - { + if (wandev->state != WAN_UNCONFIGURED) { while(wandev->dev) delete_interface(wandev, wandev->dev->name, 1); if (wandev->shutdown) @@ -359,7 +364,6 @@ "on interface %s!\n", modname, skb->data[cnt+1], skb->data[cnt+2], skb->data[cnt+3], dev->name); - ; return 0; } ethertype = *((unsigned short*)&skb->data[cnt+4]); @@ -371,8 +375,7 @@ default: printk(KERN_INFO "%s: unsupported NLPID 0x%02X on interface %s!\n", - modname, skb->data[cnt], dev->name) - ; + modname, skb->data[cnt], dev->name); return 0; } skb->protocol = ethertype; @@ -382,18 +385,19 @@ return ethertype; } + /* * WAN device IOCTL. * o find WAN device associated with this node * o execute requested action or pass command to the device driver */ -int wanrouter_ioctl(struct inode* inode, struct file* file, +int wanrouter_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int err = 0; - struct proc_dir_entry* dent; - wan_device_t* wandev; + struct proc_dir_entry *dent; + wan_device_t *wandev; if (!capable(CAP_NET_ADMIN)){ return -EPERM; @@ -410,8 +414,7 @@ if (wandev->magic != ROUTER_MAGIC) return -EINVAL; - switch (cmd) - { + switch (cmd) { case ROUTER_SETUP: err = device_setup(wandev, (void*)arg); break; @@ -439,8 +442,7 @@ if ((cmd >= ROUTER_USER) && (cmd <= ROUTER_USER_MAX) && wandev->ioctl) - err = wandev->ioctl(wandev, cmd, arg) - ; + err = wandev->ioctl(wandev, cmd, arg); else err = -EINVAL; } return err; @@ -458,51 +460,52 @@ * o call driver's setup() entry point */ -static int device_setup (wan_device_t* wandev, wandev_conf_t* u_conf) +static int device_setup (wan_device_t *wandev, wandev_conf_t *u_conf) { - void* data; + void *data = NULL; wandev_conf_t *conf; - int err= -EINVAL; + int err = -EINVAL; if (wandev->setup == NULL) /* Nothing to do ? */ return 0; - + conf = kmalloc(sizeof(wandev_conf_t), GFP_KERNEL); if (conf == NULL) return -ENOBUFS; - - if(copy_from_user(conf, u_conf, sizeof(wandev_conf_t))) - { + + if(copy_from_user(conf, u_conf, sizeof(wandev_conf_t))) { kfree(conf); return -EFAULT; } - if (conf->magic != ROUTER_MAGIC) - goto bail; + if (conf->magic != ROUTER_MAGIC) { + kfree(conf); + return -EINVAL; + } - if (conf->data_size && conf->data) - { - if(conf->data_size > 128000 || conf->data_size < 0){ - goto bail; + if (conf->data_size && conf->data) { + if(conf->data_size > 128000 || conf->data_size < 0) { + kfree(conf); + return -EINVAL;; } + data = vmalloc(conf->data_size); - if (data) - { - if(!copy_from_user(data, conf->data, conf->data_size)) - { + if (data) { + if(!copy_from_user(data, conf->data, conf->data_size)){ conf->data=data; err = wandev->setup(wandev,conf); } else err = -EFAULT; } - else + else err = -ENOBUFS; - + if (data) vfree(data); + } -bail: + kfree(conf); return err; } @@ -537,7 +540,7 @@ * Get WAN device status & statistics. */ -static int device_stat (wan_device_t* wandev, wandev_stat_t* u_stat) +static int device_stat (wan_device_t *wandev, wandev_stat_t *u_stat) { wandev_stat_t stat; @@ -553,6 +556,7 @@ if(copy_to_user(u_stat, &stat, sizeof(stat))) return -EFAULT; + return 0; } @@ -569,7 +573,7 @@ static int device_new_if (wan_device_t* wandev, wanif_conf_t* u_conf) { wanif_conf_t conf; - struct net_device* dev; + struct net_device *dev; int err; if ((wandev->state == WAN_UNCONFIGURED) || (wandev->new_if == NULL)) @@ -587,8 +591,7 @@ memset(dev, 0, sizeof(struct net_device)); err = wandev->new_if(wandev, dev, &conf); - if (!err) - { + if (!err) { /* Register network interface. This will invoke init() * function supplied by the driver. If device registered * successfully, add it to the interface list. @@ -598,15 +601,13 @@ else if (dev_get(dev->name)) err = -EEXIST; /* name already exists */ - else - { + else { #ifdef WANDEBUG printk(KERN_INFO "%s: registering interface %s...\n", modname, dev->name); #endif err = register_netdev(dev); - if (!err) - { + if (!err) { cli(); /***** critical section start *****/ dev->slave = wandev->dev; wandev->dev = dev; @@ -622,25 +623,28 @@ return err; } + /* * Delete WAN logical channel. * o verify user address space * o copy configuration data to kernel address space */ -static int device_del_if (wan_device_t* wandev, char* u_name) +static int device_del_if (wan_device_t *wandev, char *u_name) { char name[WAN_IFNAME_SZ + 1]; if (wandev->state == WAN_UNCONFIGURED) return -ENODEV; - + memset(name, 0, sizeof(name)); + if(copy_from_user(name, u_name, WAN_IFNAME_SZ)) return -EFAULT; return delete_interface(wandev, name, 0); } + /* * Miscellaneous Functions */ @@ -650,9 +654,9 @@ * Return pointer to the WAN device data space or NULL if device not found. */ -static wan_device_t* find_device (char* name) +static wan_device_t *find_device(char *name) { - wan_device_t* wandev; + wan_device_t *wandev; for (wandev = router_devlist;wandev && strcmp(wandev->name, name); wandev = wandev->next); @@ -676,7 +680,7 @@ * sure that opened interfaces are not removed! */ -static int delete_interface (wan_device_t* wandev, char* name, int force) +static int delete_interface (wan_device_t *wandev, char *name, int force) { struct net_device *dev, *prev; @@ -687,16 +691,16 @@ if (dev == NULL) return -ENODEV; /* interface not found */ - if (dev->start) - { - if (force) - { + if (dev->start) { + if (force) { printk(KERN_WARNING - "%s: deleting opened interface %s!\n",modname, name); + "%s: deleting opened interface %s!\n", + modname, name); } else return -EBUSY; /* interface in use */ } + if (wandev->del_if) wandev->del_if(wandev, dev); @@ -708,7 +712,7 @@ --wandev->ndev; sti(); /****** critical section end ******/ - printk("Unregistering '%s'\n", dev->name); + printk("Unregistering '%s'\n", dev->name); unregister_netdev(dev); kfree(dev); return 0; @@ -722,4 +726,3 @@ /* * End */ - diff -ur --new-file old/linux/net/wanrouter/wanproc.c new/linux/net/wanrouter/wanproc.c --- old/linux/net/wanrouter/wanproc.c Sun Dec 5 17:42:03 1999 +++ new/linux/net/wanrouter/wanproc.c Sat Jan 22 21:31:10 2000 @@ -4,21 +4,23 @@ * This module is completely hardware-independent and provides * access to the router using Linux /proc filesystem. * -* Author: Gene Kozin +* Author: Gideon Hack * -* Copyright: (c) 1995-1997 Sangoma Technologies Inc. +* Copyright: (c) 1995-1999 Sangoma Technologies 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. * ============================================================================ +* Jun 02, 1999 Gideon Hack Updates for Linux 2.2.X kernels. * Jun 29, 1997 Alan Cox Merged with 1.0.3 vendor code * Jan 29, 1997 Gene Kozin v1.0.1. Implemented /proc read routines * Jan 30, 1997 Alan Cox Hacked around for 2.1 * Dec 13, 1996 Gene Kozin Initial version (based on Sangoma's WANPIPE) *****************************************************************************/ +#include #include #include /* offsetof(), etc. */ #include /* return codes */ @@ -36,6 +38,8 @@ /****** Defines and Macros **************************************************/ +#define PROC_STATS_FORMAT "%30s: %12lu\n" + #ifndef min #define min(a,b) (((a)<(b))?(a):(b)) #endif @@ -45,11 +49,12 @@ #define PROC_BUFSZ 4000 /* buffer size for printing proc info */ + /****** Data Types **********************************************************/ typedef struct wan_stat_entry { - struct wan_stat_entry * next; + struct wan_stat_entry *next; char *description; /* description string */ void *data; /* -> data */ unsigned data_type; /* data type */ @@ -83,7 +88,6 @@ /* * Generic /proc/net/router/ file and inode operations */ - static struct file_operations router_fops = { NULL, /* lseek */ @@ -266,7 +270,7 @@ /* * Read router proc directory entry. - * This is universal routine for reading all entries in /proc/net/router + * This is universal routine for reading all entries in /proc/net/wanrouter * directory. Each directory entry contains a pointer to the 'method' for * preparing data for that entry. * o verify arguments @@ -300,8 +304,7 @@ pos = dent->get_info(page, dent->data, 0, 0); offs = file->f_pos; - if (offs < pos) - { + if (offs < pos) { len = min(pos - offs, count); if(copy_to_user(buf, (page + offs), len)) return -EFAULT; @@ -325,15 +328,14 @@ strcpy(buf, conf_hdr); for (wandev = router_devlist; wandev && (cnt < (PROC_BUFSZ - 120)); - wandev = wandev->next) - { + wandev = wandev->next) { if (wandev->state) cnt += sprintf(&buf[cnt], "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n", wandev->name, wandev->ioport, wandev->irq, wandev->dma, - virt_to_phys(wandev->maddr), + wandev->maddr, wandev->msize, wandev->hw_opt[0], wandev->hw_opt[1], @@ -351,13 +353,16 @@ static int status_get_info(char* buf, char** start, off_t offs, int len) { - int cnt = sizeof(stat_hdr) - 1; + int cnt = 0; wan_device_t* wandev; - strcpy(buf, stat_hdr); + + cnt += sprintf(&buf[cnt], "\nSTATUS FOR PORT 0\n\n"); + strcpy(&buf[cnt], stat_hdr); + cnt += sizeof(stat_hdr) - 1; + for (wandev = router_devlist; wandev && (cnt < (PROC_BUFSZ - 80)); - wandev = wandev->next) - { + wandev = wandev->next) { if (!wandev->state) continue; cnt += sprintf(&buf[cnt], "%-15s|%-7s|%-9s|%-8s|%9u|%5u|%3u |", @@ -367,10 +372,10 @@ wandev->clocking ? "internal" : "external", wandev->bps, wandev->mtu, - wandev->ndev) - ; - switch (wandev->state) - { + wandev->ndev); + + switch (wandev->state) { + case WAN_UNCONFIGURED: cnt += sprintf(&buf[cnt], "%-12s\n", "unconfigured"); break; @@ -407,56 +412,64 @@ { wan_device_t* wandev = (void*)start; int cnt = 0; + int rslt = 0; if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC)) return 0; if (!wandev->state) - return sprintf(&buf[cnt], "device is not configured!\n") - ; + return sprintf(&buf[cnt], "device is not configured!\n"); /* Update device statistics */ - if (wandev->update) wandev->update(wandev); + if (wandev->update) { - cnt += sprintf(&buf[cnt], "%30s: %12lu\n", - "total frames received", wandev->stats.rx_packets) - ; - cnt += sprintf(&buf[cnt], "%30s: %12lu\n", - "receiver overrun errors", wandev->stats.rx_over_errors) - ; - cnt += sprintf(&buf[cnt], "%30s: %12lu\n", - "CRC errors", wandev->stats.rx_crc_errors) - ; - cnt += sprintf(&buf[cnt], "%30s: %12lu\n", - "frame length errors", wandev->stats.rx_length_errors) - ; - cnt += sprintf(&buf[cnt], "%30s: %12lu\n", - "frame format errors", wandev->stats.rx_frame_errors) - ; - cnt += sprintf(&buf[cnt], "%30s: %12lu\n", - "aborted frames received", wandev->stats.rx_missed_errors) - ; - cnt += sprintf(&buf[cnt], "%30s: %12lu\n", - "reveived frames dropped", wandev->stats.rx_dropped) - ; - cnt += sprintf(&buf[cnt], "%30s: %12lu\n", - "other receive errors", wandev->stats.rx_errors) - ; - cnt += sprintf(&buf[cnt], "\n%30s: %12lu\n", - "total frames transmitted", wandev->stats.tx_packets) - ; - cnt += sprintf(&buf[cnt], "%30s: %12lu\n", - "aborted frames transmitted", wandev->stats.tx_aborted_errors) - ; - cnt += sprintf(&buf[cnt], "%30s: %12lu\n", - "transmit frames dropped", wandev->stats.tx_dropped) - ; - cnt += sprintf(&buf[cnt], "%30s: %12lu\n", - "transmit collisions", wandev->stats.collisions) - ; - cnt += sprintf(&buf[cnt], "%30s: %12lu\n", - "other transmit errors", wandev->stats.tx_errors) - ; - return cnt; + rslt = wandev->update(wandev); + if(rslt) { + switch (rslt) { + case -EAGAIN: + return sprintf(&buf[cnt], "Device is busy!\n"); + + default: + return sprintf(&buf[cnt], + "Device is not configured!\n"); + } + } + } + + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "total packets received", wandev->stats.rx_packets); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "total packets transmitted", wandev->stats.tx_packets); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "total bytes received", wandev->stats.rx_bytes); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "total bytes transmitted", wandev->stats.tx_bytes); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "bad packets received", wandev->stats.rx_errors); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "packet transmit problems", wandev->stats.tx_errors); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "received frames dropped", wandev->stats.rx_dropped); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "transmit frames dropped", wandev->stats.tx_dropped); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "multicast packets received", wandev->stats.multicast); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "transmit collisions", wandev->stats.collisions); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "receive length errors", wandev->stats.rx_length_errors); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "receiver overrun errors", wandev->stats.rx_over_errors); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "CRC errors", wandev->stats.rx_crc_errors); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "frame format errors (aborts)", wandev->stats.rx_frame_errors); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "receiver fifo overrun", wandev->stats.rx_fifo_errors); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "receiver missed packet", wandev->stats.rx_missed_errors); + cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT, + "aborted frames transmitted", wandev->stats.tx_aborted_errors); + return cnt; } /* @@ -490,3 +503,8 @@ } #endif + +/* + * End + */ + .