diff -u --recursive --new-file v2.2.2/linux/CREDITS linux/CREDITS --- v2.2.2/linux/CREDITS Tue Feb 23 15:21:31 1999 +++ linux/CREDITS Sun Mar 7 16:15:39 1999 @@ -1061,6 +1061,14 @@ S: L3R 8B2 S: Canada +N: Russell Kroll +E: rkroll@exploits.org +W: http://www.exploits.org/ +D: V4L Aztech radio card driver, mods to Aimslab driver +S: Post Office Box 49458 +S: Colorado Springs, Colorado 80949-9458 +S: USA + N: Gero Kuhlmann E: gero@gkminix.han.de D: mounting root via NFS @@ -2003,6 +2011,14 @@ S: Chudenicka 8 S: 10200 Prague 10, Hostivar S: Czech Republic + +N: James R. Van Zandt +E: jrv@vanzandt.mv.com +P: 1024/E298966D F0 37 4F FD E5 7E C5 E6 F1 A0 1E 22 6F 46 DA 0C +D: Author and maintainer of the Double Talk speech synthesizer driver +S: 27 Spencer Drive +S: Nashua, New Hampshire 03062 +S: USA N: Andrew Veliath E: andrewtv@usa.net diff -u --recursive --new-file v2.2.2/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.2.2/linux/Documentation/Configure.help Tue Feb 23 15:21:31 1999 +++ linux/Documentation/Configure.help Mon Mar 8 10:14:35 1999 @@ -1089,25 +1089,6 @@ recommended to read the NET-3-HOWTO, available via FTP (user: anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. -Network aliasing -CONFIG_NET_ALIAS - If you say Y here, you will be able to set multiple network - addresses on the same low-level network device driver. This is - typically used for services that act differently based on the - address they listen on (e.g. "multihosting" or "virtual domains" or - "virtual hosting services" on the web server apache and the ftp - server wuftpd -- read the Virtual-Services-HOWTO, available via FTP - (user: anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO) - or for connecting to different logical networks through the same - physical interface (most commonly an Ethernet networking card). See - Documentation/networking/alias.txt for more info. - - This is the generic part, later when configuring network protocol - options you will be asked for protocol-specific aliasing support, - and you will have to say Y to at least one of them, most likely to - "IP: aliasing support". If you need this feature (for any protocol, - like IP) say Y; if unsure, say N. - Socket filtering CONFIG_FILTER The Linux Socket Filter is derived from the Berkeley Packet Filter. @@ -2099,7 +2080,7 @@ CONFIG_PNP_PARPORT Some IEEE-1284 conforming parallel-port devices can identify themselves when requested. Say Y to enable this feature, or M to - compile it as a module (parport_ieee1284.o). If in doubt, say N. + compile it as a module (parport_probe.o). If in doubt, say N. Enable loadable module support CONFIG_MODULES @@ -2735,20 +2716,6 @@ enabled. Those programs that would benefit from disabling this facility can do it on a per connection basis themselves. -IP: Drop source routed frames -CONFIG_IP_NOSR - Usually, the originator of an IP frame (packet) specifies only the - destination, and the hosts along the way do the routing, i.e. they - decide how to forward the frame. However, there is a feature of the - IP protocol that allows to specify the full route for a given frame - already at its origin. A frame with such a fully specified route is - called "source routed". The question now is whether we should honour - these route requests when such frames arrive, or if we should drop - all those frames instead. Honouring them can introduce security - problems (and is rarely a useful feature), and hence it is - recommended that you say Y here unless you really know what you're - doing. - IP: Allow large windows (not recommended if <16 MB of memory) CONFIG_SKB_LARGE On high speed, long distance networks the performance limit on @@ -4203,6 +4170,17 @@ say M here and read Documentation/modules.txt. The module will be called initio.o +Initio 91XXU(W) SCSI support +CONFIG_SCSI_INITIO + This is support for the Initio 91XXU(W) SCSI host adapter. + Please read the SCSI-HOWTO, available via FTP (user: anonymous) at + ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + + If you want to compile this as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read Documentation/modules.txt. The module will be + called initio.o + PAS16 SCSI support CONFIG_SCSI_PAS16 This is support for a SCSI host adapter. It is explained in section @@ -4216,6 +4194,17 @@ The module will be called pas16.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. +Initio INI-A100U2W SCSI support +CONFIG_SCSI_INIA100 + This is support for the Initio INI-A100U2W SCSI host adapter. + Please read the SCSI-HOWTO, available via FTP (user: anonymous) at + ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + + If you want to compile this as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read Documentation/modules.txt. The module will be + called a100u2w.o + PCI2000 support CONFIG_SCSI_PCI2000 This is support for the PCI2000I EIDE interface card which acts as a @@ -4408,6 +4397,23 @@ say M here and read Documentation/modules.txt. The module will be called NCR53c406.o. +Symbios Logic sym53c416 support +CONFIG_SCSI_SYM53C416 + This is support for the sym53c416 SCSI host adapter. This is the + SCSI adapter that comes with some hp scanners. This driver requires that + the sym53c416 is configured first using some sort of pnp configuration + program (e.g. isapnp) or by a PnP aware BIOS. If you are using isapnp then + you need to compile it as a module and then load it using insmod after + isapnp has run. The parameters of the configured card(s) should be passed + to the driver. The format is: + + insmod sym53c416 sym53c416=, [sym53c416_1=,] + + There is support for up to four adapters. If you want to compile this + driver as a module ( = code which can be inserted in and removed from + the running kernel whenever you want), say M here and read + Documentation/modules.txt. + Tekram DC390(T) and Am53/79C974 (PCscsi) SCSI support CONFIG_SCSI_DC390T This driver supports PCI SCSI host adapters based on the Am53C974A @@ -8485,6 +8491,15 @@ This driver does not exist at this point, so you might as well say N. +Double Talk PC internal speech card support +CONFIG_DTLK + This driver is for the DoubleTalk PC, a speech synthesizer + manufactured by RC Systems (http://www.rcsys.com/). It is also + called the `internal DoubleTalk'. If you want to compile this as a + module ( = code which can be inserted in and removed from the + running kernel whenever you want), say M here and read + Documentation/modules.txt. The module will be called dtlk.o. + Advanced Power Management CONFIG_APM APM is a BIOS specification for saving power using several different @@ -8924,6 +8939,20 @@ here (the module will be called sound.o) if you haven't found a driver for your sound card above, then pick your driver from the list below. + +Persistent DMA buffers +CONFIG_SOUND_DMAP + Linux can often have problems allocating DMA buffers for ISA cards on + machines with more than 16MB of RAM. This is because ISA DMA buffers + must exist below the 16MB boundry and it is quite possible that we + can't find a large enough free block in this region after the machine + has been running for any amount of time. If you say Y here the DMA + buffers (64Kb) will be allocated at boot time and kept until the + shutdown. This option is only usefull if you say Y to OSS sound + modules. If you say M to OSS sound modules then you can just pass to + the sound.o module a "dmabuf=1" command-line argument. + + Say Y unless you have 16MB or less RAM or a PCI sound card. Support for Aztech Sound Galaxy (non-PnP) cards CONFIG_SOUND_SGALAXY @@ -10503,6 +10532,44 @@ CONFIG_RADIO_SF16FMI_PORT Enter the I/O port of your SF16FMI radio card. +Typhoon Radio +CONFIG_RADIO_TYPHOON + Choose Y here if you have one of these FM radio cards, and then fill + in the port address and the frequency used for muting below. + + In order to control your radio card, you will need to use programs + that are compatible with the Video for Linux API. Information on + this API and pointers to "v4l" programs may be found on the WWW at + http://roadrunner.swansea.uk.linux.org/v4l.shtml; to browse the WWW, + you need to have access to a machine on the Internet that has a + program like lynx or netscape. + + If you want to compile this driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read Documentation/modules.txt. The module will be + called radio-typhoon.o + +Support for /proc/radio-typhoon +CONFIG_RADIO_TYPHOON_PROC_FS + Say Y here if you want the typhoon radio card driver to write + status information (frequency, volume, muted, mute frequency, + base address) to /proc/radio-typhoon. The file can be viewed with + your favorite pager (i.e. use "more /proc/radio-typhoon" or "less + /proc/radio-typhoon" or simply "cat /proc/radio-typhoon"). + +Typhoon I/O port (0x316 or 0x336) +CONFIG_RADIO_TYPHOON_PORT + Enter the I/O port of your Typhoon or EcoRadio radio card. + +Typhoon frequency set when muting the device (kHz) +CONFIG_RADIO_TYPHOON_MUTEFREQ + Enter the frequency used for muting the radio. The device is never + completely silent. If the volume is just turned down, you can still + hear silent voices and music. For that reason, the frequency of the + radio device is set to the frequency you can enter here whenever + the device is muted. There should be no local radio station at that + frequency. + Zoltrix Radio CONFIG_RADIO_ZOLTRIX Choose Y here if you have one of these FM radio cards, and then fill @@ -10748,24 +10815,10 @@ Documentation/modules.txt. IrLAN emulates an Ethernet and makes it possible to put up a wireless LAN using infrared beams. -IrLAN Client Protocol -CONFIG_IRLAN_CLIENT - Say Y here if you want to build support for the IrLAN client - protocol. If you want to compile it as a module, say M here and read - Documentation/modules.txt. The IrLAN client protocol can be used to - talk with infrared access points like the HP NetbeamIR, or the ESI - JetEye NET. You can also connect to another Linux machine running - the IrLAN server protocol for ad-hoc networking! - -IrLAN Server Protocol -CONFIG_IRLAN_SERVER - Say Y here if you want to build support for infrared LAN access. If - you want to compile it as a module, say M here and read - Documentation/modules.txt. The IrLAN server protocol makes it - possible to set up a wireless LAN with a machine running the IrLAN - client protocol. Notice that the IrLAN server protocol currently - only emulates an access point and does not implement the ad-hoc - specification of IrLAN, but this will not be noticeable by the user. + The IrLAN protocol can be used to talk with infrared access points + like the HP NetbeamIR, or the ESI JetEye NET. You can also connect + to another Linux machine running the IrLAN protocol for ac-hoc + networking! IrOBEX Protocol CONFIG_IROBEX @@ -10877,6 +10930,15 @@ the normal 9-pin serial port connector, and can currently only be used by IrTTY. To activate support for Tekram dongles you will have to insert "irattach -d tekram" in the /etc/irda/drivers script. + +Greenwich GIrBIL dongle +CONFIG_GIRBIL_DONGLE + Say Y here if you want to build support for the Greenwich GIrBIL + dongle. If you want to compile it as a module, say M here and read + Documentation/modules.txt. The Greenwich dongle attaches to the + normal 9-pin serial port connector, and can currently only be used + by IrTTY. To activate support for Greenwich dongles you will have to + insert "irattach -d girbil" in the /etc/irda/drivers script. VME (Motorola and BVM) support CONFIG_VME diff -u --recursive --new-file v2.2.2/linux/Documentation/filesystems/fat_cvf.txt linux/Documentation/filesystems/fat_cvf.txt --- v2.2.2/linux/Documentation/filesystems/fat_cvf.txt Wed Jun 24 22:54:02 1998 +++ linux/Documentation/filesystems/fat_cvf.txt Sun Feb 28 09:47:37 1999 @@ -1,4 +1,4 @@ -This is the main documentation for the CVF-FAT filesystem extension. 31DEC1997 +This is the main documentation for the CVF-FAT filesystem extension. 18Nov1998 Table of Contents: @@ -37,14 +37,9 @@ CVF filesystems cannot do bmap. It's impossible in principle. Thus all actions that require bmap do not work (swapping, writable mmapping). Read-only mmapping works because the FAT driver has a hack for this - situation :) Well, with some tricks writable mmapping could work, - (proof: they did under old dmsdos), but..... (hint: readpage/writepage - interface functions) ...... but the FAT driver has to support them - first without bmap :-) - - We'll see. If someone points me to an application that needs this, I - might be persuaded to implement it :). CVF-FAT is already prepared - for using readpage. + situation :) Well, writable mmapping should now work using the readpage + interface function which has been hacked into the FAT driver just for + CVF-FAT :) - attention, DOSEmu users @@ -66,11 +61,28 @@ cvf_format=xxx Forces the driver to use the CVF module "xxx" instead of auto-detection. - This is only necessary if the CVF format is not recognized correctly + Without this option, the CVF-FAT interface asks all currently loaded + CVF modules whether they recognize the CVF. Therefore, this option is + only necessary if the CVF format is not recognized correctly because of bugs or incompatibilities in the CVF modules. (It skips the detect_cvf call.) "xxx" may be the text "none" (without the quotes) to inhibit using any of the loaded CVF modules, just in case a CVF - module insists on mounting plain FAT filesystems by misunderstanding :) + module insists on mounting plain FAT filesystems by misunderstanding. + "xxx" may also be the text "autoload", which has a special meaning for + a module loader, but does not skip auto-detection. + + If the kernel supports kmod, the cvf_format=xxx option also controls + on-demand CVF module loading. Without this option, nothing is loaded + on demand. With cvf_format=xxx, a module "xxx" is requested automatically + before mounting the compressed filesystem (unless "xxx" is "none"). In + case there is a difference between the CVF format name and the module + name, setup aliases in your modules configuration. If the string "xxx" + is "autoload", a non-existent module "cvf_autoload" is requested which + can be used together with a special modules configuration (alias and + pre-install statements) in order to load more than one CVF module, let + them detect automatically which kind of CVF is to be mounted, and only + keep the "right" module in memory. For examples please refer to the + dmsdos documentation (ftp and http addresses see below). cvf_options=yyy Option string passed to the CVF module. I.e. only the "yyy" is passed @@ -80,8 +92,8 @@ misinterpretation by the FAT driver, which would recognize the text after a comma as a FAT driver option and might get confused or print strange error messages. The documentation for the CVF module should - offer a different separation symbol, for example the dot ".", which - is only valid inside the string "yyy". + offer a different separation symbol, for example the dot "." or the + plus sign "+", which is only valid inside the string "yyy". 4. Description of the CVF-FAT interface @@ -120,11 +132,11 @@ is set, mmap is set to generic_file_mmap and readpage is caught and redirected to the cvf_readpage function. If it is not set, readpage is set to generic_readpage and mmap is caught and redirected - to cvf_mmap. + to cvf_mmap. (If you want writable mmap use the readpage interface.) - detect_cvf: A function that is called to decide whether the filesystem is a CVF of the type the module supports. The detect_cvf function must return 0 - for "NO, I DON'T KNOW THIS GARBAGE" or anything !=0 for "YES, THIS IS + for "NO, I DON'T KNOW THIS GARBAGE" or anything >0 for "YES, THIS IS THE KIND OF CVF I SUPPORT". The function must maintain the module usage counters for safety, i.e. do MOD_INC_USE_COUNT at the beginning and MOD_DEC_USE_COUNT at the end. The function *must not* assume that @@ -180,11 +192,19 @@ that has not been previously registered. The code uses the version id to distinguish the modules, so be sure to keep it unique. -5. CVS Modules +5. CVF Modules ------------------------------------------------------------------------------ Refer to the dmsdos module (the successor of the dmsdos filesystem) for a sample implementation. It can currently be found at - ftp://fb9nt.uni-duisburg.de/pub/linux/dmsdos + ftp://fb9nt.uni-duisburg.de/pub/linux/dmsdos/dmsdos-x.y.z.tgz + ftp://sunsite.unc.edu/pub/Linux/system/Filesystems/dosfs/dmsdos-x.y.z.tgz + ftp://ftp.uni-stuttgart.de/pub/systems/linux/local/system/dmsdos-x.y.z.tgz + +(where x.y.z is to be replaced with the actual version number). Full +documentation about dmsdos is included in the dmsdos package, but can also +be found at + http://fb9nt.uni-duisburg.de/mitarbeiter/gockel/software/dmsdos/index.html + http://www.yk.rim.or.jp/~takafumi/dmsdos/index.html (in Japanese). diff -u --recursive --new-file v2.2.2/linux/Documentation/sound/CMI8330 linux/Documentation/sound/CMI8330 --- v2.2.2/linux/Documentation/sound/CMI8330 Wed Dec 31 16:00:00 1969 +++ linux/Documentation/sound/CMI8330 Sun Mar 7 15:22:06 1999 @@ -0,0 +1,86 @@ +How to enable CMI 8330 soundchip on Linux +------------------------------------------ +Stefan Laudat + +Hello folks, + + The CMI8330 soundchip is a very small chip found on many recent + motherboards. In order to use it you just have to use a proper + isapnp.conf and a little bit of patience. + + Of course you will have to compile kernel sound support as module, + as shown below: + +CONFIG_SOUND=m +CONFIG_SOUND_OSS=m +CONFIG_SOUND_SB=m +CONFIG_SOUND_ADLIB=m +CONFIG_SOUND_MPU401=m +# Just for fun :) +CONFIG_SOUND_MSS=m + + The /etc/isapnp.conf file will be: + + + +(READPORT 0x0203) +(ISOLATE PRESERVE) +(IDENTIFY *) +(VERBOSITY 2) +(CONFLICT (IO FATAL)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) # or WARNING +(VERIFYLD N) +# WSS + +(CONFIGURE CMI0001/16777472 (LD 0 +(IO 0 (SIZE 8) (BASE 0x0530)) +(IO 1 (SIZE 8) (BASE 0x0388)) +(INT 0 (IRQ 5 (MODE +E))) +(DMA 0 (CHANNEL 0)) +(NAME "CMI0001/16777472[0]{CMI8330/C3D Audio Adapter}") +(ACT Y) +)) + +# Control device ? + +(CONFIGURE CMI0001/16777472 (LD 1 +(IO 0 (SIZE 2) (BASE 0x0330)) +(INT 0 (IRQ 11 (MODE +E))) +(NAME "CMI0001/16777472[1]{CMI8330/C3D Audio Adapter}") +(ACT Y) +)) + +# Joystick + +(CONFIGURE CMI0001/16777472 (LD 2 +(IO 0 (SIZE 8) (BASE 0x0200)) +(NAME "CMI0001/16777472[2]{CMI8330/C3D Audio Adapter}") +(ACT Y) +)) + +# SB... +(CONFIGURE CMI0001/16777472 (LD 3 +(IO 0 (SIZE 16) (BASE 0x0220)) +(INT 0 (IRQ 7 (MODE +E))) +(DMA 0 (CHANNEL 1)) +(DMA 1 (CHANNEL 5)) +(NAME "CMI0001/16777472[3]{CMI8330/C3D Audio Adapter}") +(ACT Y) +)) + + +(WAITFORKEY) + + + + The module sequence is trivial: + +/sbin/modprobe sound +# You need to load the ad1848 module first. That matters, otherwise the +# chip falls into soundblaster compatibility and you won't get it back out +/sbin/insmod ad1848 io=0x530 dma=0 irq=5 soundpro=1 +/sbin/insmod uart401 +/sbin/insmod sb io=0x220 irq=5 dma=1 dma16=-1 +/sbin/insmod mpu401 io=0x330 +/sbin/insmod opl3 io=0x388 + + The soundchip is now fully initialized. Enjoy it. diff -u --recursive --new-file v2.2.2/linux/Documentation/sound/VIBRA16 linux/Documentation/sound/VIBRA16 --- v2.2.2/linux/Documentation/sound/VIBRA16 Wed Dec 31 16:00:00 1969 +++ linux/Documentation/sound/VIBRA16 Sun Mar 7 15:22:06 1999 @@ -0,0 +1,80 @@ +Sound Blaster 16X Vibra addendum +-------------------------------- +by Marius Ilioaea + Stefan Laudat + +Sat Mar 6 23:55:27 EET 1999 + + Hello again, + + Playing with a SB Vibra 16x soundcard we found it very difficult +to setup because the kernel reported a lot of DMA errors and wouldn't +simply play any sound. + A good starting point is that the vibra16x chip full-duplex facility +is neither still exploited by the sb driver found in the linux kernel +(tried it with a 2.2.2-ac7), nor in the commercial OSS package (it reports +it as half-duplex soundcard). Oh, I almost forgot, the RedHat sndconfig +failed detecting it ;) + So, the big problem still remains, because the sb module wants a +8-bit and a 16-bit dma, which we could not allocate for vibra... it supports +only two 8-bit dma channels, the second one will be passed to the module +as a 16 bit channel, the kernel will yield about that but everything will +be okay, trust us. + The only inconvenient you may find is that you will have +some sound playing jitters if you have HDD dma support enabled - but this +will happen with almost all soundcards... + + A fully working isapnp.conf is just here: + + + +(READPORT 0x0203) +(ISOLATE PRESERVE) +(IDENTIFY *) +(VERBOSITY 2) +(CONFLICT (IO FATAL)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) # or WARNING +# SB 16 and OPL3 devices +(CONFIGURE CTL00f0/-1 (LD 0 +(INT 0 (IRQ 5 (MODE +E))) +(DMA 0 (CHANNEL 1)) +(DMA 1 (CHANNEL 3)) +(IO 0 (SIZE 16) (BASE 0x0220)) +(IO 2 (SIZE 4) (BASE 0x0388)) +(NAME "CTL00f0/-1[0]{Audio }") +(ACT Y) +)) + +# Joystick device - only if you need it :-/ + +(CONFIGURE CTL00f0/-1 (LD 1 +(IO 0 (SIZE 1) (BASE 0x0200)) +(NAME "CTL00f0/-1[1]{Game }") +(ACT Y) +)) +(WAITFORKEY) + + + + So, after a good kernel modules compilation and a 'depmod -a kernel_ver' +you may want to: + +modprobe sb io=0x220 irq=5 dma=1 dma16=3 + + Or, take the hard way: + +insmod souncore +insmod sound +insmod uart401 +insmod sb io=0x220 irq=5 dma=1 dma16=3 +# do you need MIDI? +insmod opl3=0x388 + + Just in case, the kernel sound support should be: + +CONFIG_SOUND=m +CONFIG_SOUND_OSS=m +CONFIG_SOUND_SB=m + + Enjoy your new noisy Linux box! ;) + + diff -u --recursive --new-file v2.2.2/linux/MAINTAINERS linux/MAINTAINERS --- v2.2.2/linux/MAINTAINERS Tue Feb 23 15:21:32 1999 +++ linux/MAINTAINERS Sun Mar 7 16:15:39 1999 @@ -246,6 +246,12 @@ L: linux-kernel@vger.rutgers.edu S: Maintained +DOUBLETALK DRIVER +P: James R. Van Zandt +M: jrv@vanzandt.mv.com +L: blinux-list@redhat.com +S: Maintained + EATA-DMA SCSI DRIVER P: Michael Neuffer M: mike@i-Connect.Net @@ -324,7 +330,7 @@ M: arobinso@nyx.net L: linux-kernel@vger.rutgers.edu W: http://www.nyx.net/~arobinso -S: Maintainted +S: Maintained HFS FILESYSTEM P: Adrian Sun @@ -522,7 +528,7 @@ NETWORKING [IPv4/IPv6] P: David S. Miller -M: davem@dm.cobaltmicro.com +M: davem@redhat.com P: Andi Kleen M: ak@muc.de P: Alexey Kuznetsov @@ -678,9 +684,18 @@ S: Supported SPARC: +P: David S. Miller +M: davem@dm.cobaltmicro.com P: Eddie C. Dost M: ecd@skynet.be +P: Jakub Jelinek +M: jj@sunsite.ms.mff.cuni.cz +P: Anton Blanchard +M: anton@jubilex.progsoc.uts.edu.au L: sparclinux@vger.rutgers.edu +L: ultralinux@vger.rutgers.edu +W: http://ultra.linux.cz +W: http://www.geog.ubc.ca/s_linux.html S: Maintained SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER diff -u --recursive --new-file v2.2.2/linux/Makefile linux/Makefile --- v2.2.2/linux/Makefile Tue Feb 23 15:21:32 1999 +++ linux/Makefile Wed Feb 24 16:30:59 1999 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 2 -SUBLEVEL = 2 +SUBLEVEL = 3 EXTRAVERSION = ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) diff -u --recursive --new-file v2.2.2/linux/arch/alpha/boot/main.c linux/arch/alpha/boot/main.c --- v2.2.2/linux/arch/alpha/boot/main.c Sun Aug 4 03:37:59 1996 +++ linux/arch/alpha/boot/main.c Thu Feb 25 10:46:51 1999 @@ -22,61 +22,27 @@ extern int vsprintf(char *, const char *, va_list); extern unsigned long switch_to_osf_pal(unsigned long nr, struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa, - unsigned long vptb, unsigned long *kstk); - -int printk(const char * fmt, ...) -{ - va_list args; - int i, j, written, remaining, num_nl; - static char buf[1024]; - char * str; - - va_start(args, fmt); - i = vsprintf(buf, fmt, args); - va_end(args); - - /* expand \n into \r\n: */ - - num_nl = 0; - for (j = 0; j < i; ++j) { - if (buf[j] == '\n') - ++num_nl; - } - remaining = i + num_nl; - for (j = i - 1; j >= 0; --j) { - buf[j + num_nl] = buf[j]; - if (buf[j] == '\n') { - --num_nl; - buf[j + num_nl] = '\r'; - } - } - - str = buf; - do { - written = puts(str, remaining); - remaining -= written; - str += written; - } while (remaining > 0); - return i; -} - -#define hwrpb (*INIT_HWRPB) + unsigned long *vptb); +struct hwrpb_struct *hwrpb = INIT_HWRPB; +static struct pcb_struct pcb_va[1]; /* * Find a physical address of a virtual object.. * * This is easy using the virtual page table address. */ -struct pcb_struct * find_pa(unsigned long *vptb, struct pcb_struct * pcb) + +static inline void * +find_pa(unsigned long *vptb, void *ptr) { - unsigned long address = (unsigned long) pcb; + unsigned long address = (unsigned long) ptr; unsigned long result; result = vptb[address >> 13]; result >>= 32; result <<= 13; result |= address & 0x1fff; - return (struct pcb_struct *) result; + return (void *) result; } /* @@ -88,30 +54,19 @@ * code has the L1 page table identity-map itself in the second PTE * in the L1 page table. Thus the L1-page is virtually addressable * itself (through three levels) at virtual address 0x200802000. - * - * As we don't want it there anyway, we also move the L1 self-map - * up as high as we can, so that the last entry in the L1 page table - * maps the page tables. - * - * As a result, the OSF/1 pal-code will instead use a virtual page table - * map located at 0xffffffe00000000. */ -#define pcb_va ((struct pcb_struct *) 0x20000000) -#define old_vptb (0x0000000200000000UL) -#define new_vptb (0xfffffffe00000000UL) -void pal_init(void) + +#define VPTB ((unsigned long *) 0x200000000) +#define L1 ((unsigned long *) 0x200802000) + +void +pal_init(void) { - unsigned long i, rev, sum; - unsigned long *L1, *l; + unsigned long i, rev; struct percpu_struct * percpu; struct pcb_struct * pcb_pa; - /* Find the level 1 page table and duplicate it in high memory */ - L1 = (unsigned long *) 0x200802000UL; /* (1<<33 | 1<<23 | 1<<13) */ - L1[1023] = L1[1]; - - percpu = (struct percpu_struct *) (hwrpb.processor_offset + (unsigned long) &hwrpb), - + /* Create the dummy PCB. */ pcb_va->ksp = 0; pcb_va->usp = 0; pcb_va->ptbr = L1[1] >> 32; @@ -119,39 +74,32 @@ pcb_va->pcc = 0; pcb_va->unique = 0; pcb_va->flags = 1; - pcb_pa = find_pa((unsigned long *) old_vptb, pcb_va); - printk("Switching to OSF PAL-code .. "); + pcb_va->res1 = 0; + pcb_va->res2 = 0; + pcb_pa = find_pa(VPTB, pcb_va); + /* * a0 = 2 (OSF) - * a1 = return address, but we give the asm the virtual addr of the PCB + * a1 = return address, but we give the asm the vaddr of the PCB * a2 = physical addr of PCB * a3 = new virtual page table pointer - * a4 = KSP (but we give it 0, asm sets it) + * a4 = KSP (but the asm sets it) */ - i = switch_to_osf_pal( - 2, - pcb_va, - pcb_pa, - new_vptb, - 0); + srm_printk("Switching to OSF PAL-code .. "); + + i = switch_to_osf_pal(2, pcb_va, pcb_pa, VPTB); if (i) { - printk("failed, code %ld\n", i); + srm_printk("failed, code %ld\n", i); halt(); } + + percpu = (struct percpu_struct *) + (INIT_HWRPB->processor_offset + (unsigned long) INIT_HWRPB); rev = percpu->pal_revision = percpu->palcode_avail[2]; - hwrpb.vptb = new_vptb; + srm_printk("Ok (rev %lx)\n", rev); - /* update checksum: */ - sum = 0; - for (l = (unsigned long *) &hwrpb; l < (unsigned long *) &hwrpb.chksum; ++l) - sum += *l; - hwrpb.chksum = sum; - - printk("Ok (rev %lx)\n", rev); - /* remove the old virtual page-table mapping */ - L1[1] = 0; - flush_tlb_all(); + tbia(); /* do it directly in case we are SMP */ } static inline long openboot(void) @@ -159,15 +107,15 @@ char bootdev[256]; long result; - result = dispatch(CCB_GET_ENV, ENV_BOOTED_DEV, bootdev, 255); + result = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_DEV, bootdev, 255); if (result < 0) return result; - return dispatch(CCB_OPEN, bootdev, result & 255); + return srm_dispatch(CCB_OPEN, bootdev, result & 255); } static inline long close(long dev) { - return dispatch(CCB_CLOSE, dev); + return srm_dispatch(CCB_CLOSE, dev); } static inline long load(long dev, unsigned long addr, unsigned long count) @@ -176,15 +124,15 @@ extern char _end; long result, boot_size = &_end - (char *) BOOT_ADDR; - result = dispatch(CCB_GET_ENV, ENV_BOOTED_FILE, bootfile, 255); + result = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_FILE, bootfile, 255); if (result < 0) return result; result &= 255; bootfile[result] = '\0'; if (result) - printk("Boot file specification (%s) not implemented\n", + srm_printk("Boot file specification (%s) not implemented\n", bootfile); - return dispatch(CCB_READ, dev, count, addr, boot_size/512 + 1); + return srm_dispatch(CCB_READ, dev, count, addr, boot_size/512 + 1); } /* @@ -208,27 +156,27 @@ int nbytes; char envval[256]; - printk("Linux/AXP bootloader for Linux " UTS_RELEASE "\n"); - if (hwrpb.pagesize != 8192) { - printk("Expected 8kB pages, got %ldkB\n", hwrpb.pagesize >> 10); + srm_printk("Linux/AXP bootloader for Linux " UTS_RELEASE "\n"); + if (INIT_HWRPB->pagesize != 8192) { + srm_printk("Expected 8kB pages, got %ldkB\n", INIT_HWRPB->pagesize >> 10); return; } pal_init(); dev = openboot(); if (dev < 0) { - printk("Unable to open boot device: %016lx\n", dev); + srm_printk("Unable to open boot device: %016lx\n", dev); return; } dev &= 0xffffffff; - printk("Loading vmlinux ..."); + srm_printk("Loading vmlinux ..."); i = load(dev, START_ADDR, KERNEL_SIZE); close(dev); if (i != KERNEL_SIZE) { - printk("Failed (%lx)\n", i); + srm_printk("Failed (%lx)\n", i); return; } - nbytes = dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS, + nbytes = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS, envval, sizeof(envval)); if (nbytes < 0) { nbytes = 0; @@ -236,7 +184,7 @@ envval[nbytes] = '\0'; strcpy((char*)ZERO_PAGE, envval); - printk(" Ok\nNow booting the kernel\n"); + srm_printk(" Ok\nNow booting the kernel\n"); runkernel(); for (i = 0 ; i < 0x100000000 ; i++) /* nothing */; diff -u --recursive --new-file v2.2.2/linux/arch/alpha/defconfig linux/arch/alpha/defconfig --- v2.2.2/linux/arch/alpha/defconfig Mon Dec 28 15:00:52 1998 +++ linux/arch/alpha/defconfig Thu Feb 25 10:46:46 1999 @@ -91,7 +91,6 @@ # CONFIG_PACKET is not set # CONFIG_NETLINK is not set # CONFIG_FIREWALL is not set -# CONFIG_NET_ALIAS is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y diff -u --recursive --new-file v2.2.2/linux/arch/arm/defconfig linux/arch/arm/defconfig --- v2.2.2/linux/arch/arm/defconfig Thu Aug 6 14:06:28 1998 +++ linux/arch/arm/defconfig Thu Feb 25 10:46:46 1999 @@ -80,7 +80,6 @@ # CONFIG_PACKET is not set # CONFIG_NETLINK is not set # CONFIG_FIREWALL is not set -# CONFIG_NET_ALIAS is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y diff -u --recursive --new-file v2.2.2/linux/arch/i386/defconfig linux/arch/i386/defconfig --- v2.2.2/linux/arch/i386/defconfig Tue Feb 23 15:21:32 1999 +++ linux/arch/i386/defconfig Sun Mar 7 20:38:44 1999 @@ -104,7 +104,6 @@ CONFIG_PACKET=y # CONFIG_NETLINK is not set # CONFIG_FIREWALL is not set -# CONFIG_NET_ALIAS is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y @@ -121,7 +120,6 @@ # (it is safe to leave these untouched) # # CONFIG_INET_RARP is not set -CONFIG_IP_NOSR=y CONFIG_SKB_LARGE=y # @@ -172,7 +170,9 @@ # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_GENERIC_NCR5380 is not set # CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_NCR53C7xx is not set CONFIG_SCSI_NCR53C8XX=y CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=4 @@ -186,6 +186,7 @@ # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set # CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_SEAGATE is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set @@ -281,6 +282,7 @@ # Joystick support # # CONFIG_JOYSTICK is not set +# CONFIG_DTLK is not set # # Ftape, the floppy tape device driver diff -u --recursive --new-file v2.2.2/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c --- v2.2.2/linux/arch/i386/kernel/bios32.c Wed Jan 20 23:14:04 1999 +++ linux/arch/i386/kernel/bios32.c Mon Mar 8 11:08:02 1999 @@ -14,7 +14,7 @@ * Hannover, Germany * hm@ix.de * - * Copyright 1997, 1998 Martin Mares + * Copyright 1997--1999 Martin Mares * * For more information, please consult the following manuals (look at * http://www.pcisig.com/ for how to get them): @@ -71,6 +71,10 @@ * a large gallery of common hardware bug workarounds (watch the comments) * -- the PCI specs themselves are sane, but most implementors should be * hit hard with \hammer scaled \magstep5. [mj] + * + * Jan 23, 1999 : More improvements to peer host bridge logic. i450NX fixup. [mj] + * + * Feb 8, 1999 : Added UM8886BF I/O address fixup. [mj] */ #include @@ -171,6 +175,7 @@ #define PCI_NO_SORT 0x100 #define PCI_BIOS_SORT 0x200 #define PCI_NO_CHECKS 0x400 +#define PCI_NO_PEER_FIXUP 0x800 static unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2; @@ -521,6 +526,8 @@ unsigned short segment; } pci_indirect = { 0, __KERNEL_CS }; +static int pci_bios_present; + __initfunc(static int check_pcibios(void)) { u32 signature, eax, ebx, ecx; @@ -803,7 +810,7 @@ * which used BIOS ordering, we are bound to do this... */ -__initfunc(void pcibios_sort(void)) +static void __init pcibios_sort(void) { struct pci_dev *dev = pci_devices; struct pci_dev **last = &pci_devices; @@ -856,7 +863,7 @@ static int pci_last_io_addr __initdata = 0x5800; -__initfunc(void pcibios_fixup_io_addr(struct pci_dev *dev, int idx)) +static void __init pcibios_fixup_io_addr(struct pci_dev *dev, int idx) { unsigned short cmd; unsigned int reg = PCI_BASE_ADDRESS_0 + 4*idx; @@ -868,13 +875,16 @@ printk("PCI: Unassigned I/O space for %02x:%02x\n", bus, devfn); return; } - if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && idx < 4) { + if (((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && idx < 4) || + (dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) { /* * In case the BIOS didn't assign an address 0--3 to an IDE * controller, we don't try to fix it as it means "use default * addresses" at least with several broken chips and the IDE * driver needs the original settings to recognize which devices * correspond to the primary controller. + * + * We don't assign VGA I/O ranges as well. */ return; } @@ -914,7 +924,7 @@ * expected to be unique) and remove the ghost devices. */ -__initfunc(void pcibios_fixup_ghosts(struct pci_bus *b)) +static void __init pcibios_fixup_ghosts(struct pci_bus *b) { struct pci_dev *d, *e, **z; int mirror = PCI_DEVFN(16,0); @@ -954,12 +964,17 @@ * the reality doesn't pass this test and the bus number is usually * set by BIOS to the first free value. */ -__initfunc(void pcibios_fixup_peer_bridges(void)) +static void __init pcibios_fixup_peer_bridges(void) { struct pci_bus *b = &pci_root; int i, n, cnt=-1; struct pci_dev *d; +#ifdef CONFIG_VISWS + pci_scan_peer_bridge(1); + return; +#endif + #ifdef CONFIG_PCI_DIRECT /* * Don't search for peer host bridges if we use config type 2 @@ -969,6 +984,7 @@ if (access_pci == &pci_direct_conf2) return; #endif + for(d=b->devices; d; d=d->sibling) if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST) cnt++; @@ -979,6 +995,20 @@ for(i=0; i<256; i += 8) if (!pcibios_read_config_word(n, i, PCI_VENDOR_ID, &l) && l != 0x0000 && l != 0xffff) { +#ifdef CONFIG_PCI_BIOS + if (pci_bios_present) { + int succ, idx = 0; + u8 bios_bus, bios_dfn; + u16 d; + pcibios_read_config_word(n, i, PCI_DEVICE_ID, &d); + DBG("BIOS test for %02x:%02x (%04x:%04x)\n", n, i, l, d); + while ((succ = pci_bios_find_device(l, d, idx, &bios_bus, &bios_dfn)) && + (bios_bus != n || bios_dfn != i)) + idx++; + if (!succ) + break; + } +#endif DBG("Found device at %02x:%02x\n", n, i); found++; if (!pcibios_read_config_word(n, i, PCI_CLASS_DEVICE, &l) && @@ -989,13 +1019,7 @@ break; if (found) { printk("PCI: Discovered primary peer bus %02x\n", n); - b = kmalloc(sizeof(*b), GFP_KERNEL); - memset(b, 0, sizeof(*b)); - b->next = pci_root.next; - pci_root.next = b; - b->number = b->secondary = n; - b->subordinate = 0xff; - b->subordinate = pci_scan_bus(b); + b = pci_scan_peer_bridge(n); n = b->subordinate; } n++; @@ -1003,11 +1027,75 @@ } /* + * Exceptions for specific devices. Usually work-arounds for fatal design flaws. + */ + +static void __init pci_fixup_i450nx(struct pci_dev *d) +{ + /* + * i450NX -- Find and scan all secondary buses on all PXB's. + */ + int pxb, reg; + u8 busno, suba, subb; + reg = 0xd0; + for(pxb=0; pxb<2; pxb++) { + pci_read_config_byte(d, reg++, &busno); + pci_read_config_byte(d, reg++, &suba); + pci_read_config_byte(d, reg++, &subb); + DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb); + if (busno) + pci_scan_peer_bridge(busno); /* Bus A */ + if (suba < subb) + pci_scan_peer_bridge(suba+1); /* Bus B */ + } + pci_probe |= PCI_NO_PEER_FIXUP; +} + +static void __init pci_fixup_umc_ide(struct pci_dev *d) +{ + /* + * UM8886BF IDE controller sets region type bits incorrectly, + * therefore they look like memory despite of them being I/O. + */ + int i; + + for(i=0; i<4; i++) + d->base_address[i] |= PCI_BASE_ADDRESS_SPACE_IO; +} + +struct dev_ex { + u16 vendor, device; + void (*handler)(struct pci_dev *); + char *comment; +}; + +static struct dev_ex __initdata dev_ex_table[] = { + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx, "Scanning peer host bridges" }, + { PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF, pci_fixup_umc_ide, "Working around UM8886BF bugs" } +}; + +static void __init pcibios_scan_buglist(struct pci_bus *b) +{ + struct pci_dev *d; + int i; + + for(d=b->devices; d; d=d->sibling) + for(i=0; ivendor == d->vendor && e->device == d->device) { + printk("PCI: %02x:%02x [%04x/%04x]: %s\n", + b->number, d->devfn, d->vendor, d->device, e->comment); + e->handler(d); + } + } +} + +/* * Fix base addresses, I/O and memory enables and IRQ's (mostly work-arounds * for buggy PCI BIOS'es :-[). */ -__initfunc(void pcibios_fixup_devices(void)) +static void __init pcibios_fixup_devices(void) { struct pci_dev *dev; int i, has_io, has_mem; @@ -1099,7 +1187,8 @@ __initfunc(void pcibios_fixup(void)) { - pcibios_fixup_peer_bridges(); + if (!(pci_probe & PCI_NO_PEER_FIXUP)) + pcibios_fixup_peer_bridges(); pcibios_fixup_devices(); #ifdef CONFIG_PCI_BIOS @@ -1111,6 +1200,7 @@ __initfunc(void pcibios_fixup_bus(struct pci_bus *b)) { pcibios_fixup_ghosts(b); + pcibios_scan_buglist(b); } /* @@ -1126,8 +1216,10 @@ struct pci_access *dir = NULL; #ifdef CONFIG_PCI_BIOS - if ((pci_probe & PCI_PROBE_BIOS) && ((bios = pci_find_bios()))) + if ((pci_probe & PCI_PROBE_BIOS) && ((bios = pci_find_bios()))) { pci_probe |= PCI_BIOS_SORT; + pci_bios_present = 1; + } #endif #ifdef CONFIG_PCI_DIRECT if (pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2)) @@ -1139,10 +1231,6 @@ access_pci = bios; } -#if !defined(CONFIG_PCI_BIOS) && !defined(CONFIG_PCI_DIRECT) -#error PCI configured with neither PCI BIOS or PCI direct access support. -#endif - __initfunc(char *pcibios_setup(char *str)) { if (!strcmp(str, "off")) { @@ -1178,5 +1266,9 @@ return NULL; } #endif + else if (!strcmp(str, "nopeer")) { + pci_probe |= PCI_NO_PEER_FIXUP; + return NULL; + } return str; } diff -u --recursive --new-file v2.2.2/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c --- v2.2.2/linux/arch/i386/kernel/time.c Wed Jan 20 23:14:04 1999 +++ linux/arch/i386/kernel/time.c Mon Mar 8 11:38:51 1999 @@ -30,19 +30,6 @@ * serialize accesses to xtime/lost_ticks). */ -/* What about the "updated NTP code" stuff in 2.0 time.c? It's not in - * 2.1, perhaps it should be ported, too. - * - * What about the BUGGY_NEPTUN_TIMER stuff in do_slow_gettimeoffset()? - * Whatever it fixes, is it also fixed in the new code from the Jumbo - * patch, so that that code can be used instead? - * - * The CPU Hz should probably be displayed in check_bugs() together - * with the CPU vendor and type. Perhaps even only in MHz, though that - * takes away some of the fun of the new code :) - * - * - Michael Krause */ - #include #include #include @@ -556,70 +543,72 @@ * device. */ +#define CALIBRATE_LATCH (5 * LATCH) +#define CALIBRATE_TIME (5 * 1000020/HZ) + __initfunc(static unsigned long calibrate_tsc(void)) { - unsigned long retval; + /* Set the Gate high, disable speaker */ + outb((inb(0x61) & ~0x02) | 0x01, 0x61); - __asm__( /* set the Gate high, program CTC channel 2 for mode 0 - * (interrupt on terminal count mode), binary count, - * load 5 * LATCH count, (LSB and MSB) - * to begin countdown, read the TSC and busy wait. - * BTW LATCH is calculated in timex.h from the HZ value - */ + /* + * Now let's take care of CTC channel 2 + * + * Set the Gate high, program CTC channel 2 for mode 0, + * (interrupt on terminal count mode), binary count, + * load 5 * LATCH count, (LSB and MSB) to begin countdown. + */ + outb(0xb0, 0x43); /* binary, mode 0, LSB/MSB, Ch 2 */ + outb(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */ + outb(CALIBRATE_LATCH >> 8, 0x42); /* MSB of count */ - /* Set the Gate high, disable speaker */ - "inb $0x61, %%al\n\t" /* Read port */ - "andb $0xfd, %%al\n\t" /* Turn off speaker Data */ - "orb $0x01, %%al\n\t" /* Set Gate high */ - "outb %%al, $0x61\n\t" /* Write port */ - - /* Now let's take care of CTC channel 2 */ - "movb $0xb0, %%al\n\t" /* binary, mode 0, LSB/MSB, ch 2*/ - "outb %%al, $0x43\n\t" /* Write to CTC command port */ - "movl %1, %%eax\n\t" - "outb %%al, $0x42\n\t" /* LSB of count */ - "shrl $8, %%eax\n\t" - "outb %%al, $0x42\n\t" /* MSB of count */ - - /* Read the TSC; counting has just started */ - "rdtsc\n\t" - /* Move the value for safe-keeping. */ - "movl %%eax, %%ebx\n\t" - "movl %%edx, %%ecx\n\t" - - /* Busy wait. Only 50 ms wasted at boot time. */ - "0: inb $0x61, %%al\n\t" /* Read Speaker Output Port */ - "testb $0x20, %%al\n\t" /* Check CTC channel 2 output (bit 5) */ - "jz 0b\n\t" - - /* And read the TSC. 5 jiffies (50.00077ms) have elapsed. */ - "rdtsc\n\t" - - /* Great. So far so good. Store last TSC reading in - * last_tsc_low (only 32 lsb bits needed) */ - "movl %%eax, last_tsc_low\n\t" - /* And now calculate the difference between the readings. */ - "subl %%ebx, %%eax\n\t" - "sbbl %%ecx, %%edx\n\t" /* 64-bit subtract */ - /* but probably edx = 0 at this point (see below). */ - /* Now we have 5 * (TSC counts per jiffy) in eax. We want - * to calculate TSC->microsecond conversion factor. */ - - /* Note that edx (high 32-bits of difference) will now be - * zero iff CPU clock speed is less than 85 GHz. Moore's - * law says that this is likely to be true for the next - * 12 years or so. You will have to change this code to - * do a real 64-by-64 divide before that time's up. */ - "movl %%eax, %%ecx\n\t" - "xorl %%eax, %%eax\n\t" - "movl %2, %%edx\n\t" - "divl %%ecx\n\t" /* eax= 2^32 / (1 * TSC counts per microsecond) */ - /* Return eax for the use of fast_gettimeoffset */ - "movl %%eax, %0\n\t" - : "=r" (retval) - : "r" (5 * LATCH), "r" (5 * 1000020/HZ) - : /* we clobber: */ "ax", "bx", "cx", "dx", "cc", "memory"); - return retval; + { + unsigned long startlow, starthigh; + unsigned long endlow, endhigh; + unsigned long count; + + __asm__ __volatile__("rdtsc":"=a" (startlow),"=d" (starthigh)); + count = 0; + do { + count++; + } while ((inb(0x61) & 0x20) == 0); + __asm__ __volatile__("rdtsc":"=a" (endlow),"=d" (endhigh)); + + last_tsc_low = endlow; + + /* Error: ECTCNEVERSET */ + if (count <= 1) + goto bad_ctc; + + /* 64-bit subtract - gcc just messes up with long longs */ + __asm__("subl %2,%0\n\t" + "sbbl %3,%1" + :"=a" (endlow), "=d" (endhigh) + :"g" (startlow), "g" (starthigh), + "0" (endlow), "1" (endhigh)); + + /* Error: ECPUTOOFAST */ + if (endhigh) + goto bad_ctc; + + /* Error: ECPUTOOSLOW */ + if (endlow <= CALIBRATE_TIME) + goto bad_ctc; + + __asm__("divl %2" + :"=a" (endlow), "=d" (endhigh) + :"r" (endlow), "0" (0), "1" (CALIBRATE_TIME)); + + return endlow; + } + + /* + * The CTC wasn't reliable: we got a hit on the very first read, + * or the CPU was so fast/slow that the quotient wouldn't fit in + * 32 bits.. + */ +bad_ctc: + return 0; } __initfunc(void time_init(void)) @@ -655,23 +644,26 @@ dodgy_tsc(); if (boot_cpu_data.x86_capability & X86_FEATURE_TSC) { + unsigned long tsc_quotient = calibrate_tsc(); + if (tsc_quotient) { + fast_gettimeoffset_quotient = tsc_quotient; + use_tsc = 1; #ifndef do_gettimeoffset - do_gettimeoffset = do_fast_gettimeoffset; + do_gettimeoffset = do_fast_gettimeoffset; #endif - do_get_fast_time = do_gettimeofday; - use_tsc = 1; - fast_gettimeoffset_quotient = calibrate_tsc(); - - /* report CPU clock rate in Hz. - * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) = - * clock/second. Our precision is about 100 ppm. - */ - { unsigned long eax=0, edx=1000000; - __asm__("divl %2" - :"=a" (cpu_hz), "=d" (edx) - :"r" (fast_gettimeoffset_quotient), - "0" (eax), "1" (edx)); - printk("Detected %ld Hz processor.\n", cpu_hz); + do_get_fast_time = do_gettimeofday; + + /* report CPU clock rate in Hz. + * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) = + * clock/second. Our precision is about 100 ppm. + */ + { unsigned long eax=0, edx=1000000; + __asm__("divl %2" + :"=a" (cpu_hz), "=d" (edx) + :"r" (tsc_quotient), + "0" (eax), "1" (edx)); + printk("Detected %ld Hz processor.\n", cpu_hz); + } } } diff -u --recursive --new-file v2.2.2/linux/arch/m68k/defconfig linux/arch/m68k/defconfig --- v2.2.2/linux/arch/m68k/defconfig Wed Jan 20 23:14:04 1999 +++ linux/arch/m68k/defconfig Thu Feb 25 10:46:46 1999 @@ -78,7 +78,6 @@ CONFIG_PACKET=y # CONFIG_NETLINK is not set # CONFIG_FIREWALL is not set -# CONFIG_NET_ALIAS is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y diff -u --recursive --new-file v2.2.2/linux/arch/mips/defconfig linux/arch/mips/defconfig --- v2.2.2/linux/arch/mips/defconfig Fri Oct 23 22:01:19 1998 +++ linux/arch/mips/defconfig Thu Feb 25 10:46:47 1999 @@ -90,7 +90,6 @@ # CONFIG_PACKET is not set # CONFIG_NETLINK is not set # CONFIG_FIREWALL is not set -# CONFIG_NET_ALIAS is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y diff -u --recursive --new-file v2.2.2/linux/arch/ppc/apus_defconfig linux/arch/ppc/apus_defconfig --- v2.2.2/linux/arch/ppc/apus_defconfig Mon Dec 28 15:00:52 1998 +++ linux/arch/ppc/apus_defconfig Thu Feb 25 10:46:47 1999 @@ -100,7 +100,6 @@ # CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set # CONFIG_FIREWALL is not set -CONFIG_NET_ALIAS=y # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y diff -u --recursive --new-file v2.2.2/linux/arch/ppc/chrp_defconfig linux/arch/ppc/chrp_defconfig --- v2.2.2/linux/arch/ppc/chrp_defconfig Mon Dec 28 15:00:52 1998 +++ linux/arch/ppc/chrp_defconfig Thu Feb 25 10:46:47 1999 @@ -85,7 +85,6 @@ # CONFIG_PACKET is not set # CONFIG_NETLINK is not set # CONFIG_FIREWALL is not set -CONFIG_NET_ALIAS=y # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y diff -u --recursive --new-file v2.2.2/linux/arch/ppc/common_defconfig linux/arch/ppc/common_defconfig --- v2.2.2/linux/arch/ppc/common_defconfig Fri Jan 8 22:36:02 1999 +++ linux/arch/ppc/common_defconfig Thu Feb 25 10:46:47 1999 @@ -87,7 +87,6 @@ # CONFIG_PACKET is not set # CONFIG_NETLINK is not set # CONFIG_FIREWALL is not set -# CONFIG_NET_ALIAS is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y diff -u --recursive --new-file v2.2.2/linux/arch/ppc/defconfig linux/arch/ppc/defconfig --- v2.2.2/linux/arch/ppc/defconfig Thu Jan 7 15:11:36 1999 +++ linux/arch/ppc/defconfig Thu Feb 25 10:46:47 1999 @@ -102,7 +102,6 @@ # CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set # CONFIG_FIREWALL is not set -CONFIG_NET_ALIAS=y # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y diff -u --recursive --new-file v2.2.2/linux/arch/ppc/mbx_defconfig linux/arch/ppc/mbx_defconfig --- v2.2.2/linux/arch/ppc/mbx_defconfig Mon Dec 28 15:00:52 1998 +++ linux/arch/ppc/mbx_defconfig Thu Feb 25 10:46:47 1999 @@ -75,7 +75,6 @@ # CONFIG_PACKET is not set # CONFIG_NETLINK is not set # CONFIG_FIREWALL is not set -# CONFIG_NET_ALIAS is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y diff -u --recursive --new-file v2.2.2/linux/arch/ppc/pmac_defconfig linux/arch/ppc/pmac_defconfig --- v2.2.2/linux/arch/ppc/pmac_defconfig Thu Jan 7 15:11:36 1999 +++ linux/arch/ppc/pmac_defconfig Thu Feb 25 10:46:47 1999 @@ -102,7 +102,6 @@ # CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set # CONFIG_FIREWALL is not set -CONFIG_NET_ALIAS=y # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y diff -u --recursive --new-file v2.2.2/linux/arch/ppc/prep_defconfig linux/arch/ppc/prep_defconfig --- v2.2.2/linux/arch/ppc/prep_defconfig Mon Dec 28 15:00:52 1998 +++ linux/arch/ppc/prep_defconfig Thu Feb 25 10:46:47 1999 @@ -84,7 +84,6 @@ # CONFIG_PACKET is not set # CONFIG_NETLINK is not set # CONFIG_FIREWALL is not set -# CONFIG_NET_ALIAS is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y diff -u --recursive --new-file v2.2.2/linux/arch/sparc/defconfig linux/arch/sparc/defconfig --- v2.2.2/linux/arch/sparc/defconfig Tue Dec 22 14:16:54 1998 +++ linux/arch/sparc/defconfig Thu Feb 25 10:46:47 1999 @@ -101,7 +101,6 @@ CONFIG_PACKET=y # CONFIG_NETLINK is not set # CONFIG_FIREWALL is not set -# CONFIG_NET_ALIAS is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y diff -u --recursive --new-file v2.2.2/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig --- v2.2.2/linux/arch/sparc64/defconfig Tue Dec 22 14:16:54 1998 +++ linux/arch/sparc64/defconfig Thu Feb 25 10:46:47 1999 @@ -128,7 +128,6 @@ CONFIG_PACKET=y # CONFIG_NETLINK is not set # CONFIG_FIREWALL is not set -# CONFIG_NET_ALIAS is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y diff -u --recursive --new-file v2.2.2/linux/drivers/block/genhd.c linux/drivers/block/genhd.c --- v2.2.2/linux/drivers/block/genhd.c Tue Feb 23 15:21:32 1999 +++ linux/drivers/block/genhd.c Wed Feb 24 16:27:53 1999 @@ -879,7 +879,7 @@ res = 0; for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) { - if(!(bh = bread(dev,blk,get_ptable_blocksize(dev)))) { + if(!(bh = bread(dev,blk,512))) { printk("Dev %s: unable to read RDB block %d\n", kdevname(dev),blk); goto rdb_done; @@ -896,7 +896,7 @@ blk = htonl(rdb->rdb_PartitionList); brelse(bh); for (part = 1; blk > 0 && part <= 16; part++) { - if (!(bh = bread(dev,blk, get_ptable_blocksize(dev)))) { + if (!(bh = bread(dev,blk, 512))) { printk("Dev %s: unable to read partition block %d\n", kdevname(dev),blk); goto rdb_done; diff -u --recursive --new-file v2.2.2/linux/drivers/block/hd.c linux/drivers/block/hd.c --- v2.2.2/linux/drivers/block/hd.c Tue Jan 19 11:32:51 1999 +++ linux/drivers/block/hd.c Wed Feb 24 16:27:53 1999 @@ -744,11 +744,12 @@ */ - if ((cmos_disks = CMOS_READ(0x12)) & 0xf0) + if ((cmos_disks = CMOS_READ(0x12)) & 0xf0) { if (cmos_disks & 0x0f) NR_HD = 2; else NR_HD = 1; + } } #endif /* __i386__ */ for (drive=0 ; drive < NR_HD ; drive++) { diff -u --recursive --new-file v2.2.2/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v2.2.2/linux/drivers/block/ide.c Tue Jan 19 11:32:51 1999 +++ linux/drivers/block/ide.c Wed Feb 24 16:27:54 1999 @@ -2068,6 +2068,12 @@ (unsigned long *) &loc->start)) return -EFAULT; return 0; } + case BLKSSZGET: + /* Block size of media */ + return put_user(blksize_size[HWIF(drive)->major] + [minor&PARTN_MASK], + (int *)arg); + case BLKFLSBUF: if (!capable(CAP_SYS_ADMIN)) return -EACCES; fsync_dev(inode->i_rdev); diff -u --recursive --new-file v2.2.2/linux/drivers/block/nbd.c linux/drivers/block/nbd.c --- v2.2.2/linux/drivers/block/nbd.c Tue Dec 22 14:16:55 1998 +++ linux/drivers/block/nbd.c Mon Mar 8 13:05:11 1999 @@ -17,6 +17,7 @@ * 97-4-11 Making protocol independent of endianity etc. * 97-9-13 Cosmetic changes * 98-5-13 Attempt to make 64-bit-clean on 64-bit machines + * 99-1-11 Attempt to make 64-bit-clean on 32-bit machines * * possible FIXME: make set_sock / set_blksize / set_size / do_it one syscall * why not: would need verify_area and friends, would share yet another @@ -45,8 +46,9 @@ #define LO_MAGIC 0x68797548 static int nbd_blksizes[MAX_NBD]; +static int nbd_blksize_bits[MAX_NBD]; static int nbd_sizes[MAX_NBD]; -static int nbd_bytesizes[MAX_NBD]; +static u64 nbd_bytesizes[MAX_NBD]; static struct nbd_device nbd_dev[MAX_NBD]; @@ -149,7 +151,7 @@ DEBUG("NBD: sending control, "); request.magic = htonl(NBD_REQUEST_MAGIC); request.type = htonl(req->cmd); - request.from = cpu_to_be64( (u64) req->sector * (u64) 512); + request.from = cpu_to_be64( (u64) req->sector << 9); request.len = htonl(req->current_nr_sectors << 9); memcpy(request.handle, &req, sizeof(req)); @@ -340,7 +342,7 @@ unsigned int cmd, unsigned long arg) { struct nbd_device *lo; - int dev, error; + int dev, error, temp; /* Anyone capable of this syscall can do *real bad* things */ @@ -355,6 +357,7 @@ lo = &nbd_dev[dev]; switch (cmd) { case NBD_CLEAR_SOCK: + nbd_clear_que(lo); if (lo->head || lo->tail) { printk(KERN_ERR "nbd: Some requests are in progress -> can not turn off.\n"); return -EBUSY; @@ -380,14 +383,25 @@ } return error; case NBD_SET_BLKSIZE: - if ((arg & 511) || (arg > PAGE_SIZE)) + if ((arg & (arg-1)) || (arg < 512) || (arg > PAGE_SIZE)) return -EINVAL; nbd_blksizes[dev] = arg; - nbd_sizes[dev] = arg/nbd_blksizes[dev]; + temp = arg >> 9; + nbd_blksize_bits[dev] = 9; + while (temp > 1) { + nbd_blksize_bits[dev]++; + temp >>= 1; + } + nbd_sizes[dev] = nbd_bytesizes[dev] >> nbd_blksize_bits[dev]; + nbd_bytesizes[dev] = nbd_sizes[dev] << nbd_blksize_bits[dev]; return 0; case NBD_SET_SIZE: - nbd_bytesizes[dev] = arg; - nbd_sizes[dev] = arg/nbd_blksizes[dev]; + nbd_sizes[dev] = arg >> nbd_blksize_bits[dev]; + nbd_bytesizes[dev] = nbd_sizes[dev] << nbd_blksize_bits[dev]; + return 0; + case NBD_SET_SIZE_BLOCKS: + nbd_sizes[dev] = arg; + nbd_bytesizes[dev] = arg << nbd_blksize_bits[dev]; return 0; case NBD_DO_IT: if (!lo->file) @@ -404,7 +418,7 @@ return 0; #endif case BLKGETSIZE: - return put_user(nbd_bytesizes[dev]/512, (long *) arg); + return put_user(nbd_bytesizes[dev] << 9, (long *) arg); } return -EINVAL; } @@ -420,6 +434,7 @@ if (dev >= MAX_NBD) return -ENODEV; fsync_dev(inode->i_rdev); + invalidate_buffers(inode->i_rdev); lo = &nbd_dev[dev]; if (lo->refcnt <= 0) printk(KERN_ALERT "nbd_release: refcount(%d) <= 0\n", lo->refcnt); @@ -478,8 +493,9 @@ nbd_dev[i].magic = LO_MAGIC; nbd_dev[i].flags = 0; nbd_blksizes[i] = 1024; - nbd_bytesizes[i] = 0x7fffffff; - nbd_sizes[i] = nbd_bytesizes[i]/nbd_blksizes[i]; + nbd_blksize_bits[i] = 10; + nbd_bytesizes[i] = 0x7ffffc00; /* 2GB */ + nbd_sizes[i] = nbd_bytesizes[i] >> nbd_blksize_bits[i]; } return 0; } diff -u --recursive --new-file v2.2.2/linux/drivers/block/rd.c linux/drivers/block/rd.c --- v2.2.2/linux/drivers/block/rd.c Wed Aug 26 11:37:35 1998 +++ linux/drivers/block/rd.c Wed Feb 24 16:27:54 1999 @@ -170,14 +170,12 @@ break; case BLKGETSIZE: /* Return device size */ if (!arg) return -EINVAL; - err = verify_area(VERIFY_WRITE, (long *) arg, - sizeof(long)); - if (err) - return err; - put_user(rd_length[MINOR(inode->i_rdev)] / 512, + return put_user(rd_length[MINOR(inode->i_rdev)] / 512, (long *) arg); - return 0; - + case BLKSSZGET: + /* Block size of media */ + return put_user(rd_blocksizes[MINOR(inode->i_rdev)], + (int *)arg); default: break; }; diff -u --recursive --new-file v2.2.2/linux/drivers/char/Config.in linux/drivers/char/Config.in --- v2.2.2/linux/drivers/char/Config.in Mon Dec 28 15:00:52 1998 +++ linux/drivers/char/Config.in Sun Mar 7 16:15:39 1999 @@ -139,6 +139,16 @@ if [ "$CONFIG_RADIO_SF16FMI" = "y" ]; then hex ' SF16FMI I/O port (0x284 or 0x384)' CONFIG_RADIO_SF16FMI_PORT 284 fi + dep_tristate 'Typhoon Radio (a.k.a. EcoRadio)' CONFIG_RADIO_TYPHOON $CONFIG_VIDEO_DEV + if [ "$CONFIG_PROC_FS" = "y" ]; then + if [ "$CONFIG_RADIO_TYPHOON" != "n" ]; then + bool ' Support for /proc/radio-typhoon' CONFIG_RADIO_TYPHOON_PROC_FS + fi + fi + if [ "$CONFIG_RADIO_TYPHOON" = "y" ]; then + hex ' Typhoon I/O port (0x316 or 0x336)' CONFIG_RADIO_TYPHOON_PORT 316 + int ' Typhoon frequency set when muting the device (kHz)' CONFIG_RADIO_TYPHOON_MUTEFREQ 87500 + fi dep_tristate 'Zoltrix Radio' CONFIG_RADIO_ZOLTRIX $CONFIG_VIDEO_DEV if [ "$CONFIG_RADIO_ZOLTRIX" = "y" ]; then hex ' ZOLTRIX I/O port (0x20c or 0x30c)' CONFIG_RADIO_ZOLTRIX_PORT 20c @@ -155,6 +165,8 @@ source drivers/char/joystick/Config.in fi endmenu + +tristate 'Double Talk PC internal speech card support' CONFIG_DTLK mainmenu_option next_comment comment 'Ftape, the floppy tape device driver' diff -u --recursive --new-file v2.2.2/linux/drivers/char/Makefile linux/drivers/char/Makefile --- v2.2.2/linux/drivers/char/Makefile Mon Dec 28 15:00:52 1998 +++ linux/drivers/char/Makefile Sun Mar 7 16:15:39 1999 @@ -176,6 +176,14 @@ endif endif +ifeq ($(CONFIG_DTLK),y) +L_OBJS += dtlk.o +else + ifeq ($(CONFIG_DTLK),m) + M_OBJS += dtlk.o + endif +endif + ifeq ($(CONFIG_MS_BUSMOUSE),y) L_OBJS += msbusmouse.o else @@ -361,6 +369,14 @@ else ifeq ($(CONFIG_RADIO_RTRACK2),m) M_OBJS += radio-rtrack2.o + endif +endif + +ifeq ($(CONFIG_RADIO_TYPHOON),y) +L_OBJS += radio-typhoon.o +else + ifeq ($(CONFIG_RADIO_TYPHOON),m) + M_OBJS += radio-typhoon.o endif endif diff -u --recursive --new-file v2.2.2/linux/drivers/char/bttv.c linux/drivers/char/bttv.c --- v2.2.2/linux/drivers/char/bttv.c Tue Feb 23 15:21:33 1999 +++ linux/drivers/char/bttv.c Mon Mar 8 10:14:40 1999 @@ -1558,12 +1558,33 @@ static void bttv_close(struct video_device *dev) { struct bttv *btv=(struct bttv *)dev; - + btv->user--; audio(btv, AUDIO_INTERN); btv->cap&=~3; bt848_set_risc_jmps(btv); + /* + * A word of warning. At this point the chip + * is still capturing because its FIFO hasn't emptied + * and the DMA control operations are posted PCI + * operations. + */ + + btread(BT848_I2C); /* This fixes the PCI posting delay */ + + /* + * This is sucky but right now I can't find a good way to + * be sure its safe to free the buffer. We wait 5-6 fields + * which is more than sufficient to be sure. + */ + + current->state = TASK_UNINTERRUPTIBLE; + schedule_timeout(HZ/10); /* Wait 1/10th of a second */ + + /* + * We have allowed it to drain. + */ if(btv->fbuffer) rvfree((void *) btv->fbuffer, 2*BTTV_MAX_FBUF); btv->fbuffer=0; @@ -3037,7 +3058,7 @@ btv->risc_jmp[12]=BT848_RISC_JUMP; btv->risc_jmp[13]=virt_to_bus(btv->risc_jmp); - /* enable cpaturing and DMA */ + /* enable capturing */ btaor(flags, ~0x0f, BT848_CAP_CTL); if (flags&0x0f) bt848_dma(btv, 3); @@ -3242,7 +3263,7 @@ if (astat&BT848_INT_SCERR) { IDEBUG(printk ("bttv%d: IRQ_SCERR\n", btv->nr)); bt848_dma(btv, 0); - bt848_dma(btv, 1); + bt848_dma(btv, 3); wake_up_interruptible(&btv->vbiq); wake_up_interruptible(&btv->capq); diff -u --recursive --new-file v2.2.2/linux/drivers/char/console.c linux/drivers/char/console.c --- v2.2.2/linux/drivers/char/console.c Wed Jan 20 23:14:05 1999 +++ linux/drivers/char/console.c Thu Feb 25 10:02:12 1999 @@ -203,7 +203,14 @@ static inline unsigned short *screenpos(int currcons, int offset, int viewed) { - unsigned short *p = (unsigned short *)(visible_origin + offset); + unsigned short *p; + + if (!viewed) + p = (unsigned short *)(origin + offset); + else if (!sw->con_screen_pos) + p = (unsigned short *)(visible_origin + offset); + else + p = sw->con_screen_pos(vc_cons[currcons].d, offset); return p; } @@ -253,16 +260,16 @@ unsigned int xx, yy, offset; u16 *p; - if (start < origin) { - count -= origin - start; - start = origin; - } - if (count <= 0) - return; - offset = (start - origin) / 2; - xx = offset % video_num_columns; - yy = offset / video_num_columns; p = (u16 *) start; + if (!sw->con_getxy) { + offset = (start - origin) / 2; + xx = offset % video_num_columns; + yy = offset / video_num_columns; + } else { + int nxx, nyy; + start = sw->con_getxy(vc_cons[currcons].d, start, &nxx, &nyy); + xx = nxx; yy = nyy; + } for(;;) { u16 attrib = scr_readw(p) & 0xff00; int startx = xx; @@ -285,6 +292,10 @@ break; xx = 0; yy++; + if (sw->con_getxy) { + p = (u16 *)start; + start = sw->con_getxy(vc_cons[currcons].d, start, NULL, NULL); + } } #endif } @@ -2778,7 +2789,7 @@ set_cursor(currcons); } -u16 vcs_scr_readw(int currcons, u16 *org) +u16 vcs_scr_readw(int currcons, const u16 *org) { if ((unsigned long)org == pos && softcursor_original != -1) return softcursor_original; diff -u --recursive --new-file v2.2.2/linux/drivers/char/dtlk.c linux/drivers/char/dtlk.c --- v2.2.2/linux/drivers/char/dtlk.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/dtlk.c Sun Mar 7 16:15:39 1999 @@ -0,0 +1,722 @@ +/* -*- linux-c -*- + * dtlk.c - DoubleTalk PC driver for Linux kernel 2.0.29 + * + * $Id: dtlk.c,v 1.19 1999/02/28 12:13:13 jrv Exp jrv $ + * + * Original author: Chris Pallotta + * Current maintainer: Jim Van Zandt + */ + +/* This driver is for the DoubleTalk PC, a speech synthesizer + manufactured by RC Systems (http://www.rcsys.com/). It was written + based on documentation in their User's Manual file and Developer's + Tools disk. + + The DoubleTalk PC contains four voice synthesizers: text-to-speech + (TTS), linear predictive coding (LPC), PCM/ADPCM, and CVSD. It + also has a tone generator. Output data for LPC are written to the + LPC port, and output data for the other modes are written to the + TTS port. + + Two kinds of data can be read from the DoubleTalk: status + information (in response to the "\001?" interrogation command) is + read from the TTS port, and index markers (which mark the progress + of the speech) are read from the LPC port. Not all models of the + DoubleTalk PC implement index markers. Both the TTS and LPC ports + can also display status flags. + + The DoubleTalk PC generates no interrupts. + + These characteristics are mapped into the Unix stream I/O model as + follows: + + "write" sends bytes to the TTS port. It is the responsibility of + the user program to switch modes among TTS, PCM/ADPCM, and CVSD. + This driver was written for use with the text-to-speech + synthesizer. If LPC output is needed some day, other minor device + numbers can be used to select among output modes. + + "read" gets index markers from the LPC port. If the device does + not implement index markers, the read will fail with error EINVAL. + + Status information is available using the DTLK_INTERROGATE ioctl. + + */ + +#ifdef MODVERSIONS +#include +#endif + +#ifdef MODULE +#include +#include +#else +#define MOD_INC_USE_COUNT +#define MOD_DEC_USE_COUNT +#endif + +#define KERNEL +#include + +#include +#include +#include /* for verify_area */ +#include /* for -EBUSY */ +#include /* for check_region, request_region */ +#include /* for loops_per_sec */ +#include /* for put_user_byte */ +#include /* for inb_p, outb_p, inb, outb, etc. */ +#include /* for get_user, etc. */ +#include /* for wait_queue */ +#include /* for __init */ +#include /* for POLLIN, etc. */ +#include /* local header file for DoubleTalk values */ + +#ifdef TRACING +#define TRACE_TEXT(str) printk(str); +#define TRACE_RET printk(")") +#else /* !TRACING */ +#define TRACE_TEXT(str) ((void) 0) +#define TRACE_RET ((void) 0) +#endif /* TRACING */ + + +static int dtlk_major; +static int dtlk_port_lpc; +static int dtlk_port_tts; +static int dtlk_busy; +static int dtlk_timer_active; +static int dtlk_has_indexing; +static unsigned int dtlk_portlist[] = +{0x25e, 0x29e, 0x2de, 0x31e, 0x35e, 0x39e, 0}; +static struct wait_queue *dtlk_process_list = NULL; +static struct timer_list dtlk_timer; + +/* prototypes for file_operations struct */ +static ssize_t dtlk_read(struct file *, char *, + size_t nbytes, loff_t * ppos); +static ssize_t dtlk_write(struct file *, const char *, + size_t nbytes, loff_t * ppos); +static unsigned int dtlk_poll(struct file *, poll_table *); +static int dtlk_open(struct inode *, struct file *); +static int dtlk_release(struct inode *, struct file *); +static int dtlk_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); + +static struct file_operations dtlk_fops = +{ + NULL, /* lseek */ + dtlk_read, + dtlk_write, + NULL, /* readdir */ + dtlk_poll, + dtlk_ioctl, + NULL, /* mmap */ + dtlk_open, + NULL, /* flush */ + dtlk_release, + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL /* lock */ +}; + +/* local prototypes */ +static void dtlk_delay(int ms); +static int dtlk_dev_probe(void); +static struct dtlk_settings *dtlk_interrogate(void); +static int dtlk_readable(void); +static char dtlk_read_lpc(void); +static char dtlk_read_tts(void); +static void dtlk_stop_timer(void); +static int dtlk_writeable(void); +static char dtlk_write_bytes(const char *buf, int n); +static char dtlk_write_tts(char); +/* + static void dtlk_handle_error(char, char, unsigned int); + static char dtlk_write_byte(unsigned int, const char*); + */ +static void dtlk_timer_tick(unsigned long data); + +static ssize_t dtlk_read(struct file *file, char *buf, + size_t count, loff_t * ppos) +{ + unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); + char ch; + int retval, i = 0, retries; + + /* Can't seek (pread) on the DoubleTalk. */ + if (ppos != &file->f_pos) + return -ESPIPE; + + TRACE_TEXT("(dtlk_read"); + /* printk("DoubleTalk PC - dtlk_read()\n"); */ + + if (minor != DTLK_MINOR || !dtlk_has_indexing) + return -EINVAL; + + for (retries = 0; retries < loops_per_sec / 10; retries++) { + while (i < count && dtlk_readable()) { + ch = dtlk_read_lpc(); + /* printk("dtlk_read() reads 0x%02x\n", ch); */ + if ((retval = put_user(ch, buf++))) + return retval; + i++; + } + if (i) + return i; + if (file->f_flags & O_NONBLOCK) + break; + dtlk_delay(10); + } + if (retries == loops_per_sec) + printk(KERN_ERR "dtlk_read times out\n"); + TRACE_RET; + return -EAGAIN; +} + +static ssize_t dtlk_write(struct file *file, const char *buf, + size_t count, loff_t * ppos) +{ + int i = 0, retries = 0, err, ch; + + TRACE_TEXT("(dtlk_write"); +#ifdef TRACING + printk(" \""); + { + int i, ch; + for (i = 0; i < count; i++) { + err = get_user(ch, buf + i); + if (' ' <= ch && ch <= '~') + printk("%c", ch); + else + printk("\\%03o", ch); + } + printk("\""); + } +#endif + + /* Can't seek (pwrite) on the DoubleTalk. */ + if (ppos != &file->f_pos) + return -ESPIPE; + + if (MINOR(file->f_dentry->d_inode->i_rdev) != DTLK_MINOR) + return -EINVAL; + + while (1) { + while (i < count && (err = get_user(ch, buf)) == 0 && + (ch == DTLK_CLEAR || dtlk_writeable())) { + dtlk_write_tts(ch); + buf++; + i++; + if (i % 5 == 0) + /* We yield our time until scheduled + again. This reduces the transfer + rate to 500 bytes/sec, but that's + still enough to keep up with the + speech synthesizer. */ + dtlk_delay(1); + else { + /* the RDY bit goes zero 2-3 usec + after writing, and goes 1 again + 180-190 usec later. Here, we wait + up to 250 usec for the RDY bit to + go nonzero. */ + for (retries = 0; + retries < loops_per_sec / 4000; + retries++) + if (inb_p(dtlk_port_tts) & + TTS_WRITABLE) + break; + } + retries = 0; + } + if (i == count) + return i; + if (file->f_flags & O_NONBLOCK) + break; + + dtlk_delay(1); + + if (++retries > 10 * HZ) { /* wait no more than 10 sec + from last write */ + printk("dtlk: write timeout. " + "inb_p(dtlk_port_tts) = 0x%02x\n", + inb_p(dtlk_port_tts)); + TRACE_RET; + return -EBUSY; + } + } + TRACE_RET; + return -EAGAIN; +} + +static unsigned int dtlk_poll(struct file *file, poll_table * wait) +{ + int mask = 0; + TRACE_TEXT(" dtlk_poll"); + /* + static long int j; + printk("."); + printk("<%ld>", jiffies-j); + j=jiffies; + */ + poll_wait(file, &dtlk_process_list, wait); + + if (dtlk_has_indexing && dtlk_readable()) { + dtlk_stop_timer(); + mask = POLLIN | POLLRDNORM; + } + if (dtlk_writeable()) { + dtlk_stop_timer(); + mask |= POLLOUT | POLLWRNORM; + } + /* there are no exception conditions */ + + if (mask == 0 && !dtlk_timer_active) { + /* not ready just yet. There won't be any interrupts, + so we set a timer instead. */ + dtlk_timer_active = 1; + dtlk_timer.expires = jiffies + HZ / 100; + add_timer(&dtlk_timer); + } + return 0; +} + +static void dtlk_stop_timer() +{ + if (dtlk_timer_active) { + dtlk_timer_active = 0; + del_timer(&dtlk_timer); + } +} + +static void dtlk_timer_tick(unsigned long data) +{ + + wake_up_interruptible(&dtlk_process_list); + + if (dtlk_timer_active) { + del_timer(&dtlk_timer); + dtlk_timer.expires = jiffies + HZ / 100; + add_timer(&dtlk_timer); + } +} + +static int dtlk_ioctl(struct inode *inode, + struct file *file, + unsigned int cmd, + unsigned long arg) +{ + struct dtlk_settings *sp; + int err; + char portval; + TRACE_TEXT(" dtlk_ioctl"); + + switch (cmd) { + + case DTLK_INTERROGATE: + sp = dtlk_interrogate(); + err = copy_to_user((char *) arg, (char *) sp, + sizeof(struct dtlk_settings)); + if (err) + return -EINVAL; + return 0; + + case DTLK_STATUS: + portval = inb_p(dtlk_port_tts); + return put_user(portval, (char *) arg); + + default: + return -EINVAL; + } +} + +static int dtlk_open(struct inode *inode, struct file *file) +{ + MOD_INC_USE_COUNT; + TRACE_TEXT("(dtlk_open"); + + switch (MINOR(inode->i_rdev)) { + case DTLK_MINOR: + if (dtlk_busy) + return -EBUSY; + return 0; + + default: + return -ENXIO; + } +} + +static int dtlk_release(struct inode *inode, struct file *file) +{ + MOD_DEC_USE_COUNT; + TRACE_TEXT("(dtlk_release"); + + switch (MINOR(inode->i_rdev)) { + case DTLK_MINOR: + break; + + default: + break; + } + TRACE_RET; + + dtlk_stop_timer(); + + return 0; +} + +int __init dtlk_init(void) +{ + dtlk_port_lpc = 0; + dtlk_port_tts = 0; + dtlk_busy = 0; + dtlk_timer_active = 0; + dtlk_major = register_chrdev(0, "dtlk", &dtlk_fops); + if (dtlk_major == 0) { + printk(KERN_ERR "DoubleTalk PC - cannot register device\n"); + return 0; + } + if (dtlk_dev_probe() == 0) + printk(", MAJOR %d\n", dtlk_major); + + init_timer(&dtlk_timer); + dtlk_timer.function = dtlk_timer_tick; + dtlk_process_list = NULL; + + return 0; +} + +#ifdef MODULE +int init_module(void) +{ + return dtlk_init(); +} + +void cleanup_module(void) +{ + dtlk_write_bytes("goodbye", 8); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(5 * HZ / 10); /* nap 0.50 sec but + could be awakened + earlier by + signals... */ + + dtlk_write_tts(DTLK_CLEAR); + unregister_chrdev(dtlk_major, "dtlk"); + release_region(dtlk_port_lpc, DTLK_IO_EXTENT); +} + +#endif + +/* ------------------------------------------------------------------------ */ + +/* sleep for ms milliseconds */ +static void dtlk_delay(int ms) +{ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((ms * HZ + 1000 - HZ) / 1000); + current->state = TASK_RUNNING; +} + +static int dtlk_readable(void) +{ + TRACE_TEXT(" dtlk_readable"); + return inb_p(dtlk_port_lpc) != 0x7f; +} + +static int dtlk_writeable(void) +{ + /* TRACE_TEXT(" dtlk_writeable"); */ +#ifdef TRACING + printk(" dtlk_writeable(%02x)", inb_p(dtlk_port_tts)); +#endif + return inb_p(dtlk_port_tts) & TTS_WRITABLE; +} + +static int __init dtlk_dev_probe(void) +{ + unsigned int testval = 0; + int i = 0; + struct dtlk_settings *sp; + + if (dtlk_port_lpc | dtlk_port_tts) + return -EBUSY; + + for (i = 0; dtlk_portlist[i]; i++) { +#if 0 + printk("DoubleTalk PC - Port %03x = %04x\n", + dtlk_portlist[i], (testval = inw_p(dtlk_portlist[i]))); +#endif + + if (check_region(dtlk_portlist[i], DTLK_IO_EXTENT)) + continue; + testval = inw_p(dtlk_portlist[i]); + if ((testval &= 0xfbff) == 0x107f) { + request_region(dtlk_portlist[i], DTLK_IO_EXTENT, + "dtlk"); + dtlk_port_lpc = dtlk_portlist[i]; + dtlk_port_tts = dtlk_port_lpc + 1; + + sp = dtlk_interrogate(); + printk("DoubleTalk PC at %03x-%03x, " + "ROM version %s, serial number %u", + dtlk_portlist[i], dtlk_portlist[i] + + DTLK_IO_EXTENT - 1, + sp->rom_version, sp->serial_number); + + /* put LPC port into known state, so + dtlk_readable() gives valid result */ + outb_p(0xff, dtlk_port_lpc); + + /* INIT string and index marker */ + dtlk_write_bytes("\036\1@\0\0012I\r", 8); + /* posting an index takes 18 msec. Here, we + wait up to 100 msec to see whether it + appears. */ + dtlk_delay(100); + dtlk_has_indexing = dtlk_readable(); + +#ifdef INSCOPE + { +/* This macro records ten samples read from the LPC port, for later display */ +#define LOOK \ +for (i = 0; i < 10; i++) \ + { \ + buffer[b++] = inb_p(dtlk_port_lpc); \ + __delay(loops_per_sec/1000000); \ + } + char buffer[1000]; + int b = 0, i, j; + + LOOK + outb_p(0xff, dtlk_port_lpc); + buffer[b++] = 0; + LOOK + dtlk_write_bytes("\0012I\r", 4); + buffer[b++] = 0; + __delay(50 * loops_per_sec / 1000); + outb_p(0xff, dtlk_port_lpc); + buffer[b++] = 0; + LOOK + + printk("\n"); + for (j = 0; j < b; j++) + printk(" %02x", buffer[j]); + printk("\n"); + } +#endif /* INSCOPE */ + +#ifdef OUTSCOPE + { +/* This macro records ten samples read from the TTS port, for later display */ +#define LOOK \ +for (i = 0; i < 10; i++) \ + { \ + buffer[b++] = inb_p(dtlk_port_tts); \ + __delay(loops_per_sec/1000000); /* 1 us */ \ + } + char buffer[1000]; + int b = 0, i, j; + + __delay(loops_per_sec / 100); /* 10 ms */ + LOOK + outb_p(0x03, dtlk_port_tts); + buffer[b++] = 0; + LOOK + LOOK + + printk("\n"); + for (j = 0; j < b; j++) + printk(" %02x", buffer[j]); + printk("\n"); + } +#endif /* OUTSCOPE */ + + dtlk_write_bytes("Double Talk found", 18); + + return 0; + } + } + + printk(KERN_INFO "\nDoubleTalk PC - not found\n"); + return -ENODEV; +} + +/* + static void dtlk_handle_error(char op, char rc, unsigned int minor) + { + printk(KERN_INFO"\nDoubleTalk PC - MINOR: %d, OPCODE: %d, ERROR: %d\n", + minor, op, rc); + return; + } + */ + +/* interrogate the DoubleTalk PC and return its settings */ +static struct dtlk_settings *dtlk_interrogate(void) +{ + unsigned char *t; + static char buf[sizeof(struct dtlk_settings) + 1]; + int total, i; + static struct dtlk_settings status; + TRACE_TEXT("(dtlk_interrogate"); + dtlk_write_bytes("\030\001?", 3); + for (total = 0, i = 0; i < 50; i++) { + buf[total] = dtlk_read_tts(); + if (total > 2 && buf[total] == 0x7f) + break; + if (total < sizeof(struct dtlk_settings)) + total++; + } + /* + if (i==50) printk("interrogate() read overrun\n"); + for (i=0; i 0); + if (retries == 0) + printk(KERN_ERR "dtlk_read_lpc() timeout\n"); + + TRACE_RET; + return ch; +} + +#ifdef NEVER +static char dtlk_write_byte(unsigned int minor, const char *buf) +{ + char ch; + int err; + /* TRACE_TEXT("(dtlk_write_byte"); */ + err = get_user(ch, buf); + /* printk(" dtlk_write_byte(%d, 0x%02x)", minor, (int)ch); */ + + ch = dtlk_write_tts(ch); + /* + TRACE_RET; */ + return ch; +} +#endif /* NEVER */ + +/* write n bytes to tts port */ +static char dtlk_write_bytes(const char *buf, int n) +{ + char val = 0; + /* printk("dtlk_write_bytes(\"%-*s\", %d)\n", n, buf, n); */ + TRACE_TEXT("(dtlk_write_bytes"); + while (n-- > 0) + val = dtlk_write_tts(*buf++); + TRACE_RET; + return val; +} + +static char dtlk_write_tts(char ch) +{ + int retries = 0; +#ifdef TRACING + printk(" dtlk_write_tts("); + if (' ' <= ch && ch <= '~') + printk("'%c'", ch); + else + printk("0x%02x", ch); +#endif + if (ch != DTLK_CLEAR) /* no flow control for CLEAR command */ + while ((inb_p(dtlk_port_tts) & TTS_WRITABLE) == 0 && + retries++ < DTLK_MAX_RETRIES) /* DT ready? */ + ; + if (retries == DTLK_MAX_RETRIES) + printk(KERN_ERR "dtlk_write_tts() timeout\n"); + + outb_p(ch, dtlk_port_tts); /* output to TTS port */ + /* the RDY bit goes zero 2-3 usec after writing, and goes + 1 again 180-190 usec later. Here, we wait up to 10 + usec for the RDY bit to go zero. */ + for (retries = 0; retries < loops_per_sec / 100000; retries++) + if ((inb_p(dtlk_port_tts) & TTS_WRITABLE) == 0) + break; + +#ifdef TRACING + printk(")\n"); +#endif + return 0; +} diff -u --recursive --new-file v2.2.2/linux/drivers/char/ftape/zftape/zftape-init.c linux/drivers/char/ftape/zftape/zftape-init.c --- v2.2.2/linux/drivers/char/ftape/zftape/zftape-init.c Wed Aug 26 11:37:37 1998 +++ linux/drivers/char/ftape/zftape/zftape-init.c Sun Mar 7 10:42:26 1999 @@ -280,8 +280,6 @@ static struct vm_operations_struct dummy = { NULL, }; vma->vm_ops = &dummy; #endif - vma->vm_file = filep; - filep->f_count++; } current->blocked = old_sigmask; /* restore mask */ TRACE_EXIT result; diff -u --recursive --new-file v2.2.2/linux/drivers/char/mem.c linux/drivers/char/mem.c --- v2.2.2/linux/drivers/char/mem.c Mon Jan 25 17:44:34 1999 +++ linux/drivers/char/mem.c Sun Mar 7 10:36:47 1999 @@ -178,8 +178,6 @@ if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start, vma->vm_page_prot)) return -EAGAIN; - vma->vm_file = file; - file->f_count++; return 0; } diff -u --recursive --new-file v2.2.2/linux/drivers/char/misc.c linux/drivers/char/misc.c --- v2.2.2/linux/drivers/char/misc.c Tue Jan 19 11:32:51 1999 +++ linux/drivers/char/misc.c Sun Mar 7 16:15:39 1999 @@ -231,6 +231,9 @@ #ifdef CONFIG_SOFT_WATCHDOG watchdog_init(); #endif +#ifdef CONFIG_DTLK + dtlk_init(); +#endif #ifdef CONFIG_APM apm_bios_init(); #endif diff -u --recursive --new-file v2.2.2/linux/drivers/char/radio-aimslab.c linux/drivers/char/radio-aimslab.c --- v2.2.2/linux/drivers/char/radio-aimslab.c Wed Jan 13 15:00:41 1999 +++ linux/drivers/char/radio-aimslab.c Sun Mar 7 15:22:06 1999 @@ -3,6 +3,11 @@ * Coverted to new API by Alan Cox * Various bugfixes and enhancements by Russell Kroll * + * History: + * 1999-02-24 Russell Kroll + * Fine tuning/VIDEO_TUNER_LOW + * Frequency range expanded to start at 87 MHz + * * TODO: Allow for more than one of these foolish entities :-) * * Notes on the hardware (reverse engineered from other peoples' @@ -156,14 +161,11 @@ /* adapted from radio-aztech.c */ - /* We want to compute x * 100 / 16 without overflow - * So we compute x*6 + (x/100)*25 to give x*6.25 - */ - - freq = freq * 6 + freq/4; /* massage the data a little */ - freq += 1070; /* IF = 10.7 MHz */ - freq /= 5; /* ref = 25 kHz */ + /* now uses VIDEO_TUNER_LOW for fine tuning */ + freq += 171200; /* Add 10.7 MHz IF */ + freq /= 800; /* Convert to 50 kHz units */ + send_0_byte (io, dev); /* 0: LSB of frequency */ for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ @@ -229,9 +231,9 @@ return -EFAULT; if(v.tuner) /* Only 1 tuner */ return -EINVAL; - v.rangelow=(88*16); - v.rangehigh=(108*16); - v.flags=0; + v.rangelow=(87*16000); + v.rangehigh=(108*16000); + v.flags=VIDEO_TUNER_LOW; v.mode=VIDEO_MODE_AUTO; v.signal=0xFFFF*rt_getsigstr(rt); if(copy_to_user(arg,&v, sizeof(v))) diff -u --recursive --new-file v2.2.2/linux/drivers/char/radio-aztech.c linux/drivers/char/radio-aztech.c --- v2.2.2/linux/drivers/char/radio-aztech.c Wed Aug 26 11:37:37 1998 +++ linux/drivers/char/radio-aztech.c Sun Mar 7 15:22:06 1999 @@ -1,9 +1,7 @@ -/* aztech.c - Aztech radio card driver for Linux 2.1 by Russell Kroll +/* radio-aztech.c - Aztech radio card driver for Linux 2.2 * - * Heavily modified to support the new 2.1 radio card interfaces by - * Russell Kroll (rkroll@exploits.org) - * - * Based on code by + * Adapted to support the Video for Linux API by + * Russell Kroll . Based on original tuner code by: * * Quay Ly * Donald Song @@ -14,6 +12,11 @@ * The basis for this code may be found at http://bigbang.vtc.vsc.edu/fmradio/ * along with more information on the card itself. * + * History: + * 1999-02-24 Russell Kroll + * Fine tuning/VIDEO_TUNER_LOW + * Range expanded to 87-108 MHz (from 87.9-107.8) + * * Notable changes from the original source: * - includes stripped down to the essentials * - for loops used as delays replaced with udelay() @@ -113,11 +116,8 @@ { int i; - /* 6.25 * */ - frequency = frequency*6 + frequency/4; /* massage data a bit */ - - frequency += 1070; /* tuning needs 24 data bits */ - frequency /= 5; + frequency += 171200; /* Add 10.7 MHz IF */ + frequency /= 800; /* Convert to 50 kHz units */ send_0_byte (dev); /* 0: LSB of frequency */ @@ -179,9 +179,9 @@ return -EFAULT; if(v.tuner) /* Only 1 tuner */ return -EINVAL; - v.rangelow=(879*16)/10; - v.rangehigh=(1078*16)/10; - v.flags=0; + v.rangelow=(87*16000); + v.rangehigh=(108*16000); + v.flags=VIDEO_TUNER_LOW; v.mode=VIDEO_MODE_AUTO; v.signal=0xFFFF*az_getsigstr(az); if(az_getstereo(az)) @@ -292,7 +292,7 @@ return -EINVAL; request_region(io, 2, "aztech"); - printk(KERN_INFO "Aztech radio card driver v0.40/19980422 rkroll@exploits.org\n"); + printk(KERN_INFO "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); /* mute card - prevents noisy bootups */ outb (0, io); return 0; diff -u --recursive --new-file v2.2.2/linux/drivers/char/radio-typhoon.c linux/drivers/char/radio-typhoon.c --- v2.2.2/linux/drivers/char/radio-typhoon.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/radio-typhoon.c Wed Feb 24 16:27:53 1999 @@ -0,0 +1,428 @@ +/* Typhoon Radio Card driver for radio support + * (c) 1999 Dr. Henrik Seidel + * + * Card manufacturer: + * http://194.18.155.92/idc/prod2.idc?nr=50753&lang=e + * + * Notes on the hardware + * + * This card has two output sockets, one for speakers and one for line. + * The speaker output has volume control, but only in four discrete + * steps. The line output has neither volume control nor mute. + * + * The card has auto-stereo according to its manual, although it all + * sounds mono to me (even with the Win/DOS drivers). Maybe it's my + * antenna - I really don't know for sure. + * + * Frequency control is done digitally. + * + * Volume control is done digitally, but there are only four different + * possible values. So you should better always turn the volume up and + * use line control. I got the best results by connecting line output + * to the sound card microphone input. For such a configuration the + * volume control has no effect, since volume control only influences + * the speaker output. + * + * There is no explicit mute/unmute. So I set the radio frequency to a + * value where I do expect just noise and turn the speaker volume down. + * The frequency change is necessary since the card never seems to be + * completely silent. + */ + +#include /* Modules */ +#include /* Initdata */ +#include /* check_region, request_region */ +#include /* radio card status report */ +#include /* outb, outb_p */ +#include /* copy to/from user */ +#include /* kernel radio structs */ +#include /* CONFIG_RADIO_TYPHOON_* */ + +#define BANNER "Typhoon Radio Card driver v0.1\n" + +#ifndef CONFIG_RADIO_TYPHOON_PORT +#define CONFIG_RADIO_TYPHOON_PORT -1 +#endif + +#ifndef CONFIG_RADIO_TYPHOON_MUTEFREQ +#define CONFIG_RADIO_TYPHOON_MUTEFREQ 0 +#endif + +struct typhoon_device { + int users; + int iobase; + int curvol; + int muted; + unsigned long curfreq; + unsigned long mutefreq; +}; + +static void typhoon_setvol_generic(struct typhoon_device *dev, int vol); +static int typhoon_setfreq_generic(struct typhoon_device *dev, + unsigned long frequency); +static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency); +static void typhoon_mute(struct typhoon_device *dev); +static void typhoon_unmute(struct typhoon_device *dev); +static int typhoon_setvol(struct typhoon_device *dev, int vol); +static int typhoon_ioctl(struct video_device *dev, unsigned int cmd, void *arg); +static int typhoon_open(struct video_device *dev, int flags); +static void typhoon_close(struct video_device *dev); +#ifdef CONFIG_RADIO_TYPHOON_PROC_FS +static int typhoon_read_proc(char *buf, char **start, off_t offset, int len, + int unused); +#endif +#ifdef MODULE +int init_module(void); +void cleanup_module(void); +int typhoon_init(struct video_init *v); +#else +int typhoon_init(struct video_init *v) __init; +#endif + +static void typhoon_setvol_generic(struct typhoon_device *dev, int vol) +{ + vol >>= 14; /* Map 16 bit to 2 bit */ + vol &= 3; + outb_p(vol / 2, dev->iobase); /* Set the volume, high bit. */ + outb_p(vol % 2, dev->iobase + 2); /* Set the volume, low bit. */ +} + +static int typhoon_setfreq_generic(struct typhoon_device *dev, + unsigned long frequency) +{ + unsigned long outval; + unsigned long x; + + /* + * The frequency transfer curve is not linear. The best fit I could + * get is + * + * outval = -155 + exp((f + 15.55) * 0.057)) + * + * where frequency f is in MHz. Since we don't have exp in the kernel, + * I approximate this function by a third order polynomial. + * + */ + + x = frequency / 160; + outval = (x * x + 2500) / 5000; + outval = (outval * x + 5000) / 10000; + outval -= (10 * x * x + 10433) / 20866; + outval += 4 * x - 11505; + + outb_p((outval >> 8) & 0x01, dev->iobase + 4); + outb_p(outval >> 9, dev->iobase + 6); + outb_p(outval & 0xff, dev->iobase + 8); + + return 0; +} + +static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency) +{ + typhoon_setfreq_generic(dev, frequency); + dev->curfreq = frequency; + return 0; +} + +static void typhoon_mute(struct typhoon_device *dev) +{ + if (dev->muted == 1) + return; + typhoon_setvol_generic(dev, 0); + typhoon_setfreq_generic(dev, dev->mutefreq); + dev->muted = 1; +} + +static void typhoon_unmute(struct typhoon_device *dev) +{ + if (dev->muted == 0) + return; + typhoon_setfreq_generic(dev, dev->curfreq); + typhoon_setvol_generic(dev, dev->curvol); + dev->muted = 0; +} + +static int typhoon_setvol(struct typhoon_device *dev, int vol) +{ + if (dev->muted && vol != 0) { /* user is unmuting the card */ + dev->curvol = vol; + typhoon_unmute(dev); + return 0; + } + if (vol == dev->curvol) /* requested volume == current */ + return 0; + + if (vol == 0) { /* volume == 0 means mute the card */ + typhoon_mute(dev); + dev->curvol = vol; + return 0; + } + typhoon_setvol_generic(dev, vol); + dev->curvol = vol; + return 0; +} + + +static int typhoon_ioctl(struct video_device *dev, unsigned int cmd, void *arg) +{ + struct typhoon_device *typhoon = dev->priv; + + switch (cmd) { + case VIDIOCGCAP: + { + struct video_capability v; + v.type = VID_TYPE_TUNER; + v.channels = 1; + v.audios = 1; + /* No we don't do pictures */ + v.maxwidth = 0; + v.maxheight = 0; + v.minwidth = 0; + v.minheight = 0; + strcpy(v.name, "Typhoon Radio"); + if (copy_to_user(arg, &v, sizeof(v))) + return -EFAULT; + return 0; + } + case VIDIOCGTUNER: + { + struct video_tuner v; + if (copy_from_user(&v, arg, sizeof(v)) != 0) + return -EFAULT; + if (v.tuner) /* Only 1 tuner */ + return -EINVAL; + v.rangelow = 875 * 1600; + v.rangehigh = 1080 * 1600; + v.flags = VIDEO_TUNER_LOW; + v.mode = VIDEO_MODE_AUTO; + v.signal = 0; /* We can't get the signal strength */ + if (copy_to_user(arg, &v, sizeof(v))) + return -EFAULT; + return 0; + } + case VIDIOCSTUNER: + { + struct video_tuner v; + if (copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if (v.tuner != 0) + return -EINVAL; + /* Only 1 tuner so no setting needed ! */ + return 0; + } + case VIDIOCGFREQ: + if (copy_to_user(arg, &typhoon->curfreq, + sizeof(typhoon->curfreq))) + return -EFAULT; + return 0; + case VIDIOCSFREQ: + if (copy_from_user(&typhoon->curfreq, arg, + sizeof(typhoon->curfreq))) + return -EFAULT; + typhoon_setfreq(typhoon, typhoon->curfreq); + return 0; + case VIDIOCGAUDIO: + { + struct video_audio v; + memset(&v, 0, sizeof(v)); + v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME; + v.mode |= VIDEO_SOUND_MONO; + v.volume = typhoon->curvol; + v.step = 1 << 14; + strcpy(v.name, "Typhoon Radio"); + if (copy_to_user(arg, &v, sizeof(v))) + return -EFAULT; + return 0; + } + case VIDIOCSAUDIO: + { + struct video_audio v; + if (copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if (v.audio) + return -EINVAL; + + if (v.flags & VIDEO_AUDIO_MUTE) + typhoon_mute(typhoon); + else + typhoon_unmute(typhoon); + + if (v.flags & VIDEO_AUDIO_VOLUME) + typhoon_setvol(typhoon, v.volume); + + return 0; + } + default: + return -ENOIOCTLCMD; + } +} + +static int typhoon_open(struct video_device *dev, int flags) +{ + struct typhoon_device *typhoon = dev->priv; + if (typhoon->users) + return -EBUSY; + typhoon->users++; + MOD_INC_USE_COUNT; + return 0; +} + +static void typhoon_close(struct video_device *dev) +{ + struct typhoon_device *typhoon = dev->priv; + typhoon->users--; + MOD_DEC_USE_COUNT; +} + +static struct typhoon_device typhoon_unit = +{ + 0, /* users */ + CONFIG_RADIO_TYPHOON_PORT, /* iobase */ + 0, /* curvol */ + 0, /* muted */ + CONFIG_RADIO_TYPHOON_MUTEFREQ, /* curfreq */ + CONFIG_RADIO_TYPHOON_MUTEFREQ /* mutefreq */ +}; + +static struct video_device typhoon_radio = +{ + "Typhoon Radio", + VID_TYPE_TUNER, + VID_HARDWARE_TYPHOON, + typhoon_open, + typhoon_close, + NULL, /* Can't read (no capture ability) */ + NULL, /* Can't write */ + NULL, /* Can't poll */ + typhoon_ioctl, + NULL, + NULL +}; + +#ifdef CONFIG_RADIO_TYPHOON_PROC_FS + +static int typhoon_read_proc(char *buf, char **start, off_t offset, int len, + int unused) +{ + #ifdef MODULE + #define MODULEPROCSTRING "Driver loaded as a module" + #else + #define MODULEPROCSTRING "Driver compiled into kernel" + #endif + + #define LIMIT (PAGE_SIZE - 80) + + len = 0; + len += sprintf(buf + len, BANNER); + if (len > LIMIT) return len; + len += sprintf(buf + len, "Load type: " MODULEPROCSTRING "\n\n"); + if (len > LIMIT) return len; + len += sprintf(buf + len, "frequency = %lu kHz\n", + typhoon_unit.curfreq >> 4); + if (len > LIMIT) return len; + len += sprintf(buf + len, "volume = %d\n", typhoon_unit.curvol); + if (len > LIMIT) return len; + len += sprintf(buf + len, "mute = %s\n", typhoon_unit.muted ? + "on" : "off"); + if (len > LIMIT) return len; + len += sprintf(buf + len, "iobase = 0x%x\n", typhoon_unit.iobase); + if (len > LIMIT) return len; + len += sprintf(buf + len, "mute frequency = %lu kHz\n", + typhoon_unit.mutefreq >> 4); + return len; +} + +static struct proc_dir_entry typhoon_proc_entry = { + 0, /* low_ino: inode is dynamic */ + 13, "radio-typhoon", /* length of name and name */ + S_IFREG | S_IRUGO, /* mode */ + 1, 0, 0, /* nlinks, owner, group */ + 0, /* size -- not used */ + NULL, /* operations -- use default */ + &typhoon_read_proc, /* function used to read data */ + /* nothing more */ +}; + +#endif /* CONFIG_RADIO_TYPHOON_PROC_FS */ + +int typhoon_init(struct video_init *v) +{ + printk(KERN_INFO BANNER); + if (check_region(typhoon_unit.iobase, 8)) { + printk(KERN_ERR "radio-typhoon: port 0x%x already in use\n", + typhoon_unit.iobase); + return -EBUSY; + } + + typhoon_radio.priv = &typhoon_unit; + if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO) == -1) + return -EINVAL; + + request_region(typhoon_unit.iobase, 8, "typhoon"); + printk(KERN_INFO "radio-typhoon: port 0x%x.\n", typhoon_unit.iobase); + printk(KERN_INFO "radio-typhoon: mute frequency is %lu kHz.\n", + typhoon_unit.mutefreq); + typhoon_unit.mutefreq <<= 4; + + /* mute card - prevents noisy bootups */ + typhoon_mute(&typhoon_unit); + +#ifdef CONFIG_RADIO_TYPHOON_PROC_FS + + if (proc_register(&proc_root, &typhoon_proc_entry)) + printk(KERN_ERR "radio-typhoon: registering /proc/radio-typhoon failed\n"); + +#endif + + return 0; +} + +#ifdef MODULE + +MODULE_AUTHOR("Dr. Henrik Seidel"); +MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio)."); +MODULE_PARM(io, "i"); +MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)"); +MODULE_PARM(mutefreq, "i"); +MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)"); + +EXPORT_NO_SYMBOLS; + +static int io = -1; +static unsigned long mutefreq = 0; + +int init_module(void) +{ + if (io == -1) { + printk(KERN_ERR "radio-typhoon: You must set an I/O address with io=0x316 or io=0x336\n"); + return -EINVAL; + } + typhoon_unit.iobase = io; + + if (mutefreq < 87000 || mutefreq > 108500) { + printk(KERN_ERR "radio-typhoon: You must set a frequency (in kHz) used when muting the card,\n"); + printk(KERN_ERR "radio-typhoon: e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n"); + return -EINVAL; + } + typhoon_unit.mutefreq = mutefreq; + + return typhoon_init(NULL); +} + +void cleanup_module(void) +{ + +#ifdef CONFIG_RADIO_TYPHOON_PROC_FS + + if (proc_unregister(&proc_root, typhoon_proc_entry.low_ino)) + printk(KERN_ERR "radio-typhoon: unregistering /proc/radio-typhoon failed\n"); + +#endif + + video_unregister_device(&typhoon_radio); + release_region(io, 8); +} + +#endif + + diff -u --recursive --new-file v2.2.2/linux/drivers/char/radio-zoltrix.c linux/drivers/char/radio-zoltrix.c --- v2.2.2/linux/drivers/char/radio-zoltrix.c Fri Jan 8 22:36:05 1999 +++ linux/drivers/char/radio-zoltrix.c Wed Feb 24 16:27:53 1999 @@ -11,7 +11,8 @@ * at a low frequency, and it is not possible (at least I have not found) * to get fine volume control over the low volume range. * - * Some code derived from code by Frans Brinkman + * Some code derived from code by Romolo Manfredini + * romolo@bicnet.it * * 1999-01-05 - (C. van Schaik) * - Changed tuning to 1/160Mhz accuracy @@ -285,10 +286,10 @@ if (v.flags & VIDEO_AUDIO_MUTE) zol_mute(zol); else + { zol_unmute(zol); - - if (v.flags & VIDEO_AUDIO_VOLUME) zol_setvol(zol, v.volume / 4096); + } if (v.mode & VIDEO_SOUND_STEREO) { diff -u --recursive --new-file v2.2.2/linux/drivers/char/vc_screen.c linux/drivers/char/vc_screen.c --- v2.2.2/linux/drivers/char/vc_screen.c Wed Aug 26 11:37:37 1998 +++ linux/drivers/char/vc_screen.c Thu Feb 25 10:02:12 1999 @@ -89,6 +89,7 @@ long p = *ppos; long viewed, attr, size, read; char *buf0; + int col, maxcol; unsigned short *org = NULL; attr = (currcons & 128); @@ -111,10 +112,19 @@ count = size - p; buf0 = buf; + maxcol = video_num_columns; if (!attr) { org = screen_pos(currcons, p, viewed); - while (count-- > 0) + col = p % maxcol; + p += maxcol - col; + while (count-- > 0) { put_user(vcs_scr_readw(currcons, org++) & 0xff, buf++); + if (++col == maxcol) { + org = screen_pos(currcons, p, viewed); + col = 0; + p += maxcol; + } + } } else { if (p < HEADER_SIZE) { char header[HEADER_SIZE]; @@ -124,20 +134,35 @@ while (p < HEADER_SIZE && count > 0) { count--; put_user(header[p++], buf++); } } + p -= HEADER_SIZE; + col = (p/2) % maxcol; if (count > 0) { - p -= HEADER_SIZE; - org = screen_pos(currcons, p/2, viewed); - if ((p & 1) && count > 0) + org = screen_pos(currcons, p/2, viewed); + if ((p & 1) && count > 0) { + count--; #ifdef __BIG_ENDIAN - { count--; put_user(vcs_scr_readw(currcons, org++) & 0xff, buf++); } + put_user(vcs_scr_readw(currcons, org++) & 0xff, buf++); #else - { count--; put_user(vcs_scr_readw(currcons, org++) >> 8, buf++); } + put_user(vcs_scr_readw(currcons, org++) >> 8, buf++); #endif + p++; + if (++col == maxcol) { + org = screen_pos(currcons, p/2, viewed); + col = 0; + } + } + p /= 2; + p += maxcol - col; } while (count > 1) { put_user(vcs_scr_readw(currcons, org++), (unsigned short *) buf); buf += 2; count -= 2; + if (++col == maxcol) { + org = screen_pos(currcons, p, viewed); + col = 0; + p += maxcol; + } } if (count > 0) #ifdef __BIG_ENDIAN @@ -159,6 +184,7 @@ long p = *ppos; long viewed, attr, size, written; const char *buf0; + int col, maxcol; u16 *org0 = NULL, *org = NULL; attr = (currcons & 128); @@ -181,14 +207,22 @@ count = size - p; buf0 = buf; + maxcol = video_num_columns; if (!attr) { org0 = org = screen_pos(currcons, p, viewed); + col = p % maxcol; + p += maxcol - col; while (count > 0) { unsigned char c; count--; get_user(c, (const unsigned char*)buf++); vcs_scr_writew(currcons, (vcs_scr_readw(currcons, org) & 0xff00) | c, org); org++; + if (++col == maxcol) { + org = screen_pos(currcons, p, viewed); + col = 0; + p += maxcol; + } } } else { if (p < HEADER_SIZE) { @@ -199,8 +233,9 @@ if (!viewed) putconsxy(currcons, header+2); } + p -= HEADER_SIZE; + col = (p/2) % maxcol; if (count > 0) { - p -= HEADER_SIZE; org0 = org = screen_pos(currcons, p/2, viewed); if ((p & 1) && count > 0) { char c; @@ -214,7 +249,14 @@ (vcs_scr_readw(currcons, org) & 0xff), org); #endif org++; + p++; + if (++col == maxcol) { + org = screen_pos(currcons, p/2, viewed); + col = 0; + } } + p /= 2; + p += maxcol - col; } while (count > 1) { unsigned short w; @@ -222,6 +264,11 @@ vcs_scr_writew(currcons, w, org++); buf += 2; count -= 2; + if (++col == maxcol) { + org = screen_pos(currcons, p, viewed); + col = 0; + p += maxcol; + } } if (count > 0) { unsigned char c; diff -u --recursive --new-file v2.2.2/linux/drivers/char/videodev.c linux/drivers/char/videodev.c --- v2.2.2/linux/drivers/char/videodev.c Wed Jan 20 23:14:05 1999 +++ linux/drivers/char/videodev.c Wed Feb 24 16:27:53 1999 @@ -72,6 +72,9 @@ #ifdef CONFIG_RADIO_GEMTEK extern int gemtek_init(struct video_init *); #endif +#ifdef CONFIG_RADIO_TYPHOON +extern int typhoon_init(struct video_init *); +#endif #ifdef CONFIG_VIDEO_PMS extern int init_pms_cards(struct video_init *); #endif @@ -101,7 +104,7 @@ #endif #ifdef CONFIG_RADIO_RTRACK {"RTrack", rtrack_init}, -#endif +#endif #ifdef CONFIG_RADIO_SF16FMI {"SF16FMI", fmi_init}, #endif @@ -110,6 +113,9 @@ #endif #ifdef CONFIG_RADIO_GEMTEK {"GemTek", gemtek_init}, +#endif +#ifdef CONFIG_RADIO_TYPHOON + {"radio-typhoon", typhoon_init}, #endif {"end", NULL} }; diff -u --recursive --new-file v2.2.2/linux/drivers/net/8390.c linux/drivers/net/8390.c --- v2.2.2/linux/drivers/net/8390.c Fri Jan 8 22:36:06 1999 +++ linux/drivers/net/8390.c Wed Feb 24 16:27:53 1999 @@ -165,8 +165,10 @@ spin_lock_irqsave(&ei_local->page_lock, flags); NS8390_init(dev, 1); - spin_unlock_irqrestore(&ei_local->page_lock, flags); + /* Set the flag before we drop the lock, That way the IRQ arrives + after its set and we get no silly warnings */ dev->start = 1; + spin_unlock_irqrestore(&ei_local->page_lock, flags); ei_local->irqlock = 0; return 0; } diff -u --recursive --new-file v2.2.2/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v2.2.2/linux/drivers/net/Makefile Tue Jan 19 11:32:51 1999 +++ linux/drivers/net/Makefile Sun Mar 7 15:25:24 1999 @@ -1046,6 +1046,7 @@ ifeq ($(CONFIG_IRDA),y) SUB_DIRS += irda +MOD_IN_SUB_DIRS += irda else ifeq ($(CONFIG_IRDA),m) MOD_SUB_DIRS += irda diff -u --recursive --new-file v2.2.2/linux/drivers/net/a2065.c linux/drivers/net/a2065.c --- v2.2.2/linux/drivers/net/a2065.c Mon Oct 5 13:13:39 1998 +++ linux/drivers/net/a2065.c Thu Feb 25 10:02:13 1999 @@ -767,6 +767,8 @@ 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)); diff -u --recursive --new-file v2.2.2/linux/drivers/net/ariadne.c linux/drivers/net/ariadne.c --- v2.2.2/linux/drivers/net/ariadne.c Thu Sep 17 17:53:36 1998 +++ linux/drivers/net/ariadne.c Thu Feb 25 10:02:13 1999 @@ -171,6 +171,8 @@ 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)); diff -u --recursive --new-file v2.2.2/linux/drivers/net/cosa.c linux/drivers/net/cosa.c --- v2.2.2/linux/drivers/net/cosa.c Mon Dec 28 15:00:52 1998 +++ linux/drivers/net/cosa.c Sun Mar 7 15:47:46 1999 @@ -1,4 +1,4 @@ -/* $Id: cosa.c,v 1.11 1998/12/24 23:44:23 kas Exp $ */ +/* $Id: cosa.c,v 1.21 1999/02/06 19:49:18 kas Exp $ */ /* * Copyright (C) 1995-1997 Jan "Yenya" Kasprzak @@ -27,7 +27,7 @@ * Masaryk University (http://www.ics.muni.cz/). The hardware is * developed by Jiri Novotny . More information * and the photo of both cards is available at - * http://www.kozakmartin.cz/cosa.html. The card documentation, firmwares + * http://www.pavoucek.cz/cosa.html. The card documentation, firmwares * and other goods can be downloaded from ftp://ftp.ics.muni.cz/pub/cosa/. * For Linux-specific utilities, see below in the "Software info" section. * If you want to order the card, contact Jiri Novotny. @@ -141,11 +141,13 @@ unsigned int datareg, statusreg; /* I/O ports */ unsigned short irq, dma; /* IRQ and DMA number */ unsigned short startaddr; /* Firmware start address */ + unsigned short busmaster; /* Use busmastering? */ int nchannels; /* # of channels on this card */ int driver_status; /* For communicating with firware */ int firmware_status; /* Downloaded, reseted, etc. */ int rxbitmap, txbitmap; /* Bitmap of channels who are willing to send/receive data */ int rxtx; /* RX or TX in progress? */ + int enabled; int usage; /* usage count */ int txchan, txsize, rxsize; struct channel_data *rxchan; @@ -331,9 +333,8 @@ static int get_wait_data(struct cosa_data *cosa); static int put_wait_data(struct cosa_data *cosa, int data); static int puthexnumber(struct cosa_data *cosa, int number); -static void put_driver_status_common(struct cosa_data *cosa, int nolock); -#define put_driver_status(x) put_driver_status_common((x), 0) -#define put_driver_status_nolock(x) put_driver_status_common((x), 1) +static void put_driver_status(struct cosa_data *cosa); +static void put_driver_status_nolock(struct cosa_data *cosa); /* Interrupt handling */ static void cosa_interrupt(int irq, void *cosa, struct pt_regs *regs); @@ -357,7 +358,7 @@ #endif { int i; - printk(KERN_INFO "cosa v1.03 (c) 1997-8 Jan Kasprzak \n"); + printk(KERN_INFO "cosa v1.04 (c) 1997-8 Jan Kasprzak \n"); #ifdef __SMP__ printk(KERN_INFO "cosa: SMP found. Please mail any success/failure reports to the author.\n"); #endif @@ -630,9 +631,14 @@ if (dev->tbusy) { if (time_before(jiffies, dev->trans_start+2*HZ)) return 1; /* Two seconds timeout */ + if (test_bit(RXBIT, &chan->cosa->rxtx)) { + chan->stats.rx_errors++; + chan->stats.rx_missed_errors++; + } else { + chan->stats.tx_errors++; + chan->stats.tx_aborted_errors++; + } cosa_kick(chan->cosa); - chan->stats.tx_errors++; - chan->stats.tx_aborted_errors++; if (chan->tx_skb) { dev_kfree_skb(chan->tx_skb); chan->tx_skb = 0; @@ -659,6 +665,14 @@ d->tbusy = 1; cosa_disable_rx(chan); spin_lock_irqsave(&chan->cosa->lock, flags); + if (chan->rx_skb) { + kfree_skb(chan->rx_skb); + chan->rx_skb = 0; + } + if (chan->tx_skb) { + kfree_skb(chan->tx_skb); + chan->tx_skb = 0; + } chan->usage=0; chan->cosa->usage--; MOD_DEC_USE_COUNT; @@ -1128,6 +1142,17 @@ return nr_cards; case COSAIONRCHANS: return cosa->nchannels; + case COSAIOBMSET: + if (!suser()) + return -EACCES; + if (is_8bit(cosa)) + return -EINVAL; + if (arg != COSA_BM_OFF && arg != COSA_BM_ON) + return -EINVAL; + cosa->busmaster = arg; + return 0; + case COSAIOBMGET: + return cosa->busmaster; } return -ENOIOCTLCMD; } @@ -1208,37 +1233,67 @@ return 0; } -static void put_driver_status_common(struct cosa_data *cosa, int nolock) +static void put_driver_status(struct cosa_data *cosa) { unsigned flags=0; int status; - if (!nolock) - spin_lock_irqsave(&cosa->lock, flags); + spin_lock_irqsave(&cosa->lock, flags); status = (cosa->rxbitmap ? DRIVER_RX_READY : 0) | (cosa->txbitmap ? DRIVER_TX_READY : 0) | (cosa->txbitmap? ~(cosa->txbitmap<rxtx || nolock) { -#ifdef DEBUG_IO - debug_data_cmd(cosa, status); -#endif - cosa_putdata8(cosa, status); + if (!cosa->rxtx) { if (cosa->rxbitmap|cosa->txbitmap) { - cosa_putstatus(cosa, SR_RX_INT_ENA); + if (!cosa->enabled) { + cosa_putstatus(cosa, SR_RX_INT_ENA); #ifdef DEBUG_IO - debug_status_out(cosa, SR_RX_INT_ENA); + debug_status_out(cosa, SR_RX_INT_ENA); #endif - } else { + cosa->enabled = 1; + } + } else if (cosa->enabled) { + cosa->enabled = 0; cosa_putstatus(cosa, 0); #ifdef DEBUG_IO debug_status_out(cosa, 0); #endif } + cosa_putdata8(cosa, status); +#ifdef DEBUG_IO + debug_data_cmd(cosa, status); +#endif } - if (!nolock) - spin_unlock_irqrestore(&cosa->lock, flags); + spin_unlock_irqrestore(&cosa->lock, flags); +} + +static void put_driver_status_nolock(struct cosa_data *cosa) +{ + int status; + + status = (cosa->rxbitmap ? DRIVER_RX_READY : 0) + | (cosa->txbitmap ? DRIVER_TX_READY : 0) + | (cosa->txbitmap? ~(cosa->txbitmap<rxbitmap|cosa->txbitmap) { + cosa_putstatus(cosa, SR_RX_INT_ENA); +#ifdef DEBUG_IO + debug_status_out(cosa, SR_RX_INT_ENA); +#endif + cosa->enabled = 1; + } else { + cosa_putstatus(cosa, 0); +#ifdef DEBUG_IO + debug_status_out(cosa, 0); +#endif + cosa->enabled = 0; + } + cosa_putdata8(cosa, status); +#ifdef DEBUG_IO + debug_data_cmd(cosa, status); +#endif } /* @@ -1249,9 +1304,14 @@ static void cosa_kick(struct cosa_data *cosa) { unsigned flags, flags1; + char *s = "Unknown"; - printk(KERN_INFO "%s: DMA timeout - restarting.\n", cosa->name); + if (test_bit(RXBIT, &cosa->rxtx)) + s = "RX"; + if (test_bit(TXBIT, &cosa->rxtx)) + s = "TX"; + printk(KERN_INFO "%s: %s DMA timeout - restarting.\n", cosa->name, s); spin_lock_irqsave(&cosa->lock, flags); cosa->rxtx = 0; @@ -1261,6 +1321,13 @@ release_dma_lock(flags1); /* FIXME: Anything else? */ + udelay(100); + cosa_putstatus(cosa, 0); + udelay(100); + (void) cosa_getdata8(cosa); + udelay(100); + cosa_putdata8(cosa, 0); + udelay(100); put_driver_status_nolock(cosa); spin_unlock_irqrestore(&cosa->lock, flags); } @@ -1556,6 +1623,10 @@ * COSA status byte. I have moved the rx/tx/eot interrupt handling into * separate functions to make it more readable. These functions are inline, * so there should be no overhead of function call. + * + * In the COSA bus-master mode, we need to tell the card the address of a + * buffer. Unfortunately, COSA may be too slow for us, so we must busy-wait. + * It's time to use the bottom half :-( */ /* @@ -1606,13 +1677,13 @@ if (is_8bit(cosa)) { if (!test_bit(IRQBIT, &cosa->rxtx)) { + cosa_putstatus(cosa, SR_TX_INT_ENA); cosa_putdata8(cosa, ((cosa->txchan << 5) & 0xe0)| ((cosa->txsize >> 8) & 0x1f)); - cosa_putstatus(cosa, SR_TX_INT_ENA); #ifdef DEBUG_IO + debug_status_out(cosa, SR_TX_INT_ENA); debug_data_out(cosa, ((cosa->txchan << 5) & 0xe0)| ((cosa->txsize >> 8) & 0x1f)); - debug_status_out(cosa, SR_TX_INT_ENA); debug_data_in(cosa, cosa_getdata8(cosa)); #else cosa_getdata8(cosa); @@ -1630,27 +1701,57 @@ #endif } } else { + cosa_putstatus(cosa, SR_TX_INT_ENA); cosa_putdata16(cosa, ((cosa->txchan<<13) & 0xe000) | (cosa->txsize & 0x1fff)); - cosa_getdata16(cosa); #ifdef DEBUG_IO - debug_status_out(cosa, ((cosa->txchan<<13) & 0xe000) + debug_status_out(cosa, SR_TX_INT_ENA); + debug_data_out(cosa, ((cosa->txchan<<13) & 0xe000) | (cosa->txsize & 0x1fff)); - debug_data_in(cosa, cosa_getdata16(cosa)); + debug_data_in(cosa, cosa_getdata8(cosa)); + debug_status_out(cosa, 0); #else - cosa_getdata16(cosa); + cosa_getdata8(cosa); #endif + cosa_putstatus(cosa, 0); } - /* start the DMA */ - flags1 = claim_dma_lock(); - disable_dma(cosa->dma); - clear_dma_ff(cosa->dma); - set_dma_mode(cosa->dma, DMA_MODE_WRITE); - set_dma_addr(cosa->dma, virt_to_bus(cosa->txbuf)); - set_dma_count(cosa->dma, cosa->txsize); - enable_dma(cosa->dma); - release_dma_lock(flags1); + if (cosa->busmaster) { + unsigned long addr = virt_to_bus(cosa->txbuf); + int count=0; + printk(KERN_INFO "busmaster IRQ\n"); + while (!(cosa_getstatus(cosa)&SR_TX_RDY)) { + count++; + udelay(10); + if (count > 1000) break; + } + printk(KERN_INFO "status %x\n", cosa_getstatus(cosa)); + printk(KERN_INFO "ready after %d loops\n", count); + cosa_putdata16(cosa, (addr >> 16)&0xffff); + + count = 0; + while (!(cosa_getstatus(cosa)&SR_TX_RDY)) { + count++; + if (count > 1000) break; + udelay(10); + } + printk(KERN_INFO "ready after %d loops\n", count); + cosa_putdata16(cosa, addr &0xffff); + flags1 = claim_dma_lock(); + set_dma_mode(cosa->dma, DMA_MODE_CASCADE); + enable_dma(cosa->dma); + release_dma_lock(flags1); + } else { + /* start the DMA */ + flags1 = claim_dma_lock(); + disable_dma(cosa->dma); + clear_dma_ff(cosa->dma); + set_dma_mode(cosa->dma, DMA_MODE_WRITE); + set_dma_addr(cosa->dma, virt_to_bus(cosa->txbuf)); + set_dma_count(cosa->dma, cosa->txsize); + enable_dma(cosa->dma); + release_dma_lock(flags1); + } cosa_putstatus(cosa, SR_TX_DMA_ENA|SR_USR_INT_ENA); #ifdef DEBUG_IO debug_status_out(cosa, SR_TX_DMA_ENA|SR_USR_INT_ENA); @@ -1671,21 +1772,16 @@ if (is_8bit(cosa)) { if (!test_bit(IRQBIT, &cosa->rxtx)) { set_bit(IRQBIT, &cosa->rxtx); - cosa_putstatus(cosa, 0); cosa->rxsize = cosa_getdata8(cosa) <<8; #ifdef DEBUG_IO - debug_status_out(cosa, 0); debug_data_in(cosa, cosa->rxsize >> 8); #endif - put_driver_status_nolock(cosa); spin_unlock_irqrestore(&cosa->lock, flags); return; } else { clear_bit(IRQBIT, &cosa->rxtx); - cosa_putstatus(cosa, 0); cosa->rxsize |= cosa_getdata8(cosa) & 0xff; #ifdef DEBUG_IO - debug_status_out(cosa, 0); debug_data_in(cosa, cosa->rxsize & 0xff); #endif #if 0 @@ -1695,12 +1791,8 @@ } } else { cosa->rxsize = cosa_getdata16(cosa); - cosa_putstatus(cosa, 0); - cosa_putdata8(cosa, DRIVER_RX_READY); #ifdef DEBUG_IO debug_data_in(cosa, cosa->rxsize); - debug_status_out(cosa, 0); - debug_cmd_out(cosa, DRIVER_RX_READY); #endif #if 0 printk(KERN_INFO "cosa%d: receive rxsize = (0x%04x).\n", @@ -1725,10 +1817,7 @@ reject: /* Reject the packet */ printk(KERN_INFO "cosa%d: rejecting packet on channel %d\n", cosa->num, cosa->rxchan->num); - /* FIXME: This works for COSA only (not SRP) */ - cosa->rxtx = 0; - put_driver_status(cosa); - return; + cosa->rxbuf = cosa->bouncebuf; } /* start the DMA */ @@ -1746,8 +1835,12 @@ release_dma_lock(flags); spin_lock_irqsave(&cosa->lock, flags); cosa_putstatus(cosa, SR_RX_DMA_ENA|SR_USR_INT_ENA); + if (!is_8bit(cosa) && (status & SR_TX_RDY)) + cosa_putdata8(cosa, DRIVER_RX_READY); #ifdef DEBUG_IO debug_status_out(cosa, SR_RX_DMA_ENA|SR_USR_INT_ENA); + if (!is_8bit(cosa) && (status & SR_TX_RDY)) + debug_data_cmd(cosa, DRIVER_RX_READY); #endif spin_unlock_irqrestore(&cosa->lock, flags); } @@ -1756,11 +1849,12 @@ { unsigned long flags, flags1; spin_lock_irqsave(&cosa->lock, flags); + flags1 = claim_dma_lock(); + disable_dma(cosa->dma); + clear_dma_ff(cosa->dma); + release_dma_lock(flags1); if (test_bit(TXBIT, &cosa->rxtx)) { struct channel_data *chan = cosa->chan+cosa->txchan; -#ifdef DEBUG_IRQS - printk(KERN_INFO "cosa%d: end of transfer.\n", cosa->num); -#endif if (chan->tx_done) if (chan->tx_done(chan, cosa->txsize)) clear_bit(chan->num, &cosa->txbitmap); @@ -1775,6 +1869,9 @@ printk("\n"); } #endif + /* Packet for unknown channel? */ + if (cosa->rxbuf == cosa->bouncebuf) + goto out; if (!cosa_dma_able(cosa->rxchan, cosa->rxbuf, cosa->rxsize)) memcpy(cosa->rxbuf, cosa->bouncebuf, cosa->rxsize); if (cosa->rxchan->rx_done) @@ -1786,12 +1883,11 @@ } /* * Clear the RXBIT, TXBIT and IRQBIT (the latest should be - * cleared anyway). + * cleared anyway). We should do it as soon as possible + * so that we can tell the COSA we are done and to give it a time + * for recovery. */ - flags1 = claim_dma_lock(); - disable_dma(cosa->dma); - clear_dma_ff(cosa->dma); - release_dma_lock(flags1); +out: cosa->rxtx = 0; put_driver_status_nolock(cosa); spin_unlock_irqrestore(&cosa->lock, flags); @@ -1799,7 +1895,7 @@ static void cosa_interrupt(int irq, void *cosa_, struct pt_regs *regs) { - int status; + unsigned status; int count = 0; struct cosa_data *cosa = cosa_; again: diff -u --recursive --new-file v2.2.2/linux/drivers/net/cosa.h linux/drivers/net/cosa.h --- v2.2.2/linux/drivers/net/cosa.h Mon Dec 28 15:00:52 1998 +++ linux/drivers/net/cosa.h Sun Mar 7 15:47:46 1999 @@ -1,4 +1,4 @@ -/* $Id: cosa.h,v 1.5 1998/12/24 12:40:18 kas Exp $ */ +/* $Id: cosa.h,v 1.6 1999/01/06 14:02:44 kas Exp $ */ /* * Copyright (C) 1995-1997 Jan "Yenya" Kasprzak @@ -98,5 +98,14 @@ /* Get the number of channels on this card */ #define COSAIONRCHANS _IO('C',0xf8) + +/* Set the driver for the bus-master operations */ +#define COSAIOBMSET _IOW('C', 0xf9, sizeof(unsigned short)) + +#define COSA_BM_OFF 0 /* Bus-mastering off - use ISA DMA (default) */ +#define COSA_BM_ON 1 /* Bus-mastering on - faster but untested */ + +/* Gets the busmaster status */ +#define COSAIOBMGET _IO('C', 0xfa) #endif /* !COSA_H__ */ diff -u --recursive --new-file v2.2.2/linux/drivers/net/irda/Config.in linux/drivers/net/irda/Config.in --- v2.2.2/linux/drivers/net/irda/Config.in Wed Jan 20 23:14:05 1999 +++ linux/drivers/net/irda/Config.in Sun Mar 7 15:26:43 1999 @@ -9,6 +9,7 @@ dep_tristate ' ESI JetEye PC dongle' CONFIG_ESI_DONGLE $CONFIG_IRTTY_SIR dep_tristate ' ACTiSYS IR-220L and IR220L+ dongle' CONFIG_ACTISYS_DONGLE $CONFIG_IRTTY_SIR dep_tristate ' Tekram IrMate 210B dongle' CONFIG_TEKRAM_DONGLE $CONFIG_IRTTY_SIR + dep_tristate ' Greenwich GIrBIL dongle' CONFIG_GIRBIL_DONGLE $CONFIG_IRTTY_SIR fi fi dep_tristate ' NSC PC87108' CONFIG_NSC_FIR $CONFIG_IRDA diff -u --recursive --new-file v2.2.2/linux/drivers/net/irda/Makefile linux/drivers/net/irda/Makefile --- v2.2.2/linux/drivers/net/irda/Makefile Wed Jan 20 23:14:05 1999 +++ linux/drivers/net/irda/Makefile Sun Mar 7 15:26:43 1999 @@ -68,6 +68,14 @@ endif endif +ifeq ($(CONFIG_GIRBIL_DONGLE),y) +L_OBJS += girbil.o +else + ifeq ($(CONFIG_GIRBIL_DONGLE),m) + M_OBJS += girbil.o + endif +endif + include $(TOPDIR)/Rules.make clean: diff -u --recursive --new-file v2.2.2/linux/drivers/net/irda/actisys.c linux/drivers/net/irda/actisys.c --- v2.2.2/linux/drivers/net/irda/actisys.c Wed Jan 20 23:14:05 1999 +++ linux/drivers/net/irda/actisys.c Sun Mar 7 15:26:43 1999 @@ -1,13 +1,13 @@ /********************************************************************* * * Filename: actisys.c - * Version: 0.4 + * Version: 0.5 * Description: Implementation for the ACTiSYS IR-220L and IR-220L+ * dongles * Status: Experimental. * Author: Dag Brattli * Created at: Wed Oct 21 20:02:35 1998 - * Modified at: Mon Jan 18 11:30:25 1999 + * Modified at: Tue Feb 9 15:38:16 1999 * Modified by: Dag Brattli * * Copyright (c) 1998 Dag Brattli, All Rights Reserved. @@ -70,9 +70,10 @@ static void actisys_open( struct irda_device *idev, int type) { - strcat( idev->name, " <-> actisys"); + strcat(idev->description, " <-> actisys"); idev->io.dongle_id = type; + idev->flags |= IFF_DONGLE; MOD_INC_USE_COUNT; } @@ -85,24 +86,20 @@ /* * Function actisys_change_speed (tty, baud) * - * Change speed of the ACTiSYS IR-220L and IR-220L+ type IrDA dongles. - * To cycle through the available baud rates, pulse RTS low for a few ms. - * To be compatible with the new IR-220L+, we have to reset the dongle - * first since its not possible cycle around anymore and still be - * compatible with both dongles :-( + * Change speed of the ACTiSYS IR-220L and IR-220L+ type IrDA dongles. + * To cycle through the available baud rates, pulse RTS low for a few + * ms. */ static void actisys_change_speed( struct irda_device *idev, int baudrate) { struct irtty_cb *self; struct tty_struct *tty; - int arg; struct termios old_termios; int cflag; int current_baudrate; int index = 0; - mm_segment_t fs; - DEBUG( 0, __FUNCTION__ "()\n"); + DEBUG( 4, __FUNCTION__ "()\n"); ASSERT( idev != NULL, return;); ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -115,10 +112,10 @@ current_baudrate = idev->qos.baud_rate.value; /* Find the correct baudrate index for the currently used baudrate */ - while ( current_baudrate != baud_rates[index]) + while (current_baudrate != baud_rates[index]) index++; - DEBUG( 0, __FUNCTION__ "(), index=%d\n", index); + DEBUG( 4, __FUNCTION__ "(), index=%d\n", index); if ( !self->tty) return; @@ -127,38 +124,18 @@ /* Cycle through avaiable baudrates until we reach the correct one */ while ( current_baudrate != baudrate) { - DEBUG( 0, __FUNCTION__ "(), current baudrate = %d\n", + DEBUG( 4, __FUNCTION__ "(), current baudrate = %d\n", baud_rates[index]); - DEBUG( 0, __FUNCTION__ "(), Clearing RTS\n"); /* Set DTR, clear RTS */ - arg = TIOCM_DTR|TIOCM_OUT2; - - fs = get_fs(); - set_fs( get_ds()); - - if ( tty->driver.ioctl( tty, NULL, TIOCMSET, - (unsigned long) &arg)) { - DEBUG( 0, __FUNCTION__ - "Error clearing RTS!\n"); - } - set_fs(fs); + irtty_set_dtr_rts(tty, TRUE, FALSE); /* Wait at a few ms */ current->state = TASK_INTERRUPTIBLE; schedule_timeout(2); /* Set DTR, Set RTS */ - arg = TIOCM_DTR | TIOCM_RTS |TIOCM_OUT2; - - fs = get_fs(); - set_fs( get_ds()); - - if ( tty->driver.ioctl( tty, NULL, TIOCMSET, - (unsigned long) &arg)) { - DEBUG( 0, __FUNCTION__ "Error setting RTS!\n"); - } - set_fs(fs); + irtty_set_dtr_rts(tty, TRUE, TRUE); /* Wait at a few ms again */ current->state = TASK_INTERRUPTIBLE; @@ -172,8 +149,8 @@ current_baudrate = baud_rates[index]; } - DEBUG( 0, __FUNCTION__ "(), current baudrate = %d\n", - baud_rates[index]); + DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n", + baud_rates[index]); /* Now change the speed of the serial port */ old_termios = *(tty->termios); @@ -200,9 +177,8 @@ break; } + /* Change speed of serial port */ tty->termios->c_cflag = cflag; - - DEBUG( 0, __FUNCTION__ "(), Setting the speed of the serial port\n"); tty->driver.set_termios( tty, &old_termios); } @@ -219,10 +195,6 @@ { struct irtty_cb *self; struct tty_struct *tty; - int arg = 0; - mm_segment_t fs; - - DEBUG( 4, __FUNCTION__ "()\n"); ASSERT( idev != NULL, return;); ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -236,36 +208,16 @@ if ( !tty) return; - DEBUG( 0, __FUNCTION__ "(), Clearing DTR\n"); - arg = TIOCM_RTS | TIOCM_OUT2; - - fs = get_fs(); - set_fs( get_ds()); - - if ( tty->driver.ioctl( tty, NULL, TIOCMSET, - (unsigned long) &arg)) - { - DEBUG( 0, __FUNCTION__"(), ioctl error!\n"); - } - set_fs(fs); + /* Clear DTR */ + irtty_set_dtr_rts(tty, FALSE, TRUE); /* Sleep 10-20 ms*/ current->state = TASK_INTERRUPTIBLE; schedule_timeout(2); - DEBUG( 0, __FUNCTION__ "(), Setting DTR\n"); - arg = TIOCM_RTS | TIOCM_DTR | TIOCM_OUT2; - - fs = get_fs(); - set_fs( get_ds()); + /* Go back to normal mode */ + irtty_set_dtr_rts(tty, TRUE, TRUE); - if ( tty->driver.ioctl( tty, NULL, TIOCMSET, - (unsigned long) &arg)) - { - DEBUG( 0, __FUNCTION__"(), ioctl error!\n"); - } - set_fs(fs); - idev->qos.baud_rate.value = 9600; } @@ -287,6 +239,9 @@ } #ifdef MODULE + +MODULE_AUTHOR("Dag Brattli "); +MODULE_DESCRIPTION("ACTiSYS IR-220L and IR-220L+ dongle driver"); /* * Function init_module (void) diff -u --recursive --new-file v2.2.2/linux/drivers/net/irda/esi.c linux/drivers/net/irda/esi.c --- v2.2.2/linux/drivers/net/irda/esi.c Wed Jan 20 23:14:05 1999 +++ linux/drivers/net/irda/esi.c Sun Mar 7 15:26:43 1999 @@ -1,12 +1,12 @@ /********************************************************************* * * Filename: esi.c - * Version: 1.1 - * Description: Driver for the Extended Systems JetEye PC + * Version: 1.2 + * Description: Driver for the Extended Systems JetEye PC dongle * Status: Experimental. * Author: Thomas Davis, * Created at: Sat Feb 21 18:54:38 1998 - * Modified at: Mon Jan 18 11:30:32 1999 + * Modified at: Tue Feb 9 15:36:47 1999 * Modified by: Dag Brattli * Sources: esi.c * @@ -71,6 +71,7 @@ strcat( idev->description, " <-> esi"); idev->io.dongle_id = type; + idev->flags |= IFF_DONGLE; MOD_INC_USE_COUNT; } @@ -90,10 +91,9 @@ { struct irtty_cb *self; struct tty_struct *tty; - int arg = TIOCM_OUT2; + int dtr, rts; struct termios old_termios; int cflag; - mm_segment_t fs; ASSERT( idev != NULL, return;); ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -116,37 +116,25 @@ switch (baud) { case 19200: cflag |= B19200; - arg |= TIOCM_DTR; + dtr = TRUE; + rts = FALSE; break; case 115200: cflag |= B115200; - arg |= TIOCM_RTS | TIOCM_DTR; + dtr = rts = TRUE; break; case 9600: default: cflag |= B9600; - arg |= TIOCM_RTS; + dtr = FALSE; + rts = TRUE; break; } - + /* Change speed of serial driver */ tty->termios->c_cflag = cflag; tty->driver.set_termios( tty, &old_termios); - /* - * The ioctl function, or actually set_modem_info in serial.c - * expects a pointer to the argument in user space. To hack us - * around this we use the set_fs function to fool the routines - * that check if they are called from user space. We also need - * to send a pointer to the argument so get_user() gets happy. - * DB. - */ - fs = get_fs(); - set_fs( get_ds()); - - if ( tty->driver.ioctl( tty, NULL, TIOCMSET, (unsigned long) &arg)) { - DEBUG( 0, __FUNCTION__ "(), error setting ESI speed!\n"); - } - set_fs(fs); + irtty_set_dtr_rts(tty, dtr, rts); } static void esi_reset( struct irda_device *idev, int unused) diff -u --recursive --new-file v2.2.2/linux/drivers/net/irda/girbil.c linux/drivers/net/irda/girbil.c --- v2.2.2/linux/drivers/net/irda/girbil.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/irda/girbil.c Sun Mar 7 15:26:43 1999 @@ -0,0 +1,276 @@ +/********************************************************************* + * + * Filename: girbil.c + * Version: 1.0 + * Description: Implementation for the Greenwich GIrBIL dongle + * Status: Experimental. + * Author: Dag Brattli + * Created at: Sat Feb 6 21:02:33 1999 + * Modified at: Tue Feb 9 15:36:36 1999 + * Modified by: Dag Brattli + * + * Copyright (c) 1999 Dag Brattli, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +static void girbil_reset(struct irda_device *dev, int unused); +static void girbil_open(struct irda_device *dev, int type); +static void girbil_close(struct irda_device *dev); +static void girbil_change_speed(struct irda_device *dev, int baud); +static void girbil_init_qos(struct irda_device *idev, struct qos_info *qos); + +/* Control register 1 */ +#define GIRBIL_TXEN 0x01 /* Enable transmitter */ +#define GIRBIL_RXEN 0x02 /* Enable receiver */ +#define GIRBIL_ECAN 0x04 /* Cancel self emmited data */ +#define GIRBIL_ECHO 0x08 /* Echo control characters */ + +/* LED Current Register (0x2) */ +#define GIRBIL_HIGH 0x20 +#define GIRBIL_MEDIUM 0x21 +#define GIRBIL_LOW 0x22 + +/* Baud register (0x3) */ +#define GIRBIL_2400 0x30 +#define GIRBIL_4800 0x31 +#define GIRBIL_9600 0x32 +#define GIRBIL_19200 0x33 +#define GIRBIL_38400 0x34 +#define GIRBIL_57600 0x35 +#define GIRBIL_115200 0x36 + +/* Mode register (0x4) */ +#define GIRBIL_IRDA 0x40 +#define GIRBIL_ASK 0x41 + +/* Control register 2 (0x5) */ +#define GIRBIL_LOAD 0x51 /* Load the new baud rate value */ + +static struct dongle dongle = { + GIRBIL_DONGLE, + girbil_open, + girbil_close, + girbil_reset, + girbil_change_speed, + girbil_init_qos, +}; + +__initfunc(void girbil_init(void)) +{ + irtty_register_dongle(&dongle); +} + +void girbil_cleanup(void) +{ + irtty_unregister_dongle(&dongle); +} + +static void girbil_open(struct irda_device *idev, int type) +{ + strcat( idev->description, " <-> girbil"); + + idev->io.dongle_id = type; + idev->flags |= IFF_DONGLE; + + MOD_INC_USE_COUNT; +} + +static void girbil_close(struct irda_device *dev) +{ + MOD_DEC_USE_COUNT; +} + +/* + * Function girbil_change_speed (dev, speed) + * + * Set the speed for the Girbil type dongle. Warning, this + * function must be called with a process context! + * + */ +static void girbil_change_speed(struct irda_device *idev, int speed) +{ + struct irtty_cb *self; + struct tty_struct *tty; + struct termios old_termios; + int cflag; + __u8 control[2]; + + ASSERT(idev != NULL, return;); + ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + + self = (struct irtty_cb *) idev->priv; + + ASSERT(self != NULL, return;); + ASSERT(self->magic == IRTTY_MAGIC, return;); + + if (!self->tty) + return; + + tty = self->tty; + + old_termios = *(tty->termios); + cflag = tty->termios->c_cflag; + + cflag &= ~CBAUD; + + switch (speed) { + case 9600: + default: + cflag |= B9600; + control[0] = GIRBIL_9600; + break; + case 19200: + cflag |= B19200; + control[0] = GIRBIL_19200; + break; + case 34800: + cflag |= B38400; + control[0] = GIRBIL_38400; + break; + case 57600: + cflag |= B57600; + control[0] = GIRBIL_57600; + break; + case 115200: + cflag |= B115200; + control[0] = GIRBIL_115200; + break; + } + control[1] = GIRBIL_LOAD; + + /* Set DTR and Clear RTS to enter command mode */ + irtty_set_dtr_rts(tty, FALSE, TRUE); + + /* Write control bytes */ + if (tty->driver.write) + tty->driver.write(self->tty, 0, control, 2); + + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(2); + + /* Go back to normal mode */ + irtty_set_dtr_rts(tty, TRUE, TRUE); + + /* Now change the speed of the serial port */ + tty->termios->c_cflag = cflag; + tty->driver.set_termios(tty, &old_termios); +} + +/* + * Function girbil_reset (driver) + * + * This function resets the girbil dongle. Warning, this function + * must be called with a process context!! + * + * Algorithm: + * 0. set RTS, and wait at least 5 ms + * 1. clear RTS + */ +void girbil_reset(struct irda_device *idev, int unused) +{ + struct irtty_cb *self; + struct tty_struct *tty; + __u8 control = GIRBIL_TXEN | GIRBIL_RXEN /* | GIRBIL_ECAN */; + + ASSERT(idev != NULL, return;); + ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + + self = (struct irtty_cb *) idev->priv; + + ASSERT(self != NULL, return;); + ASSERT(self->magic == IRTTY_MAGIC, return;); + + tty = self->tty; + if (!tty) + return; + + /* Reset dongle */ + irtty_set_dtr_rts(tty, TRUE, FALSE); + + /* Sleep at least 5 ms */ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(2); + + /* Set DTR and clear RTS to enter command mode */ + irtty_set_dtr_rts(tty, FALSE, TRUE); + + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(2); + + /* Write control byte */ + if (tty->driver.write) + tty->driver.write(self->tty, 0, &control, 1); + + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(2); + + /* Go back to normal mode */ + irtty_set_dtr_rts(tty, TRUE, TRUE); +} + +/* + * Function girbil_init_qos (qos) + * + * Initialize QoS capabilities + * + */ +static void girbil_init_qos(struct irda_device *idev, struct qos_info *qos) +{ + qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; + qos->min_turn_time.bits &= 0xfe; /* All except 0 ms */ +} + +#ifdef MODULE + +MODULE_AUTHOR("Dag Brattli "); +MODULE_DESCRIPTION("Greenwich GIrBIL dongle driver"); + +/* + * Function init_module (void) + * + * Initialize Girbil module + * + */ +int init_module(void) +{ + girbil_init(); + return(0); +} + +/* + * Function cleanup_module (void) + * + * Cleanup Girbil module + * + */ +void cleanup_module(void) +{ + girbil_cleanup(); +} + +#endif /* MODULE */ diff -u --recursive --new-file v2.2.2/linux/drivers/net/irda/irport.c linux/drivers/net/irda/irport.c --- v2.2.2/linux/drivers/net/irda/irport.c Mon Jan 25 17:44:34 1999 +++ linux/drivers/net/irda/irport.c Sun Mar 7 15:26:43 1999 @@ -96,7 +96,7 @@ #ifdef MODULE static void irport_cleanup(void) { - int i; +/* int i; */ DEBUG( 4, __FUNCTION__ "()\n"); @@ -303,7 +303,6 @@ int irport_hard_xmit( struct sk_buff *skb, struct device *dev) { struct irda_device *idev; - int xbofs; int actual; DEBUG( 4, __FUNCTION__ "()\n"); diff -u --recursive --new-file v2.2.2/linux/drivers/net/irda/irtty.c linux/drivers/net/irda/irtty.c --- v2.2.2/linux/drivers/net/irda/irtty.c Wed Jan 20 23:14:05 1999 +++ linux/drivers/net/irda/irtty.c Sun Mar 7 15:26:43 1999 @@ -1,12 +1,12 @@ /********************************************************************* * * Filename: irtty.c - * Version: 1.0 + * Version: 1.1 * Description: IrDA line discipline implementation * Status: Experimental. * Author: Dag Brattli * Created at: Tue Dec 9 21:18:38 1997 - * Modified at: Mon Jan 18 15:32:03 1999 + * Modified at: Tue Feb 9 13:08:25 1999 * Modified by: Dag Brattli * Sources: slip.c by Laurence Culhane, * Fred N. van Kempen, @@ -206,6 +206,7 @@ self->idev.qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| IR_115200; self->idev.qos.min_turn_time.bits = 0x03; + self->idev.flags = IFF_SIR | IFF_PIO; irda_qos_bits_to_value( &self->idev.qos); /* Specify which buffer allocation policy we need */ @@ -272,8 +273,6 @@ kfree( self); MOD_DEC_USE_COUNT; - - DEBUG( 4, "IrTTY: close() -->\n"); } /* @@ -289,6 +288,8 @@ struct irtty_cb *self; int cflag; + DEBUG(4,__FUNCTION__ "(), <%ld>\n", jiffies); + ASSERT( idev != NULL, return;); ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -360,10 +361,15 @@ DEBUG( 0, __FUNCTION__ "(), Tekram dongle!\n"); request_module( "tekram"); break; - case ACTISYS_DONGLE: + case ACTISYS_DONGLE: /* FALLTHROUGH */ + case ACTISYS_PLUS_DONGLE: DEBUG( 0, __FUNCTION__ "(), ACTiSYS dongle!\n"); request_module( "actisys"); break; + case GIRBIL_DONGLE: + DEBUG( 0, __FUNCTION__ "(), GIrBIL dongle!\n"); + request_module( "girbil"); + break; default: DEBUG( 0, __FUNCTION__ "(), Unknown dongle type!\n"); return; @@ -373,8 +379,7 @@ node = hashbin_find( dongles, type, NULL); if ( !node) { - DEBUG( 0, __FUNCTION__ - "(), Unable to find requested dongle\n"); + DEBUG(0, __FUNCTION__ "(), Unable to find requested dongle\n"); return; } self->dongle_q = node; @@ -401,8 +406,7 @@ * The Swiss army knife of system calls :-) * */ -static int irtty_ioctl( struct tty_struct *tty, void *file, int cmd, - void *arg) +static int irtty_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) { struct irtty_cb *self; int err = 0; @@ -444,8 +448,8 @@ * been received, which can now be decapsulated and delivered for * further processing */ -static void irtty_receive_buf( struct tty_struct *tty, const unsigned - char *cp, char *fp, int count) +static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, + char *fp, int count) { struct irtty_cb *self = (struct irtty_cb *) tty->disc_data; @@ -464,11 +468,8 @@ cp++; continue; } - /* - * Unwrap and destuff one byte - */ + /* Unwrap and destuff one byte */ async_unwrap_char( &self->idev, *cp++); - /* self->rx_over_errors++; */ } } @@ -478,7 +479,7 @@ * Transmit skb * */ -static int irtty_hard_xmit( struct sk_buff *skb, struct device *dev) +static int irtty_hard_xmit(struct sk_buff *skb, struct device *dev) { struct irtty_cb *self; struct irda_device *idev; @@ -487,43 +488,40 @@ ASSERT( dev != NULL, return 0;); ASSERT( skb != NULL, return 0;); - if ( dev->tbusy) { - DEBUG( 4, __FUNCTION__ "(), tbusy==TRUE\n"); - - return -EBUSY; - } - idev = (struct irda_device *) dev->priv; - ASSERT( idev != NULL, return 0;); - ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return -1;); + ASSERT(idev != NULL, return 0;); + ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); self = (struct irtty_cb *) idev->priv; - ASSERT( self != NULL, return 0;); - ASSERT( self->magic == IRTTY_MAGIC, return 0;); + ASSERT(self != NULL, return 0;); + ASSERT(self->magic == IRTTY_MAGIC, return 0;); /* Lock transmit buffer */ - if ( irda_lock( (void *) &dev->tbusy) == FALSE) - return 0; + if (irda_lock((void *) &dev->tbusy) == FALSE) + return -EBUSY; /* * Transfer skb to tx_buff while wrapping, stuffing and making CRC */ - idev->tx_buff.len = async_wrap_skb( skb, idev->tx_buff.data, - idev->tx_buff.truesize); + idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data, + idev->tx_buff.truesize); self->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); dev->trans_start = jiffies; if ( self->tty->driver.write) - actual = self->tty->driver.write( self->tty, 0, - idev->tx_buff.data, - idev->tx_buff.len); + actual = self->tty->driver.write(self->tty, 0, + idev->tx_buff.data, + idev->tx_buff.len); idev->tx_buff.offset = actual; idev->tx_buff.head = idev->tx_buff.data + actual; + + idev->stats.tx_packets++; + idev->stats.tx_bytes += idev->tx_buff.len; #if 0 /* * Did we transmit the whole frame? Commented out for now since @@ -535,8 +533,7 @@ irda_unlock( &self->tbusy); } #endif - - dev_kfree_skb( skb); + dev_kfree_skb(skb); return 0; } @@ -587,8 +584,6 @@ tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); idev->netdev.tbusy = 0; /* Unlock */ - idev->stats.tx_packets++; - idev->stats.tx_bytes += idev->tx_buff.len; /* Tell network layer that we want more frames */ mark_bh( NET_BH); @@ -602,8 +597,6 @@ actual = tty->driver.write( tty, 0, idev->tx_buff.head, count); idev->tx_buff.offset += actual; idev->tx_buff.head += actual; - - DEBUG( 4, "actual=%d, sent %d\n", actual, count); } /* @@ -648,8 +641,7 @@ } /* Make new IrDA dongle */ - new = (struct dongle_q *) kmalloc (sizeof (struct dongle_q), - GFP_KERNEL); + new = (struct dongle_q *)kmalloc(sizeof(struct dongle_q), GFP_KERNEL); if (new == NULL) { return 1; @@ -675,6 +667,35 @@ kfree( node); } + +void irtty_set_dtr_rts(struct tty_struct *tty, int dtr, int rts) +{ + mm_segment_t fs; + int arg = TIOCM_OUT2; + + if (rts) + arg |= TIOCM_RTS; + if (dtr) + arg |= TIOCM_DTR; + + /* + * The ioctl() function, or actually set_modem_info() in serial.c + * expects a pointer to the argument in user space. To hack us + * around this, we use the set_fs() function to fool the routines + * that check if they are called from user space. We also need + * to send a pointer to the argument so get_user() gets happy. DB. + */ + + fs = get_fs(); + set_fs(get_ds()); + + if (tty->driver.ioctl(tty, NULL, TIOCMSET, (unsigned long) &arg)) { + DEBUG(0, __FUNCTION__ "(), error!\n"); + } + set_fs(fs); +} + + static int irtty_net_init( struct device *dev) { /* Set up to be a normal IrDA network device driver */ @@ -714,6 +735,9 @@ } #ifdef MODULE + +MODULE_AUTHOR("Dag Brattli "); +MODULE_DESCRIPTION("IrDA TTY device driver"); /* * Function init_module (void) diff -u --recursive --new-file v2.2.2/linux/drivers/net/irda/pc87108.c linux/drivers/net/irda/pc87108.c --- v2.2.2/linux/drivers/net/irda/pc87108.c Wed Jan 20 23:14:05 1999 +++ linux/drivers/net/irda/pc87108.c Sun Mar 7 15:26:43 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Sat Nov 7 21:43:15 1998 - * Modified at: Mon Dec 28 08:46:16 1998 + * Modified at: Tue Feb 9 13:29:40 1999 * Modified by: Dag Brattli * * Copyright (c) 1998 Dag Brattli @@ -50,7 +50,6 @@ #include #include #include -#include #include #include @@ -100,7 +99,9 @@ /* Some prototypes */ static int pc87108_open( int i, unsigned int iobase, unsigned int board_addr, unsigned int irq, unsigned int dma); +#ifdef MODULE static int pc87108_close( struct irda_device *idev); +#endif /* MODULE */ static int pc87108_probe( int iobase, int board_addr, int irq, int dma); static void pc87108_pio_receive( struct irda_device *idev); static int pc87108_dma_receive( struct irda_device *idev); @@ -221,6 +222,8 @@ idev->qos.min_turn_time.bits = 0x07; irda_qos_bits_to_value( &idev->qos); + idev->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO|IFF_DONGLE; + /* Specify which buffer allocation policy we need */ idev->rx_buff.flags = GFP_KERNEL | GFP_DMA; idev->tx_buff.flags = GFP_KERNEL | GFP_DMA; @@ -250,6 +253,7 @@ return 0; } +#ifdef MODULE /* * Function pc87108_close (idev) * @@ -276,6 +280,7 @@ return 0; } +#endif /* MODULE */ /* * Function pc87108_probe (iobase, board_addr, irq, dma) @@ -720,12 +725,6 @@ iobase = idev->io.iobase; DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); - - if ( dev->tbusy) { - DEBUG( 4, __FUNCTION__ "(), tbusy==TRUE\n"); - - return -EBUSY; - } /* Lock transmit buffer */ if ( irda_lock( (void *) &dev->tbusy) == FALSE) diff -u --recursive --new-file v2.2.2/linux/drivers/net/irda/tekram.c linux/drivers/net/irda/tekram.c --- v2.2.2/linux/drivers/net/irda/tekram.c Wed Jan 20 23:14:05 1999 +++ linux/drivers/net/irda/tekram.c Sun Mar 7 15:26:43 1999 @@ -1,12 +1,12 @@ /********************************************************************* * * Filename: tekram.c - * Version: 0.4 + * Version: 0.5 * Description: Implementation of the Tekram IrMate IR-210B dongle * Status: Experimental. * Author: Dag Brattli * Created at: Wed Oct 21 20:02:35 1998 - * Modified at: Mon Jan 18 11:30:38 1999 + * Modified at: Tue Feb 9 15:36:55 1999 * Modified by: Dag Brattli * * Copyright (c) 1998 Dag Brattli, All Rights Reserved. @@ -63,9 +63,12 @@ irtty_unregister_dongle( &dongle); } -static void tekram_open( struct irda_device *dev, int type) +static void tekram_open( struct irda_device *idev, int type) { - strcat( dev->name, " <-> tekram"); + strcat(idev->description, " <-> tekram"); + + idev->io.dongle_id = type; + idev->flags |= IFF_DONGLE; MOD_INC_USE_COUNT; } @@ -96,11 +99,8 @@ struct irtty_cb *self; struct tty_struct *tty; struct termios old_termios; - int arg = 0; int cflag; __u8 byte; - int actual; - mm_segment_t fs; DEBUG( 4, __FUNCTION__ "()\n"); @@ -147,44 +147,22 @@ } /* Set DTR, Clear RTS */ - DEBUG( 0, __FUNCTION__ "(), Setting DTR, Clearing RTS\n"); - arg = TIOCM_DTR | TIOCM_OUT2; - - fs = get_fs(); - set_fs( get_ds()); - - if ( tty->driver.ioctl( tty, NULL, TIOCMSET, - (unsigned long) &arg)) { - DEBUG( 0, "error setting Tekram speed!\n"); - } - set_fs(fs); + irtty_set_dtr_rts(tty, TRUE, FALSE); /* Wait at least 7us */ udelay( 7); - DEBUG( 0, __FUNCTION__ "(), Writing control byte\n"); /* Write control byte */ if ( tty->driver.write) - actual = tty->driver.write( self->tty, 0, &byte, 1); + tty->driver.write( self->tty, 0, &byte, 1); /* Wait at least 100 ms */ current->state = TASK_INTERRUPTIBLE; schedule_timeout( 10); /* Set DTR, Set RTS */ - DEBUG( 0, __FUNCTION__ "(), Setting DTR, Setting RTS\n"); - arg = TIOCM_DTR | TIOCM_RTS | TIOCM_OUT2; - - fs = get_fs(); - set_fs( get_ds()); - - if ( tty->driver.ioctl( tty, NULL, TIOCMSET, - (unsigned long) &arg)) { - DEBUG( 0, "error setting Tekram speed!\n"); - } - set_fs(fs); + irtty_set_dtr_rts(tty, TRUE, TRUE); - DEBUG( 0, __FUNCTION__ "(), Setting new speed on serial port\n"); /* Now change the speed of the serial port */ tty->termios->c_cflag = cflag; tty->driver.set_termios( tty, &old_termios); @@ -208,8 +186,6 @@ { struct irtty_cb *self; struct tty_struct *tty; - int arg = 0; - mm_segment_t fs; DEBUG( 4, __FUNCTION__ "()\n"); @@ -225,51 +201,22 @@ if ( !tty) return; - DEBUG( 0, __FUNCTION__ "(), Power off dongle\n"); - arg = TIOCM_RTS | TIOCM_DTR | TIOCM_OUT2; - - fs = get_fs(); - set_fs( get_ds()); - - if ( tty->driver.ioctl( tty, NULL, TIOCMSET, - (unsigned long) &arg)) - { - DEBUG(0, "error setting ESI speed!\n"); - } - set_fs(fs); + /* Power off dongle */ + irtty_set_dtr_rts(tty, FALSE, FALSE); /* Sleep 50 ms */ current->state = TASK_INTERRUPTIBLE; schedule_timeout(5); - - DEBUG( 0, __FUNCTION__ "(), Set DTR, clear RTS\n"); - /* Set DTR, clear RTS */ - arg = TIOCM_DTR | TIOCM_OUT2; - - fs = get_fs(); - set_fs( get_ds()); - - if ( tty->driver.ioctl( tty, NULL, TIOCMSET, - (unsigned long) &arg)) { - DEBUG( 0, "Error setting Tekram speed!\n"); - } - set_fs(fs); + + /* Clear DTR, Set RTS */ + irtty_set_dtr_rts(tty, FALSE, TRUE); /* Should sleep 1 ms, but 10-20 should not do any harm */ current->state = TASK_INTERRUPTIBLE; schedule_timeout(2); - DEBUG( 0, __FUNCTION__ "(), STATE3\n"); - /* Clear DTR, clear RTS */ - arg = TIOCM_OUT2; - - fs = get_fs(); - set_fs( get_ds()); - - if ( tty->driver.ioctl( tty, NULL, TIOCMSET, (unsigned long) &arg)) { - DEBUG( 0, "error setting Tekram speed!\n"); - } - set_fs(fs); + /* Set DTR, Set RTS */ + irtty_set_dtr_rts(tty, TRUE, TRUE); /* Finished! */ } @@ -287,6 +234,9 @@ } #ifdef MODULE + +MODULE_AUTHOR("Dag Brattli "); +MODULE_DESCRIPTION("Tekram IrMate IR-210B dongle driver"); /* * Function init_module (void) @@ -311,4 +261,4 @@ tekram_cleanup(); } -#endif +#endif /* MODULE */ diff -u --recursive --new-file v2.2.2/linux/drivers/net/irda/uircc.c linux/drivers/net/irda/uircc.c --- v2.2.2/linux/drivers/net/irda/uircc.c Mon Jan 25 17:44:34 1999 +++ linux/drivers/net/irda/uircc.c Sun Mar 7 15:26:43 1999 @@ -7,7 +7,7 @@ * Status: Experimental. * Author: Dag Brattli * Created at: Sat Dec 26 10:59:03 1998 - * Modified at: Tue Jan 19 23:54:04 1999 + * Modified at: Tue Feb 9 13:30:41 1999 * Modified by: Dag Brattli * * Copyright (c) 1998 Dag Brattli, All Rights Reserved. @@ -196,6 +196,8 @@ idev->qos.min_turn_time.bits = 0x07; irda_qos_bits_to_value( &idev->qos); + + idev->flags = IFF_FIR|IFF_SIR|IFF_DMA|IFF_PIO; /* Specify which buffer allocation policy we need */ idev->rx_buff.flags = GFP_KERNEL | GFP_DMA; @@ -271,9 +273,11 @@ static int uircc_probe( int iobase, int iobase2, int irq, int dma) { int version; +#if 0 int probe_irq=0; unsigned long mask; int i; +#endif DEBUG( 0, __FUNCTION__ "()\n"); @@ -442,20 +446,12 @@ DEBUG(0, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); /* Use irport for SIR speeds */ - if ( idev->io.baudrate <= 115200) { - return irport_hard_xmit( skb, dev); - } - - if ( dev->tbusy) { - __u8 sr3; - - DEBUG( 4, __FUNCTION__ "(), tbusy==TRUE\n"); - - return -EBUSY; + if (idev->io.baudrate <= 115200) { + return irport_hard_xmit(skb, dev); } /* Lock transmit buffer */ - if ( irda_lock( (void *) &dev->tbusy) == FALSE) + if (irda_lock((void *) &dev->tbusy) == FALSE) return -EBUSY; memcpy( idev->tx_buff.data, skb->data, skb->len); diff -u --recursive --new-file v2.2.2/linux/drivers/net/irda/w83977af_ir.c linux/drivers/net/irda/w83977af_ir.c --- v2.2.2/linux/drivers/net/irda/w83977af_ir.c Tue Dec 22 14:16:55 1998 +++ linux/drivers/net/irda/w83977af_ir.c Sun Mar 7 15:26:43 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Paul VanderSpek * Created at: Wed Nov 4 11:46:16 1998 - * Modified at: Mon Dec 14 21:51:53 1998 + * Modified at: Tue Feb 9 13:30:35 1999 * Modified by: Dag Brattli * * Copyright (c) 1998 Corel Computer Corp. @@ -204,6 +204,8 @@ /* The HP HDLS-1100 needs 1 ms according to the specs */ idev->qos.min_turn_time.bits = 0x03; /* 1ms and more */ irda_qos_bits_to_value( &idev->qos); + + idev->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO; /* Specify which buffer allocation policy we need */ idev->rx_buff.flags = GFP_KERNEL | GFP_DMA; @@ -468,12 +470,6 @@ iobase = idev->io.iobase; DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); - - if ( dev->tbusy) { - DEBUG( 4, __FUNCTION__ "(), tbusy==TRUE\n"); - - return -EBUSY; - } /* Lock transmit buffer */ if ( irda_lock( (void *) &dev->tbusy) == FALSE) diff -u --recursive --new-file v2.2.2/linux/drivers/net/ne.c linux/drivers/net/ne.c --- v2.2.2/linux/drivers/net/ne.c Tue Dec 22 14:16:55 1998 +++ linux/drivers/net/ne.c Sun Mar 7 15:47:46 1999 @@ -105,6 +105,7 @@ {"ET-100","ET-200", {0x00, 0x45, 0x54}}, /* YANG and YA clone */ {"COMPEX","COMPEX16",{0x00,0x80,0x48}}, /* Broken ISA Compex cards */ {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */ + {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */ {0,} }; #endif diff -u --recursive --new-file v2.2.2/linux/drivers/net/plip.c linux/drivers/net/plip.c --- v2.2.2/linux/drivers/net/plip.c Thu Jan 7 15:11:37 1999 +++ linux/drivers/net/plip.c Sun Mar 7 15:47:46 1999 @@ -1217,7 +1217,7 @@ plip_searchfor(int list[], int a) { int i; - for (i = 0; i < 3 && list[i] != -1; i++) { + for (i = 0; i < PLIP_MAX && list[i] != -1; i++) { if (list[i] == a) return 1; } return 0; @@ -1240,7 +1240,7 @@ /* If the user feeds parameters, use them */ while (pb) { if ((parport[0] == -1 && (!timid || !pb->devices)) || - plip_searchfor(parport, i)) { + plip_searchfor(parport, pb->number)) { if (i == PLIP_MAX) { printk(KERN_ERR "plip: too many devices\n"); break; diff -u --recursive --new-file v2.2.2/linux/drivers/net/shaper.c linux/drivers/net/shaper.c --- v2.2.2/linux/drivers/net/shaper.c Thu Nov 19 09:56:28 1998 +++ linux/drivers/net/shaper.c Wed Feb 24 16:27:53 1999 @@ -53,6 +53,13 @@ * This will be fixed in BETA4 */ +/* + * bh_atomic() SMP races fixes and rewritten the locking code to be SMP safe + * and irq-mask friendly. NOTE: we can't use start_bh_atomic() in kick_shaper() + * because it's going to be recalled from an irq handler, and synchronize_bh() + * is a nono if called from irq context. + * 1999 Andrea Arcangeli + */ #include #include @@ -83,21 +90,17 @@ static int shaper_lock(struct shaper *sh) { - unsigned long flags; - save_flags(flags); - cli(); /* - * Lock in an interrupt may fail + * Lock in an interrupt must fail */ - if(sh->locked && in_interrupt()) + while (test_and_set_bit(0, &sh->locked)) { - restore_flags(flags); - return 0; + if (!in_interrupt()) + sleep_on(&sh->wait_queue); + else + return 0; + } - while(sh->locked) - sleep_on(&sh->wait_queue); - sh->locked=1; - restore_flags(flags); return 1; } @@ -105,7 +108,7 @@ static void shaper_unlock(struct shaper *sh) { - sh->locked=0; + clear_bit(0, &sh->locked); wake_up(&sh->wait_queue); shaper_kick(sh); } @@ -240,7 +243,6 @@ dev_kfree_skb(ptr); } shaper_unlock(shaper); - shaper_kick(shaper); return 0; } @@ -285,24 +287,16 @@ static void shaper_kick(struct shaper *shaper) { struct sk_buff *skb; - unsigned long flags; - save_flags(flags); - cli(); - - del_timer(&shaper->timer); - /* * Shaper unlock will kick */ - if(shaper->locked) - { + if (test_and_set_bit(0, &shaper->locked)) + { if(sh_debug) printk("Shaper locked.\n"); - shaper->timer.expires=jiffies+1; - add_timer(&shaper->timer); - restore_flags(flags); + mod_timer(&shaper->timer, jiffies); return; } @@ -320,7 +314,7 @@ if(sh_debug) printk("Clock = %d, jiffies = %ld\n", skb->shapeclock, jiffies); - if(skb->shapeclock - jiffies <= SHAPER_BURST) + if(time_before_eq(skb->shapeclock - jiffies, SHAPER_BURST)) { /* * Pull the frame and get interrupts back on. @@ -329,8 +323,6 @@ skb_unlink(skb); if (shaper->recovery < skb->shapeclock + skb->shapelen) shaper->recovery = skb->shapeclock + skb->shapelen; - restore_flags(flags); - /* * Pass on to the physical target device via * our low level packet thrower. @@ -338,7 +330,6 @@ skb->shapepend=0; shaper_queue_xmit(shaper, skb); /* Fire */ - cli(); } else break; @@ -349,17 +340,9 @@ */ if(skb!=NULL) - { - del_timer(&shaper->timer); - shaper->timer.expires=skb->shapeclock; - add_timer(&shaper->timer); - } - - /* - * Interrupts on, mission complete - */ - - restore_flags(flags); + mod_timer(&shaper->timer, skb->shapeclock); + + clear_bit(0, &shaper->locked); } @@ -370,8 +353,14 @@ static void shaper_flush(struct shaper *shaper) { struct sk_buff *skb; + if(!shaper_lock(shaper)) + { + printk(KERN_ERR "shaper: shaper_flush() called by an irq!\n"); + return; + } while((skb=skb_dequeue(&shaper->sendq))!=NULL) dev_kfree_skb(skb); + shaper_unlock(shaper); } /* @@ -405,7 +394,9 @@ { struct shaper *shaper=dev->priv; shaper_flush(shaper); + start_bh_atomic(); del_timer(&shaper->timer); + end_bh_atomic(); MOD_DEC_USE_COUNT; return 0; } diff -u --recursive --new-file v2.2.2/linux/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c --- v2.2.2/linux/drivers/net/sk_g16.c Tue Jul 28 14:21:08 1998 +++ linux/drivers/net/sk_g16.c Sun Mar 7 15:47:46 1999 @@ -733,7 +733,7 @@ SK_print_pos(dev, "POS registers after ROM, RAM config"); #endif - board = (SK_RAM *) rom_addr; + board = (SK_RAM *) bus_to_virt(rom_addr); /* Read in station address */ for (i = 0, j = 0; i < ETH_ALEN; i++, j+=2) diff -u --recursive --new-file v2.2.2/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c --- v2.2.2/linux/drivers/net/smc-ultra.c Tue Feb 23 15:21:33 1999 +++ linux/drivers/net/smc-ultra.c Wed Feb 24 16:27:54 1999 @@ -2,7 +2,7 @@ /* This is a driver for the SMC Ultra and SMC EtherEZ ISA ethercards. - Written 1993-1996 by Donald Becker. + Written 1993-1998 by Donald Becker. Copyright 1993 United States Government as represented by the Director, National Security Agency. @@ -14,7 +14,7 @@ Center of Excellence in Space Data and Information Sciences Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 - This driver uses the cards in the 8390-compatible, shared memory mode. + This driver uses the cards in the 8390-compatible mode. Most of the run-time complexity is handled by the generic code in 8390.c. The code in this file is responsible for @@ -27,6 +27,8 @@ ultra_block_input() Routines for reading and writing blocks of ultra_block_output() packet buffer memory. + ultra_pio_input() + ultra_pio_output() This driver enables the shared memory only when doing the actual data transfers to avoid a bug in early version of the card that corrupted @@ -34,7 +36,7 @@ This driver now supports the programmed-I/O (PIO) data transfer mode of the EtherEZ. It does not use the non-8390-compatible "Altego" mode. - That support (if available) is smc-ez.c. + That support (if available) is in smc-ez.c. Changelog: @@ -44,8 +46,7 @@ */ static const char *version = - "smc-ultra.c:v2.00 6/6/96 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; - + "smc-ultra.c:v2.02 2/3/98 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; #include @@ -75,13 +76,13 @@ static void ultra_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset); static void ultra_block_output(struct device *dev, int count, - const unsigned char *buf, int start_page); + const unsigned char *buf, const int start_page); static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page); static void ultra_pio_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset); static void ultra_pio_output(struct device *dev, int count, - const unsigned char *buf, int start_page); + const unsigned char *buf, const int start_page); static int ultra_close_card(struct device *dev); @@ -155,11 +156,8 @@ if (load_8390_module("smc-ultra.c")) return -ENOSYS; - /* We should have a "dev" from Space.c or the static module table. */ - if (dev == NULL) { - printk("smc-ultra.c: Passed a NULL device.\n"); + if (dev == NULL) dev = init_etherdev(0, 0); - } if (ei_debug && version_printed++ == 0) printk(version); @@ -255,12 +253,19 @@ ultra_open(struct device *dev) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ + unsigned char irq2reg[] = {0, 0, 0x04, 0x08, 0, 0x0C, 0, 0x40, + 0, 0x04, 0x44, 0x48, 0, 0, 0, 0x4C, }; if (request_irq(dev->irq, ei_interrupt, 0, ei_status.name, dev)) return -EAGAIN; outb(0x00, ioaddr); /* Disable shared memory for safety. */ outb(0x80, ioaddr + 5); + /* Set the IRQ line. */ + outb(inb(ioaddr + 4) | 0x80, ioaddr + 4); + outb((inb(ioaddr + 13) & ~0x4C) | irq2reg[dev->irq], ioaddr + 13); + outb(inb(ioaddr + 4) & 0x7f, ioaddr + 4); + if (ei_status.block_input == &ultra_pio_input) { outb(0x11, ioaddr + 6); /* Enable interrupts and PIO. */ outb(0x01, ioaddr + 0x19); /* Enable ring read auto-wrap. */ @@ -358,7 +363,7 @@ byte-sequentially to IOPA, with no intervening I/O operations, and the data is read or written to the IOPD data port. The only potential complication is that the address register is shared - must be always be rewritten between each read/write direction change. + and must be always be rewritten between each read/write direction change. This is no problem for us, as the 8390 code ensures that we are single threaded. */ static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, @@ -379,20 +384,17 @@ /* For now set the address again, although it should already be correct. */ outb(ring_offset, ioaddr + IOPA); /* Set the address, LSB first. */ outb(ring_offset >> 8, ioaddr + IOPA); + /* We know skbuffs are padded to at least word alignment. */ insw(ioaddr + IOPD, buf, (count+1)>>1); -#ifdef notdef - /* We don't need this -- skbuffs are padded to at least word alignment. */ - if (count & 0x01) { - buf[count-1] = inb(ioaddr + IOPD); -#endif } static void ultra_pio_output(struct device *dev, int count, - const unsigned char *buf, int start_page) + const unsigned char *buf, const int start_page) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ outb(0x00, ioaddr + IOPA); /* Set the address, LSB first. */ outb(start_page, ioaddr + IOPA); + /* An extra odd byte is OK here as well. */ outsw(ioaddr + IOPD, buf, (count+1)>>1); } @@ -461,15 +463,12 @@ } if (register_netdev(dev) != 0) { printk(KERN_WARNING "smc-ultra.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]); - if (found != 0) { /* Got at least one. */ - lock_8390_module(); - return 0; - } + if (found != 0) return 0; /* Got at least one. */ return -ENXIO; } found++; } - lock_8390_module(); + return 0; } @@ -481,15 +480,14 @@ for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) { struct device *dev = &dev_ultra[this_dev]; if (dev->priv != NULL) { + /* NB: ultra_close_card() does free_irq + irq2dev */ int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; - void *priv = dev->priv; - /* NB: ultra_close_card() does free_irq */ + kfree(dev->priv); + dev->priv = NULL; release_region(ioaddr, ULTRA_IO_EXTENT); unregister_netdev(dev); - kfree(priv); } } - unlock_8390_module(); } #endif /* MODULE */ @@ -500,6 +498,7 @@ * version-control: t * kept-new-versions: 5 * c-indent-level: 4 + * c-basic-offset: 4 * tab-width: 4 * End: */ diff -u --recursive --new-file v2.2.2/linux/drivers/pci/pci.c linux/drivers/pci/pci.c --- v2.2.2/linux/drivers/pci/pci.c Wed Jan 20 23:14:05 1999 +++ linux/drivers/pci/pci.c Sun Mar 7 15:19:55 1999 @@ -1,12 +1,12 @@ /* - * $Id: pci.c,v 1.90 1998/09/05 12:39:39 mj Exp $ + * $Id: pci.c,v 1.91 1999/01/21 13:34:01 davem Exp $ * * PCI Bus Services, see include/linux/pci.h for further explanation. * * Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter, * David Mosberger-Tang * - * Copyright 1997 -- 1998 Martin Mares + * Copyright 1997 -- 1999 Martin Mares */ #include @@ -28,9 +28,6 @@ #endif struct pci_bus pci_root; -#ifdef CONFIG_VISWS -struct pci_bus pci_other; -#endif struct pci_dev *pci_devices = NULL; static struct pci_dev **pci_last_dev_p = &pci_devices; static int pci_reverse __initdata = 0; @@ -371,6 +368,18 @@ return max; } +struct pci_bus * __init pci_scan_peer_bridge(int bus) +{ + struct pci_bus *b; + + b = kmalloc(sizeof(*b), GFP_KERNEL); + memset(b, 0, sizeof(*b)); + b->next = pci_root.next; + pci_root.next = b; + b->number = b->secondary = bus; + b->subordinate = pci_scan_bus(b); + return b; +} __initfunc(void pci_init(void)) { @@ -385,11 +394,6 @@ memset(&pci_root, 0, sizeof(pci_root)); pci_root.subordinate = pci_scan_bus(&pci_root); -#ifdef CONFIG_VISWS - pci_other.number = 1; /* XXX unless bridge(s) on pci_root */ - pci_other.subordinate = pci_scan_bus(&pci_other); - pci_root.next = &pci_other; -#endif /* give BIOS a chance to apply platform specific fixes: */ pcibios_fixup(); @@ -402,7 +406,6 @@ pci_proc_init(); #endif } - __initfunc(void pci_setup (char *str, int *ints)) { diff -u --recursive --new-file v2.2.2/linux/drivers/sbus/char/flash.c linux/drivers/sbus/char/flash.c --- v2.2.2/linux/drivers/sbus/char/flash.c Mon Oct 5 13:13:40 1998 +++ linux/drivers/sbus/char/flash.c Sun Mar 7 10:43:29 1999 @@ -72,8 +72,6 @@ if (remap_page_range(vma->vm_start, addr, size, vma->vm_page_prot)) return -EAGAIN; - vma->vm_file = file; - file->f_count++; return 0; } diff -u --recursive --new-file v2.2.2/linux/drivers/sbus/char/vfc_dev.c linux/drivers/sbus/char/vfc_dev.c --- v2.2.2/linux/drivers/sbus/char/vfc_dev.c Sun Nov 8 14:03:01 1998 +++ linux/drivers/sbus/char/vfc_dev.c Sun Mar 7 10:43:40 1999 @@ -582,8 +582,6 @@ if(ret) return -EAGAIN; - vma->vm_file = file; - file->f_count++; return 0; } diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/ChangeLog.ncr53c8xx linux/drivers/scsi/ChangeLog.ncr53c8xx --- v2.2.2/linux/drivers/scsi/ChangeLog.ncr53c8xx Tue Jan 19 11:32:51 1999 +++ linux/drivers/scsi/ChangeLog.ncr53c8xx Sun Mar 7 10:13:22 1999 @@ -1,4 +1,26 @@ -Sat Jan 16 17:30 1998 Gerard Roudier (groudier@club-internet.fr) +Sat Mar 6 11:00 1999 Gerard Roudier (groudier@club-internet.fr) + * revision 3.1h + - Fix some oooold bug that hangs the bus if a device rejects a + negotiation. Btw, the corresponding stuff also needed some cleanup + and thus the change is a bit larger than it could have been. + - Still some typo that made compilation fail for 64 bit (trivial fix). + +Sun Feb 14:00 1999 Gerard Roudier (groudier@club-internet.fr) + * revision 3.1g + - Deal correctly with 64 bit PCI address registers on Linux 2.2. + Pointed out by Leonard Zubkoff. + - Allow to tune request_irq() flags from the boot command line using + ncr53c8xx=irqm:??, as follows: + a) If bit 0x10 is set in irqm, SA_SHIRQ flag is not used. + b) If bit 0x20 is set in irqm, SA_INTERRUPT flag is not used. + By default the driver uses both SA_SHIRQ and SA_INTERRUPT. + Option 'ncr53c8xx=irqm:0x20' may be used when an IRQ is shared by + a 53C8XX adapter and a network board. + - Tiny mispelling fixed (ABORT instead of ABRT). Was fortunately + harmless. + - Negotiate SYNC data transfers with CCS devices. + +Sat Jan 16 17:30 1999 Gerard Roudier (groudier@club-internet.fr) * revision 3.1f - Some PCI fix-ups not needed any more for PPC (from Cort). - Cache line size set to 16 DWORDS for Sparc (from DSM). diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in --- v2.2.2/linux/drivers/scsi/Config.in Mon Jan 4 15:08:17 1999 +++ linux/drivers/scsi/Config.in Wed Feb 24 16:27:54 1999 @@ -66,6 +66,7 @@ fi if [ "$CONFIG_PCI" = "y" ]; then dep_tristate 'Initio 9100U(W) support' CONFIG_SCSI_INITIO $CONFIG_SCSI + dep_tristate 'Initio INI-A100U2W support' CONFIG_SCSI_INIA100 $CONFIG_SCSI fi if [ "$CONFIG_PARPORT" != "n" ]; then dep_tristate 'IOMEGA parallel port (ppa - older drives)' CONFIG_SCSI_PPA $CONFIG_SCSI $CONFIG_PARPORT @@ -76,6 +77,7 @@ fi fi dep_tristate 'NCR53c406a SCSI support' CONFIG_SCSI_NCR53C406A $CONFIG_SCSI +dep_tristate 'symbios 53c416 SCSI support' CONFIG_SCSI_SYM53C416 $CONFIG_SCSI if [ "$CONFIG_PCI" = "y" ]; then dep_tristate 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx $CONFIG_SCSI if [ "$CONFIG_SCSI_NCR53C7xx" != "n" ]; then @@ -117,7 +119,7 @@ dep_tristate 'Qlogic FAS SCSI support' CONFIG_SCSI_QLOGIC_FAS $CONFIG_SCSI if [ "$CONFIG_PCI" = "y" ]; then dep_tristate 'Qlogic ISP SCSI support' CONFIG_SCSI_QLOGIC_ISP $CONFIG_SCSI -# dep_tristate 'Qlogic ISP FC SCSI support' CONFIG_SCSI_QLOGIC_FC $CONFIG_SCSI + dep_tristate 'Qlogic ISP FC SCSI support' CONFIG_SCSI_QLOGIC_FC $CONFIG_SCSI fi dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE $CONFIG_SCSI if [ "$CONFIG_PCI" = "y" ]; then diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile --- v2.2.2/linux/drivers/scsi/Makefile Mon Jan 4 15:08:17 1999 +++ linux/drivers/scsi/Makefile Wed Feb 24 16:27:54 1999 @@ -298,6 +298,14 @@ endif endif +ifeq ($(CONFIG_SCSI_INIA100),y) +L_OBJS += a100u2w.o +else + ifeq ($(CONFIG_SCSI_INIA100),m) + M_OBJS += a100u2w.o + endif +endif + ifeq ($(CONFIG_SCSI_QLOGIC_FC),y) L_OBJS += qlogicfc.o else @@ -576,6 +584,14 @@ endif endif +ifeq ($(CONFIG_SCSI_SYM53C416),y) +L_OBJS += sym53c416.o +else + ifeq ($(CONFIG_SCSI_SYM53C416),m) + M_OBJS += sym53c416.o + endif +endif + ifeq ($(CONFIG_BLK_DEV_IDESCSI),y) L_OBJS += ide-scsi.o else @@ -616,6 +632,9 @@ $(CC) $(CFLAGS) -c i91uscsi.c -o i91uscsi.o $(LD) -r -o initio.o ini9100u.o i91uscsi.o rm -f ini9100u.o i91uscsi.o + +a100u2w.o: inia100.o i60uscsi.o + $(LD) -r -o a100u2w.o inia100.o i60uscsi.o megaraid.o: megaraid.c $(CC) $(CFLAGS) -c megaraid.c diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/README.ncr53c8xx linux/drivers/scsi/README.ncr53c8xx --- v2.2.2/linux/drivers/scsi/README.ncr53c8xx Fri Jan 8 22:36:09 1999 +++ linux/drivers/scsi/README.ncr53c8xx Sun Mar 7 10:13:23 1999 @@ -4,7 +4,7 @@ 21 Rue Carnot 95170 DEUIL LA BARRE - FRANCE -22 November 1998 +14 February 1999 =============================================================================== 1. Introduction @@ -39,6 +39,7 @@ 14.2 Device names change when another controller is added 14.3 Using only 8 bit devices with a WIDE SCSI controller. 14.4 Possible data corruption during a Memory Write and Invalidate + 14.5 IRQ sharing problems 15. SCSI problem troubleshooting 16. Synchonous transfer negotiation tables 16.1 Synchronous timings for 53C875 and 53C860 Ultra-SCSI controllers @@ -669,6 +670,10 @@ irqm:0 always open drain irqm:1 same as initial settings (assumed BIOS settings) irqm:2 always totem pole + irqm:0x10 driver will not use SA_SHIRQ flag when requesting irq + irqm:0x20 driver will not use SA_INTERRUPT flag when requesting irq + + (Bits 0x10 and 0x20 can be combined with hardware irq mode option) Reverse probe revprob:n probe chip ids from the PCI configuration in this order: @@ -1027,7 +1032,25 @@ may only be needed under Linux when a scatter/gather list is not used and when the SCSI DATA IN phase is reentered after a phase mismatch. - +14.5 IRQ sharing problems + +When an IRQ is shared by devices that are handled by different drivers, it +may happen that one driver complains about the request of the IRQ having +failed. This may be due to one driver having requested the IRQ using the +SA_INTERRUPT flag but some other having requested the same IRQ without this +flag, or to one driver not having requested the IRQ with the SA_SHIRQ flag. + +By default, the ncr53c8xx driver requests IRQs with both the SA_INTERRUPT +and the SA_SHIRQ flag, but you can disable use of SA_INTERRUPT flags from +the boot command line by using the following option: + + ncr53c8xx=irqm:0x20 + +If this does not fix the problem, then you may want to check how all other +drivers are requesting the IRQ and report the problem. Note that if at least +a single driver does not request the IRQ with the SA_SHIRQ flag (share IRQ), +then the request of the IRQ obviously will not succeed for all the drivers. + 15. SCSI problem troubleshooting Most SCSI problems are due to a non conformant SCSI bus or to buggy diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/README.st linux/drivers/scsi/README.st --- v2.2.2/linux/drivers/scsi/README.st Wed Sep 9 14:51:08 1998 +++ linux/drivers/scsi/README.st Sun Mar 7 15:20:26 1999 @@ -2,7 +2,7 @@ The driver is currently maintained by Kai M{kisara (email Kai.Makisara@metla.fi) -Last modified: Sun Sep 6 10:03:47 1998 by makisara@home +Last modified: Sun Jan 17 10:57:41 1999 by makisara@home BASICS @@ -60,10 +60,19 @@ alternative is to make a small script that uses mt to set the defaults tailored to the system. - The driver supports fixed and variable block size (within buffer limits). Both the auto-rewind (minor equals device number) and non-rewind devices (minor is 128 + device number) are implemented. + +In variable block mode, the byte count in write() determines the size +of the physical block on tape. When reading, the drive reads the next +tape block and returns to the user the data if the read() byte count +is at least the block size. Otherwise the data is truncated. + +In fixed block mode, the data transfer between the drive and the +driver is in multiples of the block size. The write() byte count must +be a multiple of the block size. This is not required when reading but +may be advisable for portability. Support is provided for changing the tape partition and partitioning of the tape with one or two partitions. By default support for diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/atp870u.c linux/drivers/scsi/atp870u.c --- v2.2.2/linux/drivers/scsi/atp870u.c Tue Feb 23 15:21:33 1999 +++ linux/drivers/scsi/atp870u.c Wed Feb 24 16:27:54 1999 @@ -1684,7 +1684,7 @@ struct Scsi_Host * shpnt = NULL; int count = 0; static unsigned short devid[7]={0x8002,0x8010,0x8020,0x8030,0x8040,0x8050,0}; - static struct pci_dev *pdev = NULL; + static struct pci_dev *pdev = NULL, *acard_pdev[3]; printk("aec671x_detect: \n"); if (!pci_present()) @@ -1729,6 +1729,7 @@ chip_ver[2]=0; /* To avoid messing with the things below... */ + acard_pdev[2] = pdev; pci_device_fn[2] = pdev->devfn; pci_bus[2] = pdev->bus->number; @@ -1746,15 +1747,18 @@ } if ( pci_device_fn[2] < pci_device_fn[0] ) { + acard_pdev[1]=acard_pdev[0]; pci_bus[1]=pci_bus[0]; pci_device_fn[1]=pci_device_fn[0]; chip_ver[1]=chip_ver[0]; + acard_pdev[0]=acard_pdev[2]; pci_bus[0]=pci_bus[2]; pci_device_fn[0]=pci_device_fn[2]; chip_ver[0]=chip_ver[2]; } else if ( pci_device_fn[2] < pci_device_fn[1] ) { + acard_pdev[1]=acard_pdev[2]; pci_bus[1]=pci_bus[2]; pci_device_fn[1]=pci_device_fn[2]; chip_ver[1]=chip_ver[2]; @@ -1774,6 +1778,7 @@ return count; } + pdev = acard_pdev[h]; pdev->devfn = pci_device_fn[h]; pdev->bus->number = pci_bus[h]; diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c --- v2.2.2/linux/drivers/scsi/hosts.c Tue Jan 19 11:32:51 1999 +++ linux/drivers/scsi/hosts.c Wed Feb 24 16:27:54 1999 @@ -223,6 +223,10 @@ #include "NCR53c406a.h" #endif +#ifdef CONFIG_SCSI_SYM53C416 +#include "sym53c416.h" +#endif + #ifdef CONFIG_SCSI_DC390T #include "dc390.h" #endif @@ -283,6 +287,10 @@ #include "ini9100u.h" #endif +#ifdef CONFIG_SCSI_INIA100 +#include "inia100.h" +#endif + #ifdef CONFIG_SCSI_DEBUG #include "scsi_debug.h" #endif @@ -452,7 +460,7 @@ #ifdef CONFIG_SCSI_AIC7XXX AIC7XXX, #endif -#ifdef CONFIG_FD_MCS +#ifdef CONFIG_SCSI_FD_MCS FD_MCS, #endif #ifdef CONFIG_SCSI_FUTURE_DOMAIN @@ -467,6 +475,9 @@ #ifdef CONFIG_SCSI_NCR53C406A /* 53C406A should come before QLOGIC */ NCR53c406a, #endif +#ifdef CONFIG_SCSI_SYM53C416 + SYM53C416, +#endif #ifdef CONFIG_SCSI_QLOGIC_FAS QLOGICFAS, #endif @@ -532,6 +543,9 @@ #endif #ifdef CONFIG_SCSI_INITIO INI9100U, +#endif +#ifdef CONFIG_SCSI_INIA100 + INIA100, #endif #ifdef CONFIG_SCSI_QLOGICPTI QLOGICPTI, diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/i60uscsi.c linux/drivers/scsi/i60uscsi.c --- v2.2.2/linux/drivers/scsi/i60uscsi.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/i60uscsi.c Wed Feb 24 16:27:54 1999 @@ -0,0 +1,956 @@ +/************************************************************************** + * Initio A100 device driver for Linux. + * + * Copyright (c) 1994-1998 Initio Corporation + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, 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; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * -------------------------------------------------------------------------- + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + ************************************************************************* + * + * module: i60uscsi.c + * DESCRIPTION: + * This is the Linux low-level SCSI driver for Initio INIA100 SCSI host + * adapters + * + * 07/02/98 hl - v.91n Initial drivers. + * 09/14/98 hl - v1.01 Support new Kernel. + * 09/22/98 hl - v1.01a Support reset. + * 09/24/98 hl - v1.01b Fixed reset. + * 10/05/98 hl - v1.02 split the source code and release. + * 12/19/98 bv - v1.02a Use spinlocks for 2.1.95 and up + **************************************************************************/ + +#ifndef CVT_LINUX_VERSION +#define CVT_LINUX_VERSION(V,P,S) (V * 65536 + P * 256 + S) +#endif + +#include +#include +#include "i60uscsi.h" + + +/* ---- INTERNAL FUNCTIONS ---- */ +static UCHAR waitChipReady(ORC_HCS * hcsp); +static UCHAR waitFWReady(ORC_HCS * hcsp); +static UCHAR waitFWReady(ORC_HCS * hcsp); +static UCHAR waitSCSIRSTdone(ORC_HCS * hcsp); +static UCHAR waitHDOoff(ORC_HCS * hcsp); +static UCHAR waitHDIset(ORC_HCS * hcsp, UCHAR * pData); +static unsigned short get_FW_version(ORC_HCS * hcsp); +static UCHAR set_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char value); +static UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn); +static int se2_rd_all(ORC_HCS * hcsp); +static void se2_update_all(ORC_HCS * hcsp); /* setup default pattern */ +static void read_eeprom(ORC_HCS * hcsp); +static UCHAR load_FW(ORC_HCS * hcsp); +static void setup_SCBs(ORC_HCS * hcsp); +static void initAFlag(ORC_HCS * hcsp); +ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp); + +/* ---- EXTERNAL FUNCTIONS ---- */ +extern void inia100SCBPost(BYTE * pHcb, BYTE * pScb); + +/* ---- INTERNAL VARIABLES ---- */ +ORC_HCS orc_hcs[MAX_SUPPORTED_ADAPTERS]; +static INIA100_ADPT_STRUCT inia100_adpt[MAX_SUPPORTED_ADAPTERS]; +/* set by inia100_setup according to the command line */ +int orc_num_scb; + +NVRAM nvram, *nvramp = &nvram; +static UCHAR dftNvRam[64] = +{ +/*----------header -------------*/ + 0x01, /* 0x00: Sub System Vendor ID 0 */ + 0x11, /* 0x01: Sub System Vendor ID 1 */ + 0x60, /* 0x02: Sub System ID 0 */ + 0x10, /* 0x03: Sub System ID 1 */ + 0x00, /* 0x04: SubClass */ + 0x01, /* 0x05: Vendor ID 0 */ + 0x11, /* 0x06: Vendor ID 1 */ + 0x60, /* 0x07: Device ID 0 */ + 0x10, /* 0x08: Device ID 1 */ + 0x00, /* 0x09: Reserved */ + 0x00, /* 0x0A: Reserved */ + 0x01, /* 0x0B: Revision of Data Structure */ + /* -- Host Adapter Structure --- */ + 0x01, /* 0x0C: Number Of SCSI Channel */ + 0x01, /* 0x0D: BIOS Configuration 1 */ + 0x00, /* 0x0E: BIOS Configuration 2 */ + 0x00, /* 0x0F: BIOS Configuration 3 */ + /* --- SCSI Channel 0 Configuration --- */ + 0x07, /* 0x10: H/A ID */ + 0x83, /* 0x11: Channel Configuration */ + 0x20, /* 0x12: MAX TAG per target */ + 0x0A, /* 0x13: SCSI Reset Recovering time */ + 0x00, /* 0x14: Channel Configuration4 */ + 0x00, /* 0x15: Channel Configuration5 */ + /* SCSI Channel 0 Target Configuration */ + /* 0x16-0x25 */ + 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, + 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, + /* --- SCSI Channel 1 Configuration --- */ + 0x07, /* 0x26: H/A ID */ + 0x83, /* 0x27: Channel Configuration */ + 0x20, /* 0x28: MAX TAG per target */ + 0x0A, /* 0x29: SCSI Reset Recovering time */ + 0x00, /* 0x2A: Channel Configuration4 */ + 0x00, /* 0x2B: Channel Configuration5 */ + /* SCSI Channel 1 Target Configuration */ + /* 0x2C-0x3B */ + 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, + 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, + 0x00, /* 0x3C: Reserved */ + 0x00, /* 0x3D: Reserved */ + 0x00, /* 0x3E: Reserved */ + 0x00 /* 0x3F: Checksum */ +}; + + +/***************************************************************************/ +static void waitForPause(unsigned amount) +{ + ULONG the_time = jiffies + amount; /* 0.01 seconds per jiffy */ + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) + while (time_before_eq(jiffies, the_time)); +#else + while (jiffies < the_time); +#endif +} + +/***************************************************************************/ +UCHAR waitChipReady(ORC_HCS * hcsp) +{ + int i; + + for (i = 0; i < 2000; i++) { /* Wait 1 second for report timeout */ + if (ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & HOSTSTOP) /* Wait HOSTSTOP set */ + return (TRUE); + waitForPause(5); /* wait 500ms before try again */ + } + return (FALSE); +} + +/***************************************************************************/ +UCHAR waitFWReady(ORC_HCS * hcsp) +{ + int i; + + for (i = 0; i < 2000; i++) { /* Wait 1 second for report timeout */ + if (ORC_RD(hcsp->HCS_Base, ORC_HSTUS) & RREADY) /* Wait READY set */ + return (TRUE); + waitForPause(5); /* wait 500ms before try again */ + } + return (FALSE); +} + +/***************************************************************************/ +UCHAR waitSCSIRSTdone(ORC_HCS * hcsp) +{ + int i; + + for (i = 0; i < 2000; i++) { /* Wait 1 second for report timeout */ + if (!(ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & SCSIRST)) /* Wait SCSIRST done */ + return (TRUE); + waitForPause(5); /* wait 500ms before try again */ + } + return (FALSE); +} + +/***************************************************************************/ +UCHAR waitHDOoff(ORC_HCS * hcsp) +{ + int i; + + for (i = 0; i < 2000; i++) { /* Wait 1 second for report timeout */ + if (!(ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & HDO)) /* Wait HDO off */ + return (TRUE); + waitForPause(5); /* wait 500ms before try again */ + } + return (FALSE); +} + +/***************************************************************************/ +UCHAR waitHDIset(ORC_HCS * hcsp, UCHAR * pData) +{ + int i; + + for (i = 0; i < 2000; i++) { /* Wait 1 second for report timeout */ + if ((*pData = ORC_RD(hcsp->HCS_Base, ORC_HSTUS)) & HDI) + return (TRUE); /* Wait HDI set */ + waitForPause(5); /* wait 500ms before try again */ + } + return (FALSE); +} + +/***************************************************************************/ +unsigned short get_FW_version(ORC_HCS * hcsp) +{ + UCHAR bData; + union { + unsigned short sVersion; + unsigned char cVersion[2]; + } Version; + + ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_VERSION); + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */ + return (FALSE); + Version.cVersion[0] = ORC_RD(hcsp->HCS_Base, ORC_HDATA); + ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */ + + if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */ + return (FALSE); + Version.cVersion[1] = ORC_RD(hcsp->HCS_Base, ORC_HDATA); + ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */ + + return (Version.sVersion); +} + +/***************************************************************************/ +UCHAR set_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char value) +{ + ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_SET_NVM); /* Write command */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + ORC_WR(hcsp->HCS_Base + ORC_HDATA, address); /* Write address */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + ORC_WR(hcsp->HCS_Base + ORC_HDATA, value); /* Write value */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + return (TRUE); +} + +/***************************************************************************/ +UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn) +{ + unsigned char bData; + + ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_GET_NVM); /* Write command */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + ORC_WR(hcsp->HCS_Base + ORC_HDATA, address); /* Write address */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */ + return (FALSE); + *pDataIn = ORC_RD(hcsp->HCS_Base, ORC_HDATA); + ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */ + + return (TRUE); +} + +/***************************************************************************/ +void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp) +{ + scbp->SCB_Status = SCB_POST; + ORC_WR(hcsp->HCS_Base + ORC_PQUEUE, scbp->SCB_ScbIdx); + return; +} + + +/*********************************************************************** + Read SCSI H/A configuration parameters from serial EEPROM +************************************************************************/ +int se2_rd_all(ORC_HCS * hcsp) +{ + int i; + UCHAR *np, chksum = 0; + + np = (UCHAR *) nvramp; + for (i = 0; i < 64; i++, np++) { /* <01> */ + if (get_NVRAM(hcsp, (unsigned char) i, np) == FALSE) + return -1; +// *np++ = get_NVRAM(hcsp, (unsigned char ) i); + } + +/*------ Is ckecksum ok ? ------*/ + np = (UCHAR *) nvramp; + for (i = 0; i < 63; i++) + chksum += *np++; + + if (nvramp->CheckSum != (UCHAR) chksum) + return -1; + return 1; +} + +/************************************************************************ + Update SCSI H/A configuration parameters from serial EEPROM +*************************************************************************/ +void se2_update_all(ORC_HCS * hcsp) +{ /* setup default pattern */ + int i; + UCHAR *np, *np1, chksum = 0; + + /* Calculate checksum first */ + np = (UCHAR *) dftNvRam; + for (i = 0; i < 63; i++) + chksum += *np++; + *np = chksum; + + np = (UCHAR *) dftNvRam; + np1 = (UCHAR *) nvramp; + for (i = 0; i < 64; i++, np++, np1++) { + if (*np != *np1) { + set_NVRAM(hcsp, (unsigned char) i, *np); + } + } + return; +} + +/************************************************************************* + Function name : read_eeprom +**************************************************************************/ +void read_eeprom(ORC_HCS * hcsp) +{ + if (se2_rd_all(hcsp) != 1) { + se2_update_all(hcsp); /* setup default pattern */ + se2_rd_all(hcsp); /* load again */ + } +} + + +/***************************************************************************/ +UCHAR load_FW(ORC_HCS * hcsp) +{ + U32 dData; + USHORT wBIOSAddress; + USHORT i; + UCHAR *pData, bData; + + + bData = ORC_RD(hcsp->HCS_Base, ORC_GCFG); + ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData | EEPRG); /* Enable EEPROM programming */ + ORC_WR(hcsp->HCS_Base + ORC_EBIOSADR2, 0x00); + ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x00); + if (ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA) != 0x55) { + ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */ + return (FALSE); + } + ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x01); + if (ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA) != 0xAA) { + ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */ + return (FALSE); + } + ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST | DOWNLOAD); /* Enable SRAM programming */ + pData = (UCHAR *) & dData; + dData = 0; /* Initial FW address to 0 */ + ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x10); + *pData = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ + ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x11); + *(pData + 1) = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ + ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x12); + *(pData + 2) = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ + ORC_WR(hcsp->HCS_Base + ORC_EBIOSADR2, *(pData + 2)); + ORC_WRLONG(hcsp->HCS_Base + ORC_FWBASEADR, dData); /* Write FW address */ + + wBIOSAddress = (USHORT) dData; /* FW code locate at BIOS address + ? */ + for (i = 0, pData = (UCHAR *) & dData; /* Download the code */ + i < 0x1000; /* Firmware code size = 4K */ + i++, wBIOSAddress++) { + ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, wBIOSAddress); + *pData++ = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ + if ((i % 4) == 3) { + ORC_WRLONG(hcsp->HCS_Base + ORC_RISCRAM, dData); /* Write every 4 bytes */ + pData = (UCHAR *) & dData; + } + } + + ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST | DOWNLOAD); /* Reset program count 0 */ + wBIOSAddress -= 0x1000; /* Reset the BIOS adddress */ + for (i = 0, pData = (UCHAR *) & dData; /* Check the code */ + i < 0x1000; /* Firmware code size = 4K */ + i++, wBIOSAddress++) { + ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, wBIOSAddress); + *pData++ = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ + if ((i % 4) == 3) { + if (ORC_RDLONG(hcsp->HCS_Base, ORC_RISCRAM) != dData) { + ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST); /* Reset program to 0 */ + ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /*Disable EEPROM programming */ + return (FALSE); + } + pData = (UCHAR *) & dData; + } + } + ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST); /* Reset program to 0 */ + ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */ + return (TRUE); +} + +/***************************************************************************/ +void setup_SCBs(ORC_HCS * hcsp) +{ + ORC_SCB *pVirScb; + int i; + UCHAR j; + ESCB *pVirEscb; + PVOID pPhysEscb; + PVOID tPhysEscb; + + j = 0; + pVirScb = NULL; + tPhysEscb = (PVOID) NULL; + pPhysEscb = (PVOID) NULL; + /* Setup SCB HCS_Base and SCB Size registers */ + ORC_WR(hcsp->HCS_Base + ORC_SCBSIZE, orc_num_scb); /* Total number of SCBs */ + /* SCB HCS_Base address 0 */ + ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE0, hcsp->HCS_physScbArray); + /* SCB HCS_Base address 1 */ + ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE1, hcsp->HCS_physScbArray); + + /* setup scatter list address with one buffer */ + pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray; + pVirEscb = (ESCB *) hcsp->HCS_virEscbArray; + + for (i = 0; i < orc_num_scb; i++) { +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) + pPhysEscb = (PVOID) ((ULONG) hcsp->HCS_virEscbArray + (sizeof(ESCB) * i)); + pVirScb->SCB_SGPAddr = (U32) VIRT_TO_BUS(pPhysEscb); + pVirScb->SCB_SensePAddr = (U32) VIRT_TO_BUS(pPhysEscb); +#else + pPhysEscb = (PVOID) (hcsp->HCS_physEscbArray + (sizeof(ESCB) * i)); + pVirScb->SCB_SGPAddr = (U32) pPhysEscb; + pVirScb->SCB_SensePAddr = (U32) pPhysEscb; +#endif + pVirScb->SCB_EScb = pVirEscb; + pVirScb->SCB_ScbIdx = i; + pVirScb++; + pVirEscb++; + } + + return; +} + +/***************************************************************************/ +static void initAFlag(ORC_HCS * hcsp) +{ + UCHAR i, j; + + for (i = 0; i < MAX_CHANNELS; i++) { + for (j = 0; j < 8; j++) { + hcsp->BitAllocFlag[i][j] = 0xffffffff; + } + } +} + +/***************************************************************************/ +int init_orchid(ORC_HCS * hcsp) +{ + UBYTE *readBytep; + USHORT revision; + UCHAR i; + + initAFlag(hcsp); + ORC_WR(hcsp->HCS_Base + ORC_GIMSK, 0xFF); /* Disable all interrupt */ + if (ORC_RD(hcsp->HCS_Base, ORC_HSTUS) & RREADY) { /* Orchid is ready */ + revision = get_FW_version(hcsp); + if (revision == 0xFFFF) { + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, DEVRST); /* Reset Host Adapter */ + if (waitChipReady(hcsp) == FALSE) + return (-1); + load_FW(hcsp); /* Download FW */ + setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, 0); /* clear HOSTSTOP */ + if (waitFWReady(hcsp) == FALSE) + return (-1); + /* Wait for firmware ready */ + } else { + setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */ + } + } else { /* Orchid is not Ready */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, DEVRST); /* Reset Host Adapter */ + if (waitChipReady(hcsp) == FALSE) + return (-1); + load_FW(hcsp); /* Download FW */ + setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); /* Do Hardware Reset & */ + + /* clear HOSTSTOP */ + if (waitFWReady(hcsp) == FALSE) /* Wait for firmware ready */ + return (-1); + } + +/*------------- get serial EEProm settting -------*/ + + read_eeprom(hcsp); + + if (nvramp->Revision != 1) + return (-1); + + hcsp->HCS_SCSI_ID = nvramp->SCSI0Id; + hcsp->HCS_BIOS = nvramp->BIOSConfig1; + hcsp->HCS_MaxTar = MAX_TARGETS; + readBytep = (UCHAR *) & (nvramp->Target00Config); + for (i = 0; i < 16; readBytep++, i++) { + hcsp->TargetFlag[i] = *readBytep; + hcsp->MaximumTags[i] = orc_num_scb; + } /* for */ + + if (nvramp->SCSI0Config & NCC_BUSRESET) { /* Reset SCSI bus */ + hcsp->HCS_Flags |= HCF_SCSI_RESET; + } + ORC_WR(hcsp->HCS_Base + ORC_GIMSK, 0xFB); /* enable RP FIFO interrupt */ + return (0); +} + +/***************************************************************************** + Function name : orc_reset_scsi_bus + Description : Reset registers, reset a hanging bus and + kill active and disconnected commands for target w/o soft reset + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +int orc_reset_scsi_bus(ORC_HCS * pHCB) +{ /* I need Host Control Block Information */ + ULONG flags; + +#if 0 + printk("inia100: enter inia100_reset\n"); +#endif + +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + save_flags(flags); + cli(); +#else + spin_lock_irqsave(&(pHCB->BitAllocFlagLock), flags); +#endif + + initAFlag(pHCB); + /* reset scsi bus */ + ORC_WR(pHCB->HCS_Base + ORC_HCTRL, SCSIRST); + if (waitSCSIRSTdone(pHCB) == FALSE) { +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + restore_flags(flags); +#else + spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); +#endif + return (SCSI_RESET_ERROR); + } else { +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + restore_flags(flags); +#else + spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); +#endif + return (SCSI_RESET_SUCCESS); + } +} + +/***************************************************************************** + Function name : orc_device_reset + Description : Reset registers, reset a hanging bus and + kill active and disconnected commands for target w/o soft reset + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned int ResetFlags) +{ /* I need Host Control Block Information */ + ORC_SCB *pScb; + ESCB *pVirEscb; + ORC_SCB *pVirScb; + UCHAR i; + ULONG flags; + +#if 0 + printk("inia100: enter inia100_reset\n"); +#endif + +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + save_flags(flags); + cli(); +#else + spin_lock_irqsave(&(pHCB->BitAllocFlagLock), flags); +#endif + pScb = (ORC_SCB *) NULL; + pVirEscb = (ESCB *) NULL; + + /* setup scatter list address with one buffer */ + pVirScb = (ORC_SCB *) pHCB->HCS_virScbArray; + + initAFlag(pHCB); + /* device reset */ + for (i = 0; i < orc_num_scb; i++) { + pVirEscb = pVirScb->SCB_EScb; + if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == (unsigned char *) SCpnt)) + break; + pVirScb++; + } + + if (i == orc_num_scb) { + printk("Unable to Reset - No SCB Found\n"); +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + restore_flags(flags); +#else + spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); +#endif + return (SCSI_RESET_NOT_RUNNING); + } + if ((pScb = orc_alloc_scb(pHCB)) == NULL) { +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + restore_flags(flags); +#else + spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); +#endif + return (SCSI_RESET_NOT_RUNNING); + } + pScb->SCB_Opcode = ORC_BUSDEVRST; + pScb->SCB_Target = target; + pScb->SCB_HaStat = 0; + pScb->SCB_TaStat = 0; + pScb->SCB_Status = 0x0; + pScb->SCB_Link = 0xFF; + pScb->SCB_Reserved0 = 0; + pScb->SCB_Reserved1 = 0; + pScb->SCB_XferLen = 0; + pScb->SCB_SGLen = 0; + + pVirEscb->SCB_Srb = 0; + if (ResetFlags & SCSI_RESET_SYNCHRONOUS) { + pVirEscb->SCB_Srb = (unsigned char *) SCpnt; + } + orc_exec_scb(pHCB, pScb); /* Start execute SCB */ +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + restore_flags(flags); +#else + spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); +#endif + return SCSI_RESET_PENDING; +} + + +/***************************************************************************/ +ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp) +{ + ORC_SCB *pTmpScb; + UCHAR Ch; + ULONG idx; + UCHAR index; + UCHAR i; + ULONG flags; + +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + save_flags(flags); + cli(); +#else + spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags); +#endif + Ch = hcsp->HCS_Index; + for (i = 0; i < 8; i++) { + for (index = 0; index < 32; index++) { + if ((hcsp->BitAllocFlag[Ch][i] >> index) & 0x01) { + hcsp->BitAllocFlag[Ch][i] &= ~(1 << index); + break; + } + } + idx = index + 32 * i; + pTmpScb = (PVOID) ((ULONG) hcsp->HCS_virScbArray + (idx * sizeof(ORC_SCB))); +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + restore_flags(flags); +#else + spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); +#endif + return (pTmpScb); + } +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + restore_flags(flags); +#else + spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); +#endif + return (NULL); +} + + +/***************************************************************************/ +void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp) +{ + ULONG flags; + UCHAR Index; + UCHAR i; + UCHAR Ch; + +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + save_flags(flags); + cli(); +#else + spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags); +#endif + Ch = hcsp->HCS_Index; + Index = scbp->SCB_ScbIdx; + i = Index / 32; + Index %= 32; + hcsp->BitAllocFlag[Ch][i] |= (1 << Index); +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + restore_flags(flags); +#else + spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); +#endif +} + + +/***************************************************************************** + Function name : Addinia100_into_Adapter_table + Description : This function will scan PCI bus to get all Orchid card + Input : None. + Output : None. + Return : SUCCESSFUL - Successful scan + ohterwise - No drives founded +*****************************************************************************/ +int Addinia100_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt, + BYTE bBus, BYTE bDevice) +{ + unsigned int i, j; + + for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) { + if (inia100_adpt[i].ADPT_BIOS < wBIOS) + continue; + if (inia100_adpt[i].ADPT_BIOS == wBIOS) { + if (inia100_adpt[i].ADPT_BASE == wBASE) + if (inia100_adpt[i].ADPT_Bus != 0xFF) + return (FAILURE); + else if (inia100_adpt[i].ADPT_BASE < wBASE) + continue; + } + for (j = MAX_SUPPORTED_ADAPTERS - 1; j > i; j--) { + inia100_adpt[j].ADPT_BASE = inia100_adpt[j - 1].ADPT_BASE; + inia100_adpt[j].ADPT_INTR = inia100_adpt[j - 1].ADPT_INTR; + inia100_adpt[j].ADPT_BIOS = inia100_adpt[j - 1].ADPT_BIOS; + inia100_adpt[j].ADPT_Bus = inia100_adpt[j - 1].ADPT_Bus; + inia100_adpt[j].ADPT_Device = inia100_adpt[j - 1].ADPT_Device; + } + inia100_adpt[i].ADPT_BASE = wBASE; + inia100_adpt[i].ADPT_INTR = bInterrupt; + inia100_adpt[i].ADPT_BIOS = wBIOS; + inia100_adpt[i].ADPT_Bus = bBus; + inia100_adpt[i].ADPT_Device = bDevice; + return (SUCCESSFUL); + } + return (FAILURE); +} + + +/***************************************************************************** + Function name : init_inia100Adapter_table + Description : This function will scan PCI bus to get all Orchid card + Input : None. + Output : None. + Return : SUCCESSFUL - Successful scan + ohterwise - No drives founded +*****************************************************************************/ +void init_inia100Adapter_table(void) +{ + int i; + + for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) { /* Initialize adapter structure */ + inia100_adpt[i].ADPT_BIOS = 0xffff; + inia100_adpt[i].ADPT_BASE = 0xffff; + inia100_adpt[i].ADPT_INTR = 0xff; + inia100_adpt[i].ADPT_Bus = 0xff; + inia100_adpt[i].ADPT_Device = 0xff; + } +} + +/***************************************************************************** + Function name : get_orcPCIConfig + Description : + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +void get_orcPCIConfig(ORC_HCS * pCurHcb, int ch_idx) +{ + pCurHcb->HCS_Base = inia100_adpt[ch_idx].ADPT_BASE; /* Supply base address */ + pCurHcb->HCS_BIOS = inia100_adpt[ch_idx].ADPT_BIOS; /* Supply BIOS address */ + pCurHcb->HCS_Intr = inia100_adpt[ch_idx].ADPT_INTR; /* Supply interrupt line */ + return; +} + + +/***************************************************************************** + Function name : abort_SCB + Description : Abort a queued command. + (commands that are on the bus can't be aborted easily) + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb) +{ + unsigned char bData, bStatus; + + ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_ABORT_SCB); /* Write command */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + ORC_WR(hcsp->HCS_Base + ORC_HDATA, pScb->SCB_ScbIdx); /* Write address */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */ + return (FALSE); + bStatus = ORC_RD(hcsp->HCS_Base, ORC_HDATA); + ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */ + + if (bStatus == 1) /* 0 - Successfully */ + return (FALSE); /* 1 - Fail */ + return (TRUE); +} + +/***************************************************************************** + Function name : inia100_abort + Description : Abort a queued command. + (commands that are on the bus can't be aborted easily) + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +int orc_abort_srb(ORC_HCS * hcsp, ULONG SCpnt) +{ + ESCB *pVirEscb; + ORC_SCB *pVirScb; + UCHAR i; + ULONG flags; + +#if 0 + printk("inia100: abort SRB \n"); +#endif +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + save_flags(flags); + cli(); +#else + spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags); +#endif + + pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray; + + for (i = 0; i < orc_num_scb; i++, pVirScb++) { + pVirEscb = pVirScb->SCB_EScb; + if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == (unsigned char *) SCpnt)) { + if (pVirScb->SCB_TagMsg == 0) { +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + restore_flags(flags); +#else + spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); +#endif + return (SCSI_ABORT_BUSY); + } else { + if (abort_SCB(hcsp, pVirScb)) { + pVirEscb->SCB_Srb = NULL; +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + restore_flags(flags); +#else + spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); +#endif + return (SCSI_ABORT_SUCCESS); + } else { +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + restore_flags(flags); +#else + spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); +#endif + return (SCSI_ABORT_NOT_RUNNING); + } + } + } + } +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2,1,95) + restore_flags(flags); +#else + spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); +#endif + return (SCSI_ABORT_NOT_RUNNING); +} + +/*********************************************************************** + Routine Description: + This is the interrupt service routine for the Orchid SCSI adapter. + It reads the interrupt register to determine if the adapter is indeed + the source of the interrupt and clears the interrupt at the device. + Arguments: + HwDeviceExtension - HBA miniport driver's adapter data storage + Return Value: +***********************************************************************/ +void orc_interrupt( + ORC_HCS * hcsp +) +{ + BYTE bScbIdx; + ORC_SCB *pScb; + + if (ORC_RD(hcsp->HCS_Base, ORC_RQUEUECNT) == 0) { + return; // (FALSE); + + } + do { + bScbIdx = ORC_RD(hcsp->HCS_Base, ORC_RQUEUE); + + pScb = (ORC_SCB *) ((ULONG) hcsp->HCS_virScbArray + (ULONG) (sizeof(ORC_SCB) * bScbIdx)); + pScb->SCB_Status = 0x0; + + inia100SCBPost((BYTE *) hcsp, (BYTE *) pScb); + } while (ORC_RD(hcsp->HCS_Base, ORC_RQUEUECNT)); + return; //(TRUE); + +} /* End of I1060Interrupt() */ diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/i60uscsi.h linux/drivers/scsi/i60uscsi.h --- v2.2.2/linux/drivers/scsi/i60uscsi.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/i60uscsi.h Wed Feb 24 16:27:54 1999 @@ -0,0 +1,574 @@ +/************************************************************************** + * Initio A100 device driver for Linux. + * + * Copyright (c) 1994-1998 Initio Corporation + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, 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; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * -------------------------------------------------------------------------- + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + ************************************************************************** + * + * Module: inia100.h + * Description: INI-A100U2W LINUX device driver header + * Revision History: + * 06/18/98 HL, Initial Version 1.02 + * 12/19/98 bv, v1.02a Use spinlocks for 2.1.95 and up. + **************************************************************************/ + +#include + +#define ULONG unsigned long +#define PVOID void * +#define USHORT unsigned short +#define UCHAR unsigned char +#define BYTE unsigned char +#define WORD unsigned short +#define DWORD unsigned long +#define UBYTE unsigned char +#define UWORD unsigned short +#define UDWORD unsigned long +#ifdef ALPHA +#define U32 unsigned int +#else +#define U32 unsigned long +#endif + +#ifndef NULL +#define NULL 0 /* zero */ +#endif +#ifndef TRUE +#define TRUE (1) /* boolean true */ +#endif +#ifndef FALSE +#define FALSE (0) /* boolean false */ +#endif +#ifndef FAILURE +#define FAILURE (-1) +#endif +#if 1 +#define ORC_MAXQUEUE 245 +#else +#define ORC_MAXQUEUE 25 +#endif + +#define TOTAL_SG_ENTRY 32 +#define MAX_TARGETS 16 +#define IMAX_CDB 15 +#define SENSE_SIZE 14 +#define MAX_SUPPORTED_ADAPTERS 4 +#define SUCCESSFUL 0x00 + +#define I920_DEVICE_ID 0x0002 /* Initio's inic-950 product ID */ + +/************************************************************************/ +/* Scatter-Gather Element Structure */ +/************************************************************************/ +typedef struct ORC_SG_Struc { + U32 SG_Ptr; /* Data Pointer */ + U32 SG_Len; /* Data Length */ +} ORC_SG; + +typedef struct inia100_Adpt_Struc { + UWORD ADPT_BIOS; /* 0 */ + UWORD ADPT_BASE; /* 1 */ + UBYTE ADPT_Bus; /* 2 */ + UBYTE ADPT_Device; /* 3 */ + UBYTE ADPT_INTR; /* 4 */ +} INIA100_ADPT_STRUCT; + + +/* SCSI related definition */ +#define DISC_NOT_ALLOW 0x80 /* Disconnect is not allowed */ +#define DISC_ALLOW 0xC0 /* Disconnect is allowed */ + + +#define ORC_OFFSET_SCB 16 +#define ORC_MAX_SCBS 250 +#define MAX_CHANNELS 2 +#define MAX_ESCB_ELE 64 +#define TCF_DRV_255_63 0x0400 + +/********************************************************/ +/* Orchid Configuration Register Set */ +/********************************************************/ +#define ORC_PVID 0x00 /* Vendor ID */ +#define ORC_VENDOR_ID 0x1101 /* Orchid vendor ID */ +#define ORC_PDID 0x02 /* Device ID */ +#define ORC_DEVICE_ID 0x1060 /* Orchid device ID */ +#define ORC_COMMAND 0x04 /* Command */ +#define BUSMS 0x04 /* BUS MASTER Enable */ +#define IOSPA 0x01 /* IO Space Enable */ +#define ORC_STATUS 0x06 /* Status register */ +#define ORC_REVISION 0x08 /* Revision number */ +#define ORC_BASE 0x10 /* Base address */ +#define ORC_BIOS 0x50 /* Expansion ROM base address */ +#define ORC_INT_NUM 0x3C /* Interrupt line */ +#define ORC_INT_PIN 0x3D /* Interrupt pin */ + + +/********************************************************/ +/* Orchid Host Command Set */ +/********************************************************/ +#define ORC_CMD_NOP 0x00 /* Host command - NOP */ +#define ORC_CMD_VERSION 0x01 /* Host command - Get F/W version */ +#define ORC_CMD_ECHO 0x02 /* Host command - ECHO */ +#define ORC_CMD_SET_NVM 0x03 /* Host command - Set NVRAM */ +#define ORC_CMD_GET_NVM 0x04 /* Host command - Get NVRAM */ +#define ORC_CMD_GET_BUS_STATUS 0x05 /* Host command - Get SCSI bus status */ +#define ORC_CMD_ABORT_SCB 0x06 /* Host command - Abort SCB */ +#define ORC_CMD_ISSUE_SCB 0x07 /* Host command - Issue SCB */ + +/********************************************************/ +/* Orchid Register Set */ +/********************************************************/ +#define ORC_GINTS 0xA0 /* Global Interrupt Status */ +#define QINT 0x04 /* Reply Queue Interrupt */ +#define ORC_GIMSK 0xA1 /* Global Interrupt MASK */ +#define MQINT 0x04 /* Mask Reply Queue Interrupt */ +#define ORC_GCFG 0xA2 /* Global Configure */ +#define EEPRG 0x01 /* Enable EEPROM programming */ +#define ORC_GSTAT 0xA3 /* Global status */ +#define WIDEBUS 0x10 /* Wide SCSI Devices connected */ +#define ORC_HDATA 0xA4 /* Host Data */ +#define ORC_HCTRL 0xA5 /* Host Control */ +#define SCSIRST 0x80 /* SCSI bus reset */ +#define HDO 0x40 /* Host data out */ +#define HOSTSTOP 0x02 /* Host stop RISC engine */ +#define DEVRST 0x01 /* Device reset */ +#define ORC_HSTUS 0xA6 /* Host Status */ +#define HDI 0x02 /* Host data in */ +#define RREADY 0x01 /* RISC engine is ready to receive */ +#define ORC_NVRAM 0xA7 /* Nvram port address */ +#define SE2CS 0x008 +#define SE2CLK 0x004 +#define SE2DO 0x002 +#define SE2DI 0x001 +#define ORC_PQUEUE 0xA8 /* Posting queue FIFO */ +#define ORC_PQCNT 0xA9 /* Posting queue FIFO Cnt */ +#define ORC_RQUEUE 0xAA /* Reply queue FIFO */ +#define ORC_RQUEUECNT 0xAB /* Reply queue FIFO Cnt */ +#define ORC_FWBASEADR 0xAC /* Firmware base address */ + +#define ORC_EBIOSADR0 0xB0 /* External Bios address */ +#define ORC_EBIOSADR1 0xB1 /* External Bios address */ +#define ORC_EBIOSADR2 0xB2 /* External Bios address */ +#define ORC_EBIOSDATA 0xB3 /* External Bios address */ + +#define ORC_SCBSIZE 0xB7 /* SCB size register */ +#define ORC_SCBBASE0 0xB8 /* SCB base address 0 */ +#define ORC_SCBBASE1 0xBC /* SCB base address 1 */ + +#define ORC_RISCCTL 0xE0 /* RISC Control */ +#define PRGMRST 0x002 +#define DOWNLOAD 0x001 +#define ORC_PRGMCTR0 0xE2 /* RISC program counter */ +#define ORC_PRGMCTR1 0xE3 /* RISC program counter */ +#define ORC_RISCRAM 0xEC /* RISC RAM data port 4 bytes */ + +typedef struct orc_extended_scb { /* Extended SCB */ + ORC_SG ESCB_SGList[TOTAL_SG_ENTRY]; /*0 Start of SG list */ + unsigned char *SCB_Srb; /*50 SRB Pointer */ +// Scsi_Cmnd *SCB_Srb; /*50 SRB Pointer */ +} ESCB; + +/*********************************************************************** + SCSI Control Block +************************************************************************/ +typedef struct orc_scb { /* Scsi_Ctrl_Blk */ + UBYTE SCB_Opcode; /*00 SCB command code&residual */ + UBYTE SCB_Flags; /*01 SCB Flags */ + UBYTE SCB_Target; /*02 Target Id */ + UBYTE SCB_Lun; /*03 Lun */ + U32 SCB_Reserved0; /*04 Reserved for ORCHID must 0 */ + U32 SCB_XferLen; /*08 Data Transfer Length */ + U32 SCB_Reserved1; /*0C Reserved for ORCHID must 0 */ + U32 SCB_SGLen; /*10 SG list # * 8 */ + U32 SCB_SGPAddr; /*14 SG List Buf physical Addr */ + U32 SCB_SGPAddrHigh; /*18 SG Buffer high physical Addr */ + UBYTE SCB_HaStat; /*1C Host Status */ + UBYTE SCB_TaStat; /*1D Target Status */ + UBYTE SCB_Status; /*1E SCB status */ + UBYTE SCB_Link; /*1F Link pointer, default 0xFF */ + UBYTE SCB_SenseLen; /*20 Sense Allocation Length */ + UBYTE SCB_CDBLen; /*21 CDB Length */ + UBYTE SCB_Ident; /*22 Identify */ + UBYTE SCB_TagMsg; /*23 Tag Message */ + UBYTE SCB_CDB[IMAX_CDB]; /*24 SCSI CDBs */ + UBYTE SCB_ScbIdx; /*3C Index for this ORCSCB */ + U32 SCB_SensePAddr; /*34 Sense Buffer physical Addr */ + + ESCB *SCB_EScb; /*38 Extended SCB Pointer */ +#ifndef ALPHA + UBYTE SCB_Reserved2[4]; /*3E Reserved for Driver use */ +#endif +} ORC_SCB; + +/* Opcodes of ORCSCB_Opcode */ +#define ORC_EXECSCSI 0x00 /* SCSI initiator command with residual */ +#define ORC_BUSDEVRST 0x01 /* SCSI Bus Device Reset */ + +/* Status of ORCSCB_Status */ +#define SCB_COMPLETE 0x00 /* SCB request completed */ +#define SCB_POST 0x01 /* SCB is posted by the HOST */ + +/* Bit Definition for ORCSCB_Flags */ +#define SCF_DISINT 0x01 /* Disable HOST interrupt */ +#define SCF_DIR 0x18 /* Direction bits */ +#define SCF_NO_DCHK 0x00 /* Direction determined by SCSI */ +#define SCF_DIN 0x08 /* From Target to Initiator */ +#define SCF_DOUT 0x10 /* From Initiator to Target */ +#define SCF_NO_XF 0x18 /* No data transfer */ +#define SCF_POLL 0x40 + +/* Error Codes for ORCSCB_HaStat */ +#define HOST_SEL_TOUT 0x11 +#define HOST_DO_DU 0x12 +#define HOST_BUS_FREE 0x13 +#define HOST_BAD_PHAS 0x14 +#define HOST_INV_CMD 0x16 +#define HOST_SCSI_RST 0x1B +#define HOST_DEV_RST 0x1C + + +/* Error Codes for ORCSCB_TaStat */ +#define TARGET_CHK_COND 0x02 +#define TARGET_BUSY 0x08 +#define TARGET_TAG_FULL 0x28 + + +/* Queue tag msg: Simple_quque_tag, Head_of_queue_tag, Ordered_queue_tag */ +#define MSG_STAG 0x20 +#define MSG_HTAG 0x21 +#define MSG_OTAG 0x22 + +#define MSG_IGNOREWIDE 0x23 + +#define MSG_IDENT 0x80 +#define MSG_DISC 0x40 /* Disconnect allowed */ + + +/* SCSI MESSAGE */ +#define MSG_EXTEND 0x01 +#define MSG_SDP 0x02 +#define MSG_ABORT 0x06 +#define MSG_REJ 0x07 +#define MSG_NOP 0x08 +#define MSG_PARITY 0x09 +#define MSG_DEVRST 0x0C +#define MSG_STAG 0x20 + +/*********************************************************************** + Target Device Control Structure +**********************************************************************/ + +typedef struct ORC_Tar_Ctrl_Struc { + UBYTE TCS_DrvDASD; /* 6 */ + UBYTE TCS_DrvSCSI; /* 7 */ + UBYTE TCS_DrvHead; /* 8 */ + UWORD TCS_DrvFlags; /* 4 */ + UBYTE TCS_DrvSector; /* 7 */ +} ORC_TCS, *PORC_TCS; + +/* Bit Definition for TCF_DrvFlags */ +#define TCS_DF_NODASD_SUPT 0x20 /* Suppress OS/2 DASD Mgr support */ +#define TCS_DF_NOSCSI_SUPT 0x40 /* Suppress OS/2 SCSI Mgr support */ + + +/*********************************************************************** + Host Adapter Control Structure +************************************************************************/ +typedef struct ORC_Ha_Ctrl_Struc { + USHORT HCS_Base; /* 00 */ + UBYTE HCS_Index; /* 02 */ + UBYTE HCS_Intr; /* 04 */ + UBYTE HCS_SCSI_ID; /* 06 H/A SCSI ID */ + UBYTE HCS_BIOS; /* 07 BIOS configuration */ + + UBYTE HCS_Flags; /* 0B */ + UBYTE HCS_HAConfig1; /* 1B SCSI0MAXTags */ + UBYTE HCS_MaxTar; /* 1B SCSI0MAXTags */ + + USHORT HCS_Units; /* Number of units this adapter */ + USHORT HCS_AFlags; /* Adapter info. defined flags */ + ULONG HCS_Timeout; /* Adapter timeout value */ + PVOID HCS_virScbArray; /* 28 Virtual Pointer to SCB array */ + U32 HCS_physScbArray; /* Scb Physical address */ + PVOID HCS_virEscbArray; /* Virtual pointer to ESCB Scatter list */ + U32 HCS_physEscbArray; /* scatter list Physical address */ + UBYTE TargetFlag[16]; /* 30 target configuration, TCF_EN_TAG */ + UBYTE MaximumTags[16]; /* 40 ORC_MAX_SCBS */ + UBYTE ActiveTags[16][16]; /* 50 */ + ORC_TCS HCS_Tcs[16]; /* 28 */ + U32 BitAllocFlag[MAX_CHANNELS][8]; /* Max STB is 256, So 256/32 */ +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) + spinlock_t BitAllocFlagLock; +#endif + ULONG pSRB_head; + ULONG pSRB_tail; +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) + spinlock_t pSRB_lock; +#endif +} ORC_HCS; + +/* Bit Definition for HCS_Flags */ + +#define HCF_SCSI_RESET 0x01 /* SCSI BUS RESET */ +#define HCF_PARITY 0x02 /* parity card */ +#define HCF_LVDS 0x10 /* parity card */ + +/* Bit Definition for TargetFlag */ + +#define TCF_EN_255 0x08 +#define TCF_EN_TAG 0x10 +#define TCF_BUSY 0x20 +#define TCF_DISCONNECT 0x40 +#define TCF_SPIN_UP 0x80 + +/* Bit Definition for HCS_AFlags */ +#define HCS_AF_IGNORE 0x01 /* Adapter ignore */ +#define HCS_AF_DISABLE_RESET 0x10 /* Adapter disable reset */ +#define HCS_AF_DISABLE_ADPT 0x80 /* Adapter disable */ + + +/*---------------------------------------*/ +/* TimeOut for RESET to complete (30s) */ +/* */ +/* After a RESET the drive is checked */ +/* every 200ms. */ +/*---------------------------------------*/ +#define DELAYED_RESET_MAX (30*1000L) +#define DELAYED_RESET_INTERVAL 200L + +/*----------------------------------------------*/ +/* TimeOut for IRQ from last interrupt (5s) */ +/*----------------------------------------------*/ +#define IRQ_TIMEOUT_INTERVAL (5*1000L) + +/*----------------------------------------------*/ +/* Retry Delay interval (200ms) */ +/*----------------------------------------------*/ +#define DELAYED_RETRY_INTERVAL 200L + +#define INQUIRY_SIZE 36 +#define CAPACITY_SIZE 8 +#define DEFAULT_SENSE_LEN 14 + +#define DEVICE_NOT_FOUND 0x86 + +/*----------------------------------------------*/ +/* Definition for PCI device */ +/*----------------------------------------------*/ +#define MAX_PCI_DEVICES 21 +#define MAX_PCI_BUSES 8 + +typedef struct Adpt_Struc { + USHORT ADPT_BIOS; /* 0 */ + UBYTE ADPT_BASE; /* 1 */ + UBYTE ADPT_Bus; /* 2 */ + UBYTE ADPT_Device; /* 3 */ + UBYTE ADPT_Reserved[3]; +} JACS, *PJACS; + +typedef struct _NVRAM { +/*----------header ---------------*/ + UCHAR SubVendorID0; /* 00 - Sub Vendor ID */ + UCHAR SubVendorID1; /* 00 - Sub Vendor ID */ + UCHAR SubSysID0; /* 02 - Sub System ID */ + UCHAR SubSysID1; /* 02 - Sub System ID */ + UCHAR SubClass; /* 04 - Sub Class */ + UCHAR VendorID0; /* 05 - Vendor ID */ + UCHAR VendorID1; /* 05 - Vendor ID */ + UCHAR DeviceID0; /* 07 - Device ID */ + UCHAR DeviceID1; /* 07 - Device ID */ + UCHAR Reserved0[2]; /* 09 - Reserved */ + UCHAR Revision; /* 0B - Revision of data structure */ + /* ----Host Adapter Structure ---- */ + UCHAR NumOfCh; /* 0C - Number of SCSI channel */ + UCHAR BIOSConfig1; /* 0D - BIOS configuration 1 */ + UCHAR BIOSConfig2; /* 0E - BIOS boot channel&target ID */ + UCHAR BIOSConfig3; /* 0F - BIOS configuration 3 */ + /* ----SCSI channel Structure ---- */ + /* from "CTRL-I SCSI Host Adapter SetUp menu " */ + UCHAR SCSI0Id; /* 10 - Channel 0 SCSI ID */ + UCHAR SCSI0Config; /* 11 - Channel 0 SCSI configuration */ + UCHAR SCSI0MaxTags; /* 12 - Channel 0 Maximum tags */ + UCHAR SCSI0ResetTime; /* 13 - Channel 0 Reset recovering time */ + UCHAR ReservedforChannel0[2]; /* 14 - Reserved */ + + /* ----SCSI target Structure ---- */ + /* from "CTRL-I SCSI device SetUp menu " */ + UCHAR Target00Config; /* 16 - Channel 0 Target 0 config */ + UCHAR Target01Config; /* 17 - Channel 0 Target 1 config */ + UCHAR Target02Config; /* 18 - Channel 0 Target 2 config */ + UCHAR Target03Config; /* 19 - Channel 0 Target 3 config */ + UCHAR Target04Config; /* 1A - Channel 0 Target 4 config */ + UCHAR Target05Config; /* 1B - Channel 0 Target 5 config */ + UCHAR Target06Config; /* 1C - Channel 0 Target 6 config */ + UCHAR Target07Config; /* 1D - Channel 0 Target 7 config */ + UCHAR Target08Config; /* 1E - Channel 0 Target 8 config */ + UCHAR Target09Config; /* 1F - Channel 0 Target 9 config */ + UCHAR Target0AConfig; /* 20 - Channel 0 Target A config */ + UCHAR Target0BConfig; /* 21 - Channel 0 Target B config */ + UCHAR Target0CConfig; /* 22 - Channel 0 Target C config */ + UCHAR Target0DConfig; /* 23 - Channel 0 Target D config */ + UCHAR Target0EConfig; /* 24 - Channel 0 Target E config */ + UCHAR Target0FConfig; /* 25 - Channel 0 Target F config */ + + UCHAR SCSI1Id; /* 26 - Channel 1 SCSI ID */ + UCHAR SCSI1Config; /* 27 - Channel 1 SCSI configuration */ + UCHAR SCSI1MaxTags; /* 28 - Channel 1 Maximum tags */ + UCHAR SCSI1ResetTime; /* 29 - Channel 1 Reset recovering time */ + UCHAR ReservedforChannel1[2]; /* 2A - Reserved */ + + /* ----SCSI target Structure ---- */ + /* from "CTRL-I SCSI device SetUp menu " */ + UCHAR Target10Config; /* 2C - Channel 1 Target 0 config */ + UCHAR Target11Config; /* 2D - Channel 1 Target 1 config */ + UCHAR Target12Config; /* 2E - Channel 1 Target 2 config */ + UCHAR Target13Config; /* 2F - Channel 1 Target 3 config */ + UCHAR Target14Config; /* 30 - Channel 1 Target 4 config */ + UCHAR Target15Config; /* 31 - Channel 1 Target 5 config */ + UCHAR Target16Config; /* 32 - Channel 1 Target 6 config */ + UCHAR Target17Config; /* 33 - Channel 1 Target 7 config */ + UCHAR Target18Config; /* 34 - Channel 1 Target 8 config */ + UCHAR Target19Config; /* 35 - Channel 1 Target 9 config */ + UCHAR Target1AConfig; /* 36 - Channel 1 Target A config */ + UCHAR Target1BConfig; /* 37 - Channel 1 Target B config */ + UCHAR Target1CConfig; /* 38 - Channel 1 Target C config */ + UCHAR Target1DConfig; /* 39 - Channel 1 Target D config */ + UCHAR Target1EConfig; /* 3A - Channel 1 Target E config */ + UCHAR Target1FConfig; /* 3B - Channel 1 Target F config */ + UCHAR reserved[3]; /* 3C - Reserved */ + /* ---------- CheckSum ---------- */ + UCHAR CheckSum; /* 3F - Checksum of NVRam */ +} NVRAM, *PNVRAM; + +/* Bios Configuration for nvram->BIOSConfig1 */ +#define NBC_BIOSENABLE 0x01 /* BIOS enable */ +#define NBC_CDROM 0x02 /* Support bootable CDROM */ +#define NBC_REMOVABLE 0x04 /* Support removable drive */ + +/* Bios Configuration for nvram->BIOSConfig2 */ +#define NBB_TARGET_MASK 0x0F /* Boot SCSI target ID number */ +#define NBB_CHANL_MASK 0xF0 /* Boot SCSI channel number */ + +/* Bit definition for nvram->SCSIConfig */ +#define NCC_BUSRESET 0x01 /* Reset SCSI bus at power up */ +#define NCC_PARITYCHK 0x02 /* SCSI parity enable */ +#define NCC_LVDS 0x10 /* Enable LVDS */ +#define NCC_ACTTERM1 0x20 /* Enable active terminator 1 */ +#define NCC_ACTTERM2 0x40 /* Enable active terminator 2 */ +#define NCC_AUTOTERM 0x80 /* Enable auto termination */ + +/* Bit definition for nvram->TargetxConfig */ +#define NTC_PERIOD 0x07 /* Maximum Sync. Speed */ +#define NTC_1GIGA 0x08 /* 255 head / 63 sectors (64/32) */ +#define NTC_NO_SYNC 0x10 /* NO SYNC. NEGO */ +#define NTC_NO_WIDESYNC 0x20 /* NO WIDE SYNC. NEGO */ +#define NTC_DISC_ENABLE 0x40 /* Enable SCSI disconnect */ +#define NTC_SPINUP 0x80 /* Start disk drive */ + +/* Default NVRam values */ +#define NBC_DEFAULT (NBC_ENABLE) +#define NCC_DEFAULT (NCC_BUSRESET | NCC_AUTOTERM | NCC_PARITYCHK) +#define NCC_MAX_TAGS 0x20 /* Maximum tags per target */ +#define NCC_RESET_TIME 0x0A /* SCSI RESET recovering time */ +#define NTC_DEFAULT (NTC_1GIGA | NTC_NO_WIDESYNC | NTC_DISC_ENABLE) + +typedef union { /* Union define for mechanism 1 */ + struct { + unsigned char RegNum; + unsigned char FcnNum:3; + unsigned char DeviceNum:5; + unsigned char BusNum; + unsigned char Reserved:7; + unsigned char Enable:1; + } sConfigAdr; + unsigned long lConfigAdr; +} CONFIG_ADR; + +typedef union { /* Union define for mechanism 2 */ + struct { + unsigned char RegNum; + unsigned char DeviceNum; + unsigned short Reserved; + } sHostAdr; + unsigned long lHostAdr; +} HOST_ADR; + +#define ORC_RD(x,y) (UCHAR)(inb( (int)((ULONG)((ULONG)x+(UCHAR)y)) )) +#define ORC_RDLONG(x,y) (long)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) )) + +#define ORC_WR( adr,data) outb( (UCHAR)(data), (int)(adr)) +#define ORC_WRSHORT(adr,data) outw( (UWORD)(data), (int)(adr)) +#define ORC_WRLONG( adr,data) outl( (ULONG)(data), (int)(adr)) + + +#define SCSI_ABORT_SNOOZE 0 +#define SCSI_ABORT_SUCCESS 1 +#define SCSI_ABORT_PENDING 2 +#define SCSI_ABORT_BUSY 3 +#define SCSI_ABORT_NOT_RUNNING 4 +#define SCSI_ABORT_ERROR 5 + +#define SCSI_RESET_SNOOZE 0 +#define SCSI_RESET_PUNT 1 +#define SCSI_RESET_SUCCESS 2 +#define SCSI_RESET_PENDING 3 +#define SCSI_RESET_WAKEUP 4 +#define SCSI_RESET_NOT_RUNNING 5 +#define SCSI_RESET_ERROR 6 + +#define SCSI_RESET_SYNCHRONOUS 0x01 +#define SCSI_RESET_ASYNCHRONOUS 0x02 +#define SCSI_RESET_SUGGEST_BUS_RESET 0x04 +#define SCSI_RESET_SUGGEST_HOST_RESET 0x08 + +#define SCSI_RESET_BUS_RESET 0x100 +#define SCSI_RESET_HOST_RESET 0x200 +#define SCSI_RESET_ACTION 0xff diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/inia100.c linux/drivers/scsi/inia100.c --- v2.2.2/linux/drivers/scsi/inia100.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/inia100.c Wed Feb 24 16:27:54 1999 @@ -0,0 +1,952 @@ +/************************************************************************** + * Initio A100 device driver for Linux. + * + * Copyright (c) 1994-1998 Initio Corporation + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, 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; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * -------------------------------------------------------------------------- + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + ************************************************************************** + * + * module: inia100.c + * DESCRIPTION: + * This is the Linux low-level SCSI driver for Initio INIA100 SCSI host + * adapters + * 09/24/98 hl - v1.02 initial production release. + * 12/19/98 bv - v1.02a Use spinlocks for 2.1.95 and up. + **************************************************************************/ + +#define CVT_LINUX_VERSION(V,P,S) (V * 65536 + P * 256 + S) + +#ifndef LINUX_VERSION_CODE +#include +#endif + +#ifdef MODULE +#include +#endif + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE <= CVT_LINUX_VERSION(2,1,92) +#include +#endif +#include +#include +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,23) +#include +#endif +#include +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) +#include +#endif +#include "sd.h" +#include "scsi.h" +#include "hosts.h" +#include "inia100.h" +#include +#include + + +#else + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "../block/blk.h" +#include "scsi.h" +#include "sd.h" +#include "hosts.h" +#include +#include "inia100.h" +#endif + +#ifdef MODULE +Scsi_Host_Template driver_template = INIA100; +#include "scsi_module.c" +#endif + +#define ORC_RDWORD(x,y) (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) )) + +char *inia100_Copyright = "Copyright (C) 1998-99"; +char *inia100_InitioName = "by Initio Corporation"; +char *inia100_ProductName = "INI-A100U2W"; +char *inia100_Version = "v1.02a"; + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) +struct proc_dir_entry proc_scsi_inia100 = +{ + PROC_SCSI_INIA100, 7, "INIA100", + S_IFDIR | S_IRUGO | S_IXUGO, 2, + 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; +#endif + +/* set by inia100_setup according to the command line */ +static int setup_called = 0; +static int orc_num_ch = MAX_SUPPORTED_ADAPTERS; /* Maximum 4 adapters */ + +/* ---- INTERNAL VARIABLES ---- */ +#define NUMBER(arr) (sizeof(arr) / sizeof(arr[0])) +static char *setup_str = (char *) NULL; + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) +static void inia100_intr0(int irq, void *dev_id, struct pt_regs *); +static void inia100_intr1(int irq, void *dev_id, struct pt_regs *); +static void inia100_intr2(int irq, void *dev_id, struct pt_regs *); +static void inia100_intr3(int irq, void *dev_id, struct pt_regs *); +static void inia100_intr4(int irq, void *dev_id, struct pt_regs *); +static void inia100_intr5(int irq, void *dev_id, struct pt_regs *); +static void inia100_intr6(int irq, void *dev_id, struct pt_regs *); +static void inia100_intr7(int irq, void *dev_id, struct pt_regs *); +#else +static void inia100_intr0(int irq, struct pt_regs *); +static void inia100_intr1(int irq, struct pt_regs *); +static void inia100_intr2(int irq, struct pt_regs *); +static void inia100_intr3(int irq, struct pt_regs *); +static void inia100_intr4(int irq, struct pt_regs *); +static void inia100_intr5(int irq, struct pt_regs *); +static void inia100_intr6(int irq, struct pt_regs *); +static void inia100_intr7(int irq, struct pt_regs *); +#endif + +static void inia100_panic(char *msg); +void inia100SCBPost(BYTE * pHcb, BYTE * pScb); + +/* ---- EXTERNAL VARIABLES ---- */ +extern int Addinia100_into_Adapter_table(WORD, WORD, BYTE, BYTE, BYTE); +extern void init_inia100Adapter_table(void); +extern ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp); +extern void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp); +extern void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp); +extern void orc_interrupt(ORC_HCS * hcsp); +extern int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned int ResetFlags); +extern int orc_reset_scsi_bus(ORC_HCS * pHCB); +extern int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb); +extern int orc_abort_srb(ORC_HCS * hcsp, ULONG SCpnt); +extern void get_orcPCIConfig(ORC_HCS * pCurHcb, int ch_idx); +extern int init_orchid(ORC_HCS * hcsp); + +extern int orc_num_scb; +extern ORC_HCS orc_hcs[]; + +/***************************************************************************** + Function name : inia100AppendSRBToQueue + Description : This function will push current request into save list + Input : pSRB - Pointer to SCSI request block. + pHCB - Pointer to host adapter structure + Output : None. + Return : None. +*****************************************************************************/ +static void inia100AppendSRBToQueue(ORC_HCS * pHCB, Scsi_Cmnd * pSRB) +{ + ULONG flags; + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) + spin_lock_irqsave(&(pHCB->pSRB_lock), flags); +#else + save_flags(flags); + cli(); +#endif + + pSRB->next = NULL; /* Pointer to next */ + if (pHCB->pSRB_head == NULL) + pHCB->pSRB_head = pSRB; + else + pHCB->pSRB_tail->next = pSRB; /* Pointer to next */ + pHCB->pSRB_tail = pSRB; +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) + spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags); +#else + restore_flags(flags); +#endif + return; +} + +/***************************************************************************** + Function name : inia100PopSRBFromQueue + Description : This function will pop current request from save list + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +static Scsi_Cmnd *inia100PopSRBFromQueue(ORC_HCS * pHCB) +{ + Scsi_Cmnd *pSRB; + ULONG flags; +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) + spin_lock_irqsave(&(pHCB->pSRB_lock), flags); +#else + save_flags(flags); + cli(); +#endif + + if ((pSRB = (Scsi_Cmnd *) pHCB->pSRB_head) != NULL) { + pHCB->pSRB_head = pHCB->pSRB_head->next; + pSRB->next = NULL; + } +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) + spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags); +#else + restore_flags(flags); +#endif + return (pSRB); +} + +/***************************************************************************** + Function name : inia100_setup + Description : + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +void inia100_setup(char *str, int *ints) +{ + if (setup_called) + inia100_panic("inia100: inia100_setup called twice.\n"); + + setup_called = ints[0]; + setup_str = str; +} + +/***************************************************************************** + Function name : orc_ReturnNumberOfAdapters + Description : This function will scan PCI bus to get all Orchid card + Input : None. + Output : None. + Return : SUCCESSFUL - Successful scan + ohterwise - No drives founded +*****************************************************************************/ +int orc_ReturnNumberOfAdapters(void) +{ + unsigned int i, iAdapters; + + iAdapters = 0; + /* + * PCI-bus probe. + */ + if (pcibios_present()) { + struct { + unsigned short vendor_id; + unsigned short device_id; + } const inia100_pci_devices[] = + { + {ORC_VENDOR_ID, I920_DEVICE_ID}, + {ORC_VENDOR_ID, ORC_DEVICE_ID} + }; + + unsigned int dRegValue; + unsigned short command; + WORD wBIOS, wBASE; + BYTE bPCIBusNum, bInterrupt, bPCIDeviceNum; + +#ifdef MMAPIO + unsigned long page_offset, base; +#endif + +#if LINUX_VERSION_CODE > CVT_LINUX_VERSION(2,1,92) + struct pci_dev *pdev = NULL; +#else + int index; + unsigned char pci_bus, pci_devfn; +#endif + + bPCIBusNum = 0; + bPCIDeviceNum = 0; + init_inia100Adapter_table(); + for (i = 0; i < NUMBER(inia100_pci_devices); i++) { +#if LINUX_VERSION_CODE > CVT_LINUX_VERSION(2,1,92) + pdev = NULL; + while ((pdev = pci_find_device(inia100_pci_devices[i].vendor_id, + inia100_pci_devices[i].device_id, + pdev))) +#else + index = 0; + while (!(pcibios_find_device(inia100_pci_devices[i].vendor_id, + inia100_pci_devices[i].device_id, + index++, &pci_bus, &pci_devfn))) +#endif + { + if (iAdapters >= MAX_SUPPORTED_ADAPTERS) + break; /* Never greater than maximum */ + + if (i == 0) { + /* + printk("inia100: The RAID controller is not supported by\n"); + printk("inia100: this driver, we are ignoring it.\n"); + */ + } else { + /* + * Read sundry information from PCI BIOS. + */ +#if LINUX_VERSION_CODE > CVT_LINUX_VERSION(2,1,92) + bPCIBusNum = pdev->bus->number; + bPCIDeviceNum = pdev->devfn; + dRegValue = pdev->base_address[0]; + if (dRegValue == -1) { /* Check return code */ + printk("\n\rinia100: orchid read configuration error.\n"); + return (0); /* Read configuration space error */ + } + /* <02> read from base address + 0x50 offset to get the wBIOS balue. */ + wBASE = (WORD) dRegValue; + + /* Now read the interrupt line */ + dRegValue = pdev->irq; + bInterrupt = dRegValue & 0xFF; /* Assign interrupt line */ + pci_read_config_word(pdev, PCI_COMMAND, &command); + pci_write_config_word(pdev, PCI_COMMAND, + command | PCI_COMMAND_MASTER | PCI_COMMAND_IO); + +#else + bPCIBusNum = pci_bus; + bPCIDeviceNum = pci_devfn; + pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_0, + &dRegValue); + if (dRegValue == -1) { /* Check return code */ + printk("\n\rinia100: Orchid read configuration error.\n"); + return (0); /* Read configuration space error */ + } + /* <02> read from base address + 0x50 offset to get the wBIOS balue. */ + wBASE = (WORD) dRegValue; + + /* Now read the interrupt line */ + pcibios_read_config_dword(pci_bus, pci_devfn, PCI_INTERRUPT_LINE, + &dRegValue); + bInterrupt = dRegValue & 0xFF; /* Assign interrupt line */ + pcibios_read_config_word(pci_bus, pci_devfn, PCI_COMMAND, &command); + pcibios_write_config_word(pci_bus, pci_devfn, PCI_COMMAND, + command | PCI_COMMAND_MASTER | PCI_COMMAND_IO); +#endif + wBASE &= PCI_BASE_ADDRESS_IO_MASK; + wBIOS = ORC_RDWORD(wBASE, 0x50); + +#ifdef MMAPIO + base = wBASE & PAGE_MASK; + page_offset = wBASE - base; + + /* + * replace the next line with this one if you are using 2.1.x: + * temp_p->maddr = ioremap(base, page_offset + 256); + */ +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,0) + wBASE = ioremap(base, page_offset + 256); +#else + wBASE = (WORD) vremap(base, page_offset + 256); +#endif + if (wBASE) { + wBASE += page_offset; + } +#endif + + if (Addinia100_into_Adapter_table(wBIOS, wBASE, bInterrupt, bPCIBusNum, + bPCIDeviceNum) == SUCCESSFUL) + iAdapters++; + } + } /* while(pdev=....) */ + } /* for PCI_DEVICES */ + } /* PCI BIOS present */ + return (iAdapters); +} + +/***************************************************************************** + Function name : inia100_detect + Description : + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +int inia100_detect(Scsi_Host_Template * tpnt) +{ + ORC_HCS *pHCB; + struct Scsi_Host *hreg; + U32 sz; + U32 i; /* 01/14/98 */ + int ok = 0, iAdapters; + ULONG dBiosAdr; + BYTE *pbBiosAdr; + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) + tpnt->proc_dir = &proc_scsi_inia100; +#endif + if (setup_called) { + /* Setup by inia100_setup */ + printk("inia100: processing commandline: "); + } + /* Get total number of adapters in the motherboard */ + iAdapters = orc_ReturnNumberOfAdapters(); + + /* printk("inia100: Total Initio Adapters = %d\n", iAdapters); */ + if (iAdapters == 0) /* If no orc founded, return */ + return (0); + + orc_num_ch = (iAdapters > orc_num_ch) ? orc_num_ch : iAdapters; + orc_num_scb = ORC_MAXQUEUE; + + /* clear the memory needed for HCS */ + i = orc_num_ch * sizeof(ORC_HCS); + memset((unsigned char *) &orc_hcs[0], 0, i); /* Initialize orc_hcs 0 */ + +#if 0 + printk("orc_num_scb= %x orc_num_ch= %x hcsize= %x scbsize= %x escbsize= %x\n", + orc_num_scb, orc_num_ch, sizeof(ORC_HCS), sizeof(ORC_SCB), sizeof(ESCB)); +#endif + + for (i = 0, pHCB = &orc_hcs[0]; /* Get pointer for control block */ + i < orc_num_ch; + i++, pHCB++) { + + pHCB->pSRB_head = NULL; /* Initial SRB save queue */ + pHCB->pSRB_tail = NULL; /* Initial SRB save queue */ +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) + pHCB->pSRB_lock = SPIN_LOCK_UNLOCKED; /* SRB save queue lock */ +#endif + /* Get total memory needed for SCB */ + sz = orc_num_scb * sizeof(ORC_SCB); + if ((pHCB->HCS_virScbArray = (PVOID) kmalloc(sz, GFP_ATOMIC | GFP_DMA)) == NULL) { + printk("inia100: SCB memory allocation error\n"); + return (0); + } + memset((unsigned char *) pHCB->HCS_virScbArray, 0, sz); + pHCB->HCS_physScbArray = (U32) VIRT_TO_BUS(pHCB->HCS_virScbArray); + + /* Get total memory needed for ESCB */ + sz = orc_num_scb * sizeof(ESCB); + if ((pHCB->HCS_virEscbArray = (PVOID) kmalloc(sz, GFP_ATOMIC | GFP_DMA)) == NULL) { + printk("inia100: ESCB memory allocation error\n"); + return (0); + } + memset((unsigned char *) pHCB->HCS_virEscbArray, 0, sz); + pHCB->HCS_physEscbArray = (U32) VIRT_TO_BUS(pHCB->HCS_virEscbArray); + + request_region(pHCB->HCS_Base, 0x100, "inia100"); /* Register */ + get_orcPCIConfig(pHCB, i); + + dBiosAdr = pHCB->HCS_BIOS; + dBiosAdr = (dBiosAdr << 4); + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) + pbBiosAdr = phys_to_virt(dBiosAdr); +#endif + + if (init_orchid(pHCB)) { /* Initial orchid chip */ + printk("inia100: initial orchid fail!!\n"); + return (0); + } + hreg = scsi_register(tpnt, sizeof(ORC_HCS)); + if (hreg == NULL) { + printk("Invalid scsi_register pointer.\n"); + } + hreg->io_port = pHCB->HCS_Base; + hreg->n_io_port = 0xff; + hreg->can_queue = orc_num_scb; /* 03/05/98 */ + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) + hreg->unique_id = pHCB->HCS_Base; + hreg->max_id = pHCB->HCS_MaxTar; +#endif + + hreg->max_lun = 32; /* 10/21/97 */ +/* + hreg->max_lun = 8; + hreg->max_channel = 1; + */ + hreg->irq = pHCB->HCS_Intr; + hreg->this_id = pHCB->HCS_SCSI_ID; /* Assign HCS index */ + hreg->base = (UCHAR *) pHCB; + +#if 1 + hreg->sg_tablesize = TOTAL_SG_ENTRY; /* Maximun support is 32 */ +#else + hreg->sg_tablesize = SG_NONE; /* No SG */ +#endif + + /* Initial orc chip */ + switch (i) { +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) + case 0: + ok = request_irq(pHCB->HCS_Intr, inia100_intr0, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + break; + case 1: + ok = request_irq(pHCB->HCS_Intr, inia100_intr1, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + break; + case 2: + ok = request_irq(pHCB->HCS_Intr, inia100_intr2, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + break; + case 3: + ok = request_irq(pHCB->HCS_Intr, inia100_intr3, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + break; + case 4: + ok = request_irq(pHCB->HCS_Intr, inia100_intr4, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + break; + case 5: + ok = request_irq(pHCB->HCS_Intr, inia100_intr5, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + break; + case 6: + ok = request_irq(pHCB->HCS_Intr, inia100_intr6, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + break; + case 7: + ok = request_irq(pHCB->HCS_Intr, inia100_intr7, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + break; + default: + inia100_panic("inia100: Too many host adapters\n"); + break; + } + + if (ok < 0) { + if (ok == -EINVAL) { + printk("inia100: bad IRQ %d.\n", pHCB->HCS_Intr); + printk(" Contact author.\n"); + } else { + if (ok == -EBUSY) + printk("inia100: IRQ %d already in use. Configure another.\n", pHCB->HCS_Intr); + else { + printk("\ninia100: Unexpected error code on requesting IRQ %d.\n", + pHCB->HCS_Intr); + printk(" Contact author.\n"); + } + } + inia100_panic("inia100: driver needs an IRQ.\n"); + } +#endif + } + + tpnt->this_id = -1; + tpnt->can_queue = 1; + return 1; +} + +/***************************************************************************** + Function name : inia100BuildSCB + Description : + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +static void inia100BuildSCB(ORC_HCS * pHCB, ORC_SCB * pSCB, Scsi_Cmnd * SCpnt) +{ /* Create corresponding SCB */ + struct scatterlist *pSrbSG; + ORC_SG *pSG; /* Pointer to SG list */ + int i; + U32 TotalLen; + ESCB *pEScb; + + pEScb = pSCB->SCB_EScb; + pEScb->SCB_Srb = SCpnt; + pSG = NULL; + + pSCB->SCB_Opcode = ORC_EXECSCSI; + pSCB->SCB_Flags = SCF_NO_DCHK; /* Clear done bit */ + pSCB->SCB_Target = SCpnt->target; + pSCB->SCB_Lun = SCpnt->lun; + pSCB->SCB_Reserved0 = 0; + pSCB->SCB_Reserved1 = 0; + pSCB->SCB_SGLen = 0; + + if ((pSCB->SCB_XferLen = (U32) SCpnt->request_bufflen)) { + pSG = (ORC_SG *) & pEScb->ESCB_SGList[0]; + if (SCpnt->use_sg) { + TotalLen = 0; + pSCB->SCB_SGLen = (U32) (SCpnt->use_sg * 8); + pSrbSG = (struct scatterlist *) SCpnt->request_buffer; + for (i = 0; i < SCpnt->use_sg; i++, pSG++, pSrbSG++) { +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) + pSG->SG_Ptr = (U32) (VIRT_TO_BUS(pSrbSG->address)); +#else + pSG->SG_Ptr = (U32) pSrbSG->address; +#endif + pSG->SG_Len = (U32) pSrbSG->length; + TotalLen += (U32) pSrbSG->length; + } + } else { /* Non SG */ + pSCB->SCB_SGLen = 0x8; +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) + pSG->SG_Ptr = (U32) (VIRT_TO_BUS(SCpnt->request_buffer)); +#else + pSG->SG_PTR = (U32) SCpnt->request_buffer; +#endif + pSG->SG_Len = (U32) SCpnt->request_bufflen; + } + } + pSCB->SCB_SGPAddr = (U32) pSCB->SCB_SensePAddr; + pSCB->SCB_HaStat = 0; + pSCB->SCB_TaStat = 0; + pSCB->SCB_Link = 0xFF; + pSCB->SCB_SenseLen = SENSE_SIZE; + pSCB->SCB_CDBLen = SCpnt->cmd_len; + if (pSCB->SCB_CDBLen >= IMAX_CDB) { + printk("max cdb length= %x\b", SCpnt->cmd_len); + pSCB->SCB_CDBLen = IMAX_CDB; + } + pSCB->SCB_Ident = SCpnt->lun | DISC_ALLOW; + if (SCpnt->device->tagged_supported) { /* Tag Support */ + pSCB->SCB_TagMsg = SIMPLE_QUEUE_TAG; /* Do simple tag only */ + } else { + pSCB->SCB_TagMsg = 0; /* No tag support */ + } + memcpy(&pSCB->SCB_CDB[0], &SCpnt->cmnd, pSCB->SCB_CDBLen); + return; +} + +/***************************************************************************** + Function name : inia100_queue + Description : Queue a command and setup interrupts for a free bus. + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +int inia100_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) +{ + register ORC_SCB *pSCB; + ORC_HCS *pHCB; /* Point to Host adapter control block */ + + if (SCpnt->lun > 16) { + SCpnt->result = (DID_TIME_OUT << 16); + done(SCpnt); /* Notify system DONE */ + return (0); + } + pHCB = (ORC_HCS *) SCpnt->host->base; + SCpnt->scsi_done = done; + /* Get free SCSI control block */ + if ((pSCB = orc_alloc_scb(pHCB)) == NULL) { + inia100AppendSRBToQueue(pHCB, SCpnt); /* Buffer this request */ + /* printk("inia100_entry: can't allocate SCB\n"); */ + return (0); + } + inia100BuildSCB(pHCB, pSCB, SCpnt); + orc_exec_scb(pHCB, pSCB); /* Start execute SCB */ + + return (0); +} + +/***************************************************************************** + Function name : inia100_command + Description : We only support command in interrupt-driven fashion + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +int inia100_command(Scsi_Cmnd * SCpnt) +{ + printk("inia100: interrupt driven driver; use inia100_queue()\n"); + return -1; +} + +/***************************************************************************** + Function name : inia100_abort + Description : Abort a queued command. + (commands that are on the bus can't be aborted easily) + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +int inia100_abort(Scsi_Cmnd * SCpnt) +{ + ORC_HCS *hcsp; + + hcsp = (ORC_HCS *) SCpnt->host->base; + return orc_abort_srb(hcsp, (ULONG) SCpnt); +} + +/***************************************************************************** + Function name : inia100_reset + Description : Reset registers, reset a hanging bus and + kill active and disconnected commands for target w/o soft reset + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +int inia100_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags) +{ /* I need Host Control Block Information */ + ORC_HCS *pHCB; + pHCB = (ORC_HCS *) SCpnt->host->base; + + if (reset_flags & (SCSI_RESET_SUGGEST_BUS_RESET | SCSI_RESET_SUGGEST_HOST_RESET)) + return orc_reset_scsi_bus(pHCB); + else + return orc_device_reset(pHCB, (ULONG) SCpnt, SCpnt->target, reset_flags); + +} + +/***************************************************************************** + Function name : inia100SCBPost + Description : This is callback routine be called when orc finish one + SCSI command. + Input : pHCB - Pointer to host adapter control block. + pSCB - Pointer to SCSI control block. + Output : None. + Return : None. +*****************************************************************************/ +void inia100SCBPost(BYTE * pHcb, BYTE * pScb) +{ + Scsi_Cmnd *pSRB; /* Pointer to SCSI request block */ + ORC_HCS *pHCB; + ORC_SCB *pSCB; + ESCB *pEScb; + + pHCB = (ORC_HCS *) pHcb; + pSCB = (ORC_SCB *) pScb; + pEScb = pSCB->SCB_EScb; + if ((pSRB = (Scsi_Cmnd *) pEScb->SCB_Srb) == 0) { + printk("inia100SCBPost: SRB pointer is empty\n"); + orc_release_scb(pHCB, pSCB); /* Release SCB for current channel */ + return; + } + pEScb->SCB_Srb = NULL; + + switch (pSCB->SCB_HaStat) { + case 0x0: + case 0xa: /* Linked command complete without error and linked normally */ + case 0xb: /* Linked command complete without error interrupt generated */ + pSCB->SCB_HaStat = 0; + break; + + case 0x11: /* Selection time out-The initiator selection or target + reselection was not complete within the SCSI Time out period */ + pSCB->SCB_HaStat = DID_TIME_OUT; + break; + + case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus + phase sequence was requested by the target. The host adapter + will generate a SCSI Reset Condition, notifying the host with + a SCRD interrupt */ + pSCB->SCB_HaStat = DID_RESET; + break; + + case 0x1a: /* SCB Aborted. 07/21/98 */ + pSCB->SCB_HaStat = DID_ABORT; + break; + + case 0x12: /* Data overrun/underrun-The target attempted to transfer more data + than was allocated by the Data Length field or the sum of the + Scatter / Gather Data Length fields. */ + case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */ + case 0x16: /* Invalid CCB Operation Code-The first byte of the CCB was invalid. */ + + default: + printk("inia100: %x %x\n", pSCB->SCB_HaStat, pSCB->SCB_TaStat); + pSCB->SCB_HaStat = DID_ERROR; /* Couldn't find any better */ + break; + } + + if (pSCB->SCB_TaStat == 2) { /* Check condition */ + memcpy((unsigned char *) &pSRB->sense_buffer[0], + (unsigned char *) &pEScb->ESCB_SGList[0], SENSE_SIZE); + } + pSRB->result = pSCB->SCB_TaStat | (pSCB->SCB_HaStat << 16); + pSRB->scsi_done(pSRB); /* Notify system DONE */ + + /* Find the next pending SRB */ + if ((pSRB = inia100PopSRBFromQueue(pHCB)) != NULL) { /* Assume resend will success */ + /* Reuse old SCB */ + inia100BuildSCB(pHCB, pSCB, pSRB); /* Create corresponding SCB */ + orc_exec_scb(pHCB, pSCB); /* Start execute SCB */ + } else { /* No Pending SRB */ + orc_release_scb(pHCB, pSCB); /* Release SCB for current channel */ + } + return; +} + +/***************************************************************************** + Function name : inia100_biosparam + Description : Return the "logical geometry" + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) +int inia100_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array) +#else +int inia100_biosparam(Scsi_Disk * disk, int dev, int *info_array) +#endif +{ + ORC_HCS *pHcb; /* Point to Host adapter control block */ + ORC_TCS *pTcb; + + pHcb = (ORC_HCS *) disk->device->host->base; + pTcb = &pHcb->HCS_Tcs[disk->device->id]; + + if (pTcb->TCS_DrvHead) { + info_array[0] = pTcb->TCS_DrvHead; + info_array[1] = pTcb->TCS_DrvSector; + info_array[2] = disk->capacity / pTcb->TCS_DrvHead / pTcb->TCS_DrvSector; + } else { + if (pTcb->TCS_DrvFlags & TCF_DRV_255_63) { + info_array[0] = 255; + info_array[1] = 63; + info_array[2] = disk->capacity / 255 / 63; + } else { + info_array[0] = 64; + info_array[1] = 32; + info_array[2] = disk->capacity >> 11; + } + } + return 0; +} + + +static void subIntr(ORC_HCS * pHCB, int irqno) +{ +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) + unsigned long flags; + + spin_lock_irqsave(&io_request_lock, flags); +#endif + + if (pHCB->HCS_Intr != irqno) { +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) + spin_unlock_irqrestore(&io_request_lock, flags); +#endif + return; + } + orc_interrupt(pHCB); + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) + spin_unlock_irqrestore(&io_request_lock, flags); +#endif +} + +/* + * Interrupts handler (main routine of the driver) + */ +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) +static void inia100_intr0(int irqno, void *dev_id, struct pt_regs *regs) +#else +static void inia100_intr0(int irqno, struct pt_regs *regs) +#endif +{ + subIntr(&orc_hcs[0], irqno); +} + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) +static void inia100_intr1(int irqno, void *dev_id, struct pt_regs *regs) +#else +static void inia100_intr1(int irqno, struct pt_regs *regs) +#endif +{ + subIntr(&orc_hcs[1], irqno); +} + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) +static void inia100_intr2(int irqno, void *dev_id, struct pt_regs *regs) +#else +static void inia100_intr2(int irqno, struct pt_regs *regs) +#endif +{ + subIntr(&orc_hcs[2], irqno); +} + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) +static void inia100_intr3(int irqno, void *dev_id, struct pt_regs *regs) +#else +static void inia100_intr3(int irqno, struct pt_regs *regs) +#endif +{ + subIntr(&orc_hcs[3], irqno); +} + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) +static void inia100_intr4(int irqno, void *dev_id, struct pt_regs *regs) +#else +static void inia100_intr4(int irqno, struct pt_regs *regs) +#endif +{ + subIntr(&orc_hcs[4], irqno); +} + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) +static void inia100_intr5(int irqno, void *dev_id, struct pt_regs *regs) +#else +static void inia100_intr5(int irqno, struct pt_regs *regs) +#endif +{ + subIntr(&orc_hcs[5], irqno); +} + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) +static void inia100_intr6(int irqno, void *dev_id, struct pt_regs *regs) +#else +static void inia100_intr6(int irqno, struct pt_regs *regs) +#endif +{ + subIntr(&orc_hcs[6], irqno); +} + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) +static void inia100_intr7(int irqno, void *dev_id, struct pt_regs *regs) +#else +static void inia100_intr7(int irqno, struct pt_regs *regs) +#endif +{ + subIntr(&orc_hcs[7], irqno); +} + +/* + * Dump the current driver status and panic... + */ +static void inia100_panic(char *msg) +{ + printk("\ninia100_panic: %s\n", msg); + panic("inia100 panic"); +} + +/*#include "inia100scsi.c" */ diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/inia100.h linux/drivers/scsi/inia100.h --- v2.2.2/linux/drivers/scsi/inia100.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/inia100.h Mon Mar 8 15:52:43 1999 @@ -0,0 +1,503 @@ +/************************************************************************** + * Initio A100 device driver for Linux. + * + * Copyright (c) 1994-1998 Initio Corporation + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, 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; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * -------------------------------------------------------------------------- + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + ************************************************************************** + * + * Module: inia100.h + * Description: INI-A100U2W LINUX device driver header + * Revision History: + * 06/18/98 HL, Initial production Version 1.02 + * 12/19/98 bv, Use spinlocks for 2.1.95 and up + ****************************************************************************/ + +#ifndef CVT_LINUX_VERSION +#define CVT_LINUX_VERSION(V,P,S) (((V) * 65536) + ((P) * 256) + (S)) +#endif + +#ifndef LINUX_VERSION_CODE +#include +#endif + +#include "sd.h" + +extern int inia100_detect(Scsi_Host_Template *); +extern int inia100_command(Scsi_Cmnd *); +extern int inia100_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); +extern int inia100_abort(Scsi_Cmnd *); +extern int inia100_reset(Scsi_Cmnd *, unsigned int); + +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1, 3, 0) +extern int inia100_biosparam(Scsi_Disk *, kdev_t, int *); /*for linux v2.0 */ +extern struct proc_dir_entry proc_scsi_inia100; +#else +extern int inia100_biosparam(Disk *, int, int *); /*for linux v1.13 */ +#endif + +#define inia100_REVID "Initio INI-A100U2W SCSI device driver; Revision: 1.02a" + +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(1, 3, 0) +#define INIA100 { \ + NULL, \ + NULL, \ + inia100_REVID, \ + inia100_detect, \ + NULL, \ + NULL, \ + inia100_command, \ + inia100_queue, \ + inia100_abort, \ + inia100_reset, \ + NULL, \ + inia100_biosparam, \ + 1, \ +7, \ +SG_ALL, \ +1, \ +0, \ +0, \ +ENABLE_CLUSTERING \ +} + +#else + +#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2, 1, 75) +#define INIA100 { \ + NULL, \ + NULL, \ + &proc_scsi_inia100, \ + NULL, \ + inia100_REVID, \ + inia100_detect, \ + NULL, \ + NULL, \ + inia100_command, \ + inia100_queue, \ + inia100_abort, \ + inia100_reset, \ + NULL, \ + inia100_biosparam, \ + 1, \ + 7, \ + 0, \ + 1, \ + 0, \ + 0, \ + ENABLE_CLUSTERING \ +} +#else /* Version >= 2.1.75 */ +#define INIA100 { \ + next: NULL, \ + module: NULL, \ + proc_dir: &proc_scsi_inia100, \ + proc_info: NULL, \ + name: inia100_REVID, \ + detect: inia100_detect, \ + release: NULL, \ + info: NULL, \ + command: inia100_command, \ + queuecommand: inia100_queue, \ + eh_strategy_handler: NULL, \ + eh_abort_handler: NULL, \ + eh_device_reset_handler: NULL, \ + eh_bus_reset_handler: NULL, \ + eh_host_reset_handler: NULL, \ + abort: inia100_abort, \ + reset: inia100_reset, \ + slave_attach: NULL, \ + bios_param: inia100_biosparam, \ + can_queue: 1, \ + this_id: 1, \ + sg_tablesize: SG_ALL, \ + cmd_per_lun: 1, \ + present: 0, \ + unchecked_isa_dma: 0, \ + use_clustering: ENABLE_CLUSTERING, \ + use_new_eh_code: 0 \ +} +#endif +#endif + +#define VIRT_TO_BUS(i) (unsigned int) virt_to_bus((void *)(i)) +#define ULONG unsigned long +#define PVOID void * +#define USHORT unsigned short +#define UCHAR unsigned char +#define BYTE unsigned char +#define WORD unsigned short +#define DWORD unsigned long +#define UBYTE unsigned char +#define UWORD unsigned short +#define UDWORD unsigned long +#ifdef ALPHA +#define U32 unsigned int +#else +#define U32 unsigned long +#endif + +#ifndef NULL +#define NULL 0 /* zero */ +#endif +#ifndef TRUE +#define TRUE (1) /* boolean true */ +#endif +#ifndef FALSE +#define FALSE (0) /* boolean false */ +#endif +#ifndef FAILURE +#define FAILURE (-1) +#endif +#if 1 +#define ORC_MAXQUEUE 245 +#else +#define ORC_MAXQUEUE 25 +#endif + +#define TOTAL_SG_ENTRY 32 +#define MAX_TARGETS 16 +#define IMAX_CDB 15 +#define SENSE_SIZE 14 +#define MAX_SUPPORTED_ADAPTERS 4 +#define SUCCESSFUL 0x00 + +#define I920_DEVICE_ID 0x0002 /* Initio's inic-950 product ID */ + +/************************************************************************/ +/* Scatter-Gather Element Structure */ +/************************************************************************/ +typedef struct ORC_SG_Struc { + U32 SG_Ptr; /* Data Pointer */ + U32 SG_Len; /* Data Length */ +} ORC_SG; + + +/* SCSI related definition */ +#define DISC_NOT_ALLOW 0x80 /* Disconnect is not allowed */ +#define DISC_ALLOW 0xC0 /* Disconnect is allowed */ + + +#define ORC_OFFSET_SCB 16 +#define ORC_MAX_SCBS 250 +#define MAX_CHANNELS 2 +#define MAX_ESCB_ELE 64 +#define TCF_DRV_255_63 0x0400 + +/********************************************************/ +/* Orchid Configuration Register Set */ +/********************************************************/ +#define ORC_PVID 0x00 /* Vendor ID */ +#define ORC_VENDOR_ID 0x1101 /* Orchid vendor ID */ +#define ORC_PDID 0x02 /* Device ID */ +#define ORC_DEVICE_ID 0x1060 /* Orchid device ID */ +#define ORC_COMMAND 0x04 /* Command */ +#define BUSMS 0x04 /* BUS MASTER Enable */ +#define IOSPA 0x01 /* IO Space Enable */ +#define ORC_STATUS 0x06 /* Status register */ +#define ORC_REVISION 0x08 /* Revision number */ +#define ORC_BASE 0x10 /* Base address */ +#define ORC_BIOS 0x50 /* Expansion ROM base address */ +#define ORC_INT_NUM 0x3C /* Interrupt line */ +#define ORC_INT_PIN 0x3D /* Interrupt pin */ + +/********************************************************/ +/* Orchid Host Command Set */ +/********************************************************/ +#define ORC_CMD_NOP 0x00 /* Host command - NOP */ +#define ORC_CMD_VERSION 0x01 /* Host command - Get F/W version */ +#define ORC_CMD_ECHO 0x02 /* Host command - ECHO */ +#define ORC_CMD_SET_NVM 0x03 /* Host command - Set NVRAM */ +#define ORC_CMD_GET_NVM 0x04 /* Host command - Get NVRAM */ +#define ORC_CMD_GET_BUS_STATUS 0x05 /* Host command - Get SCSI bus status */ +#define ORC_CMD_ABORT_SCB 0x06 /* Host command - Abort SCB */ +#define ORC_CMD_ISSUE_SCB 0x07 /* Host command - Issue SCB */ + +/********************************************************/ +/* Orchid Register Set */ +/********************************************************/ +#define ORC_GINTS 0xA0 /* Global Interrupt Status */ +#define QINT 0x04 /* Reply Queue Interrupt */ +#define ORC_GIMSK 0xA1 /* Global Interrupt MASK */ +#define MQINT 0x04 /* Mask Reply Queue Interrupt */ +#define ORC_GCFG 0xA2 /* Global Configure */ +#define EEPRG 0x01 /* Enable EEPROM programming */ +#define ORC_GSTAT 0xA3 /* Global status */ +#define WIDEBUS 0x10 /* Wide SCSI Devices connected */ +#define ORC_HDATA 0xA4 /* Host Data */ +#define ORC_HCTRL 0xA5 /* Host Control */ +#define SCSIRST 0x80 /* SCSI bus reset */ +#define HDO 0x40 /* Host data out */ +#define HOSTSTOP 0x02 /* Host stop RISC engine */ +#define DEVRST 0x01 /* Device reset */ +#define ORC_HSTUS 0xA6 /* Host Status */ +#define HDI 0x02 /* Host data in */ +#define RREADY 0x01 /* RISC engine is ready to receive */ +#define ORC_NVRAM 0xA7 /* Nvram port address */ +#define SE2CS 0x008 +#define SE2CLK 0x004 +#define SE2DO 0x002 +#define SE2DI 0x001 +#define ORC_PQUEUE 0xA8 /* Posting queue FIFO */ +#define ORC_PQCNT 0xA9 /* Posting queue FIFO Cnt */ +#define ORC_RQUEUE 0xAA /* Reply queue FIFO */ +#define ORC_RQUEUECNT 0xAB /* Reply queue FIFO Cnt */ +#define ORC_FWBASEADR 0xAC /* Firmware base address */ + +#define ORC_EBIOSADR0 0xB0 /* External Bios address */ +#define ORC_EBIOSADR1 0xB1 /* External Bios address */ +#define ORC_EBIOSADR2 0xB2 /* External Bios address */ +#define ORC_EBIOSDATA 0xB3 /* External Bios address */ + +#define ORC_SCBSIZE 0xB7 /* SCB size register */ +#define ORC_SCBBASE0 0xB8 /* SCB base address 0 */ +#define ORC_SCBBASE1 0xBC /* SCB base address 1 */ + +#define ORC_RISCCTL 0xE0 /* RISC Control */ +#define PRGMRST 0x002 +#define DOWNLOAD 0x001 +#define ORC_PRGMCTR0 0xE2 /* RISC program counter */ +#define ORC_PRGMCTR1 0xE3 /* RISC program counter */ +#define ORC_RISCRAM 0xEC /* RISC RAM data port 4 bytes */ + +typedef struct orc_extended_scb { /* Extended SCB */ + ORC_SG ESCB_SGList[TOTAL_SG_ENTRY]; /*0 Start of SG list */ + Scsi_Cmnd *SCB_Srb; /*50 SRB Pointer */ +} ESCB; + +/*********************************************************************** + SCSI Control Block +************************************************************************/ +typedef struct orc_scb { /* Scsi_Ctrl_Blk */ + UBYTE SCB_Opcode; /*00 SCB command code&residual */ + UBYTE SCB_Flags; /*01 SCB Flags */ + UBYTE SCB_Target; /*02 Target Id */ + UBYTE SCB_Lun; /*03 Lun */ + U32 SCB_Reserved0; /*04 Reserved for ORCHID must 0 */ + U32 SCB_XferLen; /*08 Data Transfer Length */ + U32 SCB_Reserved1; /*0C Reserved for ORCHID must 0 */ + U32 SCB_SGLen; /*10 SG list # * 8 */ + U32 SCB_SGPAddr; /*14 SG List Buf physical Addr */ + U32 SCB_SGPAddrHigh; /*18 SG Buffer high physical Addr */ + UBYTE SCB_HaStat; /*1C Host Status */ + UBYTE SCB_TaStat; /*1D Target Status */ + UBYTE SCB_Status; /*1E SCB status */ + UBYTE SCB_Link; /*1F Link pointer, default 0xFF */ + UBYTE SCB_SenseLen; /*20 Sense Allocation Length */ + UBYTE SCB_CDBLen; /*21 CDB Length */ + UBYTE SCB_Ident; /*22 Identify */ + UBYTE SCB_TagMsg; /*23 Tag Message */ + UBYTE SCB_CDB[IMAX_CDB]; /*24 SCSI CDBs */ + UBYTE SCB_ScbIdx; /*3C Index for this ORCSCB */ + U32 SCB_SensePAddr; /*34 Sense Buffer physical Addr */ + + ESCB *SCB_EScb; /*38 Extended SCB Pointer */ +#ifndef ALPHA + UBYTE SCB_Reserved2[4]; /*3E Reserved for Driver use */ +#endif +} ORC_SCB; + +/* Opcodes of ORCSCB_Opcode */ +#define ORC_EXECSCSI 0x00 /* SCSI initiator command with residual */ +#define ORC_BUSDEVRST 0x01 /* SCSI Bus Device Reset */ + +/* Status of ORCSCB_Status */ +#define SCB_COMPLETE 0x00 /* SCB request completed */ +#define SCB_POST 0x01 /* SCB is posted by the HOST */ + +/* Bit Definition for ORCSCB_Flags */ +#define SCF_DISINT 0x01 /* Disable HOST interrupt */ +#define SCF_DIR 0x18 /* Direction bits */ +#define SCF_NO_DCHK 0x00 /* Direction determined by SCSI */ +#define SCF_DIN 0x08 /* From Target to Initiator */ +#define SCF_DOUT 0x10 /* From Initiator to Target */ +#define SCF_NO_XF 0x18 /* No data transfer */ +#define SCF_POLL 0x40 + +/* Error Codes for ORCSCB_HaStat */ +#define HOST_SEL_TOUT 0x11 +#define HOST_DO_DU 0x12 +#define HOST_BUS_FREE 0x13 +#define HOST_BAD_PHAS 0x14 +#define HOST_INV_CMD 0x16 +#define HOST_SCSI_RST 0x1B +#define HOST_DEV_RST 0x1C + + +/* Error Codes for ORCSCB_TaStat */ +#define TARGET_CHK_COND 0x02 +#define TARGET_BUSY 0x08 +#define TARGET_TAG_FULL 0x28 + + +/* Queue tag msg: Simple_quque_tag, Head_of_queue_tag, Ordered_queue_tag */ +#define MSG_STAG 0x20 +#define MSG_HTAG 0x21 +#define MSG_OTAG 0x22 + +#define MSG_IGNOREWIDE 0x23 + +#define MSG_IDENT 0x80 +#define MSG_DISC 0x40 /* Disconnect allowed */ + + +/* SCSI MESSAGE */ +#define MSG_EXTEND 0x01 +#define MSG_SDP 0x02 +#define MSG_ABORT 0x06 +#define MSG_REJ 0x07 +#define MSG_NOP 0x08 +#define MSG_PARITY 0x09 +#define MSG_DEVRST 0x0C +#define MSG_STAG 0x20 + +/*********************************************************************** + Target Device Control Structure +**********************************************************************/ + +typedef struct ORC_Tar_Ctrl_Struc { + UBYTE TCS_DrvDASD; /* 6 */ + UBYTE TCS_DrvSCSI; /* 7 */ + UBYTE TCS_DrvHead; /* 8 */ + UWORD TCS_DrvFlags; /* 4 */ + UBYTE TCS_DrvSector; /* 7 */ +} ORC_TCS, *PORC_TCS; + +/* Bit Definition for TCF_DrvFlags */ +#define TCS_DF_NODASD_SUPT 0x20 /* Suppress OS/2 DASD Mgr support */ +#define TCS_DF_NOSCSI_SUPT 0x40 /* Suppress OS/2 SCSI Mgr support */ + + +/*********************************************************************** + Host Adapter Control Structure +************************************************************************/ +typedef struct ORC_Ha_Ctrl_Struc { + USHORT HCS_Base; /* 00 */ + UBYTE HCS_Index; /* 02 */ + UBYTE HCS_Intr; /* 04 */ + UBYTE HCS_SCSI_ID; /* 06 H/A SCSI ID */ + UBYTE HCS_BIOS; /* 07 BIOS configuration */ + + UBYTE HCS_Flags; /* 0B */ + UBYTE HCS_HAConfig1; /* 1B SCSI0MAXTags */ + UBYTE HCS_MaxTar; /* 1B SCSI0MAXTags */ + + USHORT HCS_Units; /* Number of units this adapter */ + USHORT HCS_AFlags; /* Adapter info. defined flags */ + ULONG HCS_Timeout; /* Adapter timeout value */ + PVOID HCS_virScbArray; /* 28 Virtual Pointer to SCB array */ + U32 HCS_physScbArray; /* Scb Physical address */ + PVOID HCS_virEscbArray; /* Virtual pointer to ESCB Scatter list */ + U32 HCS_physEscbArray; /* scatter list Physical address */ + UBYTE TargetFlag[16]; /* 30 target configuration, TCF_EN_TAG */ + UBYTE MaximumTags[16]; /* 40 ORC_MAX_SCBS */ + UBYTE ActiveTags[16][16]; /* 50 */ + ORC_TCS HCS_Tcs[16]; /* 28 */ + U32 BitAllocFlag[MAX_CHANNELS][8]; /* Max STB is 256, So 256/32 */ +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) + spinlock_t BitAllocFlagLock; +#endif + Scsi_Cmnd *pSRB_head; + Scsi_Cmnd *pSRB_tail; +#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) + spinlock_t pSRB_lock; +#endif +} ORC_HCS; + +/* Bit Definition for HCS_Flags */ + +#define HCF_SCSI_RESET 0x01 /* SCSI BUS RESET */ +#define HCF_PARITY 0x02 /* parity card */ +#define HCF_LVDS 0x10 /* parity card */ + +/* Bit Definition for TargetFlag */ + +#define TCF_EN_255 0x08 +#define TCF_EN_TAG 0x10 +#define TCF_BUSY 0x20 +#define TCF_DISCONNECT 0x40 +#define TCF_SPIN_UP 0x80 + +/* Bit Definition for HCS_AFlags */ +#define HCS_AF_IGNORE 0x01 /* Adapter ignore */ +#define HCS_AF_DISABLE_RESET 0x10 /* Adapter disable reset */ +#define HCS_AF_DISABLE_ADPT 0x80 /* Adapter disable */ + + +/*---------------------------------------*/ +/* TimeOut for RESET to complete (30s) */ +/* */ +/* After a RESET the drive is checked */ +/* every 200ms. */ +/*---------------------------------------*/ +#define DELAYED_RESET_MAX (30*1000L) +#define DELAYED_RESET_INTERVAL 200L + +/*----------------------------------------------*/ +/* TimeOut for IRQ from last interrupt (5s) */ +/*----------------------------------------------*/ +#define IRQ_TIMEOUT_INTERVAL (5*1000L) + +/*----------------------------------------------*/ +/* Retry Delay interval (200ms) */ +/*----------------------------------------------*/ +#define DELAYED_RETRY_INTERVAL 200L + +#define INQUIRY_SIZE 36 +#define CAPACITY_SIZE 8 +#define DEFAULT_SENSE_LEN 14 + +#define DEVICE_NOT_FOUND 0x86 + +/*----------------------------------------------*/ +/* Definition for PCI device */ +/*----------------------------------------------*/ +#define MAX_PCI_DEVICES 21 +#define MAX_PCI_BUSES 8 diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/megaraid.c linux/drivers/scsi/megaraid.c --- v2.2.2/linux/drivers/scsi/megaraid.c Wed Jan 13 15:00:42 1999 +++ linux/drivers/scsi/megaraid.c Wed Feb 24 16:27:54 1999 @@ -1,24 +1,27 @@ /*=================================================================== * * Linux MegaRAID device driver - * + * * Copyright 1998 American Megatrends 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. + * 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.92 + * Version : 0.96 * * Description: Linux device driver for AMI MegaRAID controller * + * Supported controllers: MegaRAID 418, 428, 438, 466, 762 + * + * Maintainer: Jeff L Jones + * * History: * * Version 0.90: - * Works and has been tested with the MegaRAID 428 controller, and - * the MegaRAID 438 controller. Probably works with the 466 also, - * but not tested. + * Original source contributed by Dell; integrated it into the kernel and + * cleaned up some things. Added support for 438/466 controllers. * * Version 0.91: * Aligned mailbox area on 16-byte boundry. @@ -35,31 +38,51 @@ * Removed setting of SA_INTERRUPT flag when requesting Irq. * * Version 0.92ac: - * Small changes to the comments/formatting. Plus a couple of - * added notes. Returned to the authors. No actual code changes - * save printk levels. - * 8 Oct 98 Alan Cox + * Small changes to the comments/formatting. Plus a couple of + * added notes. Returned to the authors. No actual code changes + * save printk levels. + * 8 Oct 98 Alan Cox * * Merged with 2.1.131 source tree. - * 12 Dec 98 K. Baranowski + * 12 Dec 98 K. Baranowski + * + * Version 0.93: + * Added support for vendor specific ioctl commands (0x80+xxh) + * Changed some fields in MEGARAID struct to better values. + * Added signature check for Rp controllers under 2.0 kernels + * Changed busy-wait loop to be time-based + * Fixed SMP race condition in isr + * Added kfree (sgList) on release + * Added #include linux/version.h to megaraid.h for hosts.h + * Changed max_id to represent max logical drives instead of targets. + * + * Version 0.94: + * Got rid of some excess locking/unlocking + * Fixed slight memory corruption problem while memcpy'ing into mailbox + * Changed logical drives to be reported as luns rather than targets + * Changed max_id to 16 since it is now max targets/chan again. + * Improved ioctl interface for upcoming megamgr + * + * Version 0.95: + * Fixed problem of queueing multiple commands to adapter; + * still has some strange problems on some setups, so still + * defaults to single. To enable parallel commands change + * #define MULTI_IO in megaraid.h + * Changed kmalloc allocation to be done in beginning. + * Got rid of C++ style comments + * + * Version 0.96: + * 762 fully supported. * * BUGS: - * Tested with 2.1.90, but unfortunately there is a bug in pci.c which - * fails to detect our controller. Does work with 2.1.118--don't know - * which kernel in between it was fixed in. - * With SMP enabled under 2.1.118 with more than one processor, gets an - * error message "scsi_end_request: buffer-list destroyed" under heavy - * IO, but doesn't seem to affect operation, or data integrity. The - * message doesn't occur without SMP enabled, or with one proccessor with - * SMP enabled, or under any combination under 2.0 kernels. + * Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that + * fails to detect the controller as a pci device on the system. * *===================================================================*/ -#define QISR 1 #define CRLFSTR "\n" -#define MULTIQ 1 - +#include #include #ifdef MODULE @@ -68,10 +91,8 @@ #if LINUX_VERSION_CODE >= 0x20100 char kernel_version[] = UTS_RELEASE; -/* originally ported by Dell Corporation; updated, released, and maintained by - American Megatrends */ -MODULE_AUTHOR("American Megatrends Inc."); -MODULE_DESCRIPTION("AMI MegaRAID driver"); +MODULE_AUTHOR ("American Megatrends Inc."); +MODULE_DESCRIPTION ("AMI MegaRAID driver"); #endif #endif @@ -93,6 +114,7 @@ #include #include #include /* for kmalloc() */ +#include /* for CONFIG_PCI */ #if LINUX_VERSION_CODE < 0x20100 #include #else @@ -112,14 +134,18 @@ * * #Defines * - *================================================================*/ + *================================================================ + */ #if LINUX_VERSION_CODE < 0x020100 #define ioremap vremap #define iounmap vfree /* simulate spin locks */ -typedef struct {volatile char lock;} spinlock_t; +typedef struct { + volatile char lock; +} spinlock_t; + #define spin_lock_init(x) { (x)->lock = 0;} #define spin_lock_irqsave(x,flags) { while ((x)->lock) barrier();\ (x)->lock=1; save_flags(flags);\ @@ -143,7 +169,15 @@ (*node) = obj; \ (*node)->##next = NULL; \ spin_unlock_irqrestore(&mega_lock,cpuflag);\ -}; +} + +/* a non-locking version (if we already have the lock) */ +#define ENQUEUE_NL(obj,type,list,next) \ +{ type **node; \ + for(node=&(list); *node; node=(type **)&(*node)->##next); \ + (*node) = obj; \ + (*node)->##next = NULL; \ +} #define DEQUEUE(obj,type,list,next) \ { long cpuflag; \ @@ -154,125 +188,124 @@ spin_unlock_irqrestore(&mega_lock,cpuflag);\ }; -u_long RDINDOOR(mega_host_config *megaCfg) +u_long RDINDOOR (mega_host_config * megaCfg) { - return readl(megaCfg->base + 0x20); + return readl (megaCfg->base + 0x20); } -void WRINDOOR(mega_host_config *megaCfg, u_long value) +void WRINDOOR (mega_host_config * megaCfg, u_long value) { - writel(value,megaCfg->base+0x20); + writel (value, megaCfg->base + 0x20); } -u_long RDOUTDOOR(mega_host_config *megaCfg) +u_long RDOUTDOOR (mega_host_config * megaCfg) { - return readl(megaCfg->base+0x2C); + return readl (megaCfg->base + 0x2C); } -void WROUTDOOR(mega_host_config *megaCfg, u_long value) +void WROUTDOOR (mega_host_config * megaCfg, u_long value) { - writel(value,megaCfg->base+0x2C); + writel (value, megaCfg->base + 0x2C); } /*================================================================ * * Function prototypes * - *================================================================*/ -static int MegaIssueCmd(mega_host_config *megaCfg, - u_char *mboxData, - mega_scb *scb, + *================================================================ + */ +static int MegaIssueCmd (mega_host_config * megaCfg, + u_char * mboxData, + mega_scb * scb, int intr); -static int build_sglist(mega_host_config *megaCfg, mega_scb *scb, - u_long *buffer, u_long *length); +static int build_sglist (mega_host_config * megaCfg, mega_scb * scb, + u_long * buffer, u_long * length); -static void mega_runque(void *); -static void mega_rundoneq(void); -static void mega_cmd_done(mega_host_config *,mega_scb *, int); +static void mega_runque (void *); +static void mega_rundoneq (void); +static void mega_cmd_done (mega_host_config *, mega_scb *, int); +static mega_scb *mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt); +static inline void freeSgList(mega_host_config *megaCfg); /* set SERDEBUG to 1 to enable serial debugging */ #define SERDEBUG 0 #if SERDEBUG -static void ser_init(void); -static void ser_puts(char *str); -static void ser_putc(char c); -static int ser_printk(const char *fmt, ...); +static void ser_init (void); +static void ser_puts (char *str); +static void ser_putc (char c); +static int ser_printk (const char *fmt,...); #endif /*================================================================ * * Global variables * - *================================================================*/ -static int numCtlrs = 0; -static mega_host_config *megaCtlrs[4] = { 0 }; - -/* Change this to 0 if you want to see the raw drives */ -static int use_raid = 1; + *================================================================ + */ +static int numCtlrs = 0; +static mega_host_config *megaCtlrs[12] = {0}; /* Queue of pending/completed SCBs */ -static mega_scb *qPending = NULL; +static mega_scb *qPending = NULL; static Scsi_Cmnd *qCompleted = NULL; volatile static spinlock_t mega_lock; -static struct tq_struct runq = {0,0,mega_runque,NULL}; +static struct tq_struct runq = {0, 0, mega_runque, NULL}; -struct proc_dir_entry proc_scsi_megaraid = { +struct proc_dir_entry proc_scsi_megaraid = +{ PROC_SCSI_MEGARAID, 8, "megaraid", S_IFDIR | S_IRUGO | S_IXUGO, 2 }; #if SERDEBUG -static char strbuf[MAX_SERBUF+1]; +static char strbuf[MAX_SERBUF + 1]; -static void ser_init() +static void ser_init () { - unsigned port=COM_BASE; + unsigned port = COM_BASE; - outb(0x80,port+3); - outb(0,port+1); - /* 9600 Baud, if 19200: outb(6,port) */ - outb(12, port); - outb(3,port+3); - outb(0,port+1); + outb (0x80, port + 3); + outb (0, port + 1); + /* 9600 Baud, if 19200: outb(6,port) */ + outb (12, port); + outb (3, port + 3); + outb (0, port + 1); } -static void ser_puts(char *str) +static void ser_puts (char *str) { - char *ptr; + char *ptr; - ser_init(); - for (ptr=str;*ptr;++ptr) - ser_putc(*ptr); + ser_init (); + for (ptr = str; *ptr; ++ptr) + ser_putc (*ptr); } -static void ser_putc(char c) +static void ser_putc (char c) { - unsigned port=COM_BASE; + unsigned port = COM_BASE; - while ((inb(port+5) & 0x20)==0); - outb(c,port); - if (c==0x0a) - { - while ((inb(port+5) & 0x20)==0); - outb(0x0d,port); - } + while ((inb (port + 5) & 0x20) == 0); + outb (c, port); + if (c == 0x0a) { + while ((inb (port + 5) & 0x20) == 0); + outb (0x0d, port); + } } -static int ser_printk(const char *fmt, ...) +static int ser_printk (const char *fmt,...) { - va_list args; - int i; - long flags; + va_list args; + int i; + long flags; - spin_lock_irqsave(mega_lock,flags); - va_start(args,fmt); - i = vsprintf(strbuf,fmt,args); - ser_puts(strbuf); - va_end(args); - spin_unlock_irqrestore(&mega_lock,flags); + va_start (args, fmt); + i = vsprintf (strbuf, fmt, args); + ser_puts (strbuf); + va_end (args); - return i; + return i; } #define TRACE(a) { ser_printk a;} @@ -281,14 +314,14 @@ #define TRACE(A) #endif -void callDone(Scsi_Cmnd *SCpnt) +void callDone (Scsi_Cmnd * SCpnt) { if (SCpnt->result) { - TRACE(("*** %.08lx %.02x <%d.%d.%d> = %x\n", SCpnt->serial_number, - SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, SCpnt->lun, - SCpnt->result)); + TRACE (("*** %.08lx %.02x <%d.%d.%d> = %x\n", SCpnt->serial_number, + SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, SCpnt->lun, + SCpnt->result)); } - SCpnt->scsi_done(SCpnt); + SCpnt->scsi_done (SCpnt); } /*------------------------------------------------------------------------- @@ -299,96 +332,95 @@ /*================================================ * Initialize SCB structures - *================================================*/ -static void initSCB(mega_host_config *megaCfg) + *================================================ + */ +static int initSCB (mega_host_config * megaCfg) { int idx; - for(idx=0; idxmax_cmds; idx++) { - megaCfg->scbList[idx].idx = -1; - megaCfg->scbList[idx].flag = 0; - megaCfg->scbList[idx].sgList = NULL; - megaCfg->scbList[idx].SCpnt = NULL; + for (idx = 0; idx < megaCfg->max_cmds; idx++) { + megaCfg->scbList[idx].idx = -1; + megaCfg->scbList[idx].flag = 0; + megaCfg->scbList[idx].sgList = kmalloc(sizeof(mega_sglist) * MAX_SGLIST, + GFP_ATOMIC | GFP_DMA); + if (megaCfg->scbList[idx].sgList == NULL) { + printk(KERN_WARNING "Can't allocate sglist for id %d\n",idx); + freeSgList(megaCfg); + return -1; + } + megaCfg->scbList[idx].SCpnt = NULL; } + return 0; } /*=========================== * Allocate a SCB structure - *===========================*/ -static mega_scb *allocateSCB(mega_host_config *megaCfg,Scsi_Cmnd *SCpnt) + *=========================== + */ +static mega_scb * allocateSCB (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt) { - int idx; - long flags; + int idx; + long flags; - spin_lock_irqsave(&mega_lock,flags); - for(idx=0; idxmax_cmds; idx++) { + spin_lock_irqsave (&mega_lock, flags); + for (idx = 0; idx < megaCfg->max_cmds; idx++) { if (megaCfg->scbList[idx].idx < 0) { - /* Set Index and SCB pointer */ - megaCfg->scbList[idx].flag = 0; - megaCfg->scbList[idx].idx = idx; + /* Set Index and SCB pointer */ + megaCfg->scbList[idx].idx = idx; + spin_unlock_irqrestore (&mega_lock, flags); + megaCfg->scbList[idx].flag = 0; megaCfg->scbList[idx].SCpnt = SCpnt; - megaCfg->scbList[idx].next = NULL; - spin_unlock_irqrestore(&mega_lock,flags); - - if (megaCfg->scbList[idx].sgList == NULL) { - megaCfg->scbList[idx].sgList = - kmalloc(sizeof(mega_sglist)*MAX_SGLIST,GFP_ATOMIC|GFP_DMA); - } + megaCfg->scbList[idx].next = NULL; return &megaCfg->scbList[idx]; } } - spin_unlock_irqrestore(&mega_lock,flags); + spin_unlock_irqrestore (&mega_lock, flags); + + printk (KERN_WARNING "Megaraid: Could not allocate free SCB!!!\n"); - printk(KERN_WARNING "Megaraid: Could not allocate free SCB!!!\n"); - return NULL; } /*======================= * Free a SCB structure - *=======================*/ -static void freeSCB(mega_scb *scb) + *======================= + */ +static void freeSCB (mega_scb * scb) { - long flags; - - spin_lock_irqsave(&mega_lock,flags); - scb->flag = 0; - scb->idx = -1; - scb->next = NULL; + scb->flag = 0; + scb->next = NULL; scb->SCpnt = NULL; - spin_unlock_irqrestore(&mega_lock,flags); + scb->idx = -1; } /* Run through the list of completed requests */ -static void mega_rundoneq() +static void mega_rundoneq () { mega_host_config *megaCfg; - Scsi_Cmnd *SCpnt; - long islogical; + Scsi_Cmnd *SCpnt; + char islogical; + + while (1) { + DEQUEUE (SCpnt, Scsi_Cmnd, qCompleted, host_scribble); + if (SCpnt == NULL) + return; + + megaCfg = (mega_host_config *) SCpnt->host->hostdata; - while(1) { - DEQUEUE(SCpnt, Scsi_Cmnd, qCompleted, host_scribble); - if (SCpnt == NULL) return; - - megaCfg = (mega_host_config *)SCpnt->host->hostdata; - - /* Check if we're allowing access to RAID drives or physical - * if use_raid == 1 and this wasn't a disk on the max channel or - * if use_raid == 0 and this was a disk on the max channel - * then fail. - */ - islogical = (SCpnt->channel == megaCfg->host->max_channel) ? 1 : 0; + islogical = (SCpnt->channel == megaCfg->host->max_channel && + SCpnt->target == 0); if (SCpnt->cmnd[0] == INQUIRY && - ((((u_char*)SCpnt->request_buffer)[0] & 0x1F) == TYPE_DISK) && - (islogical != use_raid)) { - SCpnt->result = 0xF0; + ((((u_char *) SCpnt->request_buffer)[0] & 0x1F) == TYPE_DISK) && + !islogical) { + SCpnt->result = 0xF0; } /* Convert result to error */ - switch(SCpnt->result) { - case 0x00: case 0x02: + switch (SCpnt->result) { + case 0x00: + case 0x02: SCpnt->result |= (DID_OK << 16); break; case 0x8: @@ -400,16 +432,16 @@ } /* Callback */ - callDone(SCpnt); + callDone (SCpnt); } } /* Add command to the list of completed requests */ -static void mega_cmd_done(mega_host_config *megaCfg,mega_scb *pScb, int status) +static void mega_cmd_done (mega_host_config * megaCfg, mega_scb * pScb, int status) { pScb->SCpnt->result = status; - ENQUEUE(pScb->SCpnt, Scsi_Cmnd, qCompleted, host_scribble); - freeSCB(pScb); + ENQUEUE (pScb->SCpnt, Scsi_Cmnd, qCompleted, host_scribble); + freeSCB (pScb); } /*---------------------------------------------------- @@ -417,42 +449,45 @@ * * Run as a scheduled task *----------------------------------------------------*/ -static void mega_runque(void *dummy) +static void mega_runque (void *dummy) { mega_host_config *megaCfg; - mega_scb *pScb; - long flags; + mega_scb *pScb; + long flags; /* Take care of any completed requests */ - mega_rundoneq(); + mega_rundoneq (); - DEQUEUE(pScb,mega_scb,qPending,next); + DEQUEUE (pScb, mega_scb, qPending, next); if (pScb) { - megaCfg = (mega_host_config *)pScb->SCpnt->host->hostdata; + if (pScb->SCpnt) { + TRACE(("NULL SCpnt for idx %d!\n",pScb->idx)); + } + megaCfg = (mega_host_config *) pScb->SCpnt->host->hostdata; - if (megaCfg->mbox->busy || megaCfg->flag & (IN_ISR|PENDING)) { - TRACE(("%.08lx %.02x <%d.%d.%d> intr%d busy%d isr%d pending%d\n", - pScb->SCpnt->serial_number, - pScb->SCpnt->cmnd[0], - pScb->SCpnt->channel, - pScb->SCpnt->target, - pScb->SCpnt->lun, - intr_count, - megaCfg->mbox->busy, - (megaCfg->flag & IN_ISR) ? 1 : 0, - (megaCfg->flag & PENDING) ? 1 : 0)); + if (megaCfg->mbox->busy || megaCfg->flag & (IN_ISR | PENDING)) { + TRACE (("%.08lx %.02x <%d.%d.%d> busy%d isr%d pending%d\n", + pScb->SCpnt->serial_number, + pScb->SCpnt->cmnd[0], + pScb->SCpnt->channel, + pScb->SCpnt->target, + pScb->SCpnt->lun, + megaCfg->mbox->busy, + (megaCfg->flag & IN_ISR) ? 1 : 0, + (megaCfg->flag & PENDING) ? 1 : 0)); } - if (MegaIssueCmd(megaCfg, pScb->mboxData, pScb, 1)) { + if (MegaIssueCmd (megaCfg, pScb->mboxData, pScb, 1)) { /* We're BUSY... come back later */ - spin_lock_irqsave(&mega_lock,flags); + spin_lock_irqsave (&mega_lock, flags); pScb->next = qPending; - qPending = pScb; - spin_unlock_irqrestore(&mega_lock,flags); + qPending = pScb; + spin_unlock_irqrestore (&mega_lock, flags); - if (!(megaCfg->flag & PENDING)) { /* If PENDING, irq will schedule task */ - queue_task(&runq, &tq_scheduler); + if (!(megaCfg->flag & PENDING)) { + /* If PENDING, irq will schedule task */ + queue_task (&runq, &tq_scheduler); } } } @@ -466,17 +501,22 @@ * If NULL is returned, the scsi_done function MUST have been called * *-------------------------------------------------------------------*/ -static mega_scb *mega_build_cmd(mega_host_config *megaCfg, Scsi_Cmnd *SCpnt) +static mega_scb * mega_build_cmd (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt) { - mega_scb *pScb; - mega_mailbox *mbox; + mega_scb *pScb; + mega_mailbox *mbox; mega_passthru *pthru; - long seg; + long seg; + char islogical; + + if (SCpnt->cmnd[0] & 0x80) /* ioctl from megamgr */ + return mega_ioctl (megaCfg, SCpnt); - /* We don't support multi-luns */ - if (SCpnt->lun != 0) { + islogical = (SCpnt->channel == megaCfg->host->max_channel && SCpnt->target == 0); + + if (!islogical && SCpnt->lun != 0) { SCpnt->result = (DID_BAD_TARGET << 16); - callDone(SCpnt); + callDone (SCpnt); return NULL; } @@ -485,45 +525,46 @@ * Logical drive commands * *-----------------------------------------------------*/ - if (SCpnt->channel == megaCfg->host->max_channel) { - switch(SCpnt->cmnd[0]) { + if (islogical) { + switch (SCpnt->cmnd[0]) { case TEST_UNIT_READY: - memset(SCpnt->request_buffer, 0, SCpnt->request_bufflen); + memset (SCpnt->request_buffer, 0, SCpnt->request_bufflen); SCpnt->result = (DID_OK << 16); - callDone(SCpnt); + callDone (SCpnt); return NULL; case MODE_SENSE: - memset(SCpnt->request_buffer, 0, SCpnt->cmnd[4]); + memset (SCpnt->request_buffer, 0, SCpnt->cmnd[4]); SCpnt->result = (DID_OK << 16); - callDone(SCpnt); + callDone (SCpnt); return NULL; case READ_CAPACITY: case INQUIRY: /* Allocate a SCB and initialize passthru */ - if ((pScb = allocateSCB(megaCfg,SCpnt)) == NULL) { + if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) { SCpnt->result = (DID_ERROR << 16); - callDone(SCpnt); + callDone (SCpnt); return NULL; } pthru = &pScb->pthru; - mbox = (mega_mailbox *)&pScb->mboxData; + mbox = (mega_mailbox *) & pScb->mboxData; - memset(mbox, 0, sizeof(pScb->mboxData)); - memset(pthru, 0, sizeof(mega_passthru)); - pthru->timeout = 0; - pthru->ars = 0; - pthru->islogical = 1; - pthru->logdrv = SCpnt->target; - pthru->cdblen = SCpnt->cmd_len; - pthru->dataxferaddr = virt_to_bus(SCpnt->request_buffer); - pthru->dataxferlen = SCpnt->request_bufflen; - memcpy(pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len); + memset (mbox, 0, sizeof (pScb->mboxData)); + memset (pthru, 0, sizeof (mega_passthru)); + pthru->timeout = 0; + pthru->ars = 1; + pthru->reqsenselen = 14; + pthru->islogical = 1; + pthru->logdrv = SCpnt->lun; + pthru->cdblen = SCpnt->cmd_len; + pthru->dataxferaddr = virt_to_bus (SCpnt->request_buffer); + pthru->dataxferlen = SCpnt->request_bufflen; + memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len); /* Initialize mailbox area */ - mbox->cmd = MEGA_MBOXCMD_PASSTHRU; - mbox->xferaddr = virt_to_bus(pthru); + mbox->cmd = MEGA_MBOXCMD_PASSTHRU; + mbox->xferaddr = virt_to_bus (pthru); return pScb; @@ -532,51 +573,51 @@ case READ_10: case WRITE_10: /* Allocate a SCB and initialize mailbox */ - if ((pScb = allocateSCB(megaCfg,SCpnt)) == NULL) { + if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) { SCpnt->result = (DID_ERROR << 16); - callDone(SCpnt); + callDone (SCpnt); return NULL; } - mbox = (mega_mailbox *)&pScb->mboxData; + mbox = (mega_mailbox *) & pScb->mboxData; - memset(mbox, 0, sizeof(pScb->mboxData)); - mbox->logdrv = SCpnt->target; - mbox->cmd = (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == READ_10) ? + memset (mbox, 0, sizeof (pScb->mboxData)); + mbox->logdrv = SCpnt->lun; + mbox->cmd = (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == READ_10) ? MEGA_MBOXCMD_LREAD : MEGA_MBOXCMD_LWRITE; - + /* 6-byte */ if (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == WRITE_6) { - mbox->numsectors = - (u_long)SCpnt->cmnd[4]; - mbox->lba = - ((u_long)SCpnt->cmnd[1] << 16) | - ((u_long)SCpnt->cmnd[2] << 8) | - (u_long)SCpnt->cmnd[3]; + mbox->numsectors = + (u_long) SCpnt->cmnd[4]; + mbox->lba = + ((u_long) SCpnt->cmnd[1] << 16) | + ((u_long) SCpnt->cmnd[2] << 8) | + (u_long) SCpnt->cmnd[3]; mbox->lba &= 0x1FFFFF; } - + /* 10-byte */ if (*SCpnt->cmnd == READ_10 || *SCpnt->cmnd == WRITE_10) { - mbox->numsectors = - (u_long)SCpnt->cmnd[8] | - ((u_long)SCpnt->cmnd[7] << 8); + mbox->numsectors = + (u_long) SCpnt->cmnd[8] | + ((u_long) SCpnt->cmnd[7] << 8); mbox->lba = - ((u_long)SCpnt->cmnd[2] << 24) | - ((u_long)SCpnt->cmnd[3] << 16) | - ((u_long)SCpnt->cmnd[4] << 8) | - (u_long)SCpnt->cmnd[5]; + ((u_long) SCpnt->cmnd[2] << 24) | + ((u_long) SCpnt->cmnd[3] << 16) | + ((u_long) SCpnt->cmnd[4] << 8) | + (u_long) SCpnt->cmnd[5]; } - + /* Calculate Scatter-Gather info */ - mbox->numsgelements = build_sglist(megaCfg, pScb, - (u_long*)&mbox->xferaddr, - (u_long*)&seg); + mbox->numsgelements = build_sglist (megaCfg, pScb, + (u_long *) & mbox->xferaddr, + (u_long *) & seg); return pScb; - + default: SCpnt->result = (DID_BAD_TARGET << 16); - callDone(SCpnt); + callDone (SCpnt); return NULL; } } @@ -587,31 +628,32 @@ *-----------------------------------------------------*/ else { /* Allocate a SCB and initialize passthru */ - if ((pScb = allocateSCB(megaCfg,SCpnt)) == NULL) { + if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) { SCpnt->result = (DID_ERROR << 16); - callDone(SCpnt); + callDone (SCpnt); return NULL; } pthru = &pScb->pthru; - mbox = (mega_mailbox *)pScb->mboxData; - - memset(mbox, 0, sizeof(pScb->mboxData)); - memset(pthru, 0, sizeof(mega_passthru)); - pthru->timeout = 0; - pthru->ars = 0; + mbox = (mega_mailbox *) pScb->mboxData; + + memset (mbox, 0, sizeof (pScb->mboxData)); + memset (pthru, 0, sizeof (mega_passthru)); + pthru->timeout = 0; + pthru->ars = 1; + pthru->reqsenselen = 14; pthru->islogical = 0; - pthru->channel = SCpnt->channel; - pthru->target = SCpnt->target; - pthru->cdblen = SCpnt->cmd_len; - memcpy(pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len); - - pthru->numsgelements = build_sglist(megaCfg, pScb, - (u_long *)&pthru->dataxferaddr, - (u_long *)&pthru->dataxferlen); - + pthru->channel = SCpnt->channel; + pthru->target = SCpnt->target; + pthru->cdblen = SCpnt->cmd_len; + memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len); + + pthru->numsgelements = build_sglist (megaCfg, pScb, + (u_long *) & pthru->dataxferaddr, + (u_long *) & pthru->dataxferlen); + /* Initialize mailbox */ - mbox->cmd = MEGA_MBOXCMD_PASSTHRU; - mbox->xferaddr = virt_to_bus(pthru); + mbox->cmd = MEGA_MBOXCMD_PASSTHRU; + mbox->xferaddr = virt_to_bus (pthru); return pScb; } @@ -619,88 +661,183 @@ } /*-------------------------------------------------------------------- + * build RAID commands for controller, passed down through ioctl() + *--------------------------------------------------------------------*/ +static mega_scb * mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt) +{ + mega_scb *pScb; + mega_ioctl_mbox *mbox; + mega_mailbox *mailbox; + mega_passthru *pthru; + long seg; + unsigned char *data = (unsigned char *)SCpnt->request_buffer; + int i; + + if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) { + SCpnt->result = (DID_ERROR << 16); + callDone (SCpnt); + return NULL; + } + +#if 0 + printk("\nBUF: "); + for (i=0;i<18;i++) { + printk(" %x",data[i]); + } + printk("......\n"); +#endif + + mbox = (mega_ioctl_mbox *) & pScb->mboxData; + mailbox = (mega_mailbox *) & pScb->mboxData; + memset (mailbox, 0, sizeof (pScb->mboxData)); + + if (data[0] == 0x03) { /* passthrough command */ + unsigned char cdblen = data[2]; + + pthru = &pScb->pthru; + memset (pthru, 0, sizeof (mega_passthru)); + pthru->islogical = (data[cdblen+3] & 0x80) ? 1:0; + pthru->timeout = data[cdblen+3] & 0x07; + pthru->reqsenselen = 14; + pthru->ars = (data[cdblen+3] & 0x08) ? 1:0; + pthru->logdrv = data[cdblen+4]; + pthru->channel = data[cdblen+5]; + pthru->target = data[cdblen+6]; + pthru->cdblen = cdblen; + memcpy (pthru->cdb, &data[3], cdblen); + + mailbox->cmd = MEGA_MBOXCMD_PASSTHRU; + mailbox->xferaddr = virt_to_bus (pthru); + + + pthru->numsgelements = build_sglist (megaCfg, pScb, + (u_long *) & pthru->dataxferaddr, + (u_long *) & pthru->dataxferlen); + + for (i=0;i<(SCpnt->request_bufflen-cdblen-7);i++) { + data[i] = data[i+cdblen+7]; + } + + return pScb; + } + /* else normal (nonpassthru) command */ + + mbox->cmd = data[0]; + mbox->channel = data[1]; + mbox->param = data[2]; + mbox->pad[0] = data[3]; + mbox->logdrv = data[4]; + + mbox->numsgelements = build_sglist (megaCfg, pScb, + (u_long *) & mbox->xferaddr, + (u_long *) & seg); + + for (i=0;i<(SCpnt->request_bufflen-6);i++) { + data[i] = data[i+6]; + } + + return (pScb); +} + + +/*-------------------------------------------------------------------- * Interrupt service routine *--------------------------------------------------------------------*/ -static void megaraid_isr(int irq, void *devp, struct pt_regs *regs) +static void megaraid_isr (int irq, void *devp, struct pt_regs *regs) { - mega_host_config *megaCfg; - u_char byte, idx, sIdx; - u_long dword; - mega_mailbox *mbox; - mega_scb *pScb; - long flags; - int qCnt, qStatus; + mega_host_config *megaCfg; + u_char byte, idx, sIdx; + u_long dword; + mega_mailbox *mbox; + mega_scb *pScb; + long flags; + int qCnt, qStatus; - megaCfg = (mega_host_config *)devp; - mbox = (mega_mailbox *)megaCfg->mbox; + megaCfg = (mega_host_config *) devp; + mbox = (mega_mailbox *) megaCfg->mbox; if (megaCfg->host->irq == irq) { - spin_lock_irqsave(&mega_lock,flags); + +#if LINUX_VERSION_CODE >= 0x20100 + spin_lock_irqsave (&io_request_lock, flags); +#endif + + spin_lock_irqsave (&mega_lock, flags); if (megaCfg->flag & IN_ISR) { - TRACE(("ISR called reentrantly!!\n")); + TRACE (("ISR called reentrantly!!\n")); } megaCfg->flag |= IN_ISR; /* Check if a valid interrupt is pending */ if (megaCfg->flag & BOARD_QUARTZ) { - dword = RDOUTDOOR(megaCfg); - if (dword != 0x10001234) { - /* Spurious interrupt */ - megaCfg->flag &= ~IN_ISR; - spin_unlock_irqrestore(&mega_lock,flags); - return; - } - WROUTDOOR(megaCfg,dword); - } else { - byte = READ_PORT(megaCfg->host->io_port, INTR_PORT); - if ((byte & VALID_INTR_BYTE) == 0) { - /* Spurious interrupt */ - megaCfg->flag &= ~IN_ISR; - spin_unlock_irqrestore(&mega_lock,flags); - return; - } - WRITE_PORT(megaCfg->host->io_port, INTR_PORT, byte); + dword = RDOUTDOOR (megaCfg); + if (dword != 0x10001234) { + /* Spurious interrupt */ + megaCfg->flag &= ~IN_ISR; + spin_unlock_irqrestore (&mega_lock, flags); +#if LINUX_VERSION_CODE >= 0x20100 + spin_unlock_irqrestore (&io_request_lock, flags); +#endif + return; + } + WROUTDOOR (megaCfg, dword); } - - qCnt = mbox->numstatus; + else { + byte = READ_PORT (megaCfg->host->io_port, INTR_PORT); + if ((byte & VALID_INTR_BYTE) == 0) { + /* Spurious interrupt */ + megaCfg->flag &= ~IN_ISR; + spin_unlock_irqrestore (&mega_lock, flags); +#if LINUX_VERSION_CODE >= 0x20100 + spin_unlock_irqrestore (&io_request_lock, flags); +#endif + return; + } + WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte); + } + + qCnt = mbox->numstatus; qStatus = mbox->status; - if (qCnt > 1) {TRACE(("ISR: Received %d status\n", qCnt)) - printk(KERN_DEBUG "Got numstatus = %d\n",qCnt); + if (qCnt > 1) { + TRACE (("ISR: Received %d status\n", qCnt)) + printk (KERN_DEBUG "Got numstatus = %d\n", qCnt); } - - for(idx=0; idxcompleted[idx]; if (sIdx > 0) { - pScb = &megaCfg->scbList[sIdx-1]; - spin_unlock_irqrestore(&mega_lock,flags); /* locks within cmd_done */ - mega_cmd_done(megaCfg,&megaCfg->scbList[sIdx-1], qStatus); - spin_lock_irqsave(&mega_lock,flags); + pScb = &megaCfg->scbList[sIdx - 1]; + /* FVF: let's try to avoid un/locking for no good reason */ + pScb->SCpnt->result = qStatus; + ENQUEUE_NL (pScb->SCpnt, Scsi_Cmnd, qCompleted, host_scribble); + freeSCB (pScb); } } if (megaCfg->flag & BOARD_QUARTZ) { - WRINDOOR(megaCfg,virt_to_bus(megaCfg->mbox)|0x2); - while (RDINDOOR(megaCfg) & 0x02); - } else { - CLEAR_INTR(megaCfg->host->io_port); + WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2); + while (RDINDOOR (megaCfg) & 0x02); + } + else { + CLEAR_INTR (megaCfg->host->io_port); } megaCfg->flag &= ~IN_ISR; megaCfg->flag &= ~PENDING; - spin_unlock_irqrestore(&mega_lock,flags); + spin_unlock_irqrestore (&mega_lock, flags); + mega_runque (NULL); - spin_lock_irqsave(&io_request_lock, flags); - mega_runque(NULL); - spin_unlock_irqrestore(&io_request_lock,flags); +#if LINUX_VERSION_CODE >= 0x20100 + spin_unlock_irqrestore (&io_request_lock, flags); +#endif #if 0 /* Queue as a delayed ISR routine */ - queue_task_irq_off(&runq, &tq_immediate); - mark_bh(IMMEDIATE_BH); - spin_unlock_irqrestore(&mega_lock,flags); + queue_task_irq_off (&runq, &tq_immediate); + mark_bh (IMMEDIATE_BH); #endif } @@ -709,15 +846,17 @@ /*==================================================*/ /* Wait until the controller's mailbox is available */ /*==================================================*/ -static int busyWaitMbox(mega_host_config *megaCfg) +static int busyWaitMbox (mega_host_config * megaCfg) { - mega_mailbox *mbox = (mega_mailbox *)megaCfg->mbox; - long counter; + mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox; + long counter; - for(counter=0; counter<0xFFFFFF; counter++) { - if (!mbox->busy) return 0; + for (counter = 0; counter < 10000; counter++) { + udelay (100); + if (!mbox->busy) + return 0; } - return -1; + return -1; /* give up after 1 second */ } /*===================================================== @@ -728,92 +867,105 @@ * u_char *mboxData - Mailbox area, 16 bytes * mega_scb *pScb - SCB posting (or NULL if N/A) * int intr - if 1, interrupt, 0 is blocking - *=====================================================*/ -static int MegaIssueCmd(mega_host_config *megaCfg, - u_char *mboxData, - mega_scb *pScb, - int intr) -{ - mega_mailbox *mbox = (mega_mailbox *)megaCfg->mbox; - long flags; - u_char byte; - u_long cmdDone; - - mboxData[0x1] = (pScb ? pScb->idx+1 : 0x00); /* Set cmdid */ - mboxData[0xF] = 1; /* Set busy */ - - /* one bad report of problem when issuing a command while pending. - * Wasn't able to duplicate, but it doesn't really affect performance - * anyway, so don't allow command while PENDING - */ + *===================================================== + */ +static int MegaIssueCmd (mega_host_config * megaCfg, + u_char * mboxData, + mega_scb * pScb, + int intr) +{ + mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox; + long flags; + u_char byte; + u_long cmdDone; + + mboxData[0x1] = (pScb ? pScb->idx + 1 : 0x00); /* Set cmdid */ + mboxData[0xF] = 1; /* Set busy */ + + spin_lock_irqsave(&mega_lock,flags); + +#if !MULTI_IO if (megaCfg->flag & PENDING) { - return -1; + spin_unlock_irqrestore(&mega_lock,flags); + return -1; } +#endif /* Wait until mailbox is free */ - if (busyWaitMbox(megaCfg)) { + if (busyWaitMbox (megaCfg)) { if (pScb) { - TRACE(("Mailbox busy %.08lx <%d.%d.%d>\n", pScb->SCpnt->serial_number, - pScb->SCpnt->channel, pScb->SCpnt->target, pScb->SCpnt->lun)); + TRACE (("Mailbox busy %.08lx <%d.%d.%d>\n", pScb->SCpnt->serial_number, + pScb->SCpnt->channel, pScb->SCpnt->target, pScb->SCpnt->lun)); + } else { + TRACE(("pScb NULL in MegaIssueCmd!\n")); } + spin_unlock_irqrestore(&mega_lock,flags); return -1; } /* Copy mailbox data into host structure */ - spin_lock_irqsave(&mega_lock,flags); - memset(mbox, 0, sizeof(mega_mailbox)); - memcpy(mbox, mboxData, 16); - spin_unlock_irqrestore(&mega_lock,flags); + memset (mbox, 0, 16); + memcpy (mbox, mboxData, 16); /* Kick IO */ megaCfg->flag |= PENDING; if (intr) { /* Issue interrupt (non-blocking) command */ if (megaCfg->flag & BOARD_QUARTZ) { - mbox->mraid_poll = 0; - mbox->mraid_ack = 0; - WRINDOOR(megaCfg, virt_to_bus(megaCfg->mbox) | 0x1); - } else { - ENABLE_INTR(megaCfg->host->io_port); - ISSUE_COMMAND(megaCfg->host->io_port); + mbox->mraid_poll = 0; + mbox->mraid_ack = 0; + WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x1); } + else { + ENABLE_INTR (megaCfg->host->io_port); + ISSUE_COMMAND (megaCfg->host->io_port); + } + spin_unlock_irqrestore(&mega_lock,flags); } - else { /* Issue non-ISR (blocking) command */ + else { /* Issue non-ISR (blocking) command */ if (megaCfg->flag & BOARD_QUARTZ) { - mbox->mraid_poll = 0; - mbox->mraid_ack = 0; - WRINDOOR(megaCfg, virt_to_bus(megaCfg->mbox) | 0x1); + mbox->mraid_poll = 0; + mbox->mraid_ack = 0; + WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x1); - while((cmdDone=RDOUTDOOR(megaCfg)) != 0x10001234); - WROUTDOOR(megaCfg, cmdDone); + while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234); + WROUTDOOR (megaCfg, cmdDone); + spin_unlock_irqrestore(&mega_lock,flags); if (pScb) { - mega_cmd_done(megaCfg,pScb, mbox->status); - mega_rundoneq(); + mega_cmd_done (megaCfg, pScb, mbox->status); + mega_rundoneq (); } - WRINDOOR(megaCfg,virt_to_bus(megaCfg->mbox) | 0x2); - while(RDINDOOR(megaCfg) & 0x2); + WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2); + while (RDINDOOR (megaCfg) & 0x2); megaCfg->flag &= ~PENDING; + } else { - DISABLE_INTR(megaCfg->host->io_port); - ISSUE_COMMAND(megaCfg->host->io_port); - - while(!((byte=READ_PORT(megaCfg->host->io_port,INTR_PORT))&INTR_VALID)); - WRITE_PORT(megaCfg->host->io_port, INTR_PORT, byte); - - ENABLE_INTR(megaCfg->host->io_port); - CLEAR_INTR(megaCfg->host->io_port); - + DISABLE_INTR (megaCfg->host->io_port); + ISSUE_COMMAND (megaCfg->host->io_port); + + while (!((byte = READ_PORT (megaCfg->host->io_port, INTR_PORT)) & INTR_VALID)); + WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte); + + + ENABLE_INTR (megaCfg->host->io_port); + CLEAR_INTR (megaCfg->host->io_port); + megaCfg->flag &= ~PENDING; + spin_unlock_irqrestore(&mega_lock,flags); + if (pScb) { - mega_cmd_done(megaCfg,pScb, mbox->status); - mega_rundoneq(); + mega_cmd_done (megaCfg, pScb, mbox->status); + mega_rundoneq (); } - megaCfg->flag &= ~PENDING; + else { + TRACE (("Error: NULL pScb!\n")); + } + } } @@ -823,42 +975,42 @@ /*------------------------------------------------------------------- * Copies data to SGLIST *-------------------------------------------------------------------*/ -static int build_sglist(mega_host_config *megaCfg, mega_scb *scb, - u_long *buffer, u_long *length) +static int build_sglist (mega_host_config * megaCfg, mega_scb * scb, + u_long * buffer, u_long * length) { struct scatterlist *sgList; int idx; /* Scatter-gather not used */ if (scb->SCpnt->use_sg == 0) { - *buffer = virt_to_bus(scb->SCpnt->request_buffer); - *length = (u_long)scb->SCpnt->request_bufflen; + *buffer = virt_to_bus (scb->SCpnt->request_buffer); + *length = (u_long) scb->SCpnt->request_bufflen; return 0; } - sgList = (struct scatterlist *)scb->SCpnt->buffer; + sgList = (struct scatterlist *) scb->SCpnt->request_buffer; if (scb->SCpnt->use_sg == 1) { - *buffer = virt_to_bus(sgList[0].address); - *length = (u_long)sgList[0].length; + *buffer = virt_to_bus (sgList[0].address); + *length = (u_long) sgList[0].length; return 0; } /* Copy Scatter-Gather list info into controller structure */ - for(idx=0; idxSCpnt->use_sg; idx++) { - scb->sgList[idx].address = virt_to_bus(sgList[idx].address); - scb->sgList[idx].length = (u_long)sgList[idx].length; + for (idx = 0; idx < scb->SCpnt->use_sg; idx++) { + scb->sgList[idx].address = virt_to_bus (sgList[idx].address); + scb->sgList[idx].length = (u_long) sgList[idx].length; } - + /* Reset pointer and length fields */ - *buffer = virt_to_bus(scb->sgList); + *buffer = virt_to_bus (scb->sgList); *length = 0; /* Return count of SG requests */ return scb->SCpnt->use_sg; } - + /*-------------------------------------------------------------------- - * Initializes the address of the controller's mailbox register + * Initializes the adress of the controller's mailbox register * The mailbox register is used to issue commands to the card. * Format of the mailbox area: * 00 01 command @@ -873,25 +1025,25 @@ * 10 01 numstatus byte * 11 01 status byte *--------------------------------------------------------------------*/ -static int mega_register_mailbox(mega_host_config *megaCfg, u_long paddr) +static int mega_register_mailbox (mega_host_config * megaCfg, u_long paddr) { /* align on 16-byte boundry */ megaCfg->mbox = &megaCfg->mailbox; - megaCfg->mbox = (mega_mailbox *) ((((ulong)megaCfg->mbox) + 16)&0xfffffff0); - paddr = (paddr+16)&0xfffffff0; + megaCfg->mbox = (mega_mailbox *) ((((ulong) megaCfg->mbox) + 16) & 0xfffffff0); + paddr = (paddr + 16) & 0xfffffff0; /* Register mailbox area with the firmware */ if (megaCfg->flag & BOARD_QUARTZ) { } else { - WRITE_PORT(megaCfg->host->io_port, MBOX_PORT0, paddr & 0xFF); - WRITE_PORT(megaCfg->host->io_port, MBOX_PORT1, (paddr >> 8) & 0xFF); - WRITE_PORT(megaCfg->host->io_port, MBOX_PORT2, (paddr >> 16) & 0xFF); - WRITE_PORT(megaCfg->host->io_port, MBOX_PORT3, (paddr >> 24) & 0xFF); - WRITE_PORT(megaCfg->host->io_port, ENABLE_MBOX_REGION, ENABLE_MBOX_BYTE); - - CLEAR_INTR(megaCfg->host->io_port); - ENABLE_INTR(megaCfg->host->io_port); + WRITE_PORT (megaCfg->host->io_port, MBOX_PORT0, paddr & 0xFF); + WRITE_PORT (megaCfg->host->io_port, MBOX_PORT1, (paddr >> 8) & 0xFF); + WRITE_PORT (megaCfg->host->io_port, MBOX_PORT2, (paddr >> 16) & 0xFF); + WRITE_PORT (megaCfg->host->io_port, MBOX_PORT3, (paddr >> 24) & 0xFF); + WRITE_PORT (megaCfg->host->io_port, ENABLE_MBOX_REGION, ENABLE_MBOX_BYTE); + + CLEAR_INTR (megaCfg->host->io_port); + ENABLE_INTR (megaCfg->host->io_port); } return 0; } @@ -899,77 +1051,79 @@ /*------------------------------------------------------------------- * Issue an adapter info query to the controller *-------------------------------------------------------------------*/ -static int mega_i_query_adapter(mega_host_config *megaCfg) +static int mega_i_query_adapter (mega_host_config * megaCfg) { mega_RAIDINQ *adapterInfo; mega_mailbox *mbox; - u_char mboxData[16]; - u_long paddr; + u_char mboxData[16]; + u_long paddr; - spin_lock_init(&mega_lock); + spin_lock_init (&mega_lock); /* Initialize adapter inquiry */ - paddr = virt_to_bus(megaCfg->mega_buffer); - mbox = (mega_mailbox *)mboxData; + paddr = virt_to_bus (megaCfg->mega_buffer); + mbox = (mega_mailbox *) mboxData; - memset((void *)megaCfg->mega_buffer, 0, sizeof(megaCfg->mega_buffer)); - memset(mbox, 0, 16); + memset ((void *) megaCfg->mega_buffer, 0, sizeof (megaCfg->mega_buffer)); + memset (mbox, 0, 16); /* Initialize mailbox registers */ - mbox->cmd = MEGA_MBOXCMD_ADAPTERINQ; + mbox->cmd = MEGA_MBOXCMD_ADAPTERINQ; mbox->xferaddr = paddr; /* Issue a blocking command to the card */ - MegaIssueCmd(megaCfg, mboxData, NULL, 0); - + MegaIssueCmd (megaCfg, mboxData, NULL, 0); + /* Initialize host/local structures with Adapter info */ - adapterInfo = (mega_RAIDINQ *)megaCfg->mega_buffer; + adapterInfo = (mega_RAIDINQ *) megaCfg->mega_buffer; megaCfg->host->max_channel = adapterInfo->AdpInfo.ChanPresent; - megaCfg->host->max_id = adapterInfo->AdpInfo.MaxTargPerChan; - megaCfg->numldrv = adapterInfo->LogdrvInfo.NumLDrv; +/* megaCfg->host->max_id = adapterInfo->AdpInfo.MaxTargPerChan; */ + megaCfg->host->max_id = 16; /* max targets/chan */ + megaCfg->numldrv = adapterInfo->LogdrvInfo.NumLDrv; #if 0 - printk(KERN_DEBUG "---- Logical drive info ----\n"); - for(i=0; inumldrv; i++) { - printk(KERN_DEBUG "%d: size: %ld prop: %x state: %x\n",i, - adapterInfo->LogdrvInfo.LDrvSize[i], - adapterInfo->LogdrvInfo.LDrvProp[i], - adapterInfo->LogdrvInfo.LDrvState[i]); - } - printk(KERN_DEBUG "---- Physical drive info ----\n"); - for(i=0; iPhysdrvInfo.PDrvState[i]); + printk ("KERN_DEBUG ---- Logical drive info ----\n"); + for (i = 0; i < megaCfg->numldrv; i++) { + printk ("%d: size: %ld prop: %x state: %x\n", i, + adapterInfo->LogdrvInfo.LDrvSize[i], + adapterInfo->LogdrvInfo.LDrvProp[i], + adapterInfo->LogdrvInfo.LDrvState[i]); + } + printk (KERN_DEBUG "---- Physical drive info ----\n"); + for (i = 0; i < MAX_PHYSICAL_DRIVES; i++) { + if (i && !(i % 8)) + printk ("\n"); + printk ("%d: %x ", i, adapterInfo->PhysdrvInfo.PDrvState[i]); } - printk("\n"); + printk ("\n"); #endif megaCfg->max_cmds = adapterInfo->AdpInfo.MaxConcCmds; -#ifdef HP /* use HP firmware and bios version encoding */ - sprintf(megaCfg->fwVer,"%c%d%d.%d%d", - adapterInfo->AdpInfo.FwVer[2], - adapterInfo->AdpInfo.FwVer[1] >> 8, - adapterInfo->AdpInfo.FwVer[1] & 0x0f, - adapterInfo->AdpInfo.FwVer[2] >> 8, - adapterInfo->AdpInfo.FwVer[2] & 0x0f); - sprintf(megaCfg->biosVer,"%c%d%d.%d%d", - adapterInfo->AdpInfo.BiosVer[2], - adapterInfo->AdpInfo.BiosVer[1] >> 8, - adapterInfo->AdpInfo.BiosVer[1] & 0x0f, - adapterInfo->AdpInfo.BiosVer[2] >> 8, - adapterInfo->AdpInfo.BiosVer[2] & 0x0f); +#ifdef HP /* use HP firmware and bios version encoding */ + sprintf (megaCfg->fwVer, "%c%d%d.%d%d", + adapterInfo->AdpInfo.FwVer[2], + adapterInfo->AdpInfo.FwVer[1] >> 8, + adapterInfo->AdpInfo.FwVer[1] & 0x0f, + adapterInfo->AdpInfo.FwVer[2] >> 8, + adapterInfo->AdpInfo.FwVer[2] & 0x0f); + sprintf (megaCfg->biosVer, "%c%d%d.%d%d", + adapterInfo->AdpInfo.BiosVer[2], + adapterInfo->AdpInfo.BiosVer[1] >> 8, + adapterInfo->AdpInfo.BiosVer[1] & 0x0f, + adapterInfo->AdpInfo.BiosVer[2] >> 8, + adapterInfo->AdpInfo.BiosVer[2] & 0x0f); #else - memcpy(megaCfg->fwVer, adapterInfo->AdpInfo.FwVer, 4); - megaCfg->fwVer[4] = 0; + memcpy (megaCfg->fwVer, adapterInfo->AdpInfo.FwVer, 4); + megaCfg->fwVer[4] = 0; - memcpy(megaCfg->biosVer, adapterInfo->AdpInfo.BiosVer, 4); - megaCfg->biosVer[4] = 0; + memcpy (megaCfg->biosVer, adapterInfo->AdpInfo.BiosVer, 4); + megaCfg->biosVer[4] = 0; #endif - printk(KERN_INFO "megaraid: [%s:%s] detected %d logical drives" CRLFSTR, - megaCfg->fwVer, - megaCfg->biosVer, - megaCfg->numldrv); + printk (KERN_INFO "megaraid: [%s:%s] detected %d logical drives" CRLFSTR, + megaCfg->fwVer, + megaCfg->biosVer, + megaCfg->numldrv); return 0; } @@ -982,47 +1136,65 @@ /*---------------------------------------------------------- * Returns data to be displayed in /proc/scsi/megaraid/X *----------------------------------------------------------*/ -int megaraid_proc_info(char *buffer, char **start, off_t offset, - int length, int inode, int inout) +int megaraid_proc_info (char *buffer, char **start, off_t offset, + int length, int inode, int inout) { *start = buffer; return 0; } -int findCard(Scsi_Host_Template *pHostTmpl, - u_short pciVendor, u_short pciDev, - long flag) +int findCard (Scsi_Host_Template * pHostTmpl, + u_short pciVendor, u_short pciDev, + long flag) { mega_host_config *megaCfg; struct Scsi_Host *host; - u_char pciBus, pciDevFun, megaIrq; - u_long megaBase; - u_short pciIdx = 0; + u_char pciBus, pciDevFun, megaIrq; + u_long megaBase; + u_short pciIdx = 0; + u_short numFound = 0; #if LINUX_VERSION_CODE < 0x20100 - while(!pcibios_find_device(pciVendor, pciDev, pciIdx,&pciBus,&pciDevFun)) { + while (!pcibios_find_device (pciVendor, pciDev, pciIdx, &pciBus, &pciDevFun)) { +#if 0 + if (flag & BOARD_QUARTZ) { + u_int magic; + pcibios_read_config_dword (pciBus, pciDevFun, + PCI_CONF_AMISIG, + &magic); + if (magic != AMI_SIGNATURE) { + pciIdx++; + continue; /* not an AMI board */ + } + } +#endif + +#if 0 + } /* keep auto-indenters happy */ +#endif + #else - struct pci_dev *pdev=pci_devices; + struct pci_dev *pdev = pci_devices; - while((pdev = pci_find_device(pciVendor, pciDev, pdev))) { + while ((pdev = pci_find_device (pciVendor, pciDev, pdev))) { pciBus = pdev->bus->number; pciDevFun = pdev->devfn; #endif - printk(KERN_INFO "megaraid: found 0x%4.04x:0x%4.04x:idx %d:bus %d:slot %d:fun %d\n", - pciVendor, - pciDev, - pciIdx, pciBus, - PCI_SLOT(pciDevFun), - PCI_FUNC(pciDevFun)); - + printk (KERN_INFO "megaraid: found 0x%4.04x:0x%4.04x:idx %d:bus %d:slot %d:fun %d\n", + pciVendor, + pciDev, + pciIdx, pciBus, + PCI_SLOT (pciDevFun), + PCI_FUNC (pciDevFun)); + /* Read the base port and IRQ from PCI */ #if LINUX_VERSION_CODE < 0x20100 - pcibios_read_config_dword(pciBus, pciDevFun, - PCI_BASE_ADDRESS_0, - (u_int *)&megaBase); - pcibios_read_config_byte(pciBus, pciDevFun, - PCI_INTERRUPT_LINE, - &megaIrq); + pcibios_read_config_dword (pciBus, pciDevFun, + PCI_BASE_ADDRESS_0, + (u_int *) & megaBase); + pcibios_read_config_byte (pciBus, pciDevFun, + PCI_INTERRUPT_LINE, + &megaIrq); #else megaBase = pdev->base_address[0]; megaIrq = pdev->irq; @@ -1031,7 +1203,7 @@ if (flag & BOARD_QUARTZ) { megaBase &= PCI_BASE_ADDRESS_MEM_MASK; - megaBase = (long) ioremap(megaBase,128); + megaBase = (long) ioremap (megaBase, 128); } else { megaBase &= PCI_BASE_ADDRESS_IO_MASK; @@ -1039,72 +1211,75 @@ } /* Initialize SCSI Host structure */ - host = scsi_register(pHostTmpl, sizeof(mega_host_config)); - megaCfg = (mega_host_config *)host->hostdata; - memset(megaCfg, 0, sizeof(mega_host_config)); - - printk(KERN_INFO " scsi%d: Found a MegaRAID controller at 0x%x, IRQ: %d" CRLFSTR, - host->host_no, (u_int)megaBase, megaIrq); - + host = scsi_register (pHostTmpl, sizeof (mega_host_config)); + megaCfg = (mega_host_config *) host->hostdata; + memset (megaCfg, 0, sizeof (mega_host_config)); + + printk (KERN_INFO " scsi%d: Found a MegaRAID controller at 0x%x, IRQ: %d" CRLFSTR, + host->host_no, (u_int) megaBase, megaIrq); + /* Copy resource info into structure */ - megaCfg->flag = flag; - megaCfg->host = host; - megaCfg->base = megaBase; - megaCfg->host->irq = megaIrq; - megaCfg->host->io_port = megaBase; + megaCfg->flag = flag; + megaCfg->host = host; + megaCfg->base = megaBase; + megaCfg->host->irq = megaIrq; + megaCfg->host->io_port = megaBase; megaCfg->host->n_io_port = 16; megaCfg->host->unique_id = (pciBus << 8) | pciDevFun; - megaCtlrs[numCtlrs++] = megaCfg; + megaCtlrs[numCtlrs++] = megaCfg; if (flag != BOARD_QUARTZ) { /* Request our IO Range */ - if (check_region(megaBase, 16)) { - printk(KERN_WARNING "megaraid: Couldn't register I/O range!" CRLFSTR); - scsi_unregister(host); + if (check_region (megaBase, 16)) { + printk (KERN_WARNING "megaraid: Couldn't register I/O range!" CRLFSTR); + scsi_unregister (host); continue; } - request_region(megaBase, 16, "megaraid"); + request_region (megaBase, 16, "megaraid"); } /* Request our IRQ */ - if (request_irq(megaIrq, megaraid_isr, SA_SHIRQ, - "megaraid", megaCfg)) { - printk(KERN_WARNING "megaraid: Couldn't register IRQ %d!" CRLFSTR, - megaIrq); - scsi_unregister(host); + if (request_irq (megaIrq, megaraid_isr, SA_SHIRQ, + "megaraid", megaCfg)) { + printk (KERN_WARNING "megaraid: Couldn't register IRQ %d!" CRLFSTR, + megaIrq); + scsi_unregister (host); continue; } - mega_register_mailbox(megaCfg, virt_to_bus((void*)&megaCfg->mailbox)); - mega_i_query_adapter(megaCfg); + mega_register_mailbox (megaCfg, virt_to_bus ((void *) &megaCfg->mailbox)); + mega_i_query_adapter (megaCfg); /* Initialize SCBs */ - initSCB(megaCfg); + if (initSCB (megaCfg)) { + scsi_unregister (host); + continue; + } + numFound++; } - return pciIdx; + return numFound; } /*--------------------------------------------------------- * Detects if a megaraid controller exists in this system *---------------------------------------------------------*/ -int megaraid_detect(Scsi_Host_Template *pHostTmpl) +int megaraid_detect (Scsi_Host_Template * pHostTmpl) { int count = 0; pHostTmpl->proc_dir = &proc_scsi_megaraid; #if LINUX_VERSION_CODE < 0x20100 - if (!pcibios_present()) - { - printk(KERN_WARNING "megaraid: PCI bios not present." CRLFSTR); - return 0; - } + if (!pcibios_present ()) { + printk (KERN_WARNING "megaraid: PCI bios not present." CRLFSTR); + return 0; + } #endif - count += findCard(pHostTmpl, 0x101E, 0x9010, 0); - count += findCard(pHostTmpl, 0x101E, 0x9060, 0); - count += findCard(pHostTmpl, 0x8086, 0x1960, BOARD_QUARTZ); + count += findCard (pHostTmpl, 0x101E, 0x9010, 0); + count += findCard (pHostTmpl, 0x101E, 0x9060, 0); + count += findCard (pHostTmpl, 0x8086, 0x1960, BOARD_QUARTZ); return count; } @@ -1112,54 +1287,67 @@ /*--------------------------------------------------------------------- * Release the controller's resources *---------------------------------------------------------------------*/ -int megaraid_release(struct Scsi_Host *pSHost) +int megaraid_release (struct Scsi_Host *pSHost) { mega_host_config *megaCfg; - mega_mailbox *mbox; - u_char mboxData[16]; + mega_mailbox *mbox; + u_char mboxData[16]; - megaCfg = (mega_host_config*)pSHost->hostdata; - mbox = (mega_mailbox *)mboxData; + megaCfg = (mega_host_config *) pSHost->hostdata; + mbox = (mega_mailbox *) mboxData; /* Flush cache to disk */ - memset(mbox, 0, 16); + memset (mbox, 0, 16); mboxData[0] = 0xA; /* Issue a blocking (interrupts disabled) command to the card */ - MegaIssueCmd(megaCfg, mboxData, NULL, 0); + MegaIssueCmd (megaCfg, mboxData, NULL, 0); - schedule(); + schedule (); /* Free our resources */ if (megaCfg->flag & BOARD_QUARTZ) { - iounmap((void *)megaCfg->base); - } else { - release_region(megaCfg->host->io_port, 16); - } - free_irq(megaCfg->host->irq, megaCfg); /* Must be freed first, otherwise - extra interrupt is generated */ - scsi_unregister(pSHost); + iounmap ((void *) megaCfg->base); + } + else { + release_region (megaCfg->host->io_port, 16); + } + free_irq (megaCfg->host->irq, megaCfg); /* Must be freed first, otherwise + + extra interrupt is generated */ + freeSgList(megaCfg); + scsi_unregister (pSHost); return 0; } +static inline void freeSgList(mega_host_config *megaCfg) +{ + int i; + + for (i = 0; i < megaCfg->max_cmds; i++) { + if (megaCfg->scbList[i].sgList) + kfree (megaCfg->scbList[i].sgList); /* free sgList */ + } +} + /*---------------------------------------------- * Get information about the card/driver *----------------------------------------------*/ -const char *megaraid_info(struct Scsi_Host *pSHost) +const char * megaraid_info (struct Scsi_Host *pSHost) { - static char buffer[512]; - mega_host_config *megaCfg; - mega_RAIDINQ *adapterInfo; + static char buffer[512]; + mega_host_config *megaCfg; + mega_RAIDINQ *adapterInfo; - megaCfg = (mega_host_config *)pSHost->hostdata; - adapterInfo = (mega_RAIDINQ *)megaCfg->mega_buffer; + megaCfg = (mega_host_config *) pSHost->hostdata; + adapterInfo = (mega_RAIDINQ *) megaCfg->mega_buffer; - sprintf(buffer, "AMI MegaRAID %s %d commands %d targs %d chans", - megaCfg->fwVer, - adapterInfo->AdpInfo.MaxConcCmds, - megaCfg->host->max_id, - megaCfg->host->max_channel); + sprintf (buffer, "AMI MegaRAID %s %d commands %d targs %d chans", + megaCfg->fwVer, + adapterInfo->AdpInfo.MaxConcCmds, + megaCfg->host->max_id, + megaCfg->host->max_channel); return buffer; } @@ -1178,29 +1366,29 @@ * 10 01 numstatus byte * 11 01 status byte *-----------------------------------------------------------------*/ -int megaraid_queue(Scsi_Cmnd *SCpnt, void (*pktComp)(Scsi_Cmnd *)) +int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *)) { mega_host_config *megaCfg; - mega_scb *pScb; + mega_scb *pScb; - megaCfg = (mega_host_config *)SCpnt->host->hostdata; + megaCfg = (mega_host_config *) SCpnt->host->hostdata; if (!(megaCfg->flag & (1L << SCpnt->channel))) { - printk(KERN_INFO "scsi%d: scanning channel %c for devices.\n", - megaCfg->host->host_no, - SCpnt->channel + 'A'); + printk (KERN_INFO "scsi%d: scanning channel %c for devices.\n", + megaCfg->host->host_no, + SCpnt->channel + 'A'); megaCfg->flag |= (1L << SCpnt->channel); } SCpnt->scsi_done = pktComp; /* Allocate and build a SCB request */ - if ((pScb = mega_build_cmd(megaCfg, SCpnt)) != NULL) { + if ((pScb = mega_build_cmd (megaCfg, SCpnt)) != NULL) { /* Add SCB to the head of the pending queue */ - ENQUEUE(pScb, mega_scb, qPending, next); + ENQUEUE (pScb, mega_scb, qPending, next); /* Issue the command to the card */ - mega_runque(NULL); + mega_runque (NULL); } return 0; @@ -1208,37 +1396,44 @@ /*---------------------------------------------------------------------- * Issue a blocking command to the controller - * - * Note - this isnt 2.0.x SMP safe *----------------------------------------------------------------------*/ -volatile static int internal_done_flag = 0; +volatile static int internal_done_flag = 0; volatile static int internal_done_errcode = 0; -static void internal_done(Scsi_Cmnd *SCpnt) +static void internal_done (Scsi_Cmnd * SCpnt) { internal_done_errcode = SCpnt->result; internal_done_flag++; } /* - * This seems dangerous in an SMP environment because - * while spinning on internal_done_flag in 2.0.x SMP - * no IRQ's will be taken, including those that might - * be needed to clear this. - * - * I think this should be using a wait queue ? - * -- AC + * This seems dangerous in an SMP environment because + * while spinning on internal_done_flag in 2.0.x SMP + * no IRQ's will be taken, including those that might + * be needed to clear this. + * + * I think this should be using a wait queue ? + * -- AC + */ + +/* + * I'll probably fix this in the next version, but + * megaraid_command() will never get called since can_queue is set, + * except maybe in a *really* old kernel in which case it's very + * unlikely they'd be using SMP anyway. Really this function is + * just here for completeness. + * - JLJ */ - -int megaraid_command(Scsi_Cmnd *SCpnt) + +int megaraid_command (Scsi_Cmnd * SCpnt) { internal_done_flag = 0; /* Queue command, and wait until it has completed */ - megaraid_queue(SCpnt, internal_done); + megaraid_queue (SCpnt, internal_done); - while(!internal_done_flag) - barrier(); + while (!internal_done_flag) + barrier (); return internal_done_errcode; } @@ -1246,67 +1441,67 @@ /*--------------------------------------------------------------------- * Abort a previous SCSI request *---------------------------------------------------------------------*/ -int megaraid_abort(Scsi_Cmnd *SCpnt) +int megaraid_abort (Scsi_Cmnd * SCpnt) { mega_host_config *megaCfg; - int idx; - long flags; + int idx; + long flags; - spin_lock_irqsave(&mega_lock,flags); + spin_lock_irqsave (&mega_lock, flags); - megaCfg = (mega_host_config *)SCpnt->host->hostdata; + megaCfg = (mega_host_config *) SCpnt->host->hostdata; - TRACE(("ABORT!!! %.08lx %.02x <%d.%d.%d>\n", - SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, - SCpnt->lun)); + TRACE (("ABORT!!! %.08lx %.02x <%d.%d.%d>\n", + SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, + SCpnt->lun)); /* * Walk list of SCBs for any that are still outstanding */ - for(idx=0; idxmax_cmds; idx++) { + for (idx = 0; idx < megaCfg->max_cmds; idx++) { if (megaCfg->scbList[idx].idx >= 0) { if (megaCfg->scbList[idx].SCpnt == SCpnt) { - freeSCB(&megaCfg->scbList[idx]); + freeSCB (&megaCfg->scbList[idx]); - SCpnt->result = (DID_RESET << 16) | (SUGGEST_RETRY<<24); - callDone(SCpnt); + SCpnt->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24); + callDone (SCpnt); } } } - spin_unlock_irqrestore(&mega_lock,flags); + spin_unlock_irqrestore (&mega_lock, flags); return SCSI_ABORT_SNOOZE; } /*--------------------------------------------------------------------- * Reset a previous SCSI request *---------------------------------------------------------------------*/ -int megaraid_reset(Scsi_Cmnd *SCpnt, unsigned int rstflags) +int megaraid_reset (Scsi_Cmnd * SCpnt, unsigned int rstflags) { mega_host_config *megaCfg; - int idx; - long flags; + int idx; + long flags; - spin_lock_irqsave(&mega_lock,flags); + spin_lock_irqsave (&mega_lock, flags); - megaCfg = (mega_host_config *)SCpnt->host->hostdata; + megaCfg = (mega_host_config *) SCpnt->host->hostdata; - TRACE(("RESET: %.08lx %.02x <%d.%d.%d>\n", - SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, - SCpnt->lun)); + TRACE (("RESET: %.08lx %.02x <%d.%d.%d>\n", + SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, + SCpnt->lun)); /* * Walk list of SCBs for any that are still outstanding */ - for(idx=0; idxmax_cmds; idx++) { + for (idx = 0; idx < megaCfg->max_cmds; idx++) { if (megaCfg->scbList[idx].idx >= 0) { SCpnt = megaCfg->scbList[idx].SCpnt; - freeSCB(&megaCfg->scbList[idx]); - SCpnt->result = (DID_RESET << 16) | (SUGGEST_RETRY<<24); - callDone(SCpnt); + freeSCB (&megaCfg->scbList[idx]); + SCpnt->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24); + callDone (SCpnt); } } - spin_unlock_irqrestore(&mega_lock,flags); + spin_unlock_irqrestore (&mega_lock, flags); return SCSI_RESET_PUNT; -} +} /*------------------------------------------------------------- * Return the disk geometry for a particular disk @@ -1318,23 +1513,23 @@ * geom[1] = sectors * geom[2] = cylinders *-------------------------------------------------------------*/ -int megaraid_biosparam(Disk *disk, kdev_t dev, int *geom) +int megaraid_biosparam (Disk * disk, kdev_t dev, int *geom) { - int heads, sectors, cylinders; + int heads, sectors, cylinders; mega_host_config *megaCfg; /* Get pointer to host config structure */ - megaCfg = (mega_host_config *)disk->device->host->hostdata; + megaCfg = (mega_host_config *) disk->device->host->hostdata; /* Default heads (64) & sectors (32) */ - heads = 64; - sectors = 32; + heads = 64; + sectors = 32; cylinders = disk->capacity / (heads * sectors); /* Handle extended translation size for logical drives > 1Gb */ if (disk->capacity >= 0x200000) { - heads = 255; - sectors = 63; + heads = 255; + sectors = 63; cylinders = disk->capacity / (heads * sectors); } diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/megaraid.h linux/drivers/scsi/megaraid.h --- v2.2.2/linux/drivers/scsi/megaraid.h Mon Jan 25 17:44:34 1999 +++ linux/drivers/scsi/megaraid.h Mon Mar 8 15:52:17 1999 @@ -1,7 +1,12 @@ #ifndef __MEGARAID_H__ #define __MEGARAID_H__ +#ifndef LINUX_VERSION_CODE #include +#endif + +#define MULTI_IO 0 /* change to 1 for fully parallel I/O to adapter */ + /* works on some systems, not on others yet */ #define IN_ISR 0x80000000L #define NO_INTR 0x40000000L @@ -20,7 +25,7 @@ #define MEGA_CMD_TIMEOUT 10 -#define MAX_SGLIST 20 +#define MAX_SGLIST 17 #define MAX_COMMANDS 254 #define MAX_LOGICAL_DRIVES 8 @@ -56,7 +61,7 @@ #define I_TOGGLE_PORT 0x01 #define INTR_PORT 0x0a -#define MAILBOX_SIZE 70 +#define MAILBOX_SIZE (sizeof(mega_mailbox)-16) #define MBOX_BUSY_PORT 0x00 #define MBOX_PORT0 0x04 #define MBOX_PORT1 0x05 @@ -96,6 +101,8 @@ #define PCI_CONF_BASE_ADDR_OFFSET 0x10 #define PCI_CONF_IRQ_OFFSET 0x3c +#define PCI_CONF_AMISIG 0xa0 +#define AMI_SIGNATURE 0x11223344 #if LINUX_VERSION_CODE < 0x20100 #define MEGARAID \ @@ -113,14 +120,14 @@ megaraid_reset, /* Reset Command Function */\ NULL, /* Slave Attach Function */\ megaraid_biosparam, /* Disk BIOS Parameters */\ - 1, /* # of cmds that can be\ + 254, /* # of cmds that can be\ outstanding at any time */\ 7, /* HBA Target ID */\ MAX_SGLIST, /* Scatter/Gather Table Size */\ - 1, /* SCSI Commands per LUN */\ + 64, /* SCSI Commands per LUN */\ 0, /* Present */\ 0, /* Default Unchecked ISA DMA */\ - ENABLE_CLUSTERING } /* Enable Clustering */ + ENABLE_CLUSTERING } /* Enable Clustering */ #else #define MEGARAID \ {\ @@ -134,10 +141,10 @@ abort: megaraid_abort, /* Abort Command Function */\ reset: megaraid_reset, /* Reset Command Function */\ bios_param: megaraid_biosparam, /* Disk BIOS Parameters */\ - can_queue: 255, /* Can Queue */\ + can_queue: 1 /* MAX_COMMANDS */, /* Can Queue */\ this_id: 7, /* HBA Target ID */\ sg_tablesize: MAX_SGLIST, /* Scatter/Gather Table Size */\ - cmd_per_lun: 1, /* SCSI Commands per LUN */\ + cmd_per_lun: 64, /* SCSI Commands per LUN */\ present: 0, /* Present */\ unchecked_isa_dma:0, /* Default Unchecked ISA DMA */\ use_clustering: ENABLE_CLUSTERING /* Enable Clustering */\ @@ -145,140 +152,150 @@ #endif /* Structures */ -typedef struct _mega_ADP_INFO -{ - u_char MaxConcCmds; - u_char RbldRate; - u_char MaxTargPerChan; - u_char ChanPresent; - u_char FwVer[4]; - u_short AgeOfFlash; - u_char ChipSet; - u_char DRAMSize; - u_char CacheFlushInterval; - u_char BiosVer[4]; - u_char resvd[7]; +typedef struct _mega_ADP_INFO { + u_char MaxConcCmds; + u_char RbldRate; + u_char MaxTargPerChan; + u_char ChanPresent; + u_char FwVer[4]; + u_short AgeOfFlash; + u_char ChipSet; + u_char DRAMSize; + u_char CacheFlushInterval; + u_char BiosVer[4]; + u_char resvd[7]; } mega_ADP_INFO; -typedef struct _mega_LDRV_INFO -{ - u_char NumLDrv; - u_char resvd[3]; - u_long LDrvSize[MAX_LOGICAL_DRIVES]; - u_char LDrvProp[MAX_LOGICAL_DRIVES]; - u_char LDrvState[MAX_LOGICAL_DRIVES]; +typedef struct _mega_LDRV_INFO { + u_char NumLDrv; + u_char resvd[3]; + u_long LDrvSize[MAX_LOGICAL_DRIVES]; + u_char LDrvProp[MAX_LOGICAL_DRIVES]; + u_char LDrvState[MAX_LOGICAL_DRIVES]; } mega_LDRV_INFO; -typedef struct _mega_PDRV_INFO -{ - u_char PDrvState[MAX_PHYSICAL_DRIVES]; - u_char resvd; +typedef struct _mega_PDRV_INFO { + u_char PDrvState[MAX_PHYSICAL_DRIVES]; + u_char resvd; } mega_PDRV_INFO; // RAID inquiry: Mailbox command 0x5 -typedef struct _mega_RAIDINQ -{ - mega_ADP_INFO AdpInfo; - mega_LDRV_INFO LogdrvInfo; - mega_PDRV_INFO PhysdrvInfo; +typedef struct _mega_RAIDINQ { + mega_ADP_INFO AdpInfo; + mega_LDRV_INFO LogdrvInfo; + mega_PDRV_INFO PhysdrvInfo; } mega_RAIDINQ; // Passthrough command: Mailbox command 0x3 -typedef struct mega_passthru -{ - u_char timeout:3; /* 0=6sec/1=60sec/2=10min/3=3hrs */ - u_char ars:1; - u_char reserved:3; - u_char islogical:1; - u_char logdrv; /* if islogical == 1 */ - u_char channel; /* if islogical == 0 */ - u_char target; /* if islogical == 0 */ - u_char queuetag; /* unused */ - u_char queueaction; /* unused */ - u_char cdb[MAX_CDB_LEN]; - u_char cdblen; - u_char reqsenselen; - u_char reqsensearea[MAX_REQ_SENSE_LEN]; - u_char numsgelements; - u_char scsistatus; - u_long dataxferaddr; - u_long dataxferlen; +typedef struct mega_passthru { + u_char timeout:3; /* 0=6sec/1=60sec/2=10min/3=3hrs */ + u_char ars:1; + u_char reserved:3; + u_char islogical:1; + u_char logdrv; /* if islogical == 1 */ + u_char channel; /* if islogical == 0 */ + u_char target; /* if islogical == 0 */ + u_char queuetag; /* unused */ + u_char queueaction; /* unused */ + u_char cdb[MAX_CDB_LEN]; + u_char cdblen; + u_char reqsenselen; + u_char reqsensearea[MAX_REQ_SENSE_LEN]; + u_char numsgelements; + u_char scsistatus; + u_long dataxferaddr; + u_long dataxferlen; } mega_passthru; -typedef struct _mega_mailbox -{ - /* 0x0 */ u_char cmd; - /* 0x1 */ u_char cmdid; - /* 0x2 */ u_short numsectors; - /* 0x4 */ u_long lba; - /* 0x8 */ u_long xferaddr; - /* 0xC */ u_char logdrv; - /* 0xD */ u_char numsgelements; - /* 0xE */ u_char resvd; - /* 0xF */ u_char busy; - /* 0x10*/ u_char numstatus; - /* 0x11*/ u_char status; - /* 0x12*/ u_char completed[46]; - u_char mraid_poll; - u_char mraid_ack; - u_char pad[16]; +typedef struct _mega_mailbox { + /* 0x0 */ u_char cmd; + /* 0x1 */ u_char cmdid; + /* 0x2 */ u_short numsectors; + /* 0x4 */ u_long lba; + /* 0x8 */ u_long xferaddr; + /* 0xC */ u_char logdrv; + /* 0xD */ u_char numsgelements; + /* 0xE */ u_char resvd; + /* 0xF */ u_char busy; + /* 0x10 */ u_char numstatus; + /* 0x11 */ u_char status; + /* 0x12 */ u_char completed[46]; + u_char mraid_poll; + u_char mraid_ack; + u_char pad[16]; } mega_mailbox; -typedef struct _mega_sglist -{ - u_long address; - u_long length; +typedef struct _mega_ioctl_mbox { + /* 0x0 */ u_char cmd; + /* 0x1 */ u_char cmdid; + /* 0x2 */ u_char channel; + /* 0x3 */ u_char param; + /* 0x4 */ u_char pad[4]; + /* 0x8 */ u_long xferaddr; + /* 0xC */ u_char logdrv; + /* 0xD */ u_char numsgelements; + /* 0xE */ u_char resvd; + /* 0xF */ u_char busy; + /* 0x10 */ u_char numstatus; + /* 0x11 */ u_char status; + /* 0x12 */ u_char completed[46]; + u_char mraid_poll; + u_char mraid_ack; + u_char malign[16]; +} mega_ioctl_mbox; + +typedef struct _mega_sglist { + u_long address; + u_long length; } mega_sglist; /* Queued command data */ typedef struct _mega_scb mega_scb; -struct _mega_scb -{ - int idx; - u_long flag; - Scsi_Cmnd *SCpnt; - u_char mboxData[16]; - mega_passthru pthru; - mega_sglist *sgList; - mega_scb *next; +struct _mega_scb { + int idx; + u_long flag; + Scsi_Cmnd *SCpnt; + u_char mboxData[16]; + mega_passthru pthru; + mega_sglist *sgList; + mega_scb *next; }; /* Per-controller data */ -typedef struct _mega_host_config -{ - u_char numldrv; - u_long flag; - u_long base; - - struct tq_struct megaTq; - - /* Host adapter parameters */ - u_char fwVer[7]; - u_char biosVer[7]; - - struct Scsi_Host *host; - - /* The following must be DMA-able!! */ - volatile mega_mailbox *mbox; - volatile mega_mailbox mailbox; - volatile u_char mega_buffer[2*1024L]; +typedef struct _mega_host_config { + u_char numldrv; + u_long flag; + u_long base; + + struct tq_struct megaTq; + + /* Host adapter parameters */ + u_char fwVer[7]; + u_char biosVer[7]; + + struct Scsi_Host *host; + + /* The following must be DMA-able!! */ + volatile mega_mailbox *mbox; + volatile mega_mailbox mailbox; + volatile u_char mega_buffer[2 * 1024L]; - u_char max_cmds; - mega_scb scbList[MAX_COMMANDS]; + u_char max_cmds; + mega_scb scbList[MAX_COMMANDS]; } mega_host_config; extern struct proc_dir_entry proc_scsi_megaraid; -const char *megaraid_info( struct Scsi_Host * ); -int megaraid_detect( Scsi_Host_Template * ); -int megaraid_release(struct Scsi_Host *); -int megaraid_command( Scsi_Cmnd * ); -int megaraid_abort( Scsi_Cmnd * ); -int megaraid_reset( Scsi_Cmnd *, unsigned int); -int megaraid_queue( Scsi_Cmnd *, void (*done)(Scsi_Cmnd *) ); -int megaraid_biosparam( Disk *, kdev_t, int * ); -int megaraid_proc_info( char *buffer, char **start, off_t offset, - int length, int hostno, int inout ); +const char *megaraid_info(struct Scsi_Host *); +int megaraid_detect(Scsi_Host_Template *); +int megaraid_release(struct Scsi_Host *); +int megaraid_command(Scsi_Cmnd *); +int megaraid_abort(Scsi_Cmnd *); +int megaraid_reset(Scsi_Cmnd *, unsigned int); +int megaraid_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); +int megaraid_biosparam(Disk *, kdev_t, int *); +int megaraid_proc_info(char *buffer, char **start, off_t offset, + int length, int hostno, int inout); #endif diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c --- v2.2.2/linux/drivers/scsi/ncr53c8xx.c Tue Feb 23 15:21:33 1999 +++ linux/drivers/scsi/ncr53c8xx.c Sun Mar 7 10:13:23 1999 @@ -73,7 +73,7 @@ */ /* -** January 16 1998, version 3.1f +** March 6 1999, version 3.1h ** ** Supported SCSI-II features: ** Synchronous negotiation @@ -2081,6 +2081,7 @@ ncrcmd msg_ext_3 [ 10]; ncrcmd msg_sdtr [ 14]; ncrcmd send_sdtr [ 7]; + ncrcmd nego_bad_phase [ 4]; ncrcmd msg_out_abort [ 10]; ncrcmd hdata_in [MAX_SCATTERH * 4]; ncrcmd hdata_in2 [ 2]; @@ -3185,16 +3186,15 @@ /* ** If a negotiation was in progress, ** negotiation failed. + ** Otherwise, let the C code print + ** some message. */ SCR_FROM_REG (HS_REG), 0, - SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)), - SIR_NEGO_FAILED, - /* - ** else make host log this message - */ SCR_INT ^ IFFALSE (DATA (HS_NEGOTIATE)), SIR_REJECT_RECEIVED, + SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)), + SIR_NEGO_FAILED, SCR_JUMP, PADDR (clrack), @@ -3304,10 +3304,9 @@ 0, SCR_CLR (SCR_ACK), 0, + SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)), + PADDRH (nego_bad_phase), -/* CHECK THE SOURCE FOR 'send_wdtr' IF YOU INTEND TO CHANGE SOMETHING HERE */ - SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)), - SIR_NEGO_PROTO, }/*-------------------------< SEND_WDTR >----------------*/,{ /* ** Send the M_X_WIDE_REQ @@ -3360,10 +3359,9 @@ 0, SCR_CLR (SCR_ACK), 0, + SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)), + PADDRH (nego_bad_phase), -/* CHECK THE SOURCE FOR 'send_sdtr' IF YOU INTEND TO CHANGE SOMETHING HERE */ - SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)), - SIR_NEGO_PROTO, }/*-------------------------< SEND_SDTR >-------------*/,{ /* ** Send the M_X_SYNC_REQ @@ -3376,6 +3374,12 @@ SCR_JUMP, PADDR (msg_out_done), +}/*-------------------------< NEGO_BAD_PHASE >------------*/,{ + SCR_INT, + SIR_NEGO_PROTO, + SCR_JUMP, + PADDR (dispatch), + }/*-------------------------< MSG_OUT_ABORT >-------------*/,{ /* ** After ABORT message, @@ -4274,7 +4278,7 @@ /* ** Set irq mode. */ - switch(driver_setup.irqm) { + switch(driver_setup.irqm & 3) { case 2: np->rv_dcntl |= IRQM; break; @@ -4665,21 +4669,11 @@ /* ** Install the interrupt handler. */ -#ifdef SCSI_NCR_SHARE_IRQ -#define NCR_SA_INTERRUPT_FLAGS (SA_INTERRUPT | SA_SHIRQ) - if (bootverbose > 1) -#ifdef __sparc__ - printk(KERN_INFO "%s: requesting shared irq %s (dev_id=0x%lx)\n", - ncr_name(np), __irq_itoa(device->slot.irq), (u_long) np); -#else - printk(KERN_INFO "%s: requesting shared irq %d (dev_id=0x%lx)\n", - ncr_name(np), device->slot.irq, (u_long) np); -#endif -#else -#define NCR_SA_INTERRUPT_FLAGS SA_INTERRUPT -#endif + if (request_irq(device->slot.irq, ncr53c8xx_intr, - NCR_SA_INTERRUPT_FLAGS, "ncr53c8xx", np)) { + ((driver_setup.irqm & 0x10) ? 0 : SA_SHIRQ) | + ((driver_setup.irqm & 0x20) ? 0 : SA_INTERRUPT), + "ncr53c8xx", np)) { #ifdef __sparc__ printk(KERN_ERR "%s: request irq %s failure\n", ncr_name(np), __irq_itoa(device->slot.irq)); @@ -4689,6 +4683,7 @@ #endif goto attach_error; } + np->irq = device->slot.irq; /* @@ -4956,9 +4951,8 @@ nego = NS_SYNC; } else { tp->period =0xffff; - tp->sval = 0xe0; PRINT_TARGET(np, cmd->target); - printk ("SYNC transfers not supported.\n"); + printk ("device did not report SYNC.\n"); }; }; @@ -5824,7 +5818,7 @@ ** announced capabilities (we need the 1rst 7 bytes). */ if (cmd->cmnd[0] == 0x12 && !(cmd->cmnd[1] & 0x3) && - cmd->cmnd[4] >= 7) { + cmd->cmnd[4] >= 7 && !cmd->use_sg) { ncr_setup_lcb (np, cmd->target, cmd->lun, (char *) cmd->request_buffer); } @@ -7051,7 +7045,7 @@ OUTONB (nc_ctest3, CLF); if ((sist & (SGE)) || - (dstat & (MDPE|BF|ABORT|IID))) { + (dstat & (MDPE|BF|ABRT|IID))) { ncr_start_reset(np); return; }; @@ -7528,7 +7522,7 @@ } else if (dsp == NCB_SCRIPTH_PHYS (np, send_wdtr) || dsp == NCB_SCRIPTH_PHYS (np, send_sdtr)) { - nxtdsp = dsp - 8; /* Should raise SIR_NEGO_PROTO */ + nxtdsp = NCB_SCRIPTH_PHYS (np, nego_bad_phase); } break; #if 0 @@ -7882,9 +7876,7 @@ np->msgin [0] = M_NOOP; np->msgout[0] = M_NOOP; cp->nego_status = 0; - OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, dispatch)); - return; -/* break; */ + break; case SIR_NEGO_SYNC: /* @@ -8657,10 +8649,15 @@ ** Evaluate trustable target/unit capabilities. ** We only believe device version >= SCSI-2 that ** use appropriate response data format (2). + ** But it seems that some CCS devices also + ** support SYNC and I donnot want to frustrate + ** anybody. ;-) */ inq_byte7 = 0; - if ((inq_data[2] & 0x7) >= 2 && (inq_data[3] & 0xf) == 2) + if ((inq_data[2] & 0x7) >= 2 && (inq_data[3] & 0xf) == 2) inq_byte7 = inq_data[7]; + else if ((inq_data[2] & 0x7) == 1 && (inq_data[3] & 0xf) == 1) + inq_byte7 = INQ7_SYNC; /* ** Throw away announced LUN capabilities if we are told @@ -9586,6 +9583,50 @@ } /* +** Generically read a base address from the PCI configuration space. +** Return the offset immediately after the base address that has +** been read. Btw, we blindly assume that the high 32 bits of 64 bit +** base addresses are set to zero on 32 bit architectures. +** +*/ +#if LINUX_VERSION_CODE <= LinuxVersionCode(2,1,92) +__initfunc( +static int +pci_read_base_address(u_char bus, u_char device_fn, int offset, u_long *base) +) +{ + u_int32 tmp; + + pcibios_read_config_dword(bus, device_fn, offset, &tmp); + *base = tmp; + offset += sizeof(u_int32); + if ((tmp & 0x7) == 0x4) { +#if BITS_PER_LONG > 32 + pcibios_read_config_dword(bus, device_fn, offset, &tmp); + *base |= (((u_long)tmp) << 32); +#endif + offset += sizeof(u_int32); + } + return offset; +} +#else /* LINUX_VERSION_CODE > LinuxVersionCode(2,1,92) */ +__initfunc( +static int +pci_get_base_address(struct pci_dev *pdev, int index, u_long *base) +) +{ + *base = pdev->base_address[index++]; + if ((*base & 0x7) == 0x4) { +#if BITS_PER_LONG > 32 + *base |= (((u_long)pdev->base_address[index]) << 32); +#endif + ++index; + } + return index; +} +#endif + +/* ** Read and check the PCI configuration for any detected NCR ** boards and save data for attaching after all boards have ** been detected. @@ -9601,61 +9642,46 @@ uchar revision; #if LINUX_VERSION_CODE > LinuxVersionCode(2,1,92) struct pci_dev *pdev; - ulong base, base_2, io_port; uint irq; #else uchar irq; - uint base, base_2, io_port; #endif + ulong base, base_2, io_port; int i; - #ifdef SCSI_NCR_NVRAM_SUPPORT ncr_nvram *nvram = device->nvram; #endif ncr_chip *chip; /* - * Read info from the PCI config space. - * pcibios_read_config_xxx() functions are assumed to be used for - * successfully detected PCI devices. - * Expecting error conditions from them is just paranoia, - * thus void cast. - */ - (void) pcibios_read_config_word(bus, device_fn, - PCI_VENDOR_ID, &vendor_id); - (void) pcibios_read_config_word(bus, device_fn, - PCI_DEVICE_ID, &device_id); - (void) pcibios_read_config_word(bus, device_fn, - PCI_COMMAND, &command); + ** Read info from the PCI config space. + ** pcibios_read_config_xxx() functions are assumed to be used for + ** successfully detected PCI devices. + */ #if LINUX_VERSION_CODE > LinuxVersionCode(2,1,92) pdev = pci_find_slot(bus, device_fn); - io_port = pdev->base_address[0]; - base = pdev->base_address[1]; - base_2 = pdev->base_address[2]; + vendor_id = pdev->vendor; + device_id = pdev->device; irq = pdev->irq; - if ((base & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) - base_2 = pdev->base_address[3]; + i = 0; + i = pci_get_base_address(pdev, i, &io_port); + i = pci_get_base_address(pdev, i, &base); + (void) pci_get_base_address(pdev, i, &base_2); #else - (void) pcibios_read_config_dword(bus, device_fn, - PCI_BASE_ADDRESS_0, &io_port); - (void) pcibios_read_config_dword(bus, device_fn, - PCI_BASE_ADDRESS_1, &base); - (void) pcibios_read_config_dword(bus, device_fn, - PCI_BASE_ADDRESS_2, &base_2); - - /* Handle 64bit base addresses for 53C896. */ - if ((base & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) - (void) pcibios_read_config_dword(bus, device_fn, - PCI_BASE_ADDRESS_3, &base_2); - (void) pcibios_read_config_byte(bus, device_fn, - PCI_INTERRUPT_LINE, &irq); -#endif - (void) pcibios_read_config_byte(bus, device_fn, - PCI_CLASS_REVISION,&revision); - (void) pcibios_read_config_byte(bus, device_fn, - PCI_CACHE_LINE_SIZE, &cache_line_size); - (void) pcibios_read_config_byte(bus, device_fn, - PCI_LATENCY_TIMER, &latency_timer); + pcibios_read_config_word(bus, device_fn, PCI_VENDOR_ID, &vendor_id); + pcibios_read_config_word(bus, device_fn, PCI_DEVICE_ID, &device_id); + pcibios_read_config_byte(bus, device_fn, PCI_INTERRUPT_LINE, &irq); + i = PCI_BASE_ADDRESS_0; + i = pci_read_base_address(bus, device_fn, i, &io_port); + i = pci_read_base_address(bus, device_fn, i, &base); + (void) pci_read_base_address(bus, device_fn, i, &base_2); +#endif + pcibios_read_config_word(bus, device_fn, PCI_COMMAND, &command); + pcibios_read_config_byte(bus, device_fn, PCI_CLASS_REVISION, &revision); + pcibios_read_config_byte(bus, device_fn, PCI_CACHE_LINE_SIZE, + &cache_line_size); + pcibios_read_config_byte(bus, device_fn, PCI_LATENCY_TIMER, + &latency_timer); /* * Check if the chip is supported diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/ncr53c8xx.h linux/drivers/scsi/ncr53c8xx.h --- v2.2.2/linux/drivers/scsi/ncr53c8xx.h Tue Jan 19 11:32:51 1999 +++ linux/drivers/scsi/ncr53c8xx.h Mon Mar 8 15:52:15 1999 @@ -45,7 +45,7 @@ /* ** Name and revision of the driver */ -#define SCSI_NCR_DRIVER_NAME "ncr53c8xx - revision 3.1f" +#define SCSI_NCR_DRIVER_NAME "ncr53c8xx - revision 3.1h" /* ** Check supported Linux versions @@ -69,7 +69,6 @@ ** These options are not tunable from 'make config' */ #define SCSI_NCR_PROC_INFO_SUPPORT -#define SCSI_NCR_SHARE_IRQ /* ** If you want a driver as small as possible, donnot define the diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/qlogicfc.c linux/drivers/scsi/qlogicfc.c --- v2.2.2/linux/drivers/scsi/qlogicfc.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/qlogicfc.c Wed Feb 24 16:27:54 1999 @@ -0,0 +1,1937 @@ +/* + * QLogic ISP2100 SCSI-FCP + * Written by Erik H. Moe, ehm@cris.com + * Copyright 1995, Erik H. Moe + * + * 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, 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. + */ + +/* Renamed and updated to 1.3.x by Michael Griffith */ + +/* This is a version of the isp1020 driver which was modified by + * Chris Loveland to support the isp2100 + */ + +/* + * $Date: 1995/09/22 02:23:15 $ + * $Revision: 0.5 $ + * + * $Log: isp1020.c,v $ + * Revision 0.5 1995/09/22 02:23:15 root + * do auto request sense + * + * Revision 0.4 1995/08/07 04:44:33 root + * supply firmware with driver. + * numerous bug fixes/general cleanup of code. + * + * Revision 0.3 1995/07/16 16:15:39 root + * added reset/abort code. + * + * Revision 0.2 1995/06/29 03:14:19 root + * fixed biosparam. + * added queue protocol. + * + * Revision 0.1 1995/06/25 01:55:45 root + * Initial release. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sd.h" +#include "hosts.h" +#include "qlogicfc.h" + +/* Configuration section **************************************************** */ + +/* Set the following macro to 1 to reload the ISP2100's firmware. This is + version 1.13 of the firmware. */ + +#define RELOAD_FIRMWARE 1 + +#define USE_NVRAM_DEFAULTS 1 + + +/* 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 ISP2100_FABRIC 0 + +/* Macros used for debugging */ +/* +#define DEBUG_ISP2100 1 +#define DEBUG_ISP2100_INT 1 +#define DEBUG_ISP2100_INTR 1 +#define DEBUG_ISP2100_SETUP 1 + +#define DEBUG_ISP2100_FABRIC 1 +*/ +/* #define TRACE_ISP 1 */ + + +#define DEFAULT_LOOP_COUNT 10000000 + +/* End Configuration section ************************************************ */ + +#include + +#if TRACE_ISP + +#define TRACE_BUF_LEN (32*1024) + +struct { + u_long next; + struct { + u_long time; + u_int index; + u_int addr; + u_char *name; + } buf[TRACE_BUF_LEN]; +} trace; + +#define TRACE(w, i, a) \ +{ \ + unsigned long flags; \ + \ + save_flags(flags); \ + cli(); \ + trace.buf[trace.next].name = (w); \ + trace.buf[trace.next].time = jiffies; \ + trace.buf[trace.next].index = (i); \ + trace.buf[trace.next].addr = (long) (a); \ + trace.next = (trace.next + 1) & (TRACE_BUF_LEN - 1); \ + restore_flags(flags); \ +} + +#else +#define TRACE(w, i, a) +#endif + +#if DEBUG_ISP2100_FABRIC +#define DEBUG_FABRIC(x) x +#else +#define DEBUG_FABRIC(x) +#endif /* DEBUG_ISP2100_FABRIC */ + + +#if DEBUG_ISP2100 +#define ENTER(x) printk("isp2100 : entering %s()\n", x); +#define LEAVE(x) printk("isp2100 : leaving %s()\n", x); +#define DEBUG(x) x +#else +#define ENTER(x) +#define LEAVE(x) +#define DEBUG(x) +#endif /* DEBUG_ISP2100 */ + +#if DEBUG_ISP2100_INTR +#define ENTER_INTR(x) printk("isp2100 : entering %s()\n", x); +#define LEAVE_INTR(x) printk("isp2100 : leaving %s()\n", x); +#define DEBUG_INTR(x) x +#else +#define ENTER_INTR(x) +#define LEAVE_INTR(x) +#define DEBUG_INTR(x) +#endif /* DEBUG ISP2100_INTR */ + + +#if defined(__i386__) +#define virt_to_bus_low32(x) virt_to_bus(x) +#define virt_to_bus_high32(x) 0x0 +#define bus_to_virt_low32(x) bus_to_virt(x) +#define bus_to_virt_high32(x) 0x0 +#elif defined(__alpha__) +#define virt_to_bus_low32(x) ((u32) (0xffffffff & virt_to_bus(x))) +#define virt_to_bus_high32(x) ((u32) (0xffffffff & (virt_to_bus(x)>>32))) +#define bus_to_virt_low32(x) ((u32) (0xffffffff & bus_to_virt(x))) +#define bus_to_virt_high32(x) ((u32) (0xffffffff & (bus_to_virt(x)>>32))) +#endif + +#define ISP2100_REV_ID 1 +#define ISP2100_REV_ID3 3 + +#define MAX_TARGETS 16 +#define MAX_LUNS 8 + +/* host configuration and control registers */ +#define HOST_HCCR 0xc0 /* host command and control */ + +/* pci bus interface registers */ +#define FLASH_BIOS_ADDR 0x00 +#define FLASH_BIOS_DATA 0x02 +#define ISP_CTRL_STATUS 0x06 /* configuration register #1 */ +#define PCI_INTER_CTL 0x08 /* pci interupt control */ +#define PCI_INTER_STS 0x0a /* pci interupt status */ +#define PCI_SEMAPHORE 0x0c /* pci semaphore */ +#define PCI_NVRAM 0x0e /* pci nvram interface */ + +/* mailbox registers */ +#define MBOX0 0x10 /* mailbox 0 */ +#define MBOX1 0x12 /* mailbox 1 */ +#define MBOX2 0x14 /* mailbox 2 */ +#define MBOX3 0x16 /* mailbox 3 */ +#define MBOX4 0x18 /* mailbox 4 */ +#define MBOX5 0x1a /* mailbox 5 */ +#define MBOX6 0x1c /* mailbox 6 */ +#define MBOX7 0x1e /* mailbox 7 */ + +/* mailbox command complete status codes */ +#define MBOX_COMMAND_COMPLETE 0x4000 +#define INVALID_COMMAND 0x4001 +#define HOST_INTERFACE_ERROR 0x4002 +#define TEST_FAILED 0x4003 +#define COMMAND_ERROR 0x4005 +#define COMMAND_PARAM_ERROR 0x4006 +#define PORT_ID_USED 0x4007 +#define LOOP_ID_USED 0x4008 +#define ALL_IDS_USED 0x4009 + +/* async event status codes */ +#define RESET_DETECTED 0x8001 +#define SYSTEM_ERROR 0x8002 +#define REQUEST_TRANSFER_ERROR 0x8003 +#define RESPONSE_TRANSFER_ERROR 0x8004 +#define REQUEST_QUEUE_WAKEUP 0x8005 +#define LIP_OCCURED 0x8010 +#define LOOP_UP 0x8011 +#define LOOP_DOWN 0x8012 +#define LIP_RECEIVED 0x8013 +#define PORT_DB_CHANGED 0x8014 +#define CHANGE_NOTIFICATION 0x8015 +#define SCSI_COMMAND_COMPLETE 0x8020 + +struct Entry_header { + u_char entry_type; + u_char entry_cnt; + u_char sys_def_1; + u_char flags; +}; + +/* entry header type commands */ +#define ENTRY_COMMAND 0x19 +#define ENTRY_CONTINUATION 0x0a +#define ENTRY_STATUS 0x03 +#define ENTRY_MARKER 0x04 + +/* entry header flag definitions */ +#define EFLAG_BUSY 2 +#define EFLAG_BAD_HEADER 4 +#define EFLAG_BAD_PAYLOAD 8 + +struct dataseg { + u_int d_base_lo; + u_int d_base_high; + u_int d_count; +}; + +struct Command_Entry { + struct Entry_header hdr; + u_int handle; + u_char target_lun; + u_char target_id; + u_short rsvd1; + u_short control_flags; + u_short rsvd2; + u_short time_out; + u_short segment_cnt; + u_char cdb[16]; + u_int total_byte_cnt; + struct dataseg dataseg[2]; +}; + +/* command entry control flag definitions */ +#define CFLAG_NODISC 0x01 +#define CFLAG_HEAD_TAG 0x02 +#define CFLAG_ORDERED_TAG 0x04 +#define CFLAG_SIMPLE_TAG 0x08 +#define CFLAG_TAR_RTN 0x10 +#define CFLAG_READ 0x20 +#define CFLAG_WRITE 0x40 + +struct Ext_Command_Entry { + struct Entry_header hdr; + u_int handle; + u_char target_lun; + u_char target_id; + u_short cdb_length; + u_short control_flags; + u_short rsvd; + u_short time_out; + u_short segment_cnt; + u_char cdb[44]; +}; + +struct Continuation_Entry { + struct Entry_header hdr; + struct dataseg dataseg[5]; +}; + +struct Marker_Entry { + struct Entry_header hdr; + u_int reserved; + u_char target_lun; + u_char target_id; + u_char modifier; + u_char rsvd; + u_char rsvds[52]; +}; + +/* marker entry modifier definitions */ +#define SYNC_DEVICE 0 +#define SYNC_TARGET 1 +#define SYNC_ALL 2 + +struct Status_Entry { + struct Entry_header hdr; + u_int handle; + u_short scsi_status; + u_short completion_status; + u_short state_flags; + u_short status_flags; + u_short res_info_len; + u_short req_sense_len; + u_int residual; + u_char res_info[8]; + u_char req_sense_data[32]; +}; + +/* status entry completion status definitions */ +#define CS_COMPLETE 0x0000 +#define CS_INCOMPLETE 0x0001 +#define CS_DMA_ERROR 0x0002 +#define CS_TRANSPORT_ERROR 0x0003 +#define CS_RESET_OCCURRED 0x0004 +#define CS_ABORTED 0x0005 +#define CS_TIMEOUT 0x0006 +#define CS_DATA_OVERRUN 0x0007 +#define CS_ABORT_MSG_FAILED 0x000e +#define CS_REJECT_MSG_FAILED 0x000f +#define CS_DATA_UNDERRUN 0x0015 +#define CS_PORT_UNAVAILABLE 0x0028 +#define CS_PORT_LOGGED_OUT 0x0029 +#define CS_PORT_CONFIG_CHANGED 0x002a + +/* status entry state flag definitions */ +#define SF_SENT_CDB 0x0400 +#define SF_TRANSFERRED_DATA 0x0800 +#define SF_GOT_STATUS 0x1000 + +/* status entry status flag definitions */ +#define STF_BUS_RESET 0x0008 +#define STF_DEVICE_RESET 0x0010 +#define STF_ABORTED 0x0020 +#define STF_TIMEOUT 0x0040 + +/* interupt control commands */ +#define ISP_EN_INT 0x8000 +#define ISP_EN_RISC 0x0008 + +/* host control commands */ +#define HCCR_NOP 0x0000 +#define HCCR_RESET 0x1000 +#define HCCR_PAUSE 0x2000 +#define HCCR_RELEASE 0x3000 +#define HCCR_SINGLE_STEP 0x4000 +#define HCCR_SET_HOST_INTR 0x5000 +#define HCCR_CLEAR_HOST_INTR 0x6000 +#define HCCR_CLEAR_RISC_INTR 0x7000 +#define HCCR_BP_ENABLE 0x8000 +#define HCCR_BIOS_DISABLE 0x9000 +#define HCCR_TEST_MODE 0xf000 + +#define RISC_BUSY 0x0004 + +/* mailbox commands */ +#define MBOX_NO_OP 0x0000 +#define MBOX_LOAD_RAM 0x0001 +#define MBOX_EXEC_FIRMWARE 0x0002 +#define MBOX_DUMP_RAM 0x0003 +#define MBOX_WRITE_RAM_WORD 0x0004 +#define MBOX_READ_RAM_WORD 0x0005 +#define MBOX_MAILBOX_REG_TEST 0x0006 +#define MBOX_VERIFY_CHECKSUM 0x0007 +#define MBOX_ABOUT_FIRMWARE 0x0008 +#define MBOX_LOAD_RISC_RAM 0x0009 +#define MBOX_DUMP_RISC_RAM 0x000a +#define MBOX_CHECK_FIRMWARE 0x000e +#define MBOX_INIT_REQ_QUEUE 0x0010 +#define MBOX_INIT_RES_QUEUE 0x0011 +#define MBOX_EXECUTE_IOCB 0x0012 +#define MBOX_WAKE_UP 0x0013 +#define MBOX_STOP_FIRMWARE 0x0014 +#define MBOX_ABORT_IOCB 0x0015 +#define MBOX_ABORT_DEVICE 0x0016 +#define MBOX_ABORT_TARGET 0x0017 +#define MBOX_BUS_RESET 0x0018 +#define MBOX_STOP_QUEUE 0x0019 +#define MBOX_START_QUEUE 0x001a +#define MBOX_SINGLE_STEP_QUEUE 0x001b +#define MBOX_ABORT_QUEUE 0x001c +#define MBOX_GET_DEV_QUEUE_STATUS 0x001d +#define MBOX_GET_FIRMWARE_STATUS 0x001f +#define MBOX_GET_INIT_SCSI_ID 0x0020 +#define MBOX_GET_RETRY_COUNT 0x0022 +#define MBOX_GET_TARGET_PARAMS 0x0028 +#define MBOX_GET_DEV_QUEUE_PARAMS 0x0029 +#define MBOX_SET_RETRY_COUNT 0x0032 +#define MBOX_SET_TARGET_PARAMS 0x0038 +#define MBOX_SET_DEV_QUEUE_PARAMS 0x0039 +#define MBOX_EXECUTE_IOCB64 0x0054 +#define MBOX_INIT_FIRMWARE 0x0060 +#define MBOX_GET_INIT_CB 0x0061 +#define MBOX_INIT_LIP 0x0062 +#define MBOX_GET_POS_MAP 0x0063 +#define MBOX_GET_PORT_DB 0x0064 +#define MBOX_CLEAR_ACA 0x0065 +#define MBOX_TARGET_RESET 0x0066 +#define MBOX_CLEAR_TASK_SET 0x0067 +#define MBOX_ABORT_TASK_SET 0x0068 +#define MBOX_GET_FIRMWARE_STATE 0x0069 +#define MBOX_GET_PORT_NAME 0x006a +#define MBOX_SEND_SNS 0x006e +#define MBOX_PORT_LOGIN 0x006f +#define MBOX_SEND_CHANGE_REQUEST 0x0070 +#define MBOX_PORT_LOGOUT 0x0071 + +#include "qlogicfc_asm.c" + +/* Each element in mbox_param is an 8 bit bitmap where each bit indicates + if that mbox should be copied as input. For example 0x2 would mean + only copy mbox1. */ + +const u_char mbox_param[] = +{ + 0x01, /* MBOX_NO_OP */ + 0x1f, /* MBOX_LOAD_RAM */ + 0x03, /* MBOX_EXEC_FIRMWARE */ + 0x1f, /* MBOX_DUMP_RAM */ + 0x07, /* MBOX_WRITE_RAM_WORD */ + 0x03, /* MBOX_READ_RAM_WORD */ + 0xff, /* MBOX_MAILBOX_REG_TEST */ + 0x03, /* MBOX_VERIFY_CHECKSUM */ + 0x01, /* MBOX_ABOUT_FIRMWARE */ + 0xff, /* MBOX_LOAD_RISC_RAM */ + 0xff, /* MBOX_DUMP_RISC_RAM */ + 0x00, /* 0x000b */ + 0x00, /* 0x000c */ + 0x00, /* 0x000d */ + 0x01, /* MBOX_CHECK_FIRMWARE */ + 0x00, /* 0x000f */ + 0x1f, /* MBOX_INIT_REQ_QUEUE */ + 0x2f, /* MBOX_INIT_RES_QUEUE */ + 0x0f, /* MBOX_EXECUTE_IOCB */ + 0x03, /* MBOX_WAKE_UP */ + 0x01, /* MBOX_STOP_FIRMWARE */ + 0x0f, /* MBOX_ABORT_IOCB */ + 0x03, /* MBOX_ABORT_DEVICE */ + 0x07, /* MBOX_ABORT_TARGET */ + 0x03, /* MBOX_BUS_RESET */ + 0x03, /* MBOX_STOP_QUEUE */ + 0x03, /* MBOX_START_QUEUE */ + 0x03, /* MBOX_SINGLE_STEP_QUEUE */ + 0x03, /* MBOX_ABORT_QUEUE */ + 0x03, /* MBOX_GET_DEV_QUEUE_STATUS */ + 0x00, /* 0x001e */ + 0x01, /* MBOX_GET_FIRMWARE_STATUS */ + 0x01, /* MBOX_GET_INIT_SCSI_ID */ + 0x00, /* 0x0021 */ + 0x01, /* MBOX_GET_RETRY_COUNT */ + 0x00, /* 0x0023 */ + 0x00, /* 0x0024 */ + 0x00, /* 0x0025 */ + 0x00, /* 0x0026 */ + 0x00, /* 0x0027 */ + 0x03, /* MBOX_GET_TARGET_PARAMS */ + 0x03, /* MBOX_GET_DEV_QUEUE_PARAMS */ + 0x00, /* 0x002a */ + 0x00, /* 0x002b */ + 0x00, /* 0x002c */ + 0x00, /* 0x002d */ + 0x00, /* 0x002e */ + 0x00, /* 0x002f */ + 0x00, /* 0x0030 */ + 0x00, /* 0x0031 */ + 0x07, /* MBOX_SET_RETRY_COUNT */ + 0x00, /* 0x0033 */ + 0x00, /* 0x0034 */ + 0x00, /* 0x0035 */ + 0x00, /* 0x0036 */ + 0x00, /* 0x0037 */ + 0x0f, /* MBOX_SET_TARGET_PARAMS */ + 0x0f, /* MBOX_SET_DEV_QUEUE_PARAMS */ + 0x00, /* 0x003a */ + 0x00, /* 0x003b */ + 0x00, /* 0x003c */ + 0x00, /* 0x003d */ + 0x00, /* 0x003e */ + 0x00, /* 0x003f */ + 0x00, /* 0x0040 */ + 0x00, /* 0x0041 */ + 0x00, /* 0x0042 */ + 0x00, /* 0x0043 */ + 0x00, /* 0x0044 */ + 0x00, /* 0x0045 */ + 0x00, /* 0x0046 */ + 0x00, /* 0x0047 */ + 0x00, /* 0x0048 */ + 0x00, /* 0x0049 */ + 0x00, /* 0x004a */ + 0x00, /* 0x004b */ + 0x00, /* 0x004c */ + 0x00, /* 0x004d */ + 0x00, /* 0x004e */ + 0x00, /* 0x004f */ + 0x00, /* 0x0050 */ + 0x00, /* 0x0051 */ + 0x00, /* 0x0052 */ + 0x00, /* 0x0053 */ + 0xcf, /* MBOX_EXECUTE_IOCB64 */ + 0x00, /* 0x0055 */ + 0x00, /* 0x0056 */ + 0x00, /* 0x0057 */ + 0x00, /* 0x0058 */ + 0x00, /* 0x0059 */ + 0x00, /* 0x005a */ + 0x00, /* 0x005b */ + 0x00, /* 0x005c */ + 0x00, /* 0x005d */ + 0x00, /* 0x005e */ + 0x00, /* 0x005f */ + 0xff, /* MBOX_INIT_FIRMWARE */ + 0xcd, /* MBOX_GET_INIT_CB */ + 0x01, /* MBOX_INIT_LIP */ + 0xcd, /* MBOX_GET_POS_MAP */ + 0xcf, /* MBOX_GET_PORT_DB */ + 0x03, /* MBOX_CLEAR_ACA */ + 0x03, /* MBOX_TARGET_RESET */ + 0x03, /* MBOX_CLEAR_TASK_SET */ + 0x03, /* MBOX_ABORT_TASK_SET */ + 0x01, /* MBOX_GET_FIRMWARE_STATE */ + 0x03, /* MBOX_GET_PORT_NAME */ + 0x00, /* 0x006b */ + 0x00, /* 0x006c */ + 0x00, /* 0x006d */ + 0xcf, /* MBOX_SEND_SNS */ + 0x0f, /* MBOX_PORT_LOGIN */ + 0x03, /* MBOX_SEND_CHANGE_REQUEST */ + 0x03, /* MBOX_PORT_LOGOUT */ +}; + +#define MAX_MBOX_COMMAND (sizeof(mbox_param)/sizeof(u_short)) + + +struct id_name_map { + u64 wwn; + u_char loop_id; +}; + +struct sns_cb { + u_short len; + u_short res1; + u_int response_low; + u_int response_high; + u_short sub_len; + u_short res2; + u_short data[22]; +}; + +/* address of instance of this struct is passed to adapter to initialize things + */ +struct init_cb { + u_char version; + u_char reseverd1[1]; + u_short firm_opts; + u_short max_frame_len; + u_short max_iocb; + u_short exec_throttle; + u_char retry_cnt; + u_char retry_delay; + u_short node_name[4]; + u_short hard_addr; + u_char reserved2[10]; + u_short req_queue_out; + u_short res_queue_in; + u_short req_queue_len; + u_short res_queue_len; + u_int req_queue_addr_lo; + u_int req_queue_addr_high; + u_int res_queue_addr_lo; + u_int res_queue_addr_high; +}; + +/* + * The result queue can be quite a bit smaller since continuation entries + * do not show up there: + */ +#define RES_QUEUE_LEN ((QLOGICFC_REQ_QUEUE_LEN + 1) / 8 - 1) +#define QUEUE_ENTRY_LEN 64 + +#if ISP2100_FABRIC +#define QLOGICFC_MAX_ID 0xff +#else +#define QLOGICFC_MAX_ID 0x80 +#endif + +struct isp2100_hostdata { + u_char revision; + struct pci_dev *pci_dev; + /* result and request queues (shared with isp2100): */ + u_int req_in_ptr; /* index of next request slot */ + u_int res_out_ptr; /* index of next result slot */ + + /* 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]; + struct init_cb control_block; + int loop_up; + unsigned long int tag_ages[126]; + 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]; + u_char mbox_done; + u64 wwn; + u_int port_id; + u_char queued; +}; + + +/* queue length's _must_ be power of two: */ +#define QUEUE_DEPTH(in, out, ql) ((in - out) & (ql)) +#define REQ_QUEUE_DEPTH(in, out) QUEUE_DEPTH(in, out, \ + QLOGICFC_REQ_QUEUE_LEN) +#define RES_QUEUE_DEPTH(in, out) QUEUE_DEPTH(in, out, RES_QUEUE_LEN) + +static void isp2100_enable_irqs(struct Scsi_Host *); +static void isp2100_disable_irqs(struct Scsi_Host *); +static int isp2100_init(struct Scsi_Host *); +static int isp2100_reset_hardware(struct Scsi_Host *); +static int isp2100_mbox_command(struct Scsi_Host *, u_short[]); +static int isp2100_return_status(struct Status_Entry *); +static void isp2100_intr_handler(int, void *, struct pt_regs *); +static void do_isp2100_intr_handler(int, void *, struct pt_regs *); +static int isp2100_make_portdb(struct Scsi_Host *); + +#if ISP2100_FABRIC +static int isp2100_init_fabric(struct Scsi_Host *, struct id_name_map *, int); +#endif + +#if USE_NVRAM_DEFAULTS +static int isp2100_get_nvram_defaults(struct Scsi_Host *, struct init_cb *); +static u_short isp2100_read_nvram_word(struct Scsi_Host *, u_short); +#endif + +#if DEBUG_ISP2100 +static void isp2100_print_scsi_cmd(Scsi_Cmnd *); +#endif + +#if DEBUG_ISP2100_INTR +static void isp2100_print_status_entry(struct Status_Entry *); +#endif + +static struct proc_dir_entry proc_scsi_isp2100 = +{ + PROC_SCSI_QLOGICFC, 7, "isp2100", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; + + +static inline void isp2100_enable_irqs(struct Scsi_Host *host) +{ + outw(ISP_EN_INT | ISP_EN_RISC, host->io_port + PCI_INTER_CTL); +} + + +static inline void isp2100_disable_irqs(struct Scsi_Host *host) +{ + outw(0x0, host->io_port + PCI_INTER_CTL); +} + + +int isp2100_detect(Scsi_Host_Template * tmpt) +{ + int hosts = 0; + int wait_time; + struct Scsi_Host *host = NULL; + struct isp2100_hostdata *hostdata; + struct pci_dev *pdev = NULL; + + ENTER("isp2100_detect"); + + tmpt->proc_dir = &proc_scsi_isp2100; + + if (pci_present() == 0) { + printk("qlogicfc : PCI not present\n"); + return 0; + } + while ((pdev = pci_find_device(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100, pdev))) { + + host = scsi_register(tmpt, sizeof(struct isp2100_hostdata)); + host->max_id = QLOGICFC_MAX_ID + 1; + host->hostt->use_new_eh_code = 1; + hostdata = (struct isp2100_hostdata *) host->hostdata; + + memset(hostdata, 0, sizeof(struct isp2100_hostdata)); + hostdata->pci_dev = pdev; + + hostdata->queued = 0; + /* set up the control block */ + hostdata->control_block.version = 0x0f; + hostdata->control_block.firm_opts = 0x010c; + hostdata->control_block.max_frame_len = 2048; + hostdata->control_block.max_iocb = 256; + hostdata->control_block.exec_throttle = 8; + hostdata->control_block.retry_delay = 5; + hostdata->control_block.retry_cnt = 0; + hostdata->control_block.node_name[0] = 0x0020; + hostdata->control_block.node_name[1] = 0xE000; + hostdata->control_block.node_name[2] = 0x008B; + hostdata->control_block.node_name[3] = 0x0000; + 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->loop_up = 0; + + if (isp2100_init(host) || isp2100_reset_hardware(host)) { + scsi_unregister(host); + continue; + } + host->this_id = tmpt->this_id; + + if (request_irq(host->irq, do_isp2100_intr_handler, SA_INTERRUPT | SA_SHIRQ, "qlogicfc", host)) { + printk("qlogicfc : interrupt %d already in use\n", + host->irq); + scsi_unregister(host); + continue; + } + if (check_region(host->io_port, 0xff)) { + printk("qlogicfc : i/o region 0x%lx-0x%lx already " + "in use\n", + host->io_port, host->io_port + 0xff); + free_irq(host->irq, host); + scsi_unregister(host); + continue; + } + request_region(host->io_port, 0xff, "qlogicfc"); + + outw(0x0, host->io_port + PCI_SEMAPHORE); + outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR); + isp2100_enable_irqs(host); + /* wait for the loop to come up */ + for (wait_time = jiffies + 20 * HZ; wait_time > jiffies && hostdata->loop_up == 0;) + barrier(); + + if (hostdata->loop_up == 0) { + printk("qlogicfc: loop is not up\n"); + release_region(host->io_port, 0xff); + free_irq(host->irq, host); + scsi_unregister(host); + continue; + } + hosts++; + } + + + /* this busy loop should not be needed but the isp2100 seems to need + some time before recognizing it is attached to a fabric */ + +#if ISP2100_FABRIC + for (wait_time = jiffies + 5 * HZ; wait_time > jiffies;) + barrier(); +#endif + + LEAVE("isp2100_detect"); + + return hosts; +} + + +static int isp2100_make_portdb(struct Scsi_Host *host) +{ + + short param[8]; + int i, j; + struct id_name_map temp[QLOGICFC_MAX_ID + 1]; + struct isp2100_hostdata *hostdata; + + isp2100_disable_irqs(host); + + memset(temp, 0, sizeof(temp)); + hostdata = (struct isp2100_hostdata *) host->hostdata; + +#if ISP2100_FABRIC + for (i = 0x81; i < QLOGICFC_MAX_ID; i++) { + param[0] = MBOX_PORT_LOGOUT; + param[1] = i << 8; + param[2] = 0; + param[3] = 0; + + isp2100_mbox_command(host, param); + + if (param[0] != MBOX_COMMAND_COMPLETE) { + printk("logout failed %x %x\n", i, param[0]); + } + } +#endif + + + param[0] = MBOX_GET_INIT_SCSI_ID; + + isp2100_mbox_command(host, param); + + if (param[0] == MBOX_COMMAND_COMPLETE) { + host->this_id = param[1]; + hostdata->port_id = ((u_int) param[3]) << 16; + hostdata->port_id |= param[2]; + } + + for (i = 0, j = 0; i <= QLOGICFC_MAX_ID; i++) { + temp[i].loop_id = host->this_id; + + param[0] = MBOX_GET_PORT_NAME; + param[1] = (i << 8) & 0xff00; + + isp2100_mbox_command(host, param); + + if (param[0] == MBOX_COMMAND_COMPLETE) { + temp[j].loop_id = i; + temp[j].wwn = ((u64) (param[2] & 0xff)) << 56; + temp[j].wwn |= ((u64) ((param[2] >> 8) & 0xff)) << 48; + temp[j].wwn |= ((u64) (param[3] & 0xff)) << 40; + temp[j].wwn |= ((u64) ((param[3] >> 8) & 0xff)) << 32; + temp[j].wwn |= ((u64) (param[6] & 0xff)) << 24; + temp[j].wwn |= ((u64) ((param[6] >> 8) & 0xff)) << 16; + temp[j].wwn |= ((u64) (param[7] & 0xff)) << 8; + temp[j].wwn |= ((u64) ((param[7] >> 8) & 0xff)); + + j++; + + } + } + + +#if ISP2100_FABRIC + isp2100_init_fabric(host, temp, j); +#endif + + for (i = 0; i <= QLOGICFC_MAX_ID; i++) { + if (temp[i].wwn != hostdata->port_db[i].wwn) { + for (j = 0; j <= QLOGICFC_MAX_ID; j++) { + if (temp[j].wwn == hostdata->port_db[i].wwn) { + hostdata->port_db[i].loop_id = temp[j].loop_id; + break; + } + } + if (j == QLOGICFC_MAX_ID + 1) + hostdata->port_db[i].loop_id = host->this_id; + + for (j = 0; j <= QLOGICFC_MAX_ID; j++) { + if (hostdata->port_db[j].wwn == temp[i].wwn || !hostdata->port_db[j].wwn) { + break; + } + } + if (j == QLOGICFC_MAX_ID + 1) + printk("qlogicfc.c: Too many scsi devices, no more room in port map.\n"); + if (!hostdata->port_db[j].wwn) { + hostdata->port_db[j].loop_id = temp[i].loop_id; + hostdata->port_db[j].wwn = temp[i].wwn; + } + } else + hostdata->port_db[i].loop_id = temp[i].loop_id; + + } + + isp2100_enable_irqs(host); + + return 0; +} + + +#if ISP2100_FABRIC + +int isp2100_init_fabric(struct Scsi_Host *host, struct id_name_map *port_db, int j) +{ + + u_short param[8]; + u64 wwn; + int done = 0; + u_short loop_id = 0x81; + u_short scsi_id = j; + u_int port_id; + struct sns_cb req; + u_char sns_response[608]; + struct isp2100_hostdata *hostdata; + + hostdata = (struct isp2100_hostdata *) host->hostdata; + + DEBUG_FABRIC(printk("qlogicfc.c: Checking for a fabric.\n")); + param[0] = MBOX_GET_PORT_NAME; + param[1] = 0x7E00; + + isp2100_mbox_command(host, param); + + if (param[0] != MBOX_COMMAND_COMPLETE) { + DEBUG_FABRIC(printk("fabric check result %x\n", param[0])); + return 0; + } + printk("qlogicfc.c: Fabric found.\n"); + + + port_id = hostdata->port_id; + while (!done) { + memset(&req, 0, sizeof(req)); + + req.len = 304; + req.response_low = virt_to_bus_low32(sns_response); + req.response_high = virt_to_bus_high32(sns_response); + req.sub_len = 6; + req.data[0] = 0x0100; + req.data[4] = (u_short) (port_id & 0xffff); + req.data[5] = (u_short) (port_id >> 16 & 0xffff); + + param[0] = MBOX_SEND_SNS; + param[1] = 14; + param[2] = virt_to_bus_low32(&req) >> 16; + param[3] = virt_to_bus_low32(&req); + param[6] = virt_to_bus_high32(&req) >> 16; + param[7] = virt_to_bus_high32(&req); + + isp2100_mbox_command(host, param); + + if (param[0] == MBOX_COMMAND_COMPLETE) { + DEBUG_FABRIC(printk("found node %02x%02x%02x%02x%02x%02x%02x%02x ", sns_response[20], sns_response[21], sns_response[22], sns_response[23], sns_response[24], sns_response[25], sns_response[26], sns_response[27])); + DEBUG_FABRIC(printk(" port id: %02x%02x%02x\n", sns_response[17], sns_response[18], sns_response[19])); + port_id = ((u_int) sns_response[17]) << 16; + port_id |= ((u_int) sns_response[18]) << 8; + port_id |= ((u_int) sns_response[19]); + wwn = ((u64) sns_response[20]) << 56; + wwn |= ((u64) sns_response[21]) << 48; + wwn |= ((u64) sns_response[22]) << 40; + wwn |= ((u64) sns_response[23]) << 32; + wwn |= ((u64) sns_response[24]) << 24; + wwn |= ((u64) sns_response[25]) << 16; + wwn |= ((u64) sns_response[26]) << 8; + wwn |= ((u64) sns_response[27]); + if (hostdata->port_id >> 8 != port_id >> 8) { + DEBUG_FABRIC(printk("adding a fabric port: %x\n", port_id)); + param[0] = MBOX_PORT_LOGIN; + param[1] = loop_id << 8; + param[2] = (u_short) (port_id >> 16); + param[3] = (u_short) (port_id); + + isp2100_mbox_command(host, param); + + if (param[0] == MBOX_COMMAND_COMPLETE) { + port_db[scsi_id].wwn = wwn; + port_db[scsi_id].loop_id = loop_id; + loop_id++; + scsi_id++; + } else { + printk("qlogicfc.c: Error performing port login %x\n", param[0]); + DEBUG_FABRIC(printk("loop_id: %x\n", loop_id)); + } + + } + if (hostdata->port_id == port_id) + done = 1; + } else { + printk("qlogicfc.c: Get All Next failed %x.\n", param[0]); + return 0; + } + } + + return 1; +} + +#endif /* ISP2100_FABRIC */ + + +int isp2100_release(struct Scsi_Host *host) +{ + struct isp2100_hostdata *hostdata; + + ENTER("isp2100_release"); + + hostdata = (struct isp2100_hostdata *) host->hostdata; + + outw(0x0, host->io_port + PCI_INTER_CTL); + free_irq(host->irq, host); + + release_region(host->io_port, 0xff); + + LEAVE("isp2100_release"); + + return 0; +} + + +const char *isp2100_info(struct Scsi_Host *host) +{ + static char buf[80]; + struct isp2100_hostdata *hostdata; + ENTER("isp2100_info"); + + hostdata = (struct isp2100_hostdata *) host->hostdata; + sprintf(buf, + "QLogic ISP2100 SCSI on PCI bus %02x device %02x irq %d base 0x%lx", + hostdata->pci_dev->bus->number, hostdata->pci_dev->devfn, host->irq, + host->io_port); + + + LEAVE("isp2100_info"); + + return buf; +} + + +/* + * The middle SCSI layer ensures that queuecommand never gets invoked + * concurrently with itself or the interrupt handler (though the + * interrupt handler may call this routine as part of + * request-completion handling). + */ +int isp2100_queuecommand(Scsi_Cmnd * Cmnd, void (*done) (Scsi_Cmnd *)) +{ + int i, sg_count, n, num_free; + u_int in_ptr, out_ptr; + struct dataseg *ds; + struct scatterlist *sg; + struct Command_Entry *cmd; + struct Continuation_Entry *cont; + struct Scsi_Host *host; + struct isp2100_hostdata *hostdata; + + ENTER("isp2100_queuecommand"); + + host = Cmnd->host; + hostdata = (struct isp2100_hostdata *) host->hostdata; + Cmnd->scsi_done = done; + + DEBUG(isp2100_print_scsi_cmd(Cmnd)); + + if (hostdata->loop_up == 2) { + hostdata->loop_up = 1; + isp2100_make_portdb(host); + for (i = 0; hostdata->port_db[i].wwn != 0; i++) { + DEBUG(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)); + } + } + if (hostdata->loop_up == -1) { + printk("qlogicfc.c: The firmware is dead, just return.\n"); + host->max_id = 0; + return 0; + } + out_ptr = inw(host->io_port + MBOX4); + in_ptr = hostdata->req_in_ptr; + + DEBUG(printk("qlogicfc : request queue depth %d\n", + REQ_QUEUE_DEPTH(in_ptr, out_ptr))); + + cmd = (struct Command_Entry *) &hostdata->req[in_ptr][0]; + in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN; + if (in_ptr == out_ptr) { + DEBUG(printk("qlogicfc : request queue overflow\n")); + return 1; + } + if (hostdata->send_marker) { + struct Marker_Entry *marker; + + TRACE("queue marker", in_ptr, 0); + + DEBUG(printk("qlogicfc : adding marker entry\n")); + marker = (struct Marker_Entry *) cmd; + memset(marker, 0, sizeof(struct Marker_Entry)); + + marker->hdr.entry_type = ENTRY_MARKER; + marker->hdr.entry_cnt = 1; + marker->modifier = SYNC_ALL; + + hostdata->send_marker = 0; + + if (((in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN) == out_ptr) { + outw(in_ptr, host->io_port + MBOX4); + hostdata->req_in_ptr = in_ptr; + DEBUG(printk("qlogicfc : request queue overflow\n")); + return 1; + } + cmd = (struct Command_Entry *) &hostdata->req[in_ptr][0]; + in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN; + } + TRACE("queue command", in_ptr, Cmnd); + + memset(cmd, 0, sizeof(struct Command_Entry)); + + /* find a free handle mapping slot */ + for (i = in_ptr; i != (in_ptr - 1) && hostdata->handle_ptrs[i]; i = ((i + 1) % (QLOGICFC_REQ_QUEUE_LEN + 1))); + + if (!hostdata->handle_ptrs[i]) { + cmd->handle = i; + hostdata->handle_ptrs[i] = Cmnd; + hostdata->handle_serials[i] = Cmnd->serial_number; + } else + printk("qlogicfc: no handle slots, this should not happen.\n"); + + cmd->hdr.entry_type = ENTRY_COMMAND; + cmd->hdr.entry_cnt = 1; + cmd->target_lun = Cmnd->lun; + cmd->target_id = hostdata->port_db[Cmnd->target].loop_id; + cmd->total_byte_cnt = (u_int) Cmnd->request_bufflen; + cmd->time_out = SCSI_TIMEOUT / HZ; + + memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len); + + if (Cmnd->use_sg) { + cmd->segment_cnt = sg_count = Cmnd->use_sg; + sg = (struct scatterlist *) Cmnd->request_buffer; + ds = cmd->dataseg; + /* fill in first two sg entries: */ + n = sg_count; + if (n > 2) + n = 2; + for (i = 0; i < n; i++) { + ds[i].d_base_lo = virt_to_bus_low32(sg->address); + ds[i].d_base_high = virt_to_bus_high32(sg->address); + ds[i].d_count = sg->length; + ++sg; + } + sg_count -= 2; + + while (sg_count > 0) { + ++cmd->hdr.entry_cnt; + cont = (struct Continuation_Entry *) + &hostdata->req[in_ptr][0]; + memset(cont, 0, sizeof(struct Continuation_Entry)); + in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN; + if (in_ptr == out_ptr) { + DEBUG(printk("isp2100: unexpected request queue overflow\n")); + return 1; + } + TRACE("queue continuation", in_ptr, 0); + cont->hdr.entry_type = ENTRY_CONTINUATION; + ds = cont->dataseg; + n = sg_count; + if (n > 5) + n = 5; + for (i = 0; i < n; ++i) { + ds[i].d_base_lo = virt_to_bus_low32(sg->address); + ds[i].d_base_high = virt_to_bus_high32(sg->address); + ds[i].d_count = sg->length; + ++sg; + } + sg_count -= n; + } + } else { + cmd->dataseg[0].d_base_lo = virt_to_bus_low32(Cmnd->request_buffer); + cmd->dataseg[0].d_base_high = virt_to_bus_high32(Cmnd->request_buffer); + cmd->dataseg[0].d_count = + (u_int) Cmnd->request_bufflen; + cmd->segment_cnt = 1; + } + + switch (Cmnd->cmnd[0]) { + case WRITE_10: + case WRITE_6: + case WRITE_BUFFER: + cmd->control_flags = CFLAG_WRITE; + break; + case REQUEST_SENSE: + /* scsi.c expects sense info in a different buffer */ + cmd->dataseg[0].d_base_lo = virt_to_bus_low32(Cmnd->sense_buffer); + cmd->dataseg[0].d_base_high = virt_to_bus_high32(Cmnd->sense_buffer); + cmd->segment_cnt = 1; + cmd->control_flags = CFLAG_READ; + break; + default: + cmd->control_flags = CFLAG_READ; + break; + } + + + if (Cmnd->device->tagged_supported) { + switch (Cmnd->tag) { + case SIMPLE_QUEUE_TAG: + cmd->control_flags |= CFLAG_SIMPLE_TAG; + break; + case HEAD_OF_QUEUE_TAG: + cmd->control_flags |= CFLAG_HEAD_TAG; + break; + case ORDERED_QUEUE_TAG: + cmd->control_flags |= CFLAG_ORDERED_TAG; + break; + default: + if ((jiffies - hostdata->tag_ages[Cmnd->target]) > (5 * HZ)) { + cmd->control_flags |= CFLAG_ORDERED_TAG; + hostdata->tag_ages[Cmnd->target] = jiffies; + } else + cmd->control_flags |= CFLAG_SIMPLE_TAG; + } + } + outw(in_ptr, host->io_port + MBOX4); + hostdata->req_in_ptr = in_ptr; + + hostdata->queued++; + + num_free = QLOGICFC_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr); + num_free = num_free - 2; + host->can_queue = hostdata->queued + num_free; + if (host->can_queue > QLOGICFC_REQ_QUEUE_LEN) + host->can_queue = QLOGICFC_REQ_QUEUE_LEN; + host->sg_tablesize = QLOGICFC_MAX_SG(num_free); + + /* this is really gross */ + if (host->can_queue < host->host_busy){ + if (host->can_queue+2 < host->host_busy) + printk("qlogicfc.c crosses its fingers.\n"); + host->can_queue = host->host_busy; + } + + LEAVE("isp2100_queuecommand"); + + return 0; +} + + +#define ASYNC_EVENT_INTERRUPT 0x01 + + +void do_isp2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned long flags; + + spin_lock_irqsave(&io_request_lock, flags); + isp2100_intr_handler(irq, dev_id, regs); + spin_unlock_irqrestore(&io_request_lock, flags); +} + +void isp2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + Scsi_Cmnd *Cmnd; + struct Status_Entry *sts; + struct Scsi_Host *host = dev_id; + struct isp2100_hostdata *hostdata; + u_int in_ptr, out_ptr, handle, num_free; + u_short status; + + ENTER_INTR("isp2100_intr_handler"); + + hostdata = (struct isp2100_hostdata *) host->hostdata; + + DEBUG_INTR(printk("qlogicfc : interrupt on line %d\n", irq)); + + if (!(inw(host->io_port + PCI_INTER_STS) & 0x08)) { + /* spurious interrupts can happen legally */ + DEBUG_INTR(printk("qlogicfc: got spurious interrupt\n")); + return; + } + in_ptr = inw(host->io_port + MBOX5); + out_ptr = hostdata->res_out_ptr; + + if ((inw(host->io_port + PCI_SEMAPHORE) & ASYNC_EVENT_INTERRUPT)) { + status = inw(host->io_port + MBOX0); + + DEBUG_INTR(printk("qlogicfc : mbox completion status: %x\n", + status)); + + switch (status) { + case LOOP_UP: + hostdata->loop_up = 2; + break; + case LOOP_DOWN: + hostdata->loop_up = 0; + break; + case LIP_OCCURED: + case CHANGE_NOTIFICATION: + case PORT_DB_CHANGED: + case LIP_RECEIVED: + if (hostdata->loop_up == 1) + hostdata->loop_up = 2; + break; + case SYSTEM_ERROR: + printk("The firmware just choked.\n"); + hostdata->loop_up = -1; + break; + case SCSI_COMMAND_COMPLETE: + handle = inw(host->io_port + MBOX1) | (inw(host->io_port + MBOX2) << 16); + Cmnd = hostdata->handle_ptrs[handle]; + hostdata->handle_ptrs[handle] = NULL; + hostdata->handle_serials[handle] = 0; + hostdata->queued--; + if (Cmnd != NULL) { + Cmnd->result = 0x0; + (*Cmnd->scsi_done) (Cmnd); + } else + printk("qlogicfc.c: got a null value out of handle_ptrs, this sucks\n"); + break; + case MBOX_COMMAND_COMPLETE: + case INVALID_COMMAND: + case HOST_INTERFACE_ERROR: + case TEST_FAILED: + case COMMAND_ERROR: + case COMMAND_PARAM_ERROR: + case PORT_ID_USED: + case LOOP_ID_USED: + case ALL_IDS_USED: + hostdata->mbox_done = 1; + outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR); + return; + default: + printk("qlogicfc: got an unknown status? %x\n", status); + } + outw(0x0, host->io_port + PCI_SEMAPHORE); + } else { + DEBUG_INTR(printk("qlogicfc : response queue update\n")); + DEBUG_INTR(printk("qlogicfc : response queue depth %d\n", RES_QUEUE_DEPTH(in_ptr, out_ptr))); + + while (out_ptr != in_ptr) { + sts = (struct Status_Entry *) &hostdata->res[out_ptr][0]; + out_ptr = (out_ptr + 1) & RES_QUEUE_LEN; + Cmnd = hostdata->handle_ptrs[sts->handle]; + + hostdata->handle_ptrs[sts->handle] = NULL; + + if (hostdata->handle_serials[sts->handle] != Cmnd->serial_number) { + hostdata->queued--; + hostdata->handle_serials[sts->handle] = 0; + outw(out_ptr, host->io_port + MBOX5); + continue; + } + hostdata->handle_serials[sts->handle] = 0; + + TRACE("done", out_ptr, Cmnd); + DEBUG_INTR(isp2100_print_status_entry(sts)); + if (sts->hdr.entry_type == ENTRY_STATUS) { + Cmnd->result = isp2100_return_status(sts); + } else { + outw(out_ptr, host->io_port + MBOX5); + continue; + } + + if (sts->completion_status == CS_RESET_OCCURRED + || sts->completion_status == CS_ABORTED + || (sts->status_flags & STF_BUS_RESET)) + hostdata->send_marker = 1; + + if (sts->scsi_status & 0x0200) + memcpy(Cmnd->sense_buffer, sts->req_sense_data, + sizeof(Cmnd->sense_buffer)); + + outw(out_ptr, host->io_port + MBOX5); + + hostdata->queued--; + if (Cmnd->scsi_done != NULL) { + (*Cmnd->scsi_done) (Cmnd); + } else + printk("Ouch, scsi done is NULL\n"); + } + hostdata->res_out_ptr = out_ptr; + } + + + out_ptr = inw(host->io_port + MBOX4); + in_ptr = hostdata->req_in_ptr; + + num_free = QLOGICFC_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr); + num_free = num_free-2; + host->can_queue = hostdata->queued + num_free; + if (host->can_queue > QLOGICFC_REQ_QUEUE_LEN) + host->can_queue = QLOGICFC_REQ_QUEUE_LEN; + host->sg_tablesize = QLOGICFC_MAX_SG(num_free); + + if (host->can_queue < host->host_busy){ + if (host->can_queue+2 < host->host_busy) + DEBUG(printk("qlogicfc crosses its fingers.\n")); + host->can_queue = host->host_busy; + } + + outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR); + LEAVE_INTR("isp2100_intr_handler"); +} + + +static int isp2100_return_status(struct Status_Entry *sts) +{ + int host_status = DID_ERROR; +#if DEBUG_ISP2100_INTR + static char *reason[] = + { + "DID_OK", + "DID_NO_CONNECT", + "DID_BUS_BUSY", + "DID_TIME_OUT", + "DID_BAD_TARGET", + "DID_ABORT", + "DID_PARITY", + "DID_ERROR", + "DID_RESET", + "DID_BAD_INTR" + }; +#endif /* DEBUG_ISP2100_INTR */ + + ENTER("isp2100_return_status"); + + DEBUG(printk("qlogicfc : completion status = 0x%04x\n", + sts->completion_status)); + + switch (sts->completion_status) { + case CS_COMPLETE: + host_status = DID_OK; + break; + case CS_INCOMPLETE: + if (!(sts->state_flags & SF_SENT_CDB)) + host_status = DID_ERROR; + else if (!(sts->state_flags & SF_TRANSFERRED_DATA)) + host_status = DID_ERROR; + else if (!(sts->state_flags & SF_GOT_STATUS)) + host_status = DID_ERROR; + break; + case CS_DMA_ERROR: + case CS_TRANSPORT_ERROR: + host_status = DID_ERROR; + break; + case CS_RESET_OCCURRED: + host_status = DID_RESET; + break; + case CS_ABORTED: + host_status = DID_ABORT; + break; + case CS_TIMEOUT: + host_status = DID_TIME_OUT; + break; + case CS_DATA_OVERRUN: + case CS_ABORT_MSG_FAILED: + host_status = DID_ERROR; + break; + case CS_DATA_UNDERRUN: + host_status = DID_OK; + break; + case CS_PORT_UNAVAILABLE: + case CS_PORT_LOGGED_OUT: + case CS_PORT_CONFIG_CHANGED: + host_status = DID_BAD_TARGET; + break; + default: + printk("qlogicfc : unknown completion status 0x%04x\n", + sts->completion_status); + host_status = DID_ERROR; + break; + } + + DEBUG_INTR(printk("qlogicfc : host status (%s) scsi status %x\n", + reason[host_status], sts->scsi_status)); + + LEAVE("isp2100_return_status"); + + return (sts->scsi_status & STATUS_MASK) | (host_status << 16); +} + + +int isp2100_abort(Scsi_Cmnd * Cmnd) +{ + u_short param[8]; + int i; + struct Scsi_Host *host; + struct isp2100_hostdata *hostdata; + int return_status = SCSI_ABORT_SUCCESS; + + ENTER("isp2100_abort"); + + host = Cmnd->host; + hostdata = (struct isp2100_hostdata *) host->hostdata; + + for (i = 0; i < QLOGICFC_REQ_QUEUE_LEN; i++) + if (hostdata->handle_ptrs[i] == Cmnd) + break; + + if (i == QLOGICFC_REQ_QUEUE_LEN) + return SCSI_ABORT_ERROR; + + isp2100_disable_irqs(host); + + param[0] = MBOX_ABORT_IOCB; + param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun; + param[2] = i >> 16; + param[3] = i & 0xffff; + + isp2100_mbox_command(host, param); + + if (param[0] != MBOX_COMMAND_COMPLETE) { + printk("qlogicfc : scsi abort failure: %x\n", param[0]); + if (param[0] == 0x4005) + Cmnd->result = DID_ERROR << 16; + if (param[0] == 0x4006) + Cmnd->result = DID_BAD_TARGET << 16; + (*Cmnd->scsi_done) (Cmnd); + return_status = SCSI_ABORT_ERROR; + } + isp2100_enable_irqs(host); + + LEAVE("isp2100_abort"); + + return return_status; +} + + +int isp2100_reset(Scsi_Cmnd * Cmnd, unsigned int reset_flags) +{ + u_short param[8]; + struct Scsi_Host *host; + struct isp2100_hostdata *hostdata; + int return_status = SCSI_RESET_SUCCESS; + + ENTER("isp2100_reset"); + + host = Cmnd->host; + hostdata = (struct isp2100_hostdata *) host->hostdata; + param[0] = MBOX_BUS_RESET; + param[1] = 3; + + isp2100_disable_irqs(host); + + isp2100_mbox_command(host, param); + + if (param[0] != MBOX_COMMAND_COMPLETE) { + printk("qlogicfc : scsi bus reset failure: %x\n", param[0]); + return_status = SCSI_RESET_ERROR; + } + isp2100_enable_irqs(host); + + LEAVE("isp2100_reset"); + + return return_status;; +} + + +int isp2100_biosparam(Disk * disk, kdev_t n, int ip[]) +{ + int size = disk->capacity; + + ENTER("isp2100_biosparam"); + + ip[0] = 64; + ip[1] = 32; + ip[2] = size >> 11; + if (ip[2] > 1024) { + ip[0] = 255; + ip[1] = 63; + ip[2] = size / (ip[0] * ip[1]); + if (ip[2] > 1023) + ip[2] = 1023; + } + LEAVE("isp2100_biosparam"); + + return 0; +} + + +static int isp2100_reset_hardware(struct Scsi_Host *host) +{ + u_short param[8]; + struct isp2100_hostdata *hostdata; + int loop_count; + + ENTER("isp2100_reset_hardware"); + + outw(0x01, host->io_port + ISP_CTRL_STATUS); + outw(HCCR_RESET, host->io_port + HOST_HCCR); + outw(HCCR_RELEASE, host->io_port + HOST_HCCR); + outw(HCCR_BIOS_DISABLE, host->io_port + HOST_HCCR); + + loop_count = DEFAULT_LOOP_COUNT; + while (--loop_count && inw(host->io_port + HOST_HCCR) == RISC_BUSY) + barrier(); + if (!loop_count) + printk("qlogicfc: reset_hardware loop timeout\n"); + + + +#if DEBUG_ISP2100 + printk("qlogicfc : mbox 0 0x%04x \n", inw(host->io_port + MBOX0)); + printk("qlogicfc : mbox 1 0x%04x \n", inw(host->io_port + MBOX1)); + printk("qlogicfc : mbox 2 0x%04x \n", inw(host->io_port + MBOX2)); + printk("qlogicfc : mbox 3 0x%04x \n", inw(host->io_port + MBOX3)); + printk("qlogicfc : mbox 4 0x%04x \n", inw(host->io_port + MBOX4)); + printk("qlogicfc : mbox 5 0x%04x \n", inw(host->io_port + MBOX5)); + printk("qlogicfc : mbox 6 0x%04x \n", inw(host->io_port + MBOX6)); + printk("qlogicfc : mbox 7 0x%04x \n", inw(host->io_port + MBOX7)); +#endif /* DEBUG_ISP2100 */ + + DEBUG(printk("qlogicfc : verifying checksum\n")); + +#if RELOAD_FIRMWARE + { + int i; + for (i = 0; i < risc_code_length01; i++) { + param[0] = MBOX_WRITE_RAM_WORD; + param[1] = risc_code_addr01 + i; + param[2] = risc_code01[i]; + + isp2100_mbox_command(host, param); + + if (param[0] != MBOX_COMMAND_COMPLETE) { + printk("qlogicfc : firmware load failure\n"); + return 1; + } + } + } +#endif /* RELOAD_FIRMWARE */ + + param[0] = MBOX_VERIFY_CHECKSUM; + param[1] = risc_code_addr01; + + isp2100_mbox_command(host, param); + + if (param[0] != MBOX_COMMAND_COMPLETE) { + printk("qlogicfc : ram checksum failure\n"); + return 1; + } + DEBUG(printk("qlogicfc : executing firmware\n")); + + param[0] = MBOX_EXEC_FIRMWARE; + param[1] = risc_code_addr01; + + isp2100_mbox_command(host, param); + + param[0] = MBOX_ABOUT_FIRMWARE; + + isp2100_mbox_command(host, param); + + if (param[0] != MBOX_COMMAND_COMPLETE) { + printk("qlogicfc : about firmware failure\n"); + return 1; + } + DEBUG(printk("qlogicfc : firmware major revision %d\n", param[1])); + DEBUG(printk("qlogicfc : firmware minor revision %d\n", param[2])); + + hostdata = (struct isp2100_hostdata *) host->hostdata; + +#ifdef USE_NVRAM_DEFAULTS + + if (isp2100_get_nvram_defaults(host, &hostdata->control_block) != 0) { + printk("qlogicfc: Could not read from NVRAM\n"); + } +#endif + + hostdata->wwn = (u64) (hostdata->control_block.node_name[0]) << 56; + hostdata->wwn |= (u64) (hostdata->control_block.node_name[0] & 0xff00) << 48; + hostdata->wwn |= (u64) (hostdata->control_block.node_name[1] & 0xff00) << 24; + hostdata->wwn |= (u64) (hostdata->control_block.node_name[1] & 0x00ff) << 48; + hostdata->wwn |= (u64) (hostdata->control_block.node_name[2] & 0x00ff) << 24; + hostdata->wwn |= (u64) (hostdata->control_block.node_name[2] & 0xff00) << 8; + hostdata->wwn |= (u64) (hostdata->control_block.node_name[3] & 0x00ff) << 8; + hostdata->wwn |= (u64) (hostdata->control_block.node_name[3] & 0xff00) >> 8; + + param[0] = MBOX_INIT_FIRMWARE; + param[2] = (u_short) (virt_to_bus_low32(&hostdata->control_block) >> 16); + param[3] = (u_short) (virt_to_bus_low32(&hostdata->control_block) & 0xffff); + param[4] = 0; + param[5] = 0; + param[6] = (u_short) (virt_to_bus_high32(&hostdata->control_block) >> 16); + param[7] = (u_short) (virt_to_bus_high32(&hostdata->control_block) & 0xffff); + isp2100_mbox_command(host, param); + if (param[0] != MBOX_COMMAND_COMPLETE) { + printk("qlogicfc.c: Ouch 0x%04x\n", param[0]); + return 1; + } + param[0] = MBOX_GET_FIRMWARE_STATE; + isp2100_mbox_command(host, param); + if (param[0] != MBOX_COMMAND_COMPLETE) { + printk("qlogicfc.c: 0x%04x\n", param[0]); + return 1; + } + + LEAVE("isp2100_reset_hardware"); + + return 0; +} + +#ifdef USE_NVRAM_DEFAULTS + +static int isp2100_get_nvram_defaults(struct Scsi_Host *host, struct init_cb *control_block) +{ + + u_short value; + if (isp2100_read_nvram_word(host, 0) != 0x5349) + return 1; + + control_block->max_frame_len = isp2100_read_nvram_word(host, 5); + control_block->max_iocb = isp2100_read_nvram_word(host, 6); + control_block->exec_throttle = isp2100_read_nvram_word(host, 7); + value = isp2100_read_nvram_word(host, 8); + control_block->node_name[0] = isp2100_read_nvram_word(host, 9); + control_block->node_name[1] = isp2100_read_nvram_word(host, 10); + control_block->node_name[2] = isp2100_read_nvram_word(host, 11); + control_block->node_name[3] = isp2100_read_nvram_word(host, 12); + control_block->hard_addr = isp2100_read_nvram_word(host, 13); + + return 0; + +} + +#endif + +static int isp2100_init(struct Scsi_Host *sh) +{ + u_int io_base; + struct isp2100_hostdata *hostdata; + u_char revision; + u_int irq; + u_short command; + struct pci_dev *pdev; + + + ENTER("isp2100_init"); + + hostdata = (struct isp2100_hostdata *) sh->hostdata; + pdev = hostdata->pci_dev; + + if (pci_read_config_word(pdev, PCI_COMMAND, &command) + || pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision)) { + printk("qlogicfc : error reading PCI configuration\n"); + return 1; + } + io_base = pdev->base_address[0]; + irq = pdev->irq; + + + + if (pdev->vendor != PCI_VENDOR_ID_QLOGIC) { + printk("qlogicfc : 0x%04x is not QLogic vendor ID\n", + pdev->vendor); + return 1; + } + if (pdev->device != PCI_DEVICE_ID_QLOGIC_ISP2100) { + printk("qlogicfc : 0x%04x does not match ISP2100 device id\n", + pdev->device); + return 1; + } + if (command & PCI_COMMAND_IO && (io_base & 3) == 1) + io_base &= PCI_BASE_ADDRESS_IO_MASK; + else { + printk("qlogicfc : i/o mapping is disabled\n"); + return 1; + } + + if (!(command & PCI_COMMAND_MASTER)) { + printk("qlogicfc : bus mastering is disabled\n"); + return 1; + } + if (revision != ISP2100_REV_ID && revision != ISP2100_REV_ID3) + printk("qlogicfc : new isp2100 revision ID (%d)\n", revision); + + + hostdata->revision = revision; + + sh->irq = irq; + sh->io_port = io_base; + + LEAVE("isp2100_init"); + + return 0; +} + +#if USE_NVRAM_DEFAULTS + +#define NVRAM_DELAY() udelay(10) /* 10 microsecond delay */ + + +u_short isp2100_read_nvram_word(struct Scsi_Host * host, u_short byte) +{ + int i; + u_short value, output, input; + + outw(0x2, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + outw(0x3, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + + byte &= 0xff; + byte |= 0x0600; + for (i = 10; i >= 0; i--) { + output = ((byte >> i) & 0x1) ? 0x4 : 0x0; + outw(output | 0x2, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + outw(output | 0x3, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + outw(output | 0x2, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + } + + for (i = 0xf, value = 0; i >= 0; i--) { + value <<= 1; + outw(0x3, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + input = inw(host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + outw(0x2, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + if (input & 0x8) + value |= 1; + } + + outw(0x0, host->io_port + PCI_NVRAM); + NVRAM_DELAY(); + + return value; +} + + +#endif /* USE_NVRAM_DEFAULTS */ + + + +/* + * currently, this is only called during initialization or abort/reset, + * at which times interrupts are disabled, so polling is OK, I guess... + */ +static int isp2100_mbox_command(struct Scsi_Host *host, u_short param[]) +{ + int loop_count; + struct isp2100_hostdata *hostdata = (struct isp2100_hostdata *) host->hostdata; + + if (mbox_param[param[0]] == 0) + return 1; + + loop_count = DEFAULT_LOOP_COUNT; + while (--loop_count && inw(host->io_port + HOST_HCCR) & 0x0080) + barrier(); + if (!loop_count) { + printk("qlogicfc: mbox_command loop timeout #1\n"); + param[0] = 0x4006; + return 1; + } + hostdata->mbox_done = 0; + + if (mbox_param[param[0]] == 0) + printk("qlogicfc: invalid mbox command\n"); + + if (mbox_param[param[0]] & 0x80) + outw(param[7], host->io_port + MBOX7); + if (mbox_param[param[0]] & 0x40) + outw(param[6], host->io_port + MBOX6); + if (mbox_param[param[0]] & 0x20) + outw(param[5], host->io_port + MBOX5); + if (mbox_param[param[0]] & 0x10) + outw(param[4], host->io_port + MBOX4); + if (mbox_param[param[0]] & 0x08) + outw(param[3], host->io_port + MBOX3); + if (mbox_param[param[0]] & 0x04) + outw(param[2], host->io_port + MBOX2); + if (mbox_param[param[0]] & 0x02) + outw(param[1], host->io_port + MBOX1); + if (mbox_param[param[0]] & 0x01) + outw(param[0], host->io_port + MBOX0); + + + outw(HCCR_SET_HOST_INTR, host->io_port + HOST_HCCR); + + while (1) { + loop_count = DEFAULT_LOOP_COUNT; + while (--loop_count && !(inw(host->io_port + PCI_INTER_STS) & 0x08)) { + barrier(); + } + + if (!loop_count) { + printk("qlogicfc: mbox_command loop timeout #2\n"); + break; + } + isp2100_intr_handler(host->irq, host, NULL); + + if (hostdata->mbox_done == 1) + break; + + } + + loop_count = DEFAULT_LOOP_COUNT; + while (--loop_count && inw(host->io_port + MBOX0) == 0x04) { + barrier(); + } + if (!loop_count) + printk("qlogicfc: mbox_command loop timeout #3\n"); + + param[7] = inw(host->io_port + MBOX7); + param[6] = inw(host->io_port + MBOX6); + param[5] = inw(host->io_port + MBOX5); + param[4] = inw(host->io_port + MBOX4); + param[3] = inw(host->io_port + MBOX3); + param[2] = inw(host->io_port + MBOX2); + param[1] = inw(host->io_port + MBOX1); + param[0] = inw(host->io_port + MBOX0); + + + outw(0x0, host->io_port + PCI_SEMAPHORE); + + if (inw(host->io_port + HOST_HCCR) & 0x0080) { + printk("mbox op is still pending\n"); + } + return 0; +} + + +#if DEBUG_ISP2100_INTR + +void isp2100_print_status_entry(struct Status_Entry *status) +{ + printk("qlogicfc : entry count = 0x%02x, type = 0x%02x, flags = 0x%02x\n", + status->hdr.entry_cnt, status->hdr.entry_type, status->hdr.flags); + printk("qlogicfc : scsi status = 0x%04x, completion status = 0x%04x\n", + status->scsi_status, status->completion_status); + printk("qlogicfc : state flags = 0x%04x, status flags = 0x%04x\n", + status->state_flags, status->status_flags); + printk("qlogicfc : response info length = 0x%04x, request sense length = 0x%04x\n", + status->res_info_len, status->req_sense_len); + printk("qlogicfc : residual transfer length = 0x%08x, response = 0x%02x\n", status->residual, status->res_info[3]); + +} + +#endif /* DEBUG_ISP2100_INTR */ + + +#if DEBUG_ISP2100 + +void isp2100_print_scsi_cmd(Scsi_Cmnd * cmd) +{ + int i; + + printk("qlogicfc : target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n", + cmd->target, cmd->lun, cmd->cmd_len); + printk("qlogicfc : command = "); + for (i = 0; i < cmd->cmd_len; i++) + printk("0x%02x ", cmd->cmnd[i]); + printk("\n"); +} + +#endif /* DEBUG_ISP2100 */ + + +#ifdef MODULE + +Scsi_Host_Template driver_template = QLOGICFC; + +#include "scsi_module.c" + +#endif diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/qlogicfc.h linux/drivers/scsi/qlogicfc.h --- v2.2.2/linux/drivers/scsi/qlogicfc.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/qlogicfc.h Wed Feb 24 16:27:54 1999 @@ -0,0 +1,102 @@ +/* + * QLogic ISP2100 SCSI-FCP + * + * Written by Erik H. Moe, ehm@cris.com + * Copyright 1995, Erik H. Moe + * + * 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, 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. + */ + +/* Renamed and updated to 1.3.x by Michael Griffith */ + +/* This is a version of the isp1020 driver which was modified by + * Chris Loveland to support the isp2100 + */ + + +/* + * $Date: 1995/09/22 02:32:56 $ + * $Revision: 0.5 $ + * + * $Log: isp1020.h,v $ + * Revision 0.5 1995/09/22 02:32:56 root + * do auto request sense + * + * Revision 0.4 1995/08/07 04:48:28 root + * supply firmware with driver. + * numerous bug fixes/general cleanup of code. + * + * Revision 0.3 1995/07/16 16:17:16 root + * added reset/abort code. + * + * Revision 0.2 1995/06/29 03:19:43 root + * fixed biosparam. + * added queue protocol. + * + * Revision 0.1 1995/06/25 01:56:13 root + * Initial release. + * + */ + +#ifndef _QLOGICFC_H +#define _QLOGICFC_H + +/* + * With the qlogic interface, every queue slot can hold a SCSI + * command with up to 2 scatter/gather entries. If we need more + * than 2 entries, continuation entries can be used that hold + * another 5 entries each. Unlike for other drivers, this means + * that the maximum number of scatter/gather entries we can + * support at any given time is a function of the number of queue + * slots available. That is, host->can_queue and host->sg_tablesize + * are dynamic and _not_ independent. This all works fine because + * requests are queued serially and the scatter/gather limit is + * determined for each queue request anew. + */ +#define QLOGICFC_REQ_QUEUE_LEN 63 /* must be power of two - 1 */ +#define QLOGICFC_MAX_SG(ql) (2 + (((ql) > 0) ? 5*((ql) - 1) : 0)) +#define QLOGICFC_CMD_PER_LUN 8 + +int isp2100_detect(Scsi_Host_Template *); +int isp2100_release(struct Scsi_Host *); +const char * isp2100_info(struct Scsi_Host *); +int isp2100_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *)); +int isp2100_abort(Scsi_Cmnd *); +int isp2100_reset(Scsi_Cmnd *, unsigned int); +int isp2100_biosparam(Disk *, kdev_t, int[]); + +#ifndef NULL +#define NULL (0) +#endif + +extern struct proc_dir_entry proc_scsi_isp2100; + +#define QLOGICFC { \ + detect: isp2100_detect, \ + release: isp2100_release, \ + info: isp2100_info, \ + queuecommand: isp2100_queuecommand, \ + abort: isp2100_abort, \ + reset: isp2100_reset, \ + bios_param: isp2100_biosparam, \ + can_queue: QLOGICFC_REQ_QUEUE_LEN, \ + this_id: -1, \ + sg_tablesize: QLOGICFC_MAX_SG(QLOGICFC_REQ_QUEUE_LEN), \ + cmd_per_lun: QLOGICFC_CMD_PER_LUN, \ + present: 0, \ + unchecked_isa_dma: 0, \ + use_clustering: DISABLE_CLUSTERING \ +} + +#endif /* _QLOGICFC_H */ + + + diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/qlogicfc_asm.c linux/drivers/scsi/qlogicfc_asm.c --- v2.2.2/linux/drivers/scsi/qlogicfc_asm.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/qlogicfc_asm.c Wed Feb 24 16:27:54 1999 @@ -0,0 +1,2985 @@ +/************************************************************************ + * * + * --- ISP2100 Fabric Initiator/Target Firmware --- * + * * + * * + * * + ************************************************************************ + */ +/* + * Firmware Version 1.13.00 (18:06 May 04, 1998) + */ + +unsigned short risc_code_version = 1*1024+13; + +unsigned char firmware_version[] = {1,13,0}; + +unsigned short risc_code_addr01 = 0x1000 ; + +unsigned short risc_code01[] = { + 0x0078, 0x1029, 0x0000, 0x5c95, 0x0000, 0x2043, 0x4f50, 0x5952, + 0x4947, 0x4854, 0x2031, 0x3939, 0x3620, 0x514c, 0x4f47, 0x4943, + 0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350, + 0x3231, 0x3030, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056, + 0x6572, 0x7369, 0x6f6e, 0x2030, 0x312e, 0x3133, 0x2020, 0x2020, + 0x2400, 0x20c1, 0x0021, 0x20a1, 0x6c95, 0x2009, 0x0000, 0x20a9, + 0x076b, 0x41a4, 0x3400, 0x20c9, 0x71ff, 0x2091, 0x2000, 0x2059, + 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x1e36, 0x2051, 0x6d00, + 0x2a70, 0x705b, 0x8c00, 0x705f, 0xffff, 0x7057, 0x8bf9, 0x7063, + 0x0300, 0x1078, 0x1264, 0x20a1, 0x7400, 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, 0x122b, 0x1078, 0x134e, 0x1078, 0x14d3, 0x1078, 0x17d7, + 0x1078, 0x324a, 0x1078, 0x54fc, 0x1078, 0x12d9, 0x1078, 0x2191, + 0x1078, 0x3875, 0x1078, 0x3655, 0x1078, 0x4064, 0x1078, 0x1c35, + 0x1078, 0x4213, 0x1078, 0x3d73, 0x1078, 0x1b5d, 0x1078, 0x1c14, + 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, 0x2a96, 0x1078, 0x21b9, 0x1078, 0x38c5, + 0x1078, 0x373c, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048, + 0x10c1, 0x1078, 0x4078, 0x0078, 0x10a4, 0x1079, 0x10c5, 0x0078, + 0x10aa, 0x1078, 0x52d8, 0x0078, 0x10b9, 0x10cf, 0x10d0, 0x1151, + 0x10cd, 0x11aa, 0x1228, 0x1229, 0x122a, 0x1078, 0x12b7, 0x007c, + 0x127e, 0x0f7e, 0x2091, 0x8000, 0x1078, 0x2aec, 0x2079, 0x0100, + 0x7844, 0xa005, 0x00c0, 0x1142, 0x2011, 0x318e, 0x1078, 0x40d1, + 0x780f, 0x00ff, 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011, 0x8010, + 0x73b8, 0x1078, 0x2a53, 0x1078, 0x5129, 0x2011, 0x0004, 0x1078, + 0x6135, 0x1078, 0x35ef, 0x70c7, 0x0000, 0x70bf, 0x0000, 0x70c3, + 0x0000, 0x1078, 0x1145, 0x2011, 0x0000, 0x2079, 0x6d51, 0x7804, + 0xd0ac, 0x0040, 0x1104, 0xc295, 0x70a4, 0xa005, 0x0040, 0x1109, + 0xc29d, 0x72be, 0xa296, 0x0004, 0x0040, 0x112a, 0x2011, 0x0001, + 0x1078, 0x6135, 0x708b, 0x0000, 0x708f, 0xffff, 0x7003, 0x0002, + 0x0f7f, 0x1078, 0x1ee6, 0x2011, 0x0005, 0x1078, 0x5232, 0x1078, + 0x476a, 0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f, 0x127f, + 0x0078, 0x1144, 0x7003, 0x0003, 0x2001, 0x0000, 0x1078, 0x1dc9, + 0x2011, 0x0000, 0x1078, 0x5232, 0x2011, 0x0000, 0x1078, 0x523c, + 0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f, 0x1078, 0x476a, + 0x1078, 0x4821, 0x0f7f, 0x127f, 0x007c, 0x0c7e, 0x20a9, 0x0082, + 0x2009, 0x007e, 0x1078, 0x342f, 0x8108, 0x00f0, 0x114a, 0x0c7f, + 0x007c, 0x127e, 0x2091, 0x8000, 0x708c, 0xa086, 0xffff, 0x0040, + 0x115f, 0x1078, 0x1ee6, 0x1078, 0x476a, 0x0078, 0x11a8, 0x70bc, + 0xd09c, 0x0040, 0x1187, 0xd084, 0x0040, 0x1187, 0x0f7e, 0x2079, + 0x0100, 0x790c, 0xc1b5, 0x790e, 0x0f7f, 0xd08c, 0x0040, 0x1187, + 0x70c0, 0xa086, 0xffff, 0x0040, 0x1183, 0x1078, 0x1fdb, 0x1078, + 0x476a, 0x2011, 0x0001, 0x2019, 0x0000, 0x1078, 0x2013, 0x1078, + 0x476a, 0x0078, 0x11a8, 0x70c4, 0xa005, 0x00c0, 0x11a8, 0x7088, + 0xa005, 0x00c0, 0x11a8, 0x7003, 0x0003, 0x708f, 0xffff, 0x2001, + 0x0000, 0x1078, 0x1dc9, 0x1078, 0x2ad1, 0x2001, 0x6f11, 0x2004, + 0xa086, 0x0005, 0x00c0, 0x11a0, 0x2011, 0x0000, 0x1078, 0x5232, + 0x2011, 0x0000, 0x1078, 0x523c, 0x1078, 0x476a, 0x1078, 0x4821, + 0x127f, 0x007c, 0x017e, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079, + 0x0100, 0x7843, 0x0000, 0x7924, 0xd1b4, 0x0040, 0x11b9, 0x7827, + 0x0040, 0xd19c, 0x0040, 0x11be, 0x7827, 0x0008, 0x007e, 0x037e, + 0x157e, 0x7900, 0xa18a, 0x0003, 0x0050, 0x11e4, 0x7954, 0xd1ac, + 0x00c0, 0x11e4, 0x2009, 0x00f8, 0x1078, 0x3233, 0x7843, 0x0090, + 0x7843, 0x0010, 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x00c0, 0x11dc, + 0x7824, 0xd0ac, 0x00c0, 0x1218, 0x00f0, 0x11d4, 0x2001, 0x0001, + 0x1078, 0x1dc9, 0x0078, 0x1221, 0x7853, 0x0000, 0x782f, 0x0020, + 0x20a9, 0x0008, 0x00e0, 0x11ea, 0x2091, 0x6000, 0x00f0, 0x11ea, + 0x7853, 0x0400, 0x782f, 0x0000, 0x2009, 0x00f8, 0x1078, 0x3233, + 0x20a9, 0x000e, 0x0005, 0x00f0, 0x11fa, 0x7853, 0x1400, 0x7843, + 0x0090, 0x7843, 0x0010, 0x2019, 0x61a8, 0x7854, 0x0005, 0x0005, + 0xd08c, 0x0040, 0x120f, 0x7824, 0xd0ac, 0x00c0, 0x1218, 0x8319, + 0x00c0, 0x1205, 0x2001, 0x0001, 0x1078, 0x1dc9, 0x0078, 0x121f, + 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, 0x1237, 0x704f, 0xffff, 0x0078, 0x1239, 0x704f, + 0x0000, 0x7053, 0xffff, 0x7067, 0x0000, 0x706b, 0x0000, 0x2061, + 0x6f00, 0x6003, 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, + 0x0200, 0x6013, 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, + 0x07d0, 0x2061, 0x6f08, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, + 0x0000, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, + 0x0001, 0x601f, 0x0000, 0x007c, 0x1078, 0x128a, 0x2011, 0x0000, + 0x81ff, 0x0040, 0x1289, 0xa186, 0x0001, 0x00c0, 0x1279, 0x705f, + 0x8fff, 0x7057, 0x7c01, 0x7063, 0x0100, 0x705b, 0x7c00, 0x0078, + 0x1287, 0xa186, 0x0002, 0x00c0, 0x1281, 0x2011, 0x0000, 0x0078, + 0x1287, 0xa186, 0x0005, 0x00c0, 0x1287, 0x2011, 0x0001, 0x1078, + 0x12b1, 0x007c, 0x2009, 0x0000, 0x2011, 0x0000, 0x1078, 0x12b1, + 0x2019, 0xaaaa, 0x2061, 0xffff, 0x2362, 0x2c24, 0x2061, 0x7fff, + 0x2c04, 0xa406, 0x0040, 0x129f, 0xc18d, 0x0078, 0x12ac, 0xc185, + 0x2011, 0x0001, 0x1078, 0x12b1, 0x2061, 0xffff, 0x2362, 0x2c04, + 0xa306, 0x00c0, 0x12ac, 0xc195, 0x2011, 0x0001, 0x1078, 0x12b1, + 0x007c, 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0, 0x007c, 0x2091, + 0x8000, 0x0068, 0x12b9, 0x007e, 0x017e, 0x2079, 0x0000, 0x7818, + 0xa084, 0x0000, 0x00c0, 0x12bf, 0x017f, 0x792e, 0x007f, 0x782a, + 0x007f, 0x7826, 0x7823, 0x8002, 0x781b, 0x0001, 0x2091, 0x5000, + 0x2091, 0x4080, 0x2079, 0x6d00, 0x7803, 0x0005, 0x0078, 0x12d6, + 0x007c, 0x2071, 0x6d00, 0x7158, 0x712e, 0x2021, 0x0001, 0xa190, + 0x002d, 0xa298, 0x002d, 0x0048, 0x12ef, 0x705c, 0xa302, 0x00c8, + 0x12ef, 0x220a, 0x2208, 0x2310, 0x8420, 0x0078, 0x12e1, 0x200b, + 0x0000, 0x749e, 0x74a2, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000, + 0x2071, 0x6d00, 0x70a0, 0xa0ea, 0x0010, 0x00c8, 0x1302, 0xa06e, + 0x0078, 0x130c, 0x8001, 0x70a2, 0x702c, 0x2068, 0x2d04, 0x702e, + 0x206b, 0x0000, 0x6807, 0x0000, 0x127f, 0x0e7f, 0x007c, 0x0e7e, + 0x2071, 0x6d00, 0x127e, 0x2091, 0x8000, 0x70a0, 0x8001, 0x00c8, + 0x131c, 0xa06e, 0x0078, 0x1325, 0x70a2, 0x702c, 0x2068, 0x2d04, + 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x127f, 0x0e7f, 0x007c, + 0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0x6d00, 0x702c, 0x206a, + 0x2d00, 0x702e, 0x70a0, 0x8000, 0x70a2, 0x127f, 0x0e7f, 0x007c, + 0x8dff, 0x0040, 0x1344, 0x6804, 0x6807, 0x0000, 0x007e, 0x1078, + 0x1328, 0x0d7f, 0x0078, 0x1338, 0x007c, 0x0e7e, 0x2071, 0x6d00, + 0x70a0, 0xa08a, 0x0010, 0xa00d, 0x0e7f, 0x007c, 0x0e7e, 0x2071, + 0x6f31, 0x7007, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000, 0x2071, + 0x0000, 0x7010, 0xa085, 0x8004, 0x7012, 0x0e7f, 0x007c, 0x0e7e, + 0x2270, 0x700b, 0x0000, 0x2071, 0x6f31, 0x7018, 0xa088, 0x6f3a, + 0x220a, 0x8000, 0xa084, 0x0007, 0x701a, 0x7004, 0xa005, 0x00c0, + 0x1377, 0x0f7e, 0x2079, 0x0010, 0x1078, 0x1388, 0x0f7f, 0x0e7f, + 0x007c, 0x0e7e, 0x2071, 0x6f31, 0x7004, 0xa005, 0x00c0, 0x1386, + 0x0f7e, 0x2079, 0x0010, 0x1078, 0x1388, 0x0f7f, 0x0e7f, 0x007c, + 0x7000, 0x0079, 0x138b, 0x138f, 0x13f9, 0x1416, 0x1416, 0x7018, + 0x711c, 0xa106, 0x00c0, 0x1397, 0x7007, 0x0000, 0x007c, 0x0d7e, + 0xa180, 0x6f3a, 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, 0x13b9, 0x7007, 0x0001, 0x1078, 0x13be, + 0x007c, 0x7007, 0x0002, 0x1078, 0x13d4, 0x007c, 0x017e, 0x027e, + 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x13c9, 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, 0x13e8, 0x2110, 0xa006, + 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803, + 0x0001, 0x3300, 0x7016, 0x157f, 0x147f, 0x137f, 0x027f, 0x017f, + 0x007c, 0x137e, 0x147e, 0x157e, 0x2099, 0x6dc5, 0x20a1, 0x0018, + 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000, + 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x700b, + 0x6dc0, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x137e, 0x147e, + 0x157e, 0x2001, 0x6df4, 0x209c, 0x20a1, 0x0014, 0x7803, 0x0026, + 0x2001, 0x6df5, 0x20ac, 0x53a6, 0x2099, 0x6df6, 0x20a1, 0x0018, + 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000, + 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c, 0x7002, 0x700b, + 0x6df1, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x017e, 0x0e7e, + 0x2071, 0x6f31, 0x0f7e, 0x2079, 0x0010, 0x7904, 0x7803, 0x0002, + 0xd1fc, 0x0040, 0x1459, 0xa18c, 0x0700, 0x0040, 0x1456, 0x7008, + 0xa080, 0x0002, 0x2003, 0x0200, 0x0078, 0x1459, 0x7004, 0x1079, + 0x145d, 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x1388, 0x1465, 0x1487, + 0x14a1, 0x14ca, 0x1463, 0x0078, 0x1463, 0x137e, 0x147e, 0x157e, + 0x7014, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x7010, 0x20a8, + 0x53a5, 0x3400, 0x7016, 0x157f, 0x147f, 0x137f, 0x700c, 0xa005, + 0x0040, 0x148e, 0x1078, 0x13be, 0x007c, 0x7008, 0xa080, 0x0002, + 0x2003, 0x0100, 0x7007, 0x0000, 0x1078, 0x1388, 0x007c, 0x700c, + 0xa005, 0x0040, 0x148e, 0x1078, 0x13d4, 0x007c, 0x0d7e, 0x7008, + 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, 0x682e, 0x783c, + 0x6832, 0x680b, 0x0100, 0x0d7f, 0x7007, 0x0000, 0x1078, 0x1388, + 0x007c, 0x137e, 0x147e, 0x157e, 0x2001, 0x6dc3, 0x2004, 0xa080, + 0x000d, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x20a9, 0x0020, + 0x53a5, 0x2001, 0x6dc5, 0x2004, 0xd0bc, 0x0040, 0x14c0, 0x2001, + 0x6dce, 0x2004, 0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020, 0x53a5, + 0x157f, 0x147f, 0x137f, 0x7007, 0x0000, 0x1078, 0x396e, 0x1078, + 0x1388, 0x007c, 0x2001, 0x6df3, 0x2003, 0x0100, 0x7007, 0x0000, + 0x1078, 0x1388, 0x007c, 0x127e, 0x2091, 0x2100, 0x2079, 0x0030, + 0x2071, 0x6f42, 0x7003, 0x0000, 0x700f, 0x6f48, 0x7013, 0x6f48, + 0x780f, 0x0070, 0x127f, 0x007c, 0x6934, 0xa184, 0x0007, 0x0079, + 0x14e9, 0x14f1, 0x151b, 0x14f1, 0x14f1, 0x14f1, 0x1500, 0x14f1, + 0x14f5, 0xa085, 0x0001, 0x0078, 0x1531, 0x684c, 0xd0bc, 0x0040, + 0x14f1, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, 0x0078, 0x1523, + 0xa18c, 0x00ff, 0xa186, 0x0015, 0x00c0, 0x14f1, 0x684c, 0xd0ac, + 0x0040, 0x14f1, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, + 0x000f, 0xa080, 0x1a82, 0x2004, 0x6832, 0xa006, 0x682e, 0x682a, + 0x6858, 0x0078, 0x152b, 0x684c, 0xd0ac, 0x0040, 0x14f1, 0xa006, + 0x682e, 0x682a, 0x6858, 0xa18c, 0x000f, 0xa188, 0x1a82, 0x210c, + 0x6932, 0x2d08, 0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, + 0x680a, 0x007c, 0x82ff, 0x0040, 0x1545, 0xa280, 0x0004, 0x0d7e, + 0x206c, 0x684c, 0xd0dc, 0x00c0, 0x1541, 0x1078, 0x14e4, 0x10c0, + 0x12b7, 0x6808, 0x8000, 0x680a, 0x0d7f, 0x127e, 0x047e, 0x037e, + 0x027e, 0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000, 0xa005, + 0x00c0, 0x1559, 0x7206, 0x2001, 0x156d, 0x007e, 0x2260, 0x0078, + 0x164f, 0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a, 0x8108, + 0xa182, 0x6f63, 0x0048, 0x1566, 0x2009, 0x6f48, 0x710e, 0x7000, + 0xa005, 0x00c0, 0x156d, 0x1078, 0x1638, 0x127f, 0x007c, 0x127e, + 0x027e, 0x037e, 0x0c7e, 0x007e, 0x2091, 0x2100, 0x007f, 0x047f, + 0x037f, 0x027f, 0x0c7e, 0x0d7e, 0x2460, 0x6110, 0x2168, 0x6a62, + 0x6b5e, 0xa005, 0x0040, 0x15bc, 0x6808, 0xa005, 0x0040, 0x15ea, + 0x7000, 0xa005, 0x00c0, 0x158e, 0x0078, 0x15b4, 0x700c, 0x7110, + 0xa106, 0x00c0, 0x15ba, 0x7004, 0xa406, 0x00c0, 0x15b4, 0x2001, + 0x0005, 0x2004, 0xd08c, 0x00c0, 0x15ee, 0x2001, 0x0207, 0x2004, + 0xd09c, 0x00c0, 0x1597, 0x7804, 0xa084, 0x6000, 0x0040, 0x15ae, + 0xa086, 0x6000, 0x0040, 0x15ae, 0x0078, 0x1597, 0x7803, 0x0004, + 0x7003, 0x0000, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x5591, + 0x0078, 0x15ee, 0x0078, 0x15ee, 0x6808, 0xa005, 0x0040, 0x15ea, + 0x7000, 0xa005, 0x00c0, 0x15c6, 0x0078, 0x15ea, 0x700c, 0x7110, + 0xa106, 0x00c0, 0x15ba, 0x7004, 0xa406, 0x00c0, 0x15ea, 0x2001, + 0x0005, 0x2004, 0xd08c, 0x00c0, 0x15ee, 0x2001, 0x0207, 0x2004, + 0xd09c, 0x00c0, 0x15cf, 0x7804, 0xa084, 0x6000, 0x0040, 0x15e6, + 0xa086, 0x6000, 0x0040, 0x15e6, 0x0078, 0x15cf, 0x7803, 0x0004, + 0x7003, 0x0000, 0x2009, 0x0048, 0x1078, 0x5591, 0x0d7f, 0x0c7f, + 0x127f, 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0x6f42, 0x7000, 0xa086, + 0x0000, 0x0040, 0x1635, 0x7004, 0xac06, 0x00c0, 0x1626, 0x2079, + 0x0030, 0x7804, 0xd0fc, 0x00c0, 0x1622, 0x2001, 0x0207, 0x2004, + 0xd09c, 0x00c0, 0x1601, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0, + 0x160d, 0x7908, 0xd1ec, 0x00c0, 0x1619, 0x2009, 0x0009, 0x0078, + 0x161b, 0x2009, 0x0019, 0x7803, 0x0002, 0x7902, 0x7003, 0x0003, + 0x0078, 0x1635, 0x1078, 0x16e5, 0x0078, 0x15f6, 0x157e, 0x20a9, + 0x0009, 0x2009, 0x6f48, 0x2104, 0xac06, 0x00c0, 0x1630, 0x200a, + 0xa188, 0x0003, 0x00f0, 0x162b, 0x157f, 0x0e7f, 0x0f7f, 0x007c, + 0x700c, 0x7110, 0xa106, 0x00c0, 0x1640, 0x7003, 0x0000, 0x007c, + 0x2104, 0x7006, 0x2060, 0x8108, 0x211c, 0x8108, 0x2124, 0x8108, + 0xa182, 0x6f63, 0x0048, 0x164e, 0x2009, 0x6f48, 0x7112, 0x8cff, + 0x00c0, 0x1658, 0x7803, 0x0019, 0x7003, 0x0003, 0x0078, 0x167b, + 0x6010, 0x2068, 0x2d58, 0x6828, 0xa406, 0x00c0, 0x1663, 0x682c, + 0xa306, 0x0040, 0x1667, 0x1078, 0x1aa2, 0x00c0, 0x1652, 0x6824, + 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f, + 0x2009, 0x0011, 0x1078, 0x167c, 0x0040, 0x167a, 0x2009, 0x0001, + 0x1078, 0x167c, 0x2d58, 0x007c, 0x8aff, 0x0040, 0x16e0, 0xa03e, + 0x2730, 0x6850, 0xd0fc, 0x00c0, 0x169b, 0x0d7e, 0x2804, 0xac68, + 0x2900, 0x0079, 0x168b, 0x16ca, 0x16ab, 0x16ab, 0x16ca, 0x16ca, + 0x16c2, 0x16ca, 0x16ab, 0x16ca, 0x16b1, 0x16b1, 0x16ca, 0x16ca, + 0x16ca, 0x16ca, 0x16b1, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, + 0x6c20, 0x0d7e, 0xd99c, 0x0040, 0x16cd, 0x2804, 0xac68, 0x6f08, + 0x6e0c, 0x0078, 0x16cd, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0078, + 0x16cd, 0x7b0c, 0xd3bc, 0x0040, 0x16ba, 0x7b08, 0xa39c, 0x0fff, + 0x0078, 0x16bb, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, + 0x0078, 0x16cd, 0x0d7f, 0x1078, 0x1a3f, 0x00c0, 0x167c, 0xa00e, + 0x0078, 0x16e0, 0x0d7f, 0x1078, 0x12b7, 0x7b22, 0x7a26, 0x7d32, + 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x0d7f, + 0x6828, 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x1078, 0x1a3f, + 0x007c, 0x1078, 0x12b7, 0x1078, 0x12b7, 0x127e, 0x2091, 0x2100, + 0x007e, 0x017e, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, + 0xa184, 0x0700, 0x00c0, 0x16e3, 0xa184, 0x0003, 0xa086, 0x0003, + 0x0040, 0x16e3, 0x7000, 0x0079, 0x16fd, 0x1701, 0x1703, 0x1779, + 0x17c0, 0x1078, 0x12b7, 0x8001, 0x7002, 0xa184, 0x0880, 0x00c0, + 0x1718, 0x8aff, 0x0040, 0x175b, 0x2009, 0x0001, 0x1078, 0x167c, + 0x0040, 0x17d3, 0x2009, 0x0001, 0x1078, 0x167c, 0x0078, 0x17d3, + 0x7803, 0x0004, 0x7003, 0x0000, 0xd1dc, 0x0040, 0x1751, 0x027e, + 0x037e, 0x6b28, 0x6a2c, 0x7820, 0x686e, 0xa31a, 0x7824, 0x6872, + 0xa213, 0x6b2a, 0x6a2e, 0x037f, 0x027f, 0x7830, 0x681e, 0x7834, + 0x6822, 0x1078, 0x1a58, 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, + 0x6832, 0x7003, 0x0000, 0x6850, 0xc0fd, 0x6852, 0x6808, 0x8001, + 0x680a, 0x00c0, 0x174d, 0x684c, 0xd0e4, 0x0040, 0x174d, 0x7004, + 0x2060, 0x2009, 0x0048, 0x1078, 0x5591, 0x1078, 0x1638, 0x0078, + 0x17d3, 0x057e, 0x7d0c, 0xd5bc, 0x00c0, 0x1758, 0x1078, 0x6c41, + 0x057f, 0x0078, 0x1773, 0x684c, 0xc0f5, 0x684e, 0x7814, 0xa005, + 0x00c0, 0x1773, 0x7003, 0x0000, 0x6808, 0x8001, 0x680a, 0x00c0, + 0x176f, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x5591, 0x1078, + 0x1638, 0x0078, 0x17d3, 0x7803, 0x0009, 0x7003, 0x0003, 0x0078, + 0x17d3, 0x8001, 0x7002, 0xd194, 0x0040, 0x178b, 0x7804, 0xd0fc, + 0x00c0, 0x16ed, 0x8aff, 0x0040, 0x17d3, 0x2009, 0x0001, 0x1078, + 0x167c, 0x0078, 0x17d3, 0xa184, 0x0880, 0x00c0, 0x1798, 0x8aff, + 0x0040, 0x17d3, 0x2009, 0x0001, 0x1078, 0x167c, 0x0078, 0x17d3, + 0x7803, 0x0004, 0x7003, 0x0000, 0xd1dc, 0x0040, 0x17b9, 0x027e, + 0x037e, 0x6b28, 0x6a2c, 0x1078, 0x1a58, 0x0d7e, 0x2804, 0xac68, + 0x6034, 0xd09c, 0x00c0, 0x17b2, 0x6808, 0xa31a, 0x680c, 0xa213, + 0x0078, 0x17b6, 0x6810, 0xa31a, 0x6814, 0xa213, 0x0d7f, 0x0078, + 0x1723, 0x057e, 0x7d0c, 0x1078, 0x6c41, 0x057f, 0x0078, 0x1773, + 0x7003, 0x0000, 0x7004, 0xa00d, 0x0040, 0x17d1, 0x6808, 0x8001, + 0x680a, 0x00c0, 0x17d1, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, + 0x5591, 0x1078, 0x1638, 0x017f, 0x007f, 0x127f, 0x007c, 0x0e7e, + 0x2071, 0x6f63, 0x7003, 0x0000, 0x0e7f, 0x007c, 0x0d7e, 0xa280, + 0x0004, 0x206c, 0x694c, 0xd1dc, 0x00c0, 0x1836, 0x6934, 0xa184, + 0x0007, 0x0079, 0x17eb, 0x17f3, 0x1821, 0x17f3, 0x17f3, 0x17f3, + 0x1806, 0x17f3, 0x17f5, 0x1078, 0x12b7, 0x684c, 0xd0b4, 0x0040, + 0x192f, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, + 0x680a, 0x6880, 0x680e, 0x6958, 0x0078, 0x1829, 0xa18c, 0x00ff, + 0xa186, 0x0015, 0x00c0, 0x1836, 0x684c, 0xd0b4, 0x0040, 0x192f, + 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, + 0x1a82, 0x2004, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0078, + 0x1832, 0x684c, 0xd0b4, 0x0040, 0x16e1, 0x6958, 0xa006, 0x682e, + 0x682a, 0x2d00, 0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x1a82, + 0x2004, 0x6832, 0x6926, 0x684c, 0xc0dd, 0x684e, 0x0d7f, 0x007c, + 0x0f7e, 0x2079, 0x0020, 0x7804, 0xd0fc, 0x10c0, 0x1933, 0x0e7e, + 0x0d7e, 0x2071, 0x6f63, 0x7000, 0xa005, 0x00c0, 0x18b2, 0x0c7e, + 0x7206, 0xa280, 0x0004, 0x205c, 0x7004, 0x2068, 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, 0x1874, 0x017e, + 0x2009, 0x0008, 0xa102, 0x017f, 0xa108, 0x791a, 0x7116, 0x701e, + 0x680c, 0xa081, 0x0000, 0x781e, 0x701a, 0xa006, 0x700e, 0x7012, + 0x7004, 0x692c, 0x6814, 0xa106, 0x00c0, 0x188b, 0x6928, 0x6810, + 0xa106, 0x0040, 0x1898, 0x037e, 0x047e, 0x6b14, 0x6c10, 0x1078, + 0x1aa2, 0x047f, 0x037f, 0x0040, 0x1898, 0x0c7f, 0x0078, 0x18b2, + 0x8aff, 0x00c0, 0x18a0, 0x0c7f, 0xa085, 0x0001, 0x0078, 0x18b2, + 0x127e, 0x2091, 0x8000, 0x2079, 0x0020, 0x2009, 0x0001, 0x1078, + 0x18b6, 0x0040, 0x18af, 0x2009, 0x0001, 0x1078, 0x18b6, 0x127f, + 0x0c7f, 0xa006, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x077e, 0x067e, + 0x057e, 0x047e, 0x037e, 0x027e, 0x8aff, 0x0040, 0x1928, 0x700c, + 0x7214, 0xa202, 0x7010, 0x7218, 0xa203, 0x0048, 0x1927, 0xa03e, + 0x2730, 0x6850, 0xd0fc, 0x00c0, 0x18e3, 0x0d7e, 0x2804, 0xac68, + 0x2900, 0x0079, 0x18d3, 0x1909, 0x18f3, 0x18f3, 0x1909, 0x1909, + 0x1901, 0x1909, 0x18f3, 0x1909, 0x18f9, 0x18f9, 0x1909, 0x1909, + 0x1909, 0x1909, 0x18f9, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, + 0x6c20, 0xd99c, 0x0040, 0x190d, 0x0d7e, 0x2804, 0xac68, 0x6f08, + 0x6e0c, 0x0078, 0x190c, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0078, + 0x190c, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0078, + 0x190c, 0x0d7f, 0x1078, 0x1a3f, 0x00c0, 0x18bc, 0xa00e, 0x0078, + 0x1928, 0x0d7f, 0x1078, 0x12b7, 0x0d7f, 0x7b22, 0x7a26, 0x7d32, + 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x6828, + 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x700c, 0xa300, 0x700e, + 0x7010, 0xa201, 0x7012, 0x1078, 0x1a3f, 0x0078, 0x1928, 0xa006, + 0x027f, 0x037f, 0x047f, 0x057f, 0x067f, 0x077f, 0x007c, 0x1078, + 0x12b7, 0x1078, 0x12b7, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, + 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x2079, 0x0020, 0x2071, 0x6f63, + 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, + 0x00c0, 0x1931, 0x7000, 0x0079, 0x194d, 0x1a09, 0x1951, 0x19d6, + 0x1a07, 0x8001, 0x7002, 0xd19c, 0x00c0, 0x1965, 0x8aff, 0x0040, + 0x199a, 0x2009, 0x0001, 0x1078, 0x18b6, 0x0040, 0x1a09, 0x2009, + 0x0001, 0x1078, 0x18b6, 0x0078, 0x1a09, 0x7803, 0x0004, 0xd194, + 0x0040, 0x1975, 0x6850, 0xc0fc, 0x6852, 0x8aff, 0x00c0, 0x1990, + 0x684c, 0xc0f5, 0x684e, 0x0078, 0x1990, 0x027e, 0x037e, 0x6b28, + 0x6a2c, 0x701c, 0xa005, 0x10c0, 0x1a11, 0x7820, 0x686e, 0xa31a, + 0x7824, 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x037f, 0x027f, 0x7830, + 0x681e, 0x7834, 0x6822, 0x1078, 0x1a58, 0x6850, 0xc0fd, 0x6852, + 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000, + 0x0078, 0x1a09, 0x711c, 0x81ff, 0x0040, 0x19af, 0x7922, 0x7827, + 0x0000, 0x7803, 0x0001, 0x7000, 0x8000, 0x7002, 0x700c, 0xa100, + 0x700e, 0x7010, 0xa081, 0x0000, 0x7012, 0x0078, 0x1a09, 0x0f7e, + 0x027e, 0x781c, 0x007e, 0x7818, 0x007e, 0x2079, 0x0100, 0x7a14, + 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, 0x7820, 0xd0bc, 0x00c0, + 0x19bd, 0x79c8, 0x007f, 0xa102, 0x78ca, 0x79c4, 0x007f, 0xa102, + 0x78c6, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, 0x027f, 0x0f7f, + 0x7803, 0x0008, 0x7003, 0x0000, 0x0078, 0x1a09, 0x8001, 0x7002, + 0xd194, 0x0040, 0x19eb, 0x7804, 0xd0fc, 0x00c0, 0x1943, 0xd19c, + 0x00c0, 0x1a05, 0x8aff, 0x0040, 0x1a09, 0x2009, 0x0001, 0x1078, + 0x18b6, 0x0078, 0x1a09, 0x027e, 0x037e, 0x6b28, 0x6a2c, 0x1078, + 0x1a58, 0x0d7e, 0x2804, 0xac68, 0x6034, 0xd09c, 0x00c0, 0x19fe, + 0x6808, 0xa31a, 0x680c, 0xa213, 0x0078, 0x1a02, 0x6810, 0xa31a, + 0x6814, 0xa213, 0x0d7f, 0x0078, 0x1979, 0x0078, 0x1975, 0x1078, + 0x12b7, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x017f, 0x007f, 0x127f, + 0x007c, 0x7920, 0xa108, 0x7922, 0x7924, 0xa189, 0x0000, 0x7926, + 0x7930, 0xa10a, 0x7932, 0x7934, 0xa18b, 0x0000, 0x7936, 0x007c, + 0x0f7e, 0x0e7e, 0x2071, 0x6f63, 0x7000, 0xa086, 0x0000, 0x0040, + 0x1a3c, 0x2079, 0x0020, 0x7804, 0xa084, 0x0003, 0x0040, 0x1a36, + 0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0, 0x1a32, 0x20e1, 0x9040, + 0x7803, 0x0002, 0x7003, 0x0000, 0x0e7f, 0x0f7f, 0x007c, 0x8840, + 0x2804, 0xa005, 0x00c0, 0x1a53, 0x6004, 0xa005, 0x0040, 0x1a55, + 0x681a, 0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x1a82, 0x2044, + 0x88ff, 0x1040, 0x12b7, 0x8a51, 0x007c, 0x2051, 0x0000, 0x007c, + 0x8a50, 0x8841, 0x2804, 0xa005, 0x00c0, 0x1a72, 0x2c00, 0xad06, + 0x0040, 0x1a67, 0x6000, 0xa005, 0x00c0, 0x1a67, 0x2d00, 0x2060, + 0x681a, 0x6034, 0xa084, 0x000f, 0xa080, 0x1a92, 0x2044, 0x88ff, + 0x1040, 0x12b7, 0x007c, 0x0000, 0x0011, 0x0015, 0x0019, 0x001d, + 0x0021, 0x0025, 0x0029, 0x0000, 0x000f, 0x0015, 0x001b, 0x0021, + 0x0027, 0x0000, 0x0000, 0x1a78, 0x1a74, 0x0000, 0x0000, 0x8000, + 0x0000, 0x1a78, 0x0000, 0x1a7f, 0x1a7c, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1a7f, 0x0000, 0x1a7a, 0x1a7a, 0x0000, 0x0000, 0x8000, + 0x0000, 0x1a7a, 0x0000, 0x1a80, 0x1a80, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1a80, 0x0a7e, 0x097e, 0x087e, 0x6858, 0xa055, 0x0040, + 0x1b28, 0x2d60, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x1a82, 0xa986, + 0x0007, 0x0040, 0x1ab7, 0xa986, 0x000f, 0x00c0, 0x1abb, 0x605c, + 0xa422, 0x6060, 0xa31a, 0x2804, 0xa045, 0x00c0, 0x1ac9, 0x0050, + 0x1ac3, 0x0078, 0x1b28, 0x6004, 0xa065, 0x0040, 0x1b28, 0x0078, + 0x1aaa, 0x2804, 0xa005, 0x0040, 0x1ae7, 0xac68, 0xd99c, 0x00c0, + 0x1ad7, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0078, 0x1adb, 0x6810, + 0xa422, 0x6814, 0xa31b, 0x0048, 0x1af5, 0x2300, 0xa405, 0x0040, + 0x1aed, 0x8a51, 0x0040, 0x1b28, 0x8840, 0x0078, 0x1ac9, 0x6004, + 0xa065, 0x0040, 0x1b28, 0x0078, 0x1aaa, 0x8a51, 0x8840, 0x2b68, + 0x6850, 0xc0fc, 0x6852, 0x0078, 0x1b22, 0x8422, 0x8420, 0x831a, + 0xa399, 0x0000, 0x0d7e, 0x2b68, 0x6c6e, 0x6b72, 0x0d7f, 0xd99c, + 0x00c0, 0x1b10, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, + 0x1048, 0x12b7, 0x6800, 0xa420, 0x6804, 0xa319, 0x0078, 0x1b1c, + 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, 0x1048, 0x12b7, + 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, 0x6b22, 0x6850, + 0xc0fd, 0x6852, 0x007f, 0x007f, 0x007f, 0xa006, 0x0078, 0x1b2d, + 0x087f, 0x097f, 0x0a7f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0005, + 0x2004, 0xa084, 0x0007, 0x0079, 0x1b35, 0x1b3d, 0x1b3e, 0x1b41, + 0x1b44, 0x1b49, 0x1b4c, 0x1b51, 0x1b56, 0x007c, 0x1078, 0x1933, + 0x007c, 0x1078, 0x16e5, 0x007c, 0x1078, 0x16e5, 0x1078, 0x1933, + 0x007c, 0x1078, 0x143e, 0x007c, 0x1078, 0x1933, 0x1078, 0x143e, + 0x007c, 0x1078, 0x16e5, 0x1078, 0x143e, 0x007c, 0x1078, 0x16e5, + 0x1078, 0x1933, 0x1078, 0x143e, 0x007c, 0x127e, 0x2091, 0x2300, + 0x2079, 0x0200, 0x2071, 0x7280, 0x2069, 0x6d00, 0x2009, 0x0004, + 0x7912, 0x7916, 0x1078, 0x1df6, 0x781b, 0x0002, 0x20e1, 0x8700, + 0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x781c, 0xa084, 0x0007, + 0x0079, 0x1b7a, 0x1b9e, 0x1b82, 0x1b86, 0x1b8a, 0x1b90, 0x1b94, + 0x1b98, 0x1b9c, 0x1078, 0x3d7c, 0x0078, 0x1b9e, 0x1078, 0x3db0, + 0x0078, 0x1b9e, 0x1078, 0x3d7c, 0x1078, 0x3db0, 0x0078, 0x1b9e, + 0x1078, 0x1ba0, 0x0078, 0x1b9e, 0x1078, 0x1ba0, 0x0078, 0x1b9e, + 0x1078, 0x1ba0, 0x0078, 0x1b9e, 0x1078, 0x1ba0, 0x127f, 0x007c, + 0x007e, 0x017e, 0x027e, 0x7930, 0xa184, 0x0003, 0x0040, 0x1baa, + 0x1078, 0x12b7, 0xa184, 0x0030, 0x0040, 0x1bbb, 0x6a00, 0xa286, + 0x0003, 0x00c0, 0x1bb5, 0x1078, 0x12b7, 0x1078, 0x31cb, 0x20e1, + 0x9010, 0x0078, 0x1bc7, 0xa184, 0x00c0, 0x0040, 0x1bc1, 0x1078, + 0x12b7, 0xa184, 0x0300, 0x0040, 0x1bc7, 0x20e1, 0x9020, 0x7932, + 0x027f, 0x017f, 0x007f, 0x007c, 0x017e, 0x0e7e, 0x0f7e, 0x2071, + 0x6d00, 0x7128, 0x2001, 0x6f03, 0x2102, 0x2001, 0x6f0b, 0x2102, + 0xa182, 0x0211, 0x00c8, 0x1be0, 0x2009, 0x0008, 0x0078, 0x1c0a, + 0xa182, 0x0259, 0x00c8, 0x1be8, 0x2009, 0x0007, 0x0078, 0x1c0a, + 0xa182, 0x02c1, 0x00c8, 0x1bf0, 0x2009, 0x0006, 0x0078, 0x1c0a, + 0xa182, 0x0349, 0x00c8, 0x1bf8, 0x2009, 0x0005, 0x0078, 0x1c0a, + 0xa182, 0x0421, 0x00c8, 0x1c00, 0x2009, 0x0004, 0x0078, 0x1c0a, + 0xa182, 0x0581, 0x00c8, 0x1c08, 0x2009, 0x0003, 0x0078, 0x1c0a, + 0x2009, 0x0002, 0x2079, 0x0200, 0x7912, 0x7916, 0x1078, 0x1df6, + 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x127e, 0x2091, 0x2200, 0x2061, + 0x0100, 0x2071, 0x6d00, 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, 0x6d2d, 0x2003, + 0x0000, 0x2001, 0x6d2c, 0x2003, 0x0001, 0x007c, 0x127e, 0x2091, + 0x2200, 0x007e, 0x017e, 0x027e, 0x6124, 0xa184, 0x002c, 0x00c0, + 0x1c4d, 0xa184, 0x0007, 0x0079, 0x1c53, 0xa195, 0x0004, 0xa284, + 0x0007, 0x0079, 0x1c53, 0x1c7f, 0x1c5b, 0x1c5f, 0x1c63, 0x1c69, + 0x1c6d, 0x1c73, 0x1c79, 0x1078, 0x4226, 0x0078, 0x1c7f, 0x1078, + 0x42e4, 0x0078, 0x1c7f, 0x1078, 0x42e4, 0x1078, 0x4226, 0x0078, + 0x1c7f, 0x1078, 0x1c84, 0x0078, 0x1c7f, 0x1078, 0x4226, 0x1078, + 0x1c84, 0x0078, 0x1c7f, 0x1078, 0x42e4, 0x1078, 0x1c84, 0x0078, + 0x1c7f, 0x1078, 0x42e4, 0x1078, 0x4226, 0x1078, 0x1c84, 0x027f, + 0x017f, 0x007f, 0x127f, 0x007c, 0xd1ac, 0x0040, 0x1d24, 0x017e, + 0x047e, 0x0c7e, 0x644c, 0x74ba, 0xa48c, 0xff00, 0xa196, 0xff00, + 0x0040, 0x1cb3, 0x6030, 0xa084, 0x00ff, 0x810f, 0xa116, 0x0040, + 0x1cb3, 0x7130, 0xd18c, 0x00c0, 0x1cb3, 0x2011, 0x6d52, 0x2214, + 0xd2ec, 0x0040, 0x1ca7, 0xc18d, 0x7132, 0x0078, 0x1cb3, 0x6240, + 0xa294, 0x0010, 0x0040, 0x1cf2, 0x6248, 0xa294, 0xff00, 0xa296, + 0xff00, 0x00c0, 0x1cf2, 0x2011, 0x8013, 0x1078, 0x2a53, 0x7130, + 0xc185, 0x7132, 0x2011, 0x6d52, 0x220c, 0xd1a4, 0x0040, 0x1cda, + 0x017e, 0x2009, 0x0001, 0x2011, 0x0100, 0x1078, 0x41f4, 0x2019, + 0x000e, 0x1078, 0x6b8f, 0xa484, 0x00ff, 0xa080, 0x2091, 0x200c, + 0xa18c, 0xff00, 0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x1078, + 0x6bf7, 0x017f, 0xd1ac, 0x00c0, 0x1ce3, 0x2019, 0x0004, 0x1078, + 0x202f, 0x0078, 0x1cf2, 0x157e, 0x20a9, 0x007f, 0x2009, 0x0000, + 0x1078, 0x3447, 0x00c0, 0x1cee, 0x1078, 0x3256, 0x8108, 0x00f0, + 0x1ce8, 0x157f, 0x0c7f, 0x047f, 0x6043, 0x0000, 0x2009, 0x00f7, + 0x1078, 0x3233, 0x2011, 0x0003, 0x1078, 0x5232, 0x2011, 0x0002, + 0x1078, 0x523c, 0x1078, 0x5148, 0x1078, 0x414c, 0x037e, 0x2019, + 0x0000, 0x1078, 0x51da, 0x037f, 0x60e3, 0x0000, 0x017f, 0x2001, + 0x6d00, 0x2014, 0xa296, 0x0004, 0x00c0, 0x1d1c, 0xd19c, 0x00c0, + 0x1d1c, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0x6d20, + 0x2003, 0x0000, 0x6027, 0x0020, 0xd194, 0x0040, 0x1d9d, 0x017e, + 0x6220, 0xd2b4, 0x0040, 0x1d5b, 0x1078, 0x414c, 0x1078, 0x4fe5, + 0x6027, 0x0004, 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, + 0x0040, 0x1d3e, 0x6803, 0x1000, 0x6803, 0x0000, 0x0d7f, 0x0c7e, + 0x2061, 0x6f10, 0x6028, 0xa09a, 0x0002, 0x00c8, 0x1d4e, 0x8000, + 0x602a, 0x0c7f, 0x1078, 0x4fd7, 0x0078, 0x1d9c, 0x2019, 0x6f19, + 0x2304, 0xa065, 0x0040, 0x1d58, 0x2009, 0x0014, 0x1078, 0x5591, + 0x0c7f, 0x0078, 0x1d9c, 0xd2bc, 0x0040, 0x1d9c, 0x1078, 0x415a, + 0x6017, 0x0010, 0x6027, 0x0004, 0x0d7e, 0x2069, 0x0140, 0x6804, + 0xa084, 0x4000, 0x0040, 0x1d70, 0x6803, 0x1000, 0x6803, 0x0000, + 0x0d7f, 0x0c7e, 0x2061, 0x6f10, 0x6044, 0xa09a, 0x0002, 0x00c8, + 0x1d91, 0x8000, 0x6046, 0x603c, 0x0c7f, 0xa005, 0x0040, 0x1d9c, + 0x1078, 0x4151, 0xa080, 0x0007, 0x2004, 0xa086, 0x0006, 0x00c0, + 0x1d8d, 0x6017, 0x0012, 0x0078, 0x1d9c, 0x6017, 0x0016, 0x0078, + 0x1d9c, 0x2019, 0x6f1f, 0x2304, 0xa065, 0x0040, 0x1d9b, 0x2009, + 0x004a, 0x1078, 0x5591, 0x0c7f, 0x017f, 0xd19c, 0x0040, 0x1dc5, + 0x017e, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x1078, 0x5232, + 0x2011, 0x0002, 0x1078, 0x523c, 0x1078, 0x5148, 0x1078, 0x414c, + 0x037e, 0x2019, 0x0000, 0x1078, 0x51da, 0x037f, 0x60e3, 0x0000, + 0x1078, 0x6c5f, 0x1078, 0x6c7d, 0x2001, 0x6d00, 0x2003, 0x0004, + 0x6027, 0x0008, 0x1078, 0x11aa, 0x017f, 0xa18c, 0xffd0, 0x6126, + 0x007c, 0x007e, 0x017e, 0x027e, 0x0e7e, 0x0f7e, 0x127e, 0x2091, + 0x8000, 0x2071, 0x6d00, 0x71b0, 0x70b2, 0xa116, 0x0040, 0x1def, + 0x81ff, 0x0040, 0x1de1, 0x2011, 0x8011, 0x1078, 0x2a53, 0x0078, + 0x1def, 0x2011, 0x8012, 0x1078, 0x2a53, 0x037e, 0x0c7e, 0x2061, + 0x0100, 0x2019, 0x0028, 0x1078, 0x202f, 0x0c7f, 0x037f, 0x127f, + 0x0f7f, 0x0e7f, 0x027f, 0x017f, 0x007f, 0x007c, 0x0c7e, 0x0f7e, + 0x007e, 0x027e, 0x2061, 0x0100, 0xa190, 0x1e09, 0x2204, 0x60f2, + 0xa190, 0x1e12, 0x2204, 0x60ee, 0x027f, 0x007f, 0x0f7f, 0x0c7f, + 0x007c, 0x083e, 0x083e, 0x083e, 0x0580, 0x0420, 0x0348, 0x02c0, + 0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x0140, 0x00f8, + 0x00d0, 0x00b0, 0x00a0, 0x2028, 0x2130, 0xa094, 0xff00, 0x00c0, + 0x1e24, 0x81ff, 0x0040, 0x1e28, 0x1078, 0x3f00, 0x0078, 0x1e2f, + 0xa080, 0x2091, 0x200c, 0xa18c, 0xff00, 0x810f, 0xa006, 0x007c, + 0xa080, 0x2091, 0x200c, 0xa18c, 0x00ff, 0x007c, 0x1e56, 0x1e5a, + 0x1e5e, 0x1e64, 0x1e6a, 0x1e70, 0x1e76, 0x1e7e, 0x1e86, 0x1e8c, + 0x1e92, 0x1e9a, 0x1ea2, 0x1eaa, 0x1eb2, 0x1ebc, 0x1ec6, 0x1ec6, + 0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6, + 0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6, 0x1ec6, 0x107e, 0x007e, + 0x0078, 0x1edf, 0x107e, 0x007e, 0x0078, 0x1edf, 0x107e, 0x007e, + 0x1078, 0x1c3e, 0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1c3e, + 0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1b2e, 0x0078, 0x1edf, + 0x107e, 0x007e, 0x1078, 0x1b2e, 0x0078, 0x1edf, 0x107e, 0x007e, + 0x1078, 0x1c3e, 0x1078, 0x1b2e, 0x0078, 0x1edf, 0x107e, 0x007e, + 0x1078, 0x1c3e, 0x1078, 0x1b2e, 0x0078, 0x1edf, 0x107e, 0x007e, + 0x1078, 0x1b72, 0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1b72, + 0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1c3e, 0x1078, 0x1b72, + 0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1c3e, 0x1078, 0x1b72, + 0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1b2e, 0x1078, 0x1b72, + 0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1b2e, 0x1078, 0x1b72, + 0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1c3e, 0x1078, 0x1b2e, + 0x1078, 0x1b72, 0x0078, 0x1edf, 0x107e, 0x007e, 0x1078, 0x1c3e, + 0x1078, 0x1b2e, 0x1078, 0x1b72, 0x0078, 0x1edf, 0x0005, 0x0078, + 0x1ec6, 0xb084, 0x003c, 0x8004, 0x8004, 0x0079, 0x1ecf, 0x1edf, + 0x1e5c, 0x1e60, 0x1e66, 0x1e6c, 0x1e72, 0x1e78, 0x1e80, 0x1e88, + 0x1e8e, 0x1e94, 0x1e9c, 0x1ea4, 0x1eac, 0x1eb4, 0x1ebe, 0x0008, + 0x1ec9, 0x007f, 0x107f, 0x2091, 0x8001, 0x007c, 0x0c7e, 0x027e, + 0x2041, 0x007e, 0x70bc, 0xd09c, 0x0040, 0x1ef0, 0x2041, 0x007f, + 0x2001, 0x010c, 0x203c, 0x727c, 0x82ff, 0x0040, 0x1f3b, 0x037e, + 0x738c, 0xa38e, 0xffff, 0x00c0, 0x1eff, 0x2019, 0x0001, 0x8314, + 0xa2e0, 0x73c0, 0x2c04, 0xa38c, 0x0001, 0x0040, 0x1f0c, 0xa084, + 0xff00, 0x8007, 0x0078, 0x1f0e, 0xa084, 0x00ff, 0xa70e, 0x0040, + 0x1f30, 0xa08e, 0x00ff, 0x0040, 0x1f36, 0x2009, 0x0000, 0x1078, + 0x1e1b, 0x1078, 0x3410, 0x00c0, 0x1f33, 0x6004, 0xa084, 0x00ff, + 0xa086, 0x0006, 0x00c0, 0x1f2a, 0x1078, 0x1f8d, 0x0040, 0x1f33, + 0x0078, 0x1f30, 0x1078, 0x208d, 0x1078, 0x1fb4, 0x0040, 0x1f33, + 0x8318, 0x0078, 0x1eff, 0x738e, 0x0078, 0x1f38, 0x708f, 0xffff, + 0x037f, 0x0078, 0x1f8a, 0xa780, 0x2091, 0x203c, 0xa7bc, 0xff00, + 0x873f, 0x708c, 0xa096, 0xffff, 0x0040, 0x1f4d, 0xa812, 0x00c8, + 0x1f5d, 0x708f, 0xffff, 0x0078, 0x1f87, 0x2009, 0x0000, 0x70bc, + 0xd09c, 0x0040, 0x1f58, 0xd094, 0x0040, 0x1f58, 0x2009, 0x007e, + 0x2100, 0xa802, 0x20a8, 0x0078, 0x1f61, 0x2008, 0x2810, 0xa202, + 0x20a8, 0x2700, 0x157e, 0x017e, 0xa106, 0x0040, 0x1f7e, 0x1078, + 0x3410, 0x00c0, 0x1f87, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, + 0x00c0, 0x1f78, 0x1078, 0x1f8d, 0x0040, 0x1f87, 0x0078, 0x1f7e, + 0x1078, 0x208d, 0x1078, 0x1fb4, 0x0040, 0x1f87, 0x017f, 0x8108, + 0x157f, 0x00f0, 0x1f61, 0x708f, 0xffff, 0x0078, 0x1f8a, 0x017f, + 0x157f, 0x718e, 0x027f, 0x0c7f, 0x007c, 0x017e, 0x077e, 0x0d7e, + 0x0c7e, 0x2c68, 0x1078, 0x5504, 0x0040, 0x1faf, 0x2d00, 0x601a, + 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x33df, 0x2001, 0x0000, + 0x1078, 0x33f3, 0x127e, 0x2091, 0x8000, 0x7088, 0x8000, 0x708a, + 0x127f, 0x2009, 0x0004, 0x1078, 0x5591, 0xa085, 0x0001, 0x0c7f, + 0x0d7f, 0x077f, 0x017f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, + 0x2c68, 0x1078, 0x5504, 0x0040, 0x1fd6, 0x2d00, 0x601a, 0x601f, + 0x0001, 0x2001, 0x0000, 0x1078, 0x33df, 0x2001, 0x0002, 0x1078, + 0x33f3, 0x127e, 0x2091, 0x8000, 0x7088, 0x8000, 0x708a, 0x127f, + 0x2009, 0x0002, 0x1078, 0x5591, 0xa085, 0x0001, 0x0c7f, 0x0d7f, + 0x077f, 0x017f, 0x007c, 0x0c7e, 0x027e, 0x2009, 0x0080, 0x1078, + 0x3410, 0x00c0, 0x1fe9, 0x1078, 0x1fec, 0x0040, 0x1fe9, 0x70c3, + 0xffff, 0x027f, 0x0c7f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, + 0x2c68, 0x1078, 0x5504, 0x0040, 0x200e, 0x2d00, 0x601a, 0x601f, + 0x0001, 0x2001, 0x0000, 0x1078, 0x33df, 0x2001, 0x0002, 0x1078, + 0x33f3, 0x127e, 0x2091, 0x8000, 0x70c4, 0x8000, 0x70c6, 0x127f, + 0x2009, 0x0002, 0x1078, 0x5591, 0xa085, 0x0001, 0x0c7f, 0x0d7f, + 0x077f, 0x017f, 0x007c, 0x0c7e, 0x0d7e, 0x2009, 0x007f, 0x1078, + 0x3410, 0x00c0, 0x202c, 0x2c68, 0x1078, 0x5504, 0x0040, 0x202c, + 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, 0x620a, 0x2009, 0x0022, + 0x1078, 0x5591, 0xa085, 0x0001, 0x0d7f, 0x0c7f, 0x007c, 0x0e7e, + 0x0c7e, 0x067e, 0x037e, 0x027e, 0x1078, 0x4463, 0x1078, 0x4417, + 0x1078, 0x59ce, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, + 0x3447, 0x00c0, 0x2047, 0x1078, 0x35cf, 0x1078, 0x3256, 0x017f, + 0x8108, 0x00f0, 0x203e, 0x027f, 0x037f, 0x067f, 0x0c7f, 0x0e7f, + 0x007c, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x6218, 0x2270, + 0x72a0, 0x027e, 0x2019, 0x0029, 0x1078, 0x445c, 0x1078, 0x43a9, + 0x2c08, 0x1078, 0x6a57, 0x017f, 0x2e60, 0x1078, 0x35cf, 0x1078, + 0x3256, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, + 0x007e, 0x6018, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x00c0, 0x2083, + 0x2071, 0x6d00, 0x7088, 0xa005, 0x0040, 0x2080, 0x8001, 0x708a, + 0x007f, 0x0e7f, 0x007c, 0x2071, 0x6d00, 0x70c4, 0xa005, 0x0040, + 0x2080, 0x8001, 0x70c6, 0x0078, 0x2080, 0x6000, 0xc08c, 0x6002, + 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, + 0x8000, 0x2071, 0x6d6d, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, + 0x703a, 0x703e, 0x7033, 0x6d7d, 0x7037, 0x6d7d, 0x7007, 0x0001, + 0x2061, 0x6d9d, 0x6003, 0x0002, 0x007c, 0x0090, 0x21b8, 0x0068, + 0x21b8, 0x2071, 0x6d6d, 0x2b78, 0x7818, 0xd084, 0x00c0, 0x21b8, + 0x2a60, 0x7820, 0xa08e, 0x0069, 0x00c0, 0x229c, 0x0079, 0x223c, + 0x007c, 0x2071, 0x6d6d, 0x7004, 0x0079, 0x21be, 0x21c2, 0x21c3, + 0x21cd, 0x21df, 0x007c, 0x0090, 0x21cc, 0x0068, 0x21cc, 0x2b78, + 0x7818, 0xd084, 0x0040, 0x21eb, 0x007c, 0x2b78, 0x2061, 0x6d9d, + 0x6008, 0xa08e, 0x0100, 0x0040, 0x21da, 0xa086, 0x0200, 0x0040, + 0x2294, 0x007c, 0x7014, 0x2068, 0x2a60, 0x7018, 0x007a, 0x7010, + 0x2068, 0x6834, 0xa086, 0x0103, 0x0040, 0x21e7, 0x007c, 0x2a60, + 0x2b78, 0x7018, 0x007a, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x00c8, + 0x21f4, 0x61b0, 0x0079, 0x21fc, 0x2100, 0xa08a, 0x0033, 0x00c8, + 0x2290, 0x61b0, 0x0079, 0x223c, 0x2272, 0x22a4, 0x22ac, 0x22b0, + 0x22b8, 0x22be, 0x22c2, 0x22cb, 0x22cf, 0x22d7, 0x22db, 0x2290, + 0x2290, 0x2290, 0x22df, 0x2290, 0x22ef, 0x2306, 0x231d, 0x2399, + 0x239e, 0x23cb, 0x2416, 0x2425, 0x2446, 0x247c, 0x2486, 0x2493, + 0x24a6, 0x24be, 0x24c7, 0x2504, 0x250a, 0x2290, 0x251a, 0x2290, + 0x2290, 0x2290, 0x2290, 0x2290, 0x251e, 0x2524, 0x2290, 0x2290, + 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x252c, 0x2290, + 0x2290, 0x2290, 0x2290, 0x2290, 0x2539, 0x253f, 0x2290, 0x2290, + 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, + 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, + 0x2290, 0x2290, 0x2290, 0x2290, 0x22d7, 0x22db, 0x2290, 0x2290, + 0x2551, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, 0x2290, + 0x2290, 0x2290, 0x2290, 0x2290, 0x259e, 0x265d, 0x2671, 0x2678, + 0x26db, 0x2736, 0x2741, 0x2783, 0x2790, 0x279d, 0x27a0, 0x2555, + 0x27c9, 0x2811, 0x281e, 0x28fd, 0x29cb, 0x29f2, 0x2ade, 0x713c, + 0x0078, 0x2272, 0x2021, 0x4000, 0x1078, 0x2a2d, 0x127e, 0x2091, + 0x8000, 0x0068, 0x227f, 0x7818, 0xd084, 0x0040, 0x2282, 0x127f, + 0x0078, 0x2276, 0x781b, 0x0001, 0x7c22, 0x7926, 0x7a2a, 0x7b2e, + 0x2091, 0x4080, 0x7007, 0x0001, 0x2091, 0x5000, 0x127f, 0x007c, + 0x2021, 0x4001, 0x0078, 0x2274, 0x2021, 0x4002, 0x0078, 0x2274, + 0x2021, 0x4003, 0x0078, 0x2274, 0x2021, 0x4005, 0x0078, 0x2274, + 0x2021, 0x4006, 0x0078, 0x2274, 0xa02e, 0x2520, 0x7b28, 0x7a2c, + 0x7824, 0x7930, 0x0078, 0x2a3c, 0x7823, 0x0004, 0x7824, 0x007a, + 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0078, 0x2a40, + 0x7924, 0x7828, 0x2114, 0x200a, 0x0078, 0x2272, 0x7924, 0x2114, + 0x0078, 0x2272, 0x2099, 0x0009, 0x20a1, 0x0009, 0x20a9, 0x0007, + 0x53a3, 0x0078, 0x2272, 0x7824, 0x2060, 0x0078, 0x22e1, 0x2009, + 0x0001, 0x2011, 0x000d, 0x2019, 0x0000, 0x0078, 0x2272, 0x7d38, + 0x7c3c, 0x0078, 0x22a6, 0x7d38, 0x7c3c, 0x0078, 0x22b2, 0x2061, + 0x1000, 0x610c, 0xa006, 0x2c14, 0xa200, 0x8c60, 0x8109, 0x00c0, + 0x22e3, 0x2010, 0xa005, 0x0040, 0x2272, 0x0078, 0x2298, 0x2061, + 0x6d51, 0x7824, 0x7930, 0xa11a, 0x00c8, 0x22a0, 0x8019, 0x0040, + 0x22a0, 0x604a, 0x6142, 0x782c, 0x6052, 0x7828, 0x6056, 0xa006, + 0x605a, 0x605e, 0x1078, 0x3890, 0x0078, 0x2272, 0x2061, 0x6d51, + 0x7824, 0x7930, 0xa11a, 0x00c8, 0x22a0, 0x8019, 0x0040, 0x22a0, + 0x604e, 0x6146, 0x782c, 0x6062, 0x7828, 0x6066, 0xa006, 0x606a, + 0x606e, 0x1078, 0x366e, 0x0078, 0x2272, 0xa02e, 0x2520, 0x81ff, + 0x00c0, 0x229c, 0x7924, 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1, + 0x6d74, 0x41a1, 0x1078, 0x2a04, 0x0040, 0x229c, 0x2009, 0x0020, + 0x1078, 0x2a3c, 0x701b, 0x2335, 0x007c, 0x6834, 0x2008, 0xa084, + 0x00ff, 0xa096, 0x0011, 0x0040, 0x2341, 0xa096, 0x0019, 0x00c0, + 0x229c, 0x810f, 0xa18c, 0x00ff, 0x0040, 0x229c, 0x710e, 0x700c, + 0x8001, 0x0040, 0x2372, 0x700e, 0x1078, 0x2a04, 0x0040, 0x229c, + 0x2009, 0x0020, 0x2061, 0x6d9d, 0x6224, 0x6328, 0x642c, 0x6530, + 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, + 0x1078, 0x2a3c, 0x701b, 0x2365, 0x007c, 0x6834, 0xa084, 0x00ff, + 0xa096, 0x0002, 0x0040, 0x2370, 0xa096, 0x000a, 0x00c0, 0x229c, + 0x0078, 0x2347, 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x1078, + 0x3344, 0x00c0, 0x2380, 0x7007, 0x0003, 0x701b, 0x2382, 0x007c, + 0x1078, 0x372d, 0x127e, 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, + 0x6d74, 0x530a, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, + 0xa5a9, 0x0000, 0xad80, 0x000d, 0x2009, 0x0020, 0x127f, 0x0078, + 0x2a40, 0x6198, 0x7824, 0x609a, 0x0078, 0x2272, 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, 0x229c, 0x1078, 0x2a1c, + 0x0040, 0x22a0, 0x7c28, 0x7d2c, 0x1078, 0x3592, 0xd28c, 0x00c0, + 0x23dd, 0x1078, 0x3522, 0x0078, 0x23df, 0x1078, 0x355e, 0x00c0, + 0x2409, 0x2061, 0x7400, 0x127e, 0x2091, 0x8000, 0x6000, 0xa086, + 0x0000, 0x0040, 0x23f7, 0x6010, 0xa06d, 0x0040, 0x23f7, 0x683c, + 0xa406, 0x00c0, 0x23f7, 0x6840, 0xa506, 0x0040, 0x2402, 0x127f, + 0xace0, 0x0008, 0x2001, 0x6d15, 0x2004, 0xac02, 0x00c8, 0x229c, + 0x0078, 0x23e3, 0x1078, 0x5f5d, 0x127f, 0x0040, 0x229c, 0x0078, + 0x2272, 0xa00e, 0x2001, 0x0005, 0x1078, 0x372d, 0x127e, 0x2091, + 0x8000, 0x1078, 0x36a1, 0x127f, 0x0078, 0x2272, 0x81ff, 0x00c0, + 0x229c, 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x1078, 0x34d7, 0x1078, + 0x35a3, 0x0040, 0x229c, 0x0078, 0x2272, 0x81ff, 0x00c0, 0x229c, + 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x2031, 0x000f, 0x1078, 0x34d7, + 0x8631, 0x00c8, 0x242e, 0x2019, 0x0005, 0x1078, 0x35c4, 0x0040, + 0x229c, 0x7828, 0xa08a, 0x1000, 0x00c8, 0x22a0, 0x8003, 0x800b, + 0x810b, 0xa108, 0x1078, 0x40de, 0x0078, 0x2272, 0x127e, 0x2091, + 0x8000, 0x81ff, 0x00c0, 0x2476, 0x2029, 0x00ff, 0x644c, 0x2400, + 0xa506, 0x0040, 0x2470, 0x2508, 0x1078, 0x3447, 0x00c0, 0x2470, + 0x2031, 0x000f, 0x1078, 0x34d7, 0x8631, 0x00c8, 0x245a, 0x2019, + 0x0004, 0x1078, 0x35c4, 0x0040, 0x2476, 0x7824, 0xa08a, 0x1000, + 0x00c8, 0x2479, 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x40de, + 0x8529, 0x00c8, 0x244f, 0x127f, 0x0078, 0x2272, 0x127f, 0x0078, + 0x229c, 0x127f, 0x0078, 0x22a0, 0x1078, 0x2a1c, 0x0040, 0x22a0, + 0x1078, 0x3507, 0x1078, 0x3592, 0x0078, 0x2272, 0x81ff, 0x00c0, + 0x229c, 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x1078, 0x34f0, 0x1078, + 0x3592, 0x0078, 0x2272, 0x81ff, 0x00c0, 0x229c, 0x1078, 0x2a1c, + 0x0040, 0x22a0, 0x1078, 0x3561, 0x0040, 0x229c, 0x1078, 0x338c, + 0x1078, 0x351b, 0x1078, 0x3592, 0x0078, 0x2272, 0x1078, 0x2a1c, + 0x0040, 0x22a0, 0x1078, 0x34d7, 0x62a0, 0x2019, 0x0005, 0x0c7e, + 0x1078, 0x35cf, 0x0c7f, 0x1078, 0x445c, 0x1078, 0x43a9, 0x2c08, + 0x1078, 0x6a57, 0x1078, 0x3592, 0x0078, 0x2272, 0x1078, 0x2a1c, + 0x0040, 0x22a0, 0x1078, 0x3592, 0x2208, 0x0078, 0x2272, 0x157e, + 0x0d7e, 0x0e7e, 0x2069, 0x6ddf, 0x6810, 0x6914, 0xa10a, 0x00c8, + 0x24d3, 0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019, 0x0000, + 0x20a9, 0x007e, 0x2069, 0x6e00, 0x2d04, 0xa075, 0x0040, 0x24e8, + 0x704c, 0x1078, 0x24f2, 0xa210, 0x7080, 0x1078, 0x24f2, 0xa318, + 0x8d68, 0x00f0, 0x24dc, 0x2300, 0xa218, 0x0e7f, 0x0d7f, 0x157f, + 0x0078, 0x2272, 0x0f7e, 0x017e, 0xa07d, 0x0040, 0x2501, 0x2001, + 0x0000, 0x8000, 0x2f0c, 0x81ff, 0x0040, 0x2501, 0x2178, 0x0078, + 0x24f9, 0x017f, 0x0f7f, 0x007c, 0x2069, 0x6ddf, 0x6910, 0x629c, + 0x0078, 0x2272, 0x81ff, 0x00c0, 0x229c, 0x614c, 0xa190, 0x2091, + 0x2214, 0xa294, 0x00ff, 0x6068, 0xa084, 0xff00, 0xa215, 0x6364, + 0x0078, 0x2272, 0x613c, 0x6240, 0x0078, 0x2272, 0x1078, 0x2a1c, + 0x0040, 0x22a0, 0x0078, 0x2272, 0x1078, 0x2a1c, 0x0040, 0x22a0, + 0x6244, 0x6338, 0x0078, 0x2272, 0x613c, 0x6240, 0x7824, 0x603e, + 0x7b28, 0x6342, 0x2069, 0x6d51, 0x831f, 0xa305, 0x6816, 0x0078, + 0x2272, 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x0078, 0x2272, 0x1078, + 0x2a1c, 0x0040, 0x22a0, 0x7828, 0xa00d, 0x0040, 0x22a0, 0x782c, + 0xa005, 0x0040, 0x22a0, 0x6244, 0x6146, 0x6338, 0x603a, 0x0078, + 0x2272, 0x7d38, 0x7c3c, 0x0078, 0x231f, 0x7824, 0xa09c, 0x00ff, + 0xa39a, 0x0003, 0x00c8, 0x229c, 0x624c, 0xa084, 0xff00, 0x8007, + 0xa206, 0x00c0, 0x256d, 0x2001, 0x6d40, 0x2009, 0x000c, 0x7a2c, + 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x2a40, 0x81ff, 0x00c0, 0x229c, + 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x6004, 0xa084, 0x00ff, 0xa086, + 0x0006, 0x00c0, 0x229c, 0x0c7e, 0x1078, 0x2a04, 0x0c7f, 0x0040, + 0x229c, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x6223, + 0x0040, 0x229c, 0x7007, 0x0003, 0x701b, 0x258f, 0x007c, 0x6830, + 0xa086, 0x0100, 0x0040, 0x229c, 0xad80, 0x000e, 0x2009, 0x000c, + 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x2a40, 0x1078, 0x2a04, + 0x0040, 0x229c, 0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, + 0x1078, 0x2a3c, 0x701b, 0x25ad, 0x007c, 0xade8, 0x000d, 0x6800, + 0xa005, 0x0040, 0x22a0, 0x6804, 0xd0ac, 0x0040, 0x25ba, 0xd0a4, + 0x0040, 0x22a0, 0xd094, 0x0040, 0x25c5, 0x0c7e, 0x2061, 0x0100, + 0x6104, 0xa18c, 0xffdf, 0x6106, 0x0c7f, 0xd08c, 0x0040, 0x25d0, + 0x0c7e, 0x2061, 0x0100, 0x6104, 0xa18d, 0x0010, 0x6106, 0x0c7f, + 0x2009, 0x0100, 0x210c, 0xa18a, 0x0002, 0x0048, 0x25e5, 0xd084, + 0x0040, 0x25e5, 0x6828, 0xa08a, 0x007f, 0x00c8, 0x22a0, 0xa088, + 0x2091, 0x210c, 0xa18c, 0x00ff, 0x6152, 0xd0dc, 0x0040, 0x25ee, + 0x6828, 0xa08a, 0x007f, 0x00c8, 0x22a0, 0x604e, 0x6808, 0xa08a, + 0x0100, 0x0048, 0x22a0, 0xa08a, 0x0841, 0x00c8, 0x22a0, 0xa084, + 0x0007, 0x00c0, 0x22a0, 0x680c, 0xa005, 0x0040, 0x22a0, 0x6810, + 0xa005, 0x0040, 0x22a0, 0x6848, 0x6940, 0xa10a, 0x00c8, 0x22a0, + 0x8001, 0x0040, 0x22a0, 0x684c, 0x6944, 0xa10a, 0x00c8, 0x22a0, + 0x8001, 0x0040, 0x22a0, 0x20a9, 0x001c, 0x2d98, 0x2069, 0x6d51, + 0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084, + 0x00ff, 0x6042, 0x1078, 0x3890, 0x1078, 0x366e, 0x6000, 0xa086, + 0x0000, 0x00c0, 0x265b, 0x6808, 0x602a, 0x1078, 0x1bcc, 0x6818, + 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, + 0x611a, 0x621e, 0x6322, 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, + 0x6312, 0x1078, 0x4168, 0x0c7e, 0x2061, 0x0100, 0x602f, 0x0040, + 0x602f, 0x0000, 0x0c7f, 0x60b4, 0xa005, 0x0040, 0x2657, 0x6003, + 0x0001, 0x2091, 0x301d, 0x1078, 0x31cb, 0x0078, 0x265b, 0x6003, + 0x0004, 0x2091, 0x301d, 0x0078, 0x2272, 0x6000, 0xa086, 0x0000, + 0x0040, 0x229c, 0x2069, 0x6d51, 0x7830, 0x6842, 0x7834, 0x6846, + 0x2d00, 0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, + 0x2a40, 0x81ff, 0x00c0, 0x229c, 0x1078, 0x31cb, 0x0078, 0x2272, + 0x81ff, 0x00c0, 0x229c, 0x617c, 0x81ff, 0x0040, 0x2692, 0x703f, + 0x0000, 0x2001, 0x73c0, 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, + 0x7d38, 0x127e, 0x2091, 0x8000, 0x1078, 0x2a40, 0x701b, 0x226f, + 0x127f, 0x007c, 0x703f, 0x0001, 0x0d7e, 0x2069, 0x73c0, 0x20a9, + 0x0040, 0x20a1, 0x73c0, 0x2019, 0xffff, 0x43a4, 0x654c, 0xa588, + 0x2091, 0x210c, 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, + 0x2100, 0xa506, 0x0040, 0x26c4, 0x1078, 0x3447, 0x00c0, 0x26c4, + 0x6014, 0x821c, 0x0048, 0x26bc, 0xa398, 0x73c0, 0xa085, 0xff00, + 0x8007, 0x201a, 0x0078, 0x26c3, 0xa398, 0x73c0, 0x2324, 0xa4a4, + 0xff00, 0xa405, 0x201a, 0x8210, 0x8108, 0xa182, 0x0080, 0x00c8, + 0x26cb, 0x0078, 0x26a8, 0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a, + 0x0d7f, 0x20a9, 0x0040, 0x20a1, 0x73c0, 0x2099, 0x73c0, 0x1078, + 0x3213, 0x0078, 0x2681, 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x0c7e, + 0x1078, 0x2a04, 0x0c7f, 0x0040, 0x229c, 0x2001, 0x6d52, 0x2004, + 0xd0b4, 0x0040, 0x2708, 0x6000, 0xd08c, 0x00c0, 0x2708, 0x6004, + 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2708, 0x6837, 0x0000, + 0x6838, 0xc0fd, 0x683a, 0x1078, 0x625b, 0x0040, 0x229c, 0x7007, + 0x0003, 0x701b, 0x2704, 0x007c, 0x1078, 0x2a1c, 0x0040, 0x22a0, + 0x20a9, 0x0029, 0x2c98, 0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9, + 0x0002, 0xac80, 0x0004, 0x2098, 0xad80, 0x0004, 0x20a0, 0x1078, + 0x3213, 0x20a9, 0x0004, 0xac80, 0x0006, 0x2098, 0xad80, 0x0006, + 0x20a0, 0x1078, 0x3213, 0x20a9, 0x0004, 0xac80, 0x000a, 0x2098, + 0xad80, 0x000a, 0x20a0, 0x1078, 0x3213, 0x2d00, 0x2009, 0x0029, + 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x2a40, 0x81ff, 0x00c0, + 0x229c, 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x1078, 0x35ae, 0x0078, + 0x2272, 0x81ff, 0x00c0, 0x229c, 0x7828, 0xa08a, 0x1000, 0x00c8, + 0x22a0, 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x2031, 0x000f, 0x1078, + 0x34d7, 0x8631, 0x00c8, 0x274f, 0x2019, 0x0004, 0x1078, 0x35c4, + 0x7924, 0x810f, 0x7a28, 0x1078, 0x275f, 0x0078, 0x2272, 0xa186, + 0x00ff, 0x0040, 0x2767, 0x1078, 0x2777, 0x0078, 0x2776, 0x2029, + 0x007e, 0x2061, 0x6d00, 0x644c, 0x2400, 0xa506, 0x0040, 0x2773, + 0x2508, 0x1078, 0x2777, 0x8529, 0x00c8, 0x276c, 0x007c, 0x1078, + 0x3447, 0x00c0, 0x2782, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108, + 0x1078, 0x40de, 0x007c, 0x81ff, 0x00c0, 0x229c, 0x1078, 0x2a1c, + 0x0040, 0x22a0, 0x1078, 0x34d7, 0x1078, 0x35b9, 0x0078, 0x2272, + 0x81ff, 0x00c0, 0x229c, 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x1078, + 0x34d7, 0x1078, 0x35a3, 0x0078, 0x2272, 0x6100, 0x0078, 0x2272, + 0x1078, 0x2a1c, 0x0040, 0x22a0, 0x6004, 0xa086, 0x0707, 0x0040, + 0x22a0, 0x2001, 0x6d00, 0x2004, 0xa086, 0x0003, 0x00c0, 0x229c, + 0x0d7e, 0xace8, 0x000a, 0x7924, 0xd184, 0x0040, 0x27b9, 0xace8, + 0x0006, 0x680c, 0x8007, 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, + 0x831f, 0x6a00, 0x8217, 0x0d7f, 0x6100, 0xa18c, 0x0200, 0x0078, + 0x2272, 0x81ff, 0x00c0, 0x229c, 0x7828, 0xa08a, 0x1000, 0x00c8, + 0x22a0, 0x7924, 0xa184, 0x00ff, 0xa082, 0x0010, 0x00c8, 0x22a0, + 0xa18c, 0xff00, 0x810f, 0xa186, 0x00ff, 0x0040, 0x27e6, 0xa182, + 0x007f, 0x00c8, 0x22a0, 0x2100, 0x1078, 0x1e30, 0x027e, 0x0c7e, + 0x127e, 0x2091, 0x8000, 0x2061, 0x6f23, 0x601b, 0x0000, 0x601f, + 0x0000, 0x2061, 0x6d00, 0x6003, 0x0001, 0x2061, 0x0100, 0x6030, + 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, 0x6043, 0x0090, 0x6043, + 0x0010, 0x2009, 0x001e, 0x2011, 0x31f0, 0x1078, 0x415f, 0x7924, + 0x810f, 0x7a28, 0x1078, 0x275f, 0x127f, 0x0c7f, 0x027f, 0x0078, + 0x2272, 0x7924, 0xa18c, 0xff00, 0x810f, 0x0c7e, 0x1078, 0x3410, + 0x2c08, 0x0c7f, 0x00c0, 0x22a0, 0x0078, 0x2272, 0x81ff, 0x00c0, + 0x229c, 0x60bc, 0xd09c, 0x0040, 0x229c, 0x1078, 0x2a04, 0x0040, + 0x229c, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x2a3c, + 0x701b, 0x2833, 0x007c, 0x2009, 0x0080, 0x1078, 0x3447, 0x00c0, + 0x229c, 0x0d7e, 0xade8, 0x000d, 0x6900, 0x6a08, 0x6b0c, 0x6c10, + 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0040, 0x28a7, 0xa0be, + 0x0112, 0x0040, 0x28a7, 0xa0be, 0x0113, 0x0040, 0x28a7, 0xa0be, + 0x0114, 0x0040, 0x28a7, 0xa0be, 0x0117, 0x0040, 0x28a7, 0xa0be, + 0x011a, 0x0040, 0x28a7, 0xa0be, 0x0121, 0x0040, 0x289d, 0xa0be, + 0x0131, 0x0040, 0x289d, 0xa0be, 0x0171, 0x0040, 0x28a7, 0xa0be, + 0x01a1, 0x00c0, 0x2870, 0x6830, 0x8007, 0x6832, 0x0078, 0x28ad, + 0xa0be, 0x0212, 0x0040, 0x28a3, 0xa0be, 0x0213, 0x0040, 0x28a3, + 0xa0be, 0x0214, 0x0040, 0x2895, 0xa0be, 0x0217, 0x0040, 0x288f, + 0xa0be, 0x021a, 0x00c0, 0x2889, 0x6838, 0x8007, 0x683a, 0x0078, + 0x28a7, 0xa0be, 0x0300, 0x0040, 0x28a7, 0x0078, 0x229c, 0xad80, + 0x0010, 0x20a9, 0x0007, 0x1078, 0x28d9, 0xad80, 0x000e, 0x20a9, + 0x0001, 0x1078, 0x28d9, 0x0078, 0x28a7, 0xad80, 0x000c, 0x1078, + 0x28e7, 0x0078, 0x28ad, 0xad80, 0x000e, 0x1078, 0x28e7, 0xad80, + 0x000c, 0x20a9, 0x0001, 0x1078, 0x28d9, 0x0c7e, 0x1078, 0x2a04, + 0x0040, 0x28ce, 0x6837, 0x0119, 0x684f, 0x0020, 0x685b, 0x0001, + 0x810b, 0x697e, 0x6883, 0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, + 0x6996, 0x689b, 0x0000, 0x0c7f, 0x0d7f, 0x1078, 0x623f, 0x0040, + 0x229c, 0x7007, 0x0003, 0x701b, 0x28d2, 0x007c, 0x0c7f, 0x0d7f, + 0x0078, 0x229c, 0x6820, 0xa086, 0x8001, 0x0040, 0x229c, 0x0078, + 0x2272, 0x017e, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x290a, + 0x8108, 0x280a, 0x8108, 0x00f0, 0x28db, 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, 0x229c, + 0x7924, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0081, 0x0048, 0x22a0, + 0xa182, 0x00ff, 0x00c8, 0x22a0, 0x7a2c, 0x7b28, 0x6064, 0xa306, + 0x00c0, 0x2918, 0x6068, 0xa206, 0x00c0, 0x2918, 0x0078, 0x22a0, + 0x0c7e, 0x1078, 0x297b, 0x2c68, 0x0c7f, 0x0040, 0x2939, 0xa0c6, + 0x4007, 0x00c0, 0x2926, 0x7c26, 0x0078, 0x2936, 0xa0c6, 0x4008, + 0x00c0, 0x292e, 0x7f26, 0x7e2a, 0x0078, 0x2936, 0xa0c6, 0x4009, + 0x00c0, 0x2934, 0x0078, 0x2936, 0x2001, 0x4006, 0x2020, 0x0078, + 0x2274, 0x017e, 0x0b7e, 0x0c7e, 0x0e7e, 0x2c70, 0x1078, 0x5504, + 0x0040, 0x2969, 0x2d00, 0x601a, 0x2e58, 0x0e7f, 0x0e7e, 0x0c7e, + 0x1078, 0x2a04, 0x0c7f, 0x2b70, 0x0040, 0x229c, 0x6837, 0x0000, + 0x2d00, 0x6012, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x33df, + 0x2001, 0x0002, 0x1078, 0x33f3, 0x127e, 0x2091, 0x8000, 0x7088, + 0x8000, 0x708a, 0x127f, 0x2009, 0x0002, 0x1078, 0x5591, 0xa085, + 0x0001, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f, 0x0040, 0x229c, 0x7007, + 0x0003, 0x701b, 0x2974, 0x007c, 0x6830, 0xa086, 0x0100, 0x00c0, + 0x2272, 0x0078, 0x229c, 0x0e7e, 0x0d7e, 0x2029, 0x0000, 0x2021, + 0x0081, 0x20a9, 0x007e, 0x2071, 0x6e81, 0x2e04, 0xa005, 0x00c0, + 0x298f, 0x2100, 0xa406, 0x0040, 0x29c0, 0x0078, 0x29b4, 0x2068, + 0x6f10, 0x2700, 0xa306, 0x00c0, 0x29a5, 0x6e14, 0x2600, 0xa206, + 0x00c0, 0x29a5, 0x2400, 0xa106, 0x00c0, 0x29a1, 0x2d60, 0x0078, + 0x29c6, 0x2001, 0x4007, 0x0078, 0x29c7, 0x2400, 0xa106, 0x00c0, + 0x29b4, 0x6e14, 0x87ff, 0x00c0, 0x29b0, 0x86ff, 0x0040, 0x29c0, + 0x2001, 0x4008, 0x0078, 0x29c7, 0x8420, 0x8e70, 0x00f0, 0x2985, + 0x2001, 0x4009, 0x0078, 0x29c7, 0x2001, 0x0001, 0x0078, 0x29c7, + 0x1078, 0x3410, 0x00c0, 0x29bc, 0x6312, 0x6216, 0xa006, 0xa005, + 0x0d7f, 0x0e7f, 0x007c, 0x81ff, 0x00c0, 0x229c, 0x1078, 0x2a04, + 0x0040, 0x229c, 0x6837, 0x0000, 0x7824, 0xa005, 0x0040, 0x22a0, + 0xa096, 0x00ff, 0x0040, 0x29e0, 0xa092, 0x0004, 0x00c8, 0x22a0, + 0x2010, 0x2d18, 0x1078, 0x2013, 0x0040, 0x229c, 0x7007, 0x0003, + 0x701b, 0x29eb, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x229c, + 0x0078, 0x2272, 0x7924, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0081, + 0x0048, 0x22a0, 0xa182, 0x00ff, 0x00c8, 0x22a0, 0x1078, 0x615b, + 0x1078, 0x342f, 0x0078, 0x2272, 0x1078, 0x12f4, 0x0040, 0x2a1b, + 0xa006, 0x6802, 0x7010, 0xa005, 0x00c0, 0x2a13, 0x2d00, 0x7012, + 0x7016, 0x0078, 0x2a19, 0x7014, 0x6802, 0x2060, 0x2d00, 0x6006, + 0x7016, 0xad80, 0x000d, 0x007c, 0x7e24, 0x860f, 0xa18c, 0x00ff, + 0x1078, 0x3447, 0x00c0, 0x2a2a, 0xa6b4, 0x00ff, 0xa682, 0x0010, + 0x0048, 0x2a2b, 0xa066, 0x8cff, 0x007c, 0x017e, 0x7110, 0x81ff, + 0x0040, 0x2a38, 0x2168, 0x6904, 0x1078, 0x1328, 0x0078, 0x2a2f, + 0x7112, 0x7116, 0x017f, 0x007c, 0x2031, 0x0001, 0x0078, 0x2a42, + 0x2031, 0x0000, 0x2061, 0x6d9d, 0x6606, 0x6112, 0x600e, 0x6226, + 0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x135f, 0x7007, 0x0002, + 0x701b, 0x2272, 0x007c, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079, + 0x0000, 0x2001, 0x6d7b, 0x2004, 0xa005, 0x00c0, 0x2a6e, 0x0068, + 0x2a6e, 0x7818, 0xd084, 0x00c0, 0x2a6e, 0x781b, 0x0001, 0x7a22, + 0x7b26, 0x7c2a, 0x2091, 0x4080, 0x0078, 0x2a93, 0x017e, 0x0c7e, + 0x0e7e, 0x2071, 0x6d6d, 0x7138, 0xa182, 0x0004, 0x0048, 0x2a7c, + 0x7030, 0x2060, 0x0078, 0x2a8d, 0x7030, 0xa0e0, 0x0008, 0xac82, + 0x6d9d, 0x0048, 0x2a85, 0x2061, 0x6d7d, 0x2c00, 0x7032, 0x81ff, + 0x00c0, 0x2a8b, 0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, + 0x0e7f, 0x0c7f, 0x017f, 0x127f, 0x0f7f, 0x007c, 0x0e7e, 0x2071, + 0x6d6d, 0x7038, 0xa005, 0x0040, 0x2acf, 0x127e, 0x2091, 0x8000, + 0x0068, 0x2ace, 0x0f7e, 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, + 0x2acd, 0x0c7e, 0x781b, 0x0001, 0x7034, 0x2060, 0x2c04, 0x7822, + 0x6004, 0x7826, 0x6008, 0x782a, 0x2091, 0x4080, 0x7038, 0x8001, + 0x703a, 0xa005, 0x00c0, 0x2ac3, 0x7033, 0x6d7d, 0x7037, 0x6d7d, + 0x0c7f, 0x0078, 0x2acd, 0xac80, 0x0008, 0xa0fa, 0x6d9d, 0x0048, + 0x2acb, 0x2001, 0x6d7d, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f, + 0x007c, 0x027e, 0x2001, 0x6d52, 0x2004, 0xd0c4, 0x0040, 0x2adc, + 0x2011, 0x8014, 0x1078, 0x2a53, 0x027f, 0x007c, 0x81ff, 0x00c0, + 0x229c, 0x127e, 0x2091, 0x8000, 0x6030, 0xc08d, 0x6032, 0x1078, + 0x31cb, 0x127f, 0x0078, 0x2272, 0x127e, 0x0c7e, 0x0e7e, 0x2061, + 0x0100, 0x2071, 0x6d00, 0x6044, 0xd0a4, 0x00c0, 0x2b11, 0xd084, + 0x0040, 0x2afe, 0x1078, 0x2c34, 0x0078, 0x2b11, 0xd08c, 0x0040, + 0x2b05, 0x1078, 0x2b4b, 0x0078, 0x2b11, 0xd094, 0x0040, 0x2b0c, + 0x1078, 0x2b2c, 0x0078, 0x2b11, 0xd09c, 0x0040, 0x2b11, 0x1078, + 0x2b15, 0x0e7f, 0x0c7f, 0x127f, 0x007c, 0x6043, 0x0040, 0x6043, + 0x0000, 0x706f, 0x0000, 0x7087, 0x0001, 0x70a7, 0x0000, 0x2009, + 0x73c0, 0x200b, 0x0000, 0x7073, 0x000f, 0x2009, 0x000f, 0x2011, + 0x3187, 0x1078, 0x415f, 0x007c, 0x7070, 0xa005, 0x00c0, 0x2b4a, + 0x2011, 0x3187, 0x1078, 0x40d1, 0x6043, 0x0020, 0x6043, 0x0000, + 0x6044, 0xd08c, 0x00c0, 0x2b46, 0x7003, 0x0001, 0x7083, 0x0000, + 0x6043, 0x0090, 0x6043, 0x0010, 0x0078, 0x2b4a, 0x7077, 0x0000, + 0x0078, 0x2b4a, 0x007c, 0x7074, 0xa08a, 0x0003, 0x00c8, 0x2b54, + 0x1079, 0x2b57, 0x0078, 0x2b56, 0x1078, 0x12b7, 0x007c, 0x2b5a, + 0x2ba9, 0x2c33, 0x0f7e, 0x7077, 0x0001, 0x20e1, 0xa000, 0x20e1, + 0x8700, 0x1078, 0x1bcc, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2079, + 0x7200, 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, 0x720c, 0x207b, 0x1101, 0x7807, 0x0000, 0x2099, + 0x6d05, 0x20a1, 0x720e, 0x20a9, 0x0004, 0x53a3, 0x2079, 0x7212, + 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0x7200, 0x20a1, 0x020b, + 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000, 0x1078, + 0x31b2, 0x0f7f, 0x707b, 0x0000, 0x6043, 0x0008, 0x6043, 0x0000, + 0x007c, 0x0d7e, 0x7078, 0x707b, 0x0000, 0xa025, 0x0040, 0x2c1d, + 0x6020, 0xd0b4, 0x00c0, 0x2c1b, 0x7184, 0x81ff, 0x0040, 0x2c04, + 0xa486, 0x000c, 0x00c0, 0x2c0f, 0xa480, 0x0018, 0x8004, 0x20a8, + 0x2011, 0x7280, 0x2019, 0x7200, 0x220c, 0x2304, 0xa106, 0x00c0, + 0x2bdb, 0x8210, 0x8318, 0x00f0, 0x2bc4, 0x6043, 0x0004, 0x608b, + 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x7077, 0x0002, 0x7083, + 0x0002, 0x0078, 0x2c1b, 0x2069, 0x7280, 0x6930, 0xa18e, 0x1101, + 0x00c0, 0x2c0f, 0x6834, 0xa005, 0x00c0, 0x2c0f, 0x6900, 0xa18c, + 0x00ff, 0x00c0, 0x2bef, 0x6804, 0xa005, 0x0040, 0x2c04, 0x2011, + 0x728e, 0x2019, 0x6d05, 0x20a9, 0x0004, 0x220c, 0x2304, 0xa102, + 0x0048, 0x2c02, 0x00c0, 0x2c0f, 0x8210, 0x8318, 0x00f0, 0x2bf5, + 0x0078, 0x2c0f, 0x7087, 0x0000, 0x20e1, 0x9080, 0x20e1, 0x4000, + 0x2099, 0x7280, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043, + 0x0008, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x2c1b, 0x60c3, + 0x000c, 0x1078, 0x31b2, 0x0d7f, 0x007c, 0x6020, 0xd0b4, 0x00c0, + 0x2c1b, 0x60c3, 0x000c, 0x2011, 0x6f1a, 0x2013, 0x0000, 0x707b, + 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x1078, + 0x4fdc, 0x0078, 0x2c1b, 0x007c, 0x7080, 0xa08a, 0x001d, 0x00c8, + 0x2c3d, 0x1079, 0x2c40, 0x0078, 0x2c3f, 0x1078, 0x12b7, 0x007c, + 0x2c64, 0x2c73, 0x2ca6, 0x2cbb, 0x2ced, 0x2d17, 0x2d49, 0x2d73, + 0x2da5, 0x2dcb, 0x2e1a, 0x2e3c, 0x2e60, 0x2e76, 0x2e9c, 0x2eaf, + 0x2eb8, 0x2ed1, 0x2f01, 0x2f2b, 0x2f5b, 0x2f85, 0x2fce, 0x3003, + 0x3025, 0x3063, 0x3087, 0x30a0, 0x30ad, 0x7003, 0x0007, 0x6004, + 0xa084, 0xfff9, 0x6006, 0x007c, 0x608b, 0xbc94, 0x608f, 0xf0f0, + 0x6043, 0x0002, 0x7083, 0x0001, 0x2009, 0x07d0, 0x2011, 0x318e, + 0x1078, 0x40c4, 0x007c, 0x0f7e, 0x7078, 0xa086, 0x0014, 0x00c0, + 0x2ca4, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x2ca4, 0x2079, + 0x7280, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x2ca2, 0x7834, 0xa005, + 0x00c0, 0x2ca2, 0x7a38, 0xd2fc, 0x0040, 0x2c98, 0x70a4, 0xa005, + 0x00c0, 0x2c98, 0x2019, 0x002a, 0x1078, 0x202f, 0x70a7, 0x0001, + 0x2011, 0x318e, 0x1078, 0x40d1, 0x7083, 0x0010, 0x1078, 0x2eb8, + 0x0078, 0x2ca4, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0003, + 0x6043, 0x0004, 0x1078, 0x321b, 0x20a3, 0x1102, 0x20a3, 0x0000, + 0x20a9, 0x000a, 0x20a3, 0x0000, 0x00f0, 0x2cb2, 0x60c3, 0x0014, + 0x1078, 0x31b2, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x2ceb, + 0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0014, 0x00c0, 0x2ce7, + 0x2079, 0x7280, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x2ce7, 0x7834, + 0xa005, 0x00c0, 0x2ce7, 0x7a38, 0xd2fc, 0x0040, 0x2ce1, 0x70a4, + 0xa005, 0x00c0, 0x2ce1, 0x2019, 0x002a, 0x1078, 0x202f, 0x70a7, + 0x0001, 0x7083, 0x0004, 0x1078, 0x2ced, 0x0078, 0x2ceb, 0x7083, + 0x0002, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0005, 0x1078, + 0x321b, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0x728e, + 0x706c, 0xa005, 0x00c0, 0x2d09, 0x714c, 0xa186, 0xffff, 0x0040, + 0x2d09, 0x1078, 0x3152, 0x0040, 0x2d09, 0x2019, 0x002a, 0x1078, + 0x202f, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x31b2, 0x007c, 0x0f7e, + 0x7078, 0xa005, 0x0040, 0x2d47, 0x2011, 0x318e, 0x1078, 0x40d1, + 0xa086, 0x0014, 0x00c0, 0x2d43, 0x2079, 0x7280, 0x7a30, 0xa296, + 0x1103, 0x00c0, 0x2d43, 0x7834, 0xa005, 0x00c0, 0x2d43, 0x7a38, + 0xd2fc, 0x0040, 0x2d3d, 0x70a4, 0xa005, 0x00c0, 0x2d3d, 0x2019, + 0x002a, 0x1078, 0x202f, 0x70a7, 0x0001, 0x7083, 0x0006, 0x1078, + 0x2d49, 0x0078, 0x2d47, 0x7083, 0x0002, 0x707b, 0x0000, 0x0f7f, + 0x007c, 0x7083, 0x0007, 0x1078, 0x321b, 0x20a3, 0x1104, 0x20a3, + 0x0000, 0x3430, 0x2011, 0x728e, 0x706c, 0xa005, 0x00c0, 0x2d65, + 0x7150, 0xa186, 0xffff, 0x0040, 0x2d65, 0xa180, 0x2091, 0x200c, + 0xa18c, 0xff00, 0x810f, 0x1078, 0x3152, 0x20a9, 0x0008, 0x2298, + 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, + 0x1078, 0x31b2, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x2da3, + 0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0014, 0x00c0, 0x2d9f, + 0x2079, 0x7280, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x2d9f, 0x7834, + 0xa005, 0x00c0, 0x2d9f, 0x7a38, 0xd2fc, 0x0040, 0x2d99, 0x70a4, + 0xa005, 0x00c0, 0x2d99, 0x2019, 0x002a, 0x1078, 0x202f, 0x70a7, + 0x0001, 0x7083, 0x0008, 0x1078, 0x2da5, 0x0078, 0x2da3, 0x7083, + 0x0002, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0009, 0x1078, + 0x321b, 0x20a3, 0x1105, 0x20a3, 0x0100, 0x3430, 0x706c, 0xa005, + 0x00c0, 0x2db8, 0x1078, 0x30bc, 0x0040, 0x2dc8, 0x0078, 0x2dc2, + 0x20a9, 0x0008, 0x2099, 0x728e, 0x26a0, 0x53a6, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x31b2, 0x0078, 0x2dca, + 0x1078, 0x2c5d, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x2e18, + 0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0014, 0x00c0, 0x2e14, + 0x2079, 0x7280, 0x7a30, 0xa296, 0x1105, 0x00c0, 0x2e14, 0x7834, + 0x2011, 0x0100, 0xa21e, 0x00c0, 0x2dfb, 0x7a38, 0xd2fc, 0x0040, + 0x2df3, 0x70a4, 0xa005, 0x00c0, 0x2df3, 0x2019, 0x002a, 0x1078, + 0x202f, 0x70a7, 0x0001, 0x707f, 0x0001, 0x7083, 0x000a, 0x1078, + 0x2e1a, 0x0078, 0x2e18, 0xa005, 0x00c0, 0x2e14, 0x7a38, 0xd2fc, + 0x0040, 0x2e0c, 0x70a4, 0xa005, 0x00c0, 0x2e0c, 0x2019, 0x002a, + 0x1078, 0x202f, 0x70a7, 0x0001, 0x707f, 0x0000, 0x7083, 0x000e, + 0x1078, 0x2e9c, 0x0078, 0x2e18, 0x7083, 0x0002, 0x707b, 0x0000, + 0x0f7f, 0x007c, 0x7083, 0x000b, 0x2011, 0x720e, 0x22a0, 0x20a9, + 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, 0x2009, 0x0000, + 0x41a4, 0x1078, 0x321b, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x6030, + 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6, 0x60c3, + 0x0084, 0x1078, 0x31b2, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, + 0x2e5e, 0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0084, 0x00c0, + 0x2e5a, 0x2079, 0x7280, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x2e5a, + 0x7834, 0xa005, 0x00c0, 0x2e5a, 0x7083, 0x000c, 0x1078, 0x2e60, + 0x0078, 0x2e5e, 0x7083, 0x0002, 0x707b, 0x0000, 0x0f7f, 0x007c, + 0x7083, 0x000d, 0x1078, 0x321b, 0x20a3, 0x1107, 0x20a3, 0x0000, + 0x2099, 0x728e, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x60c3, 0x0084, 0x1078, 0x31b2, 0x007c, 0x0f7e, 0x7078, + 0xa005, 0x0040, 0x2e9a, 0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, + 0x0084, 0x00c0, 0x2e96, 0x2079, 0x7280, 0x7a30, 0xa296, 0x1107, + 0x00c0, 0x2e96, 0x7834, 0xa005, 0x00c0, 0x2e96, 0x1078, 0x320d, + 0x7083, 0x000e, 0x1078, 0x2e9c, 0x0078, 0x2e9a, 0x7083, 0x0002, + 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x000f, 0x707b, 0x0000, + 0x608b, 0xbc85, 0x608f, 0xb5b5, 0x6043, 0x0005, 0x6043, 0x0004, + 0x2009, 0x07d0, 0x2011, 0x318e, 0x1078, 0x40c4, 0x007c, 0x7078, + 0xa005, 0x0040, 0x2eb7, 0x2011, 0x318e, 0x1078, 0x40d1, 0x007c, + 0x7083, 0x0011, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x7280, + 0x20a1, 0x020b, 0x7478, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, + 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014, 0x1078, 0x31b2, + 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x2eff, 0x2011, 0x318e, + 0x1078, 0x40d1, 0xa086, 0x0014, 0x00c0, 0x2efd, 0x2079, 0x7280, + 0x7a30, 0xa296, 0x1103, 0x00c0, 0x2efd, 0x7834, 0xa005, 0x00c0, + 0x2efd, 0x7a38, 0xd2fc, 0x0040, 0x2ef7, 0x70a4, 0xa005, 0x00c0, + 0x2ef7, 0x2019, 0x002a, 0x1078, 0x202f, 0x70a7, 0x0001, 0x7083, + 0x0012, 0x1078, 0x2f01, 0x0078, 0x2eff, 0x707b, 0x0000, 0x0f7f, + 0x007c, 0x7083, 0x0013, 0x1078, 0x3227, 0x20a3, 0x1103, 0x20a3, + 0x0000, 0x3430, 0x2011, 0x728e, 0x706c, 0xa005, 0x00c0, 0x2f1d, + 0x714c, 0xa186, 0xffff, 0x0040, 0x2f1d, 0x1078, 0x3152, 0x0040, + 0x2f1d, 0x2019, 0x002a, 0x1078, 0x202f, 0x20a9, 0x0008, 0x2298, + 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, + 0x1078, 0x31b2, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x2f59, + 0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0014, 0x00c0, 0x2f57, + 0x2079, 0x7280, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x2f57, 0x7834, + 0xa005, 0x00c0, 0x2f57, 0x7a38, 0xd2fc, 0x0040, 0x2f51, 0x70a4, + 0xa005, 0x00c0, 0x2f51, 0x2019, 0x002a, 0x1078, 0x202f, 0x70a7, + 0x0001, 0x7083, 0x0014, 0x1078, 0x2f5b, 0x0078, 0x2f59, 0x707b, + 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0015, 0x1078, 0x3227, 0x20a3, + 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0x728e, 0x706c, 0xa006, + 0x00c0, 0x2f77, 0x7150, 0xa186, 0xffff, 0x0040, 0x2f77, 0xa180, + 0x2091, 0x200c, 0xa18c, 0xff00, 0x810f, 0x1078, 0x3152, 0x20a9, + 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0014, 0x1078, 0x31b2, 0x007c, 0x0f7e, 0x7078, 0xa005, + 0x0040, 0x2fcc, 0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0014, + 0x00c0, 0x2fca, 0x2079, 0x7280, 0x7a30, 0xa296, 0x1105, 0x00c0, + 0x2fca, 0x7834, 0x2011, 0x0100, 0xa21e, 0x00c0, 0x2fb1, 0x7a38, + 0xd2fc, 0x0040, 0x2fad, 0x70a4, 0xa005, 0x00c0, 0x2fad, 0x2019, + 0x002a, 0x1078, 0x202f, 0x70a7, 0x0001, 0x707f, 0x0001, 0x0078, + 0x2fc4, 0xa005, 0x00c0, 0x2fca, 0x7a38, 0xd2fc, 0x0040, 0x2fc2, + 0x70a4, 0xa005, 0x00c0, 0x2fc2, 0x2019, 0x002a, 0x1078, 0x202f, + 0x70a7, 0x0001, 0x707f, 0x0000, 0x7083, 0x0016, 0x1078, 0x2fce, + 0x0078, 0x2fcc, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x2099, 0x7280, 0x20a1, 0x020b, 0x20a9, 0x000e, + 0x53a6, 0x3430, 0x2011, 0x728e, 0x707c, 0xa005, 0x0040, 0x2fe4, + 0x7083, 0x0017, 0x0078, 0x2fe6, 0x7083, 0x001b, 0x706c, 0xa005, + 0x00c0, 0x2ff0, 0x1078, 0x30bc, 0x0040, 0x3000, 0x0078, 0x2ffa, + 0x20a9, 0x0008, 0x2099, 0x728e, 0x26a0, 0x53a6, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x31b2, 0x0078, 0x3002, + 0x1078, 0x2c5d, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x3023, + 0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0084, 0x00c0, 0x3021, + 0x2079, 0x7280, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x3021, 0x7834, + 0xa005, 0x00c0, 0x3021, 0x7083, 0x0018, 0x1078, 0x3025, 0x0078, + 0x3023, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0019, 0x1078, + 0x3227, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x3430, 0x2099, 0x728e, + 0x2039, 0x720e, 0x27a0, 0x20a9, 0x0040, 0x53a3, 0x2728, 0x2514, + 0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007, + 0xa205, 0x202a, 0x6030, 0x2310, 0x8214, 0xa2a0, 0x720e, 0x2414, + 0xa38c, 0x0001, 0x0040, 0x3050, 0xa294, 0xff00, 0x0078, 0x3053, + 0xa294, 0x00ff, 0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, + 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, + 0x1078, 0x31b2, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x3085, + 0x2011, 0x318e, 0x1078, 0x40d1, 0xa086, 0x0084, 0x00c0, 0x3083, + 0x2079, 0x7280, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x3083, 0x7834, + 0xa005, 0x00c0, 0x3083, 0x1078, 0x320d, 0x7083, 0x001a, 0x1078, + 0x3087, 0x0078, 0x3085, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, + 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x7280, 0x20a1, + 0x020b, 0x7478, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, + 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x1078, 0x31b2, 0x007c, + 0x7078, 0xa005, 0x0040, 0x30ac, 0x2011, 0x318e, 0x1078, 0x40d1, + 0x7083, 0x001c, 0x1078, 0x30ad, 0x007c, 0x707b, 0x0000, 0x608b, + 0xbc85, 0x608f, 0xb5b5, 0x6043, 0x0001, 0x2009, 0x07d0, 0x2011, + 0x318e, 0x1078, 0x40c4, 0x007c, 0x087e, 0x097e, 0x2029, 0x6d52, + 0x252c, 0x20a9, 0x0008, 0x2041, 0x720e, 0x28a0, 0x2099, 0x728e, + 0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0040, 0x30d2, + 0x2011, 0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, 0xffff, 0x00c0, + 0x30e4, 0xd5d4, 0x0040, 0x30df, 0x8210, 0x0078, 0x30e0, 0x8211, + 0x00f0, 0x30d2, 0x0078, 0x3149, 0x82ff, 0x00c0, 0x30f6, 0xd5d4, + 0x0040, 0x30f0, 0xa1a6, 0x3fff, 0x0040, 0x30dc, 0x0078, 0x30f4, + 0xa1a6, 0x3fff, 0x0040, 0x3149, 0xa18d, 0xc000, 0x20a9, 0x0010, + 0x2019, 0x0001, 0xd5d4, 0x0040, 0x30ff, 0x2019, 0x0010, 0x2120, + 0xd5d4, 0x0040, 0x3106, 0x8423, 0x0078, 0x3107, 0x8424, 0x00c8, + 0x3114, 0xd5d4, 0x0040, 0x310f, 0x8319, 0x0078, 0x3110, 0x8318, + 0x00f0, 0x3100, 0x0078, 0x3149, 0x23a8, 0x2021, 0x0001, 0x8426, + 0x8425, 0x00f0, 0x3118, 0x2328, 0x8529, 0xa2be, 0x0007, 0x0040, + 0x312c, 0x007e, 0x2039, 0x0007, 0x2200, 0xa73a, 0x007f, 0x27a8, + 0xa5a8, 0x0010, 0x00f0, 0x3128, 0x754e, 0xa5c8, 0x2091, 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, + 0x314f, 0xa006, 0x0078, 0x314f, 0xa006, 0x1078, 0x12b7, 0x097f, + 0x087f, 0x007c, 0x2118, 0x2021, 0x0000, 0x2001, 0x0007, 0xa39a, + 0x0010, 0x0048, 0x315f, 0x8420, 0x8001, 0x0078, 0x3157, 0x2118, + 0x84ff, 0x0040, 0x3168, 0xa39a, 0x0010, 0x8421, 0x00c0, 0x3163, + 0x2021, 0x0001, 0x83ff, 0x0040, 0x3171, 0x8423, 0x8319, 0x00c0, + 0x316d, 0xa238, 0x2704, 0xa42c, 0x00c0, 0x3186, 0xa405, 0x203a, + 0x714e, 0xa1a0, 0x2091, 0x242c, 0xa5ac, 0x00ff, 0x6532, 0x60e7, + 0x0000, 0x65ea, 0x706f, 0x0001, 0xa084, 0x0000, 0x007c, 0x0e7e, + 0x2071, 0x6d00, 0x7073, 0x0000, 0x0e7f, 0x007c, 0x0e7e, 0x0f7e, + 0x2079, 0x0100, 0x2071, 0x0140, 0x1078, 0x4fe5, 0x7004, 0xa084, + 0x4000, 0x0040, 0x319f, 0x7003, 0x1000, 0x7003, 0x0000, 0x127e, + 0x2091, 0x8000, 0x2071, 0x6d00, 0x7003, 0x0001, 0x2071, 0x6d20, + 0x2073, 0x0000, 0x7843, 0x0090, 0x7843, 0x0010, 0x127f, 0x0f7f, + 0x0e7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x2011, 0x6f1a, 0x2013, + 0x0000, 0x707b, 0x0000, 0x127f, 0x20e1, 0x9080, 0x60a3, 0x0056, + 0x60a7, 0x9575, 0x1078, 0x4fdc, 0x2009, 0x07d0, 0x2011, 0x318e, + 0x1078, 0x415f, 0x007c, 0x017e, 0x027e, 0x0c7e, 0x127e, 0x2091, + 0x8000, 0x2009, 0x00f7, 0x1078, 0x3233, 0x2061, 0x6f23, 0x601b, + 0x0000, 0x601f, 0x0000, 0x2061, 0x6d00, 0x6003, 0x0001, 0x2061, + 0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x001e, 0x2011, + 0x31f0, 0x1078, 0x40c4, 0x127f, 0x0c7f, 0x027f, 0x017f, 0x007c, + 0x0e7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0x0100, 0x1078, + 0x4fe5, 0x2071, 0x0140, 0xa084, 0x4000, 0x0040, 0x3203, 0x7003, + 0x1000, 0x7003, 0x0000, 0x2001, 0x0001, 0x1078, 0x1dc9, 0x1078, + 0x31cb, 0x127f, 0x007f, 0x0e7f, 0x007c, 0x20a9, 0x0040, 0x20a1, + 0x73c0, 0x2099, 0x728e, 0x3304, 0x8007, 0x20a2, 0x9398, 0x94a0, + 0x00f0, 0x3213, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, + 0x7200, 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x007c, 0x20e1, + 0x9080, 0x20e1, 0x4000, 0x2099, 0x7280, 0x20a1, 0x020b, 0x20a9, + 0x000c, 0x53a6, 0x007c, 0x0c7e, 0x007e, 0x2061, 0x0100, 0x810f, + 0x2001, 0x6d2c, 0x2004, 0xa005, 0x00c0, 0x3244, 0x6030, 0xa084, + 0x00ff, 0xa105, 0x0078, 0x3246, 0xa185, 0x00f7, 0x604a, 0x007f, + 0x0c7f, 0x007c, 0x157e, 0x20a9, 0x00ff, 0x2009, 0x6e00, 0xa006, + 0x200a, 0x8108, 0x00f0, 0x3250, 0x157f, 0x007c, 0x0d7e, 0x037e, + 0x157e, 0x137e, 0x147e, 0x2069, 0x6d51, 0xa006, 0x6002, 0x6007, + 0x0707, 0x600a, 0x600e, 0x6012, 0xa198, 0x2091, 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, 0x604a, 0x6810, + 0x603a, 0x680c, 0x6046, 0x147f, 0x137f, 0x157f, 0x037f, 0x0d7f, + 0x007c, 0x127e, 0x2091, 0x8000, 0x6944, 0xa1b4, 0x00ff, 0xa682, + 0x0010, 0x00c8, 0x3337, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, + 0x00c8, 0x333d, 0xa188, 0x6e00, 0x2104, 0xa065, 0x0040, 0x3316, + 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x331c, 0x6078, + 0xa00d, 0x0040, 0x32c1, 0xa680, 0x6c84, 0x2004, 0xa10c, 0x00c0, + 0x3310, 0x607c, 0xa00d, 0x0040, 0x32dd, 0xa680, 0x6c84, 0x2004, + 0xa10c, 0x0040, 0x32dd, 0x694c, 0xd1fc, 0x00c0, 0x32d3, 0x1078, + 0x33d0, 0x0078, 0x330b, 0x1078, 0x33a1, 0x694c, 0xd1ec, 0x00c0, + 0x330b, 0x1078, 0x34f0, 0x0078, 0x330b, 0x694c, 0xa184, 0xa000, + 0x0040, 0x32fb, 0xd1ec, 0x0040, 0x32f4, 0xd1fc, 0x0040, 0x32ec, + 0x1078, 0x3507, 0x0078, 0x32f7, 0xa680, 0x6c84, 0x200c, 0x607c, + 0xa105, 0x607e, 0x0078, 0x32fb, 0xd1fc, 0x0040, 0x32fb, 0x1078, + 0x33a1, 0x0078, 0x330b, 0x6050, 0xa00d, 0x0040, 0x3306, 0x2d00, + 0x200a, 0x6803, 0x0000, 0x6052, 0x0078, 0x330b, 0x2d00, 0x6052, + 0x604e, 0x6803, 0x0000, 0x1078, 0x4346, 0xa006, 0x127f, 0x007c, + 0x2001, 0x0005, 0x2009, 0x0000, 0x0078, 0x3341, 0x2001, 0x0028, + 0x2009, 0x0000, 0x0078, 0x3341, 0xa082, 0x0006, 0x0048, 0x32b7, + 0x2009, 0x6d0c, 0x210c, 0xd18c, 0x0040, 0x332a, 0x2001, 0x0004, + 0x0078, 0x3333, 0xd184, 0x0040, 0x3331, 0x2001, 0x0004, 0x0078, + 0x3333, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x3341, 0x2001, + 0x0029, 0x2009, 0x0000, 0x0078, 0x3341, 0x2001, 0x0029, 0x2009, + 0x0000, 0xa005, 0x127f, 0x007c, 0x6944, 0xa1b4, 0x00ff, 0xa682, + 0x0010, 0x00c8, 0x3386, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, + 0x00c8, 0x3376, 0xa188, 0x6e00, 0x2104, 0xa065, 0x0040, 0x3376, + 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x337c, 0x684c, + 0xd0ec, 0x0040, 0x3369, 0x1078, 0x3507, 0x1078, 0x33a1, 0x0078, + 0x3371, 0x1078, 0x33a1, 0x684c, 0xd0fc, 0x0040, 0x3371, 0x1078, + 0x34f0, 0x1078, 0x351b, 0xa006, 0x0078, 0x338a, 0x2001, 0x0028, + 0x2009, 0x0000, 0x0078, 0x338a, 0xa082, 0x0006, 0x0048, 0x335f, + 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x338a, 0x2001, 0x0029, + 0x2009, 0x0000, 0xa005, 0x007c, 0x127e, 0x2091, 0x8000, 0x6050, + 0xa00d, 0x0040, 0x339a, 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, + 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x0078, + 0x3398, 0x127e, 0x2091, 0x8000, 0x604c, 0xa005, 0x0040, 0x33ad, + 0x6802, 0x2d00, 0x604e, 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, + 0x6803, 0x0000, 0x0078, 0x33ab, 0x127e, 0x2091, 0x8000, 0x604c, + 0xa06d, 0x0040, 0x33c2, 0x6800, 0xa005, 0x00c0, 0x33c0, 0x6052, + 0x604e, 0xad05, 0x127f, 0x007c, 0x604c, 0xa06d, 0x0040, 0x33cf, + 0x6800, 0xa005, 0x00c0, 0x33cd, 0x6052, 0x604e, 0xad05, 0x007c, + 0x6803, 0x0000, 0x6084, 0xa00d, 0x0040, 0x33da, 0x2d00, 0x200a, + 0x6086, 0x007c, 0x2d00, 0x6086, 0x6082, 0x0078, 0x33d9, 0x127e, + 0x0c7e, 0x027e, 0x2091, 0x8000, 0x6218, 0x2260, 0x6200, 0xa005, + 0x0040, 0x33ed, 0xc285, 0x0078, 0x33ee, 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, 0x3419, 0xa085, 0x0001, 0x0078, + 0x342d, 0xa190, 0x6e00, 0x2204, 0xa065, 0x00c0, 0x342c, 0x017e, + 0x0d7e, 0x1078, 0x12f4, 0x2d60, 0x0d7f, 0x017f, 0x0040, 0x3415, + 0x2c00, 0x2012, 0x1078, 0x3256, 0xa006, 0x027f, 0x007c, 0x027e, + 0xa182, 0x00ff, 0x0048, 0x3438, 0xa085, 0x0001, 0x0078, 0x3445, + 0x0d7e, 0xa190, 0x6e00, 0x2204, 0xa06d, 0x0040, 0x3443, 0x2013, + 0x0000, 0x1078, 0x1328, 0x0d7f, 0xa006, 0x027f, 0x007c, 0x017e, + 0xa182, 0x00ff, 0x0048, 0x3450, 0xa085, 0x0001, 0x0078, 0x3457, + 0xa188, 0x6e00, 0x2104, 0xa065, 0x0040, 0x344c, 0xa006, 0x017f, + 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x600b, 0x0000, 0x600f, + 0x0000, 0x6000, 0xc08c, 0x6002, 0x2069, 0x728e, 0x6808, 0x605e, + 0x6810, 0x6062, 0x6138, 0xa10a, 0x0048, 0x346f, 0x603a, 0x6814, + 0x6066, 0x2099, 0x7296, 0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004, + 0x53a3, 0x2099, 0x729a, 0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004, + 0x53a3, 0x2069, 0x72ae, 0x6904, 0xa18c, 0x00ff, 0x810f, 0x6808, + 0xa084, 0x00ff, 0xa105, 0x606a, 0x690c, 0x616e, 0x6810, 0x6072, + 0x6818, 0x6076, 0xa182, 0x0211, 0x00c8, 0x349a, 0x2009, 0x0008, + 0x0078, 0x34c4, 0xa182, 0x0259, 0x00c8, 0x34a2, 0x2009, 0x0007, + 0x0078, 0x34c4, 0xa182, 0x02c1, 0x00c8, 0x34aa, 0x2009, 0x0006, + 0x0078, 0x34c4, 0xa182, 0x0349, 0x00c8, 0x34b2, 0x2009, 0x0005, + 0x0078, 0x34c4, 0xa182, 0x0421, 0x00c8, 0x34ba, 0x2009, 0x0004, + 0x0078, 0x34c4, 0xa182, 0x0581, 0x00c8, 0x34c2, 0x2009, 0x0003, + 0x0078, 0x34c4, 0x2009, 0x0002, 0x6192, 0x147f, 0x137f, 0x157f, + 0x0d7f, 0x007c, 0x0e7e, 0x2071, 0x728d, 0x2e04, 0x6896, 0x2071, + 0x728e, 0x7004, 0x689a, 0x701c, 0x689e, 0x0e7f, 0x007c, 0x2001, + 0x6c84, 0xa600, 0x2004, 0x127e, 0x2091, 0x8000, 0x6178, 0xa10d, + 0x617a, 0x127f, 0x007c, 0x2001, 0x6c84, 0xa600, 0x2004, 0x8002, + 0x127e, 0x2091, 0x8000, 0x6178, 0xa10c, 0x617a, 0x127f, 0x007c, + 0x2001, 0x6c84, 0xa600, 0x2004, 0x8002, 0x127e, 0x2091, 0x8000, + 0x617c, 0xa10c, 0x617e, 0x127f, 0x0078, 0x3500, 0x1078, 0x338c, + 0x1078, 0x3561, 0x00c0, 0x34fe, 0x1078, 0x351b, 0x007c, 0x2001, + 0x6c84, 0xa600, 0x2004, 0x127e, 0x2091, 0x8000, 0x617c, 0xa10d, + 0x617e, 0x127f, 0x0078, 0x3516, 0x1078, 0x33d0, 0x1078, 0x3525, + 0x00c0, 0x3514, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x4346, + 0x127f, 0x007c, 0xa01e, 0x0078, 0x3527, 0x2019, 0x0001, 0xa00e, + 0x127e, 0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x00c0, + 0x3547, 0x8dff, 0x0040, 0x355c, 0x83ff, 0x0040, 0x353f, 0x6844, + 0xa084, 0x00ff, 0xa606, 0x0040, 0x354c, 0x0078, 0x3547, 0x683c, + 0xa406, 0x00c0, 0x3547, 0x6840, 0xa506, 0x0040, 0x354c, 0x2d08, + 0x6800, 0x2068, 0x0078, 0x3531, 0x6a00, 0x604c, 0xad06, 0x00c0, + 0x3554, 0x624e, 0x0078, 0x3557, 0xa180, 0x0000, 0x2202, 0x82ff, + 0x00c0, 0x355c, 0x6152, 0x8dff, 0x127f, 0x007c, 0xa01e, 0x0078, + 0x3563, 0x2019, 0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x0040, + 0x3591, 0x83ff, 0x0040, 0x3574, 0x6844, 0xa084, 0x00ff, 0xa606, + 0x0040, 0x3581, 0x0078, 0x357c, 0x683c, 0xa406, 0x00c0, 0x357c, + 0x6840, 0xa506, 0x0040, 0x3581, 0x2d08, 0x6800, 0x2068, 0x0078, + 0x3566, 0x6a00, 0x6080, 0xad06, 0x00c0, 0x3589, 0x6282, 0x0078, + 0x358c, 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0, 0x3591, 0x6186, + 0x8dff, 0x007c, 0x2001, 0x6c84, 0xa600, 0x2004, 0x6178, 0xa10c, + 0x0040, 0x359c, 0x2011, 0x0001, 0x617c, 0xa10c, 0x0040, 0x35a2, + 0xa295, 0x0002, 0x007c, 0x1078, 0x35ec, 0x0040, 0x35ab, 0x1078, + 0x61f8, 0x0078, 0x35ad, 0xa085, 0x0001, 0x007c, 0x1078, 0x35ec, + 0x0040, 0x35b6, 0x1078, 0x6187, 0x0078, 0x35b8, 0xa085, 0x0001, + 0x007c, 0x1078, 0x35ec, 0x0040, 0x35c1, 0x1078, 0x61cd, 0x0078, + 0x35c3, 0xa085, 0x0001, 0x007c, 0x1078, 0x35ec, 0x0040, 0x35cc, + 0x1078, 0x61a3, 0x0078, 0x35ce, 0xa085, 0x0001, 0x007c, 0x127e, + 0x007e, 0x0d7e, 0x2091, 0x8000, 0x6080, 0xa06d, 0x0040, 0x35e4, + 0x6800, 0x007e, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, + 0x36a1, 0x007f, 0x0078, 0x35d5, 0x6083, 0x0000, 0x6087, 0x0000, + 0x0d7f, 0x007f, 0x127f, 0x007c, 0x609c, 0xd0a4, 0x007c, 0x0f7e, + 0x2079, 0x6d51, 0x7804, 0xd0a4, 0x0040, 0x3618, 0x157e, 0x0c7e, + 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x3447, 0x00c0, + 0x360c, 0x6004, 0xa084, 0xff00, 0x8007, 0xa086, 0x0006, 0x00c0, + 0x360c, 0x6000, 0xc0ed, 0x6002, 0x017f, 0x8108, 0x00f0, 0x35fc, + 0x0c7f, 0x157f, 0x2009, 0x07d0, 0x2011, 0x361a, 0x1078, 0x415f, + 0x0f7f, 0x007c, 0x2011, 0x361a, 0x1078, 0x40d1, 0x157e, 0x0c7e, + 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x3447, 0x00c0, + 0x3646, 0x6000, 0xd0ec, 0x0040, 0x3646, 0x047e, 0x62a0, 0xa294, + 0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x1078, 0x6bf7, 0x6000, + 0xc0e5, 0xc0ec, 0x6002, 0x2019, 0x0029, 0x1078, 0x445c, 0x1078, + 0x43a9, 0x2009, 0x0000, 0x1078, 0x6a57, 0x047f, 0x017f, 0x8108, + 0x00f0, 0x3624, 0x0c7f, 0x157f, 0x007c, 0x0c7e, 0x6018, 0x2060, + 0x6000, 0xc0ec, 0x6002, 0x0c7f, 0x007c, 0x2071, 0x6ddf, 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, + 0x6ddf, 0x684c, 0xa005, 0x00c0, 0x367c, 0x7028, 0xc085, 0x702a, + 0xa085, 0x0001, 0x0078, 0x369f, 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, 0x36f2, 0x6804, 0xa00d, + 0x0040, 0x36c0, 0x0d7e, 0x0e7e, 0x2071, 0x6d00, 0x027e, 0xa016, + 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x00c0, + 0x36b1, 0x702e, 0x70a0, 0xa200, 0x70a2, 0x027f, 0x0e7f, 0x0d7f, + 0x2071, 0x6ddf, 0x701c, 0xa005, 0x00c0, 0x3703, 0x0068, 0x3701, + 0x2071, 0x6d51, 0x7004, 0xd09c, 0x0040, 0x3701, 0x6934, 0xa186, + 0x0103, 0x00c0, 0x3714, 0x6948, 0x6844, 0xa105, 0x00c0, 0x36f4, + 0x2009, 0x8020, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x3701, + 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, + 0x4080, 0x2071, 0x6d00, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70a0, + 0x8000, 0x70a2, 0x0e7f, 0x007c, 0x6844, 0xa086, 0x0100, 0x00c0, + 0x3701, 0x6868, 0xa005, 0x00c0, 0x3701, 0x2009, 0x8020, 0x0078, + 0x36da, 0x2071, 0x6ddf, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000, + 0x7012, 0x7018, 0xa06d, 0x711a, 0x0040, 0x3711, 0x6902, 0x0078, + 0x3712, 0x711e, 0x0078, 0x36f2, 0xa18c, 0x00ff, 0xa18e, 0x0017, + 0x0040, 0x371e, 0xa18e, 0x001f, 0x00c0, 0x3701, 0x684c, 0xd0cc, + 0x0040, 0x3701, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0, + 0x3701, 0x2009, 0x8021, 0x0078, 0x36da, 0x007e, 0x6837, 0x0103, + 0x20a9, 0x001c, 0xad80, 0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4, + 0x007f, 0x684a, 0x6952, 0x007c, 0x2071, 0x6ddf, 0x7004, 0x0079, + 0x3741, 0x3749, 0x3758, 0x37e4, 0x37e5, 0x37f5, 0x37fb, 0x374a, + 0x37d2, 0x007c, 0x127e, 0x2091, 0x8000, 0x0068, 0x3757, 0x2009, + 0x000d, 0x7030, 0x200a, 0x2091, 0x4080, 0x7007, 0x0001, 0x127f, + 0x701c, 0xa06d, 0x0040, 0x37d1, 0x0e7e, 0x2071, 0x6d51, 0x7004, + 0xd09c, 0x0040, 0x37b3, 0x6934, 0xa186, 0x0103, 0x00c0, 0x378d, + 0x6948, 0x6844, 0xa105, 0x00c0, 0x37a6, 0x2009, 0x8020, 0x127e, + 0x2091, 0x8000, 0x0068, 0x3789, 0x2071, 0x0000, 0x7018, 0xd084, + 0x00c0, 0x3789, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b, + 0x0001, 0x2091, 0x4080, 0x127f, 0x0e7f, 0x1078, 0x382e, 0x0078, + 0x37d1, 0x127f, 0x0e7f, 0x0078, 0x37d1, 0xa18c, 0x00ff, 0xa18e, + 0x0017, 0x0040, 0x3797, 0xa18e, 0x001f, 0x00c0, 0x37b3, 0x684c, + 0xd0cc, 0x0040, 0x37b3, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, + 0x00c0, 0x37b3, 0x2009, 0x8021, 0x0078, 0x376f, 0x6844, 0xa086, + 0x0100, 0x00c0, 0x37b3, 0x6868, 0xa005, 0x00c0, 0x37b3, 0x2009, + 0x8020, 0x0078, 0x376f, 0x0e7f, 0x1078, 0x3842, 0x0040, 0x37d1, + 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003, 0x00c0, + 0x37c8, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0040, 0x37c8, 0x710e, + 0x7007, 0x0003, 0x1078, 0x3862, 0x7050, 0xa086, 0x0100, 0x0040, + 0x37e5, 0x007c, 0x701c, 0xa06d, 0x0040, 0x37e3, 0x1078, 0x3842, + 0x0040, 0x37e3, 0x7007, 0x0003, 0x1078, 0x3862, 0x7050, 0xa086, + 0x0100, 0x0040, 0x37e5, 0x007c, 0x007c, 0x7050, 0xa09e, 0x0100, + 0x00c0, 0x37ee, 0x7007, 0x0004, 0x0078, 0x37f5, 0xa086, 0x0200, + 0x00c0, 0x37f4, 0x7007, 0x0005, 0x007c, 0x1078, 0x37fc, 0x7006, + 0x1078, 0x382e, 0x007c, 0x007c, 0x702c, 0x7130, 0x8108, 0xa102, + 0x0048, 0x3809, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0078, + 0x3813, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x3813, 0x7070, + 0xa081, 0x0000, 0x7072, 0x7132, 0x700c, 0x8001, 0x700e, 0x00c0, + 0x3827, 0x127e, 0x2091, 0x8000, 0x0068, 0x382a, 0x2001, 0x000d, + 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x127f, 0x007c, 0x2001, + 0x0007, 0x007c, 0x2001, 0x0006, 0x127f, 0x007c, 0x701c, 0xa06d, + 0x0040, 0x3841, 0x127e, 0x2091, 0x8000, 0x7010, 0x8001, 0x7012, + 0x2d04, 0x701e, 0xa005, 0x00c0, 0x383e, 0x701a, 0x127f, 0x1078, + 0x1328, 0x007c, 0x2019, 0x000d, 0x2304, 0x230c, 0xa10e, 0x0040, + 0x3851, 0x2304, 0x230c, 0xa10e, 0x0040, 0x3851, 0xa006, 0x0078, + 0x3861, 0x732c, 0x8319, 0x7130, 0xa102, 0x00c0, 0x385b, 0x2300, + 0xa005, 0x0078, 0x3861, 0x0048, 0x3860, 0xa302, 0x0078, 0x3861, + 0x8002, 0x007c, 0x2d00, 0x7026, 0xa080, 0x000d, 0x7056, 0x7053, + 0x0000, 0x127e, 0x2091, 0x8000, 0x2009, 0x6f31, 0x2104, 0xc08d, + 0x200a, 0x127f, 0x1078, 0x1379, 0x007c, 0x2071, 0x6dad, 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, 0x6dad, 0x6848, 0xa005, 0x00c0, 0x389e, 0x7028, + 0xc085, 0x702a, 0xa085, 0x0001, 0x0078, 0x38c3, 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, 0x6dad, + 0x7004, 0x1079, 0x3923, 0x700c, 0x0079, 0x38ce, 0x38d3, 0x38c8, + 0x38c8, 0x38c8, 0x38c8, 0x007c, 0x700c, 0x0079, 0x38d7, 0x38dc, + 0x3921, 0x3921, 0x3922, 0x3922, 0x7830, 0x7930, 0xa106, 0x0040, + 0x38e6, 0x7830, 0x7930, 0xa106, 0x00c0, 0x390c, 0x7030, 0xa10a, + 0x0040, 0x390c, 0x00c8, 0x38ee, 0x712c, 0xa10a, 0xa18a, 0x0002, + 0x00c8, 0x390d, 0x1078, 0x12f4, 0x0040, 0x390c, 0x2d00, 0x705a, + 0x7063, 0x0040, 0x2001, 0x0003, 0x7057, 0x0000, 0x127e, 0x007e, + 0x2091, 0x8000, 0x2009, 0x6f31, 0x2104, 0xc085, 0x200a, 0x007f, + 0x700e, 0x127f, 0x1078, 0x1379, 0x007c, 0x1078, 0x12f4, 0x0040, + 0x390c, 0x2d00, 0x705a, 0x1078, 0x12f4, 0x00c0, 0x3919, 0x0078, + 0x38f8, 0x2d00, 0x7086, 0x7063, 0x0080, 0x2001, 0x0004, 0x0078, + 0x38fc, 0x007c, 0x007c, 0x3934, 0x3935, 0x396c, 0x396d, 0x3921, + 0x39a3, 0x39a8, 0x39df, 0x39e0, 0x39fb, 0x39fc, 0x39fd, 0x39fe, + 0x39ff, 0x3a00, 0x3a69, 0x3a93, 0x007c, 0x700c, 0x0079, 0x3938, + 0x393d, 0x3940, 0x3950, 0x396b, 0x396b, 0x1078, 0x38d4, 0x007c, + 0x127e, 0x8001, 0x700e, 0x7058, 0x007e, 0x1078, 0x3d52, 0x0040, + 0x394d, 0x2091, 0x8000, 0x1078, 0x38d4, 0x0d7f, 0x0078, 0x3959, + 0x127e, 0x8001, 0x700e, 0x1078, 0x3d52, 0x7058, 0x2068, 0x7084, + 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, + 0xa08a, 0x0020, 0x00c8, 0x3968, 0x1079, 0x3983, 0x127f, 0x007c, + 0x127f, 0x1078, 0x3a01, 0x007c, 0x007c, 0x007c, 0x0e7e, 0x2071, + 0x6dad, 0x700c, 0x0079, 0x3974, 0x3979, 0x3979, 0x3979, 0x397b, + 0x397f, 0x0e7f, 0x007c, 0x700f, 0x0001, 0x0078, 0x3981, 0x700f, + 0x0002, 0x0e7f, 0x007c, 0x3a01, 0x3a01, 0x3a1d, 0x3a01, 0x3aff, + 0x3a01, 0x3a01, 0x3a01, 0x3a01, 0x3a01, 0x3a1d, 0x3b44, 0x3b8d, + 0x3be5, 0x3bf8, 0x3a01, 0x3a01, 0x3a39, 0x3a1d, 0x3a01, 0x3a01, + 0x3a4f, 0x3c74, 0x3c91, 0x3a01, 0x3a39, 0x3a01, 0x3a01, 0x3a01, + 0x3a01, 0x3a01, 0x3c91, 0x7020, 0x2068, 0x1078, 0x1328, 0x007c, + 0x700c, 0x0079, 0x39ab, 0x39b0, 0x39b3, 0x39c3, 0x39de, 0x39de, + 0x1078, 0x38d4, 0x007c, 0x127e, 0x8001, 0x700e, 0x7058, 0x007e, + 0x1078, 0x3d52, 0x0040, 0x39c0, 0x2091, 0x8000, 0x1078, 0x38d4, + 0x0d7f, 0x0078, 0x39cc, 0x127e, 0x8001, 0x700e, 0x1078, 0x3d52, + 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, + 0x6834, 0xa084, 0x00ff, 0xa08a, 0x001a, 0x00c8, 0x39db, 0x1079, + 0x39e1, 0x127f, 0x007c, 0x127f, 0x1078, 0x3a01, 0x007c, 0x007c, + 0x007c, 0x3a01, 0x3a1d, 0x3ae9, 0x3a01, 0x3a1d, 0x3a01, 0x3a1d, + 0x3a1d, 0x3a01, 0x3a1d, 0x3ae9, 0x3a1d, 0x3a1d, 0x3a1d, 0x3a1d, + 0x3a1d, 0x3a01, 0x3a1d, 0x3ae9, 0x3a01, 0x3a01, 0x3a1d, 0x3a01, + 0x3a01, 0x3a01, 0x3a1d, 0x007c, 0x007c, 0x007c, 0x007c, 0x007c, + 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0d5, 0x683a, + 0x127e, 0x2091, 0x8000, 0x1078, 0x36a1, 0x127f, 0x007c, 0x7007, + 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0e5, 0x683a, 0x127e, 0x2091, + 0x8000, 0x1078, 0x36a1, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, + 0xa084, 0x00ff, 0xc0ed, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, + 0x36a1, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, + 0xc0dd, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x36a1, 0x127f, + 0x007c, 0x6834, 0x8007, 0xa084, 0x00ff, 0x0040, 0x3a0f, 0x8001, + 0x00c0, 0x3a46, 0x7007, 0x0001, 0x0078, 0x3ac8, 0x7007, 0x0006, + 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x3ac8, 0x007c, 0x2d00, + 0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, 0x20a1, + 0x6dd8, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x00c8, 0x3a2b, + 0x6884, 0xa08a, 0x0003, 0x00c8, 0x3a2b, 0xa080, 0x3ab9, 0x2004, + 0x70c6, 0x7010, 0xa015, 0x0040, 0x3ab3, 0x1078, 0x12f4, 0x00c0, + 0x3a74, 0x7007, 0x000f, 0x007c, 0x2d00, 0x7022, 0x70c4, 0x2060, + 0x6000, 0x6836, 0x6004, 0xad00, 0x7096, 0x6008, 0xa20a, 0x00c8, + 0x3a83, 0xa00e, 0x2200, 0x7112, 0x620c, 0x8003, 0x800b, 0xa296, + 0x0004, 0x0040, 0x3a8c, 0xa108, 0x719a, 0x810b, 0x719e, 0xae90, + 0x0022, 0x1078, 0x135f, 0x7090, 0xa08e, 0x0100, 0x0040, 0x3aa7, + 0xa086, 0x0200, 0x0040, 0x3a9f, 0x7007, 0x0010, 0x007c, 0x7020, + 0x2068, 0x1078, 0x1328, 0x7014, 0x2068, 0x0078, 0x3a2b, 0x7020, + 0x2068, 0x7018, 0x6802, 0x6807, 0x0000, 0x2d08, 0x2068, 0x6906, + 0x711a, 0x0078, 0x3a69, 0x7014, 0x2068, 0x7007, 0x0001, 0x0078, + 0x3ac8, 0x3abc, 0x3ac0, 0x3ac4, 0x0002, 0x0011, 0x0007, 0x0004, + 0x000a, 0x000f, 0x0005, 0x0006, 0x0012, 0x000f, 0x0005, 0x0006, + 0x2009, 0x6d2c, 0x210c, 0x81ff, 0x00c0, 0x3ae3, 0x6838, 0xa084, + 0x00ff, 0x683a, 0x6853, 0x0000, 0x1078, 0x3299, 0x00c0, 0x3ad9, + 0x007c, 0x1078, 0x372d, 0x127e, 0x2091, 0x8000, 0x1078, 0x36a1, + 0x127f, 0x0078, 0x3ad8, 0x2001, 0x0028, 0x2009, 0x0000, 0x0078, + 0x3ad9, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906, 0x711a, 0x7010, + 0x8001, 0x7012, 0x0040, 0x3af8, 0x7007, 0x0006, 0x0078, 0x3afe, + 0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x107a, 0x007c, 0x7007, + 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848, 0xa084, 0x00ff, + 0x20a9, 0x0001, 0xa096, 0x0001, 0x0040, 0x3b2a, 0x2009, 0x0000, + 0x20a9, 0x007e, 0xa096, 0x0002, 0x0040, 0x3b2a, 0xa005, 0x00c0, + 0x3b41, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x3447, 0x00c0, + 0x3b41, 0x067e, 0x6e44, 0xa6b4, 0x000f, 0x1078, 0x34e3, 0x067f, + 0x0078, 0x3b41, 0x047e, 0x2011, 0x6d0c, 0x2224, 0xc484, 0xc48c, + 0x2412, 0x047f, 0x0c7e, 0x1078, 0x3447, 0x00c0, 0x3b3d, 0x2091, + 0x8000, 0x607b, 0x0000, 0x2091, 0x8001, 0x8108, 0x00f0, 0x3b33, + 0x0c7f, 0x1078, 0x1328, 0x007c, 0x127e, 0x2091, 0x8000, 0x7007, + 0x0001, 0x2001, 0x6d52, 0x2004, 0xd0a4, 0x0040, 0x3b84, 0x6944, + 0x1078, 0x3d6e, 0x6100, 0xd184, 0x0040, 0x3b69, 0x6858, 0xa084, + 0x00ff, 0x00c0, 0x3b87, 0x6000, 0xd084, 0x0040, 0x3b84, 0x6004, + 0xa005, 0x00c0, 0x3b8a, 0x6003, 0x0000, 0x600b, 0x0000, 0x0078, + 0x3b81, 0x2011, 0x0001, 0x6860, 0xa005, 0x00c0, 0x3b71, 0x2001, + 0x001e, 0x8000, 0x6016, 0x6858, 0xa084, 0x00ff, 0x0040, 0x3b84, + 0x6006, 0x6858, 0x8007, 0xa084, 0x00ff, 0x0040, 0x3b84, 0x600a, + 0x6202, 0x127f, 0x0078, 0x3d41, 0x127f, 0x0078, 0x3d39, 0x127f, + 0x0078, 0x3d31, 0x127f, 0x0078, 0x3d35, 0x127e, 0x2091, 0x8000, + 0x7007, 0x0001, 0x2001, 0x6d52, 0x2004, 0xd0a4, 0x0040, 0x3be2, + 0x6944, 0x1078, 0x3d6e, 0x6000, 0xa084, 0x0001, 0x0040, 0x3be2, + 0x6204, 0x6308, 0x6c48, 0xa484, 0x0003, 0x0040, 0x3bba, 0x6958, + 0xa18c, 0x00ff, 0x8001, 0x00c0, 0x3bb3, 0x2100, 0xa210, 0x0048, + 0x3bdf, 0x0078, 0x3bba, 0x8001, 0x00c0, 0x3bdf, 0x2100, 0xa212, + 0x0048, 0x3bdf, 0xa484, 0x000c, 0x0040, 0x3bd4, 0x6958, 0x810f, + 0xa18c, 0x00ff, 0xa082, 0x0004, 0x00c0, 0x3bcc, 0x2100, 0xa318, + 0x0048, 0x3bdf, 0x0078, 0x3bd4, 0xa082, 0x0004, 0x00c0, 0x3bdf, + 0x2100, 0xa31a, 0x0048, 0x3bdf, 0x6860, 0xa005, 0x0040, 0x3bda, + 0x8000, 0x6016, 0x6206, 0x630a, 0x127f, 0x0078, 0x3d41, 0x127f, + 0x0078, 0x3d3d, 0x127f, 0x0078, 0x3d39, 0x127e, 0x2091, 0x8000, + 0x7007, 0x0001, 0x6944, 0x1078, 0x3d6e, 0x6308, 0x8318, 0x0048, + 0x3bf5, 0x630a, 0x127f, 0x0078, 0x3d4f, 0x127f, 0x0078, 0x3d3d, + 0x127e, 0x0c7e, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac, + 0x0040, 0x3c0c, 0x027e, 0x2009, 0x0000, 0x2011, 0xfcff, 0x1078, + 0x41f4, 0x027f, 0x0078, 0x3c42, 0x6858, 0xa005, 0x0040, 0x3c56, + 0x685c, 0xa065, 0x0040, 0x3c52, 0x2001, 0x6d2c, 0x2004, 0xa005, + 0x0040, 0x3c1e, 0x1078, 0x6283, 0x0078, 0x3c24, 0x6013, 0x0400, + 0x2009, 0x0041, 0x1078, 0x5591, 0x6958, 0xa18c, 0xe600, 0xa186, + 0x2000, 0x0040, 0x3c3a, 0xa186, 0x0400, 0x0040, 0x3c3a, 0x6944, + 0x0c7e, 0x1078, 0x416d, 0x6000, 0xa084, 0xfdff, 0x6002, 0x0c7f, + 0x0078, 0x3c42, 0x027e, 0x2009, 0x0000, 0x2011, 0xfdff, 0x1078, + 0x41f4, 0x027f, 0x684c, 0xd0c4, 0x0040, 0x3c4e, 0x6944, 0x1078, + 0x416d, 0x6008, 0x8000, 0x0048, 0x3c4e, 0x600a, 0x0c7f, 0x127f, + 0x0078, 0x3d41, 0x0c7f, 0x127f, 0x0078, 0x3d39, 0x6954, 0xa186, + 0x0020, 0x0040, 0x3c6c, 0xa186, 0x0029, 0x00c0, 0x3c52, 0x6944, + 0xa18c, 0xff00, 0x810f, 0x1078, 0x3447, 0x00c0, 0x3c42, 0x6000, + 0xc0e4, 0x6002, 0x0078, 0x3c42, 0x685c, 0xa065, 0x0040, 0x3c52, + 0x6017, 0x0014, 0x0078, 0x3c42, 0x6944, 0x1078, 0x3d6e, 0x6000, + 0xa084, 0x0001, 0x0040, 0x3c8d, 0x2091, 0x8000, 0x6204, 0x8210, + 0x0048, 0x3c87, 0x6206, 0x2091, 0x8001, 0x0078, 0x3d4f, 0x2091, + 0x8001, 0x6853, 0x0016, 0x0078, 0x3d48, 0x6853, 0x0007, 0x0078, + 0x3d48, 0x6834, 0x8007, 0xa084, 0x00ff, 0x00c0, 0x3c9b, 0x1078, + 0x3a0f, 0x0078, 0x3cad, 0x2030, 0x8001, 0x00c0, 0x3ca5, 0x7007, + 0x0001, 0x1078, 0x3cae, 0x0078, 0x3cad, 0x7007, 0x0006, 0x7012, + 0x2d00, 0x7016, 0x701a, 0x704b, 0x3cae, 0x007c, 0x0e7e, 0x2009, + 0x6d2c, 0x210c, 0x81ff, 0x00c0, 0x3d28, 0x6848, 0x2070, 0xae82, + 0x7400, 0x0048, 0x3d18, 0x2001, 0x6d15, 0x2004, 0xae02, 0x00c8, + 0x3d18, 0x6944, 0x1078, 0x3d6e, 0x6100, 0xa184, 0x0001, 0x0040, + 0x3cfe, 0xa184, 0x0100, 0x00c0, 0x3d1c, 0xa184, 0x0200, 0x00c0, + 0x3d20, 0x601c, 0xa005, 0x00c0, 0x3d24, 0x711c, 0xa186, 0x0006, + 0x00c0, 0x3d03, 0x6853, 0x0000, 0x6803, 0x0000, 0x2d08, 0x127e, + 0x2091, 0x8000, 0x7010, 0xa005, 0x00c0, 0x3cf5, 0x7112, 0x7018, + 0xa065, 0x0040, 0x3d28, 0x6000, 0xd0e4, 0x00c0, 0x3d2c, 0x2e60, + 0x1078, 0x4176, 0x127f, 0x0e7f, 0x007c, 0x2068, 0x6800, 0xa005, + 0x00c0, 0x3cf5, 0x6902, 0x127f, 0x0e7f, 0x007c, 0x0e7f, 0x6853, + 0x0006, 0x0078, 0x3d48, 0x6944, 0xa18c, 0xff00, 0x810f, 0x1078, + 0x3447, 0x00c0, 0x3d2c, 0x6000, 0xd0e4, 0x00c0, 0x3d2c, 0x711c, + 0xa186, 0x0007, 0x00c0, 0x3d18, 0x6853, 0x0002, 0x0078, 0x3d2e, + 0x6853, 0x0008, 0x0078, 0x3d2e, 0x6853, 0x000e, 0x0078, 0x3d2e, + 0x6853, 0x0017, 0x0078, 0x3d2e, 0x6853, 0x0035, 0x0078, 0x3d2e, + 0x6853, 0x0028, 0x0078, 0x3d2e, 0x6853, 0x0029, 0x0e7f, 0x0078, + 0x3d48, 0x2009, 0x003e, 0x0078, 0x3d43, 0x2009, 0x0004, 0x0078, + 0x3d43, 0x2009, 0x0006, 0x0078, 0x3d43, 0x2009, 0x0016, 0x0078, + 0x3d43, 0x2009, 0x0001, 0x6854, 0xa084, 0xff00, 0xa105, 0x6856, + 0x2091, 0x8000, 0x1078, 0x36a1, 0x2091, 0x8001, 0x007c, 0x1078, + 0x1328, 0x007c, 0x702c, 0x7130, 0x8108, 0xa102, 0x0048, 0x3d5f, + 0xa00e, 0x7034, 0x7072, 0x7038, 0x7076, 0x0078, 0x3d6b, 0x7070, + 0xa080, 0x0040, 0x7072, 0x00c8, 0x3d6b, 0x7074, 0xa081, 0x0000, + 0x7076, 0xa085, 0x0001, 0x7932, 0x7132, 0x007c, 0x0d7e, 0x1078, + 0x416d, 0x0d7f, 0x007c, 0x0d7e, 0x2011, 0x0004, 0x2204, 0xa085, + 0x8002, 0x2012, 0x0d7f, 0x007c, 0x20e1, 0x0002, 0x3d08, 0x20e1, + 0x2000, 0x3d00, 0xa084, 0x7000, 0x0040, 0x3d8a, 0xa086, 0x1000, + 0x00c0, 0x3dab, 0x20e1, 0x0004, 0x3d60, 0xd1bc, 0x00c0, 0x3d91, + 0x3e60, 0xac84, 0x0007, 0x00c0, 0x3dab, 0xac82, 0x7400, 0x0048, + 0x3dab, 0x6854, 0xac02, 0x00c8, 0x3dab, 0x2009, 0x0047, 0x1078, + 0x5591, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x7a28, 0x7a1c, 0xd284, + 0x00c0, 0x3d7c, 0x007c, 0xa016, 0x1078, 0x1532, 0x0078, 0x3da1, + 0x157e, 0x137e, 0x147e, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584, + 0x0070, 0x00c0, 0x3dd9, 0xa484, 0x7000, 0xa086, 0x1000, 0x00c0, + 0x3dd9, 0x1078, 0x3de6, 0x0040, 0x3dd9, 0x20e1, 0x3000, 0x7828, + 0x7828, 0x1078, 0x3e04, 0x147f, 0x137f, 0x157f, 0x2009, 0x6f18, + 0x2104, 0xa005, 0x00c0, 0x3dd5, 0x007c, 0x1078, 0x476a, 0x0078, + 0x3dd4, 0x1078, 0x6c23, 0x1078, 0x3de6, 0x20e1, 0x3000, 0x7828, + 0x7828, 0x147f, 0x137f, 0x157f, 0x0078, 0x3dd4, 0xa484, 0x01ff, + 0x687a, 0xa005, 0x0040, 0x3df8, 0xa080, 0x001f, 0xa084, 0x03f8, + 0x80ac, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x007c, + 0x20a9, 0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, + 0xa085, 0x0001, 0x0078, 0x3df7, 0x7000, 0xa084, 0xff00, 0xa08c, + 0xf000, 0x8007, 0xa196, 0x0000, 0x00c0, 0x3e11, 0x0078, 0x3f51, + 0x007c, 0xa196, 0x2000, 0x00c0, 0x3e22, 0x6900, 0xa18e, 0x0001, + 0x00c0, 0x3e1e, 0x1078, 0x2aec, 0x0078, 0x3e10, 0x1078, 0x3e2a, + 0x0078, 0x3e10, 0xa196, 0x8000, 0x00c0, 0x3e10, 0x1078, 0x3fd7, + 0x0078, 0x3e10, 0x0c7e, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa196, + 0x0001, 0x0040, 0x3e37, 0xa196, 0x0023, 0x00c0, 0x3ef8, 0xa08e, + 0x0023, 0x00c0, 0x3e68, 0x1078, 0x404e, 0x0040, 0x3ef8, 0x7124, + 0x610a, 0x7030, 0xa08e, 0x0200, 0x00c0, 0x3e50, 0x7034, 0xa005, + 0x00c0, 0x3ef8, 0x2009, 0x0015, 0x1078, 0x5591, 0x0078, 0x3ef8, + 0xa08e, 0x0210, 0x00c0, 0x3e5a, 0x2009, 0x0015, 0x1078, 0x5591, + 0x0078, 0x3ef8, 0xa08e, 0x0100, 0x00c0, 0x3ef8, 0x7034, 0xa005, + 0x00c0, 0x3ef8, 0x2009, 0x0016, 0x1078, 0x5591, 0x0078, 0x3ef8, + 0xa08e, 0x0022, 0x00c0, 0x3ef8, 0x7030, 0xa08e, 0x0300, 0x00c0, + 0x3e79, 0x7034, 0xa005, 0x00c0, 0x3ef8, 0x2009, 0x0017, 0x0078, + 0x3eda, 0xa08e, 0x0500, 0x00c0, 0x3e85, 0x7034, 0xa005, 0x00c0, + 0x3ef8, 0x2009, 0x0018, 0x0078, 0x3eda, 0xa08e, 0x2010, 0x00c0, + 0x3e8d, 0x2009, 0x0019, 0x0078, 0x3eda, 0xa08e, 0x2110, 0x00c0, + 0x3e95, 0x2009, 0x001a, 0x0078, 0x3eda, 0xa08e, 0x5200, 0x00c0, + 0x3ea1, 0x7034, 0xa005, 0x00c0, 0x3ef8, 0x2009, 0x001b, 0x0078, + 0x3eda, 0xa08e, 0x5000, 0x00c0, 0x3ead, 0x7034, 0xa005, 0x00c0, + 0x3ef8, 0x2009, 0x001c, 0x0078, 0x3eda, 0xa08e, 0x2400, 0x00c0, + 0x3eb3, 0x0078, 0x3ed8, 0xa08e, 0x5300, 0x00c0, 0x3eb9, 0x0078, + 0x3ed8, 0xa08e, 0x0f00, 0x00c0, 0x3ec1, 0x2009, 0x0020, 0x0078, + 0x3eda, 0xa08e, 0x5300, 0x00c0, 0x3ec7, 0x0078, 0x3ed8, 0xa08e, + 0x6104, 0x00c0, 0x3ed8, 0x2009, 0x728e, 0x2011, 0x8015, 0x211c, + 0x8108, 0x2124, 0x1078, 0x2a53, 0x2009, 0x0023, 0x0078, 0x3eda, + 0x2009, 0x001d, 0x017e, 0x2011, 0x7283, 0x2204, 0x8211, 0x220c, + 0x1078, 0x1e1b, 0x00c0, 0x3efa, 0x1078, 0x3410, 0x00c0, 0x3efa, + 0x6612, 0x6516, 0x0c7e, 0x1078, 0x5504, 0x0040, 0x3efd, 0x017f, + 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x017f, 0x1078, 0x5591, + 0x0c7f, 0x007c, 0x017f, 0x0078, 0x3ef8, 0x0c7f, 0x0078, 0x3efa, + 0x0e7e, 0x0d7e, 0x2028, 0x2130, 0xa696, 0x00ff, 0x00c0, 0x3f20, + 0xa596, 0xfffd, 0x00c0, 0x3f10, 0x2009, 0x007f, 0x0078, 0x3f4d, + 0xa596, 0xfffe, 0x00c0, 0x3f18, 0x2009, 0x007e, 0x0078, 0x3f4d, + 0xa596, 0xfffc, 0x00c0, 0x3f20, 0x2009, 0x0080, 0x0078, 0x3f4d, + 0x2011, 0x0000, 0x2021, 0x007e, 0x20a9, 0x0082, 0x2071, 0x6e7e, + 0x2e1c, 0x83ff, 0x00c0, 0x3f32, 0x82ff, 0x00c0, 0x3f41, 0x2410, + 0x0078, 0x3f41, 0x2368, 0x6b10, 0x007e, 0x2100, 0xa31e, 0x007f, + 0x00c0, 0x3f41, 0x6b14, 0xa31e, 0x00c0, 0x3f41, 0x2408, 0x0078, + 0x3f4d, 0x8420, 0x8e70, 0x00f0, 0x3f28, 0x82ff, 0x00c0, 0x3f4c, + 0xa085, 0x0001, 0x0078, 0x3f4e, 0x2208, 0xa006, 0x0d7f, 0x0e7f, + 0x007c, 0xa084, 0x0007, 0x0079, 0x3f56, 0x007c, 0x3f5e, 0x3f5e, + 0x3f5e, 0x3f5e, 0x3f5e, 0x3f5f, 0x3f78, 0x3fc0, 0x007c, 0x7110, + 0xd1bc, 0x0040, 0x3f77, 0x7120, 0x2160, 0xac8c, 0x0007, 0x00c0, + 0x3f77, 0xac8a, 0x7400, 0x0048, 0x3f77, 0x6854, 0xac02, 0x00c8, + 0x3f77, 0x7124, 0x610a, 0x2009, 0x0046, 0x1078, 0x5591, 0x007c, + 0x0c7e, 0x7110, 0xd1bc, 0x00c0, 0x3fbe, 0x2011, 0x7283, 0x2204, + 0x8211, 0x220c, 0x1078, 0x1e1b, 0x00c0, 0x3fbe, 0x1078, 0x3447, + 0x00c0, 0x3fbe, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, + 0x00c0, 0x3fa3, 0x0c7e, 0x1078, 0x5504, 0x017f, 0x0040, 0x3fbe, + 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x2009, 0x0044, 0x1078, + 0x5591, 0x0078, 0x3fbe, 0x0c7e, 0x1078, 0x5504, 0x017f, 0x0040, + 0x3fbe, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0xa286, 0x0004, + 0x00c0, 0x3fb6, 0x6007, 0x0005, 0x0078, 0x3fb8, 0x6007, 0x0001, + 0x6003, 0x0001, 0x1078, 0x4376, 0x1078, 0x476a, 0x0c7f, 0x007c, + 0x7110, 0xd1bc, 0x0040, 0x3fd6, 0x7020, 0x2060, 0xac84, 0x0007, + 0x00c0, 0x3fd6, 0xac82, 0x7400, 0x0048, 0x3fd6, 0x6854, 0xac02, + 0x00c8, 0x3fd6, 0x2009, 0x0045, 0x1078, 0x5591, 0x007c, 0x7110, + 0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000, 0x00c0, 0x3fe7, 0xa084, + 0x000f, 0xa08a, 0x0006, 0x10c8, 0x12b7, 0x1079, 0x3fe8, 0x007c, + 0x3fee, 0x3fef, 0x3fee, 0x3fee, 0x4030, 0x403f, 0x007c, 0x7110, + 0xd1bc, 0x00c0, 0x402f, 0x700c, 0x7108, 0x1078, 0x1e1b, 0x00c0, + 0x402f, 0x1078, 0x3410, 0x00c0, 0x402f, 0x6612, 0x6516, 0x6204, + 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, 0x00c0, 0x4018, 0x0c7e, + 0x1078, 0x5504, 0x017f, 0x0040, 0x402f, 0x611a, 0x601f, 0x0005, + 0x7120, 0x610a, 0x2009, 0x0028, 0x1078, 0x5591, 0x0078, 0x402f, + 0x0c7e, 0x1078, 0x5504, 0x017f, 0x0040, 0x402f, 0x611a, 0x601f, + 0x0004, 0x7120, 0x610a, 0xa286, 0x0004, 0x00c0, 0x402b, 0x2009, + 0x0005, 0x0078, 0x402d, 0x2009, 0x0001, 0x1078, 0x5591, 0x007c, + 0x7110, 0xd1bc, 0x0040, 0x403e, 0x1078, 0x404e, 0x0040, 0x403e, + 0x7124, 0x610a, 0x2009, 0x0029, 0x1078, 0x5591, 0x007c, 0x7110, + 0xd1bc, 0x0040, 0x404d, 0x1078, 0x404e, 0x0040, 0x404d, 0x7124, + 0x610a, 0x2009, 0x002a, 0x1078, 0x5591, 0x007c, 0x7020, 0x2060, + 0xac84, 0x0007, 0x00c0, 0x4061, 0xac82, 0x7400, 0x0048, 0x4061, + 0x2001, 0x6d15, 0x2004, 0xac02, 0x00c8, 0x4061, 0xa085, 0x0001, + 0x007c, 0xa006, 0x0078, 0x4060, 0x2071, 0x6f23, 0x7003, 0x0003, + 0x700f, 0x0361, 0xa006, 0x701a, 0x7012, 0x7017, 0x7400, 0x7007, + 0x0000, 0x7026, 0x702b, 0x4ff2, 0x7032, 0x7037, 0x503e, 0x007c, + 0x2071, 0x6f23, 0x00e0, 0x40be, 0x2091, 0x6000, 0x700c, 0x8001, + 0x700e, 0x00c0, 0x4087, 0x700f, 0x0361, 0x7007, 0x0001, 0x127e, + 0x2091, 0x8000, 0x7024, 0xa00d, 0x0040, 0x409b, 0x7020, 0x8001, + 0x7022, 0x00c0, 0x409b, 0x7023, 0x0009, 0x8109, 0x7126, 0x00c0, + 0x409b, 0x7028, 0x107a, 0x7030, 0xa00d, 0x0040, 0x40ac, 0x702c, + 0x8001, 0x702e, 0x00c0, 0x40ac, 0x702f, 0x0009, 0x8109, 0x7132, + 0x00c0, 0x40ac, 0x7034, 0x107a, 0x7018, 0xa00d, 0x0040, 0x40bd, + 0x7008, 0x8001, 0x700a, 0x00c0, 0x40bd, 0x700b, 0x0009, 0x8109, + 0x711a, 0x00c0, 0x40bd, 0x701c, 0x107a, 0x127f, 0x7004, 0x0079, + 0x40c1, 0x40e8, 0x40e9, 0x4105, 0x0e7e, 0x2071, 0x6f23, 0x7018, + 0xa005, 0x00c0, 0x40cf, 0x711a, 0x721e, 0x700b, 0x0009, 0x0e7f, + 0x007c, 0x0e7e, 0x007e, 0x2071, 0x6f23, 0x701c, 0xa206, 0x00c0, + 0x40db, 0x701a, 0x701e, 0x007f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, + 0x6f23, 0x6088, 0xa102, 0x0048, 0x40e6, 0x618a, 0x0e7f, 0x007c, + 0x007c, 0x7110, 0x1078, 0x3447, 0x00c0, 0x40fb, 0x6088, 0x8001, + 0x0048, 0x40fb, 0x608a, 0x00c0, 0x40fb, 0x127e, 0x2091, 0x8000, + 0x1078, 0x476a, 0x127f, 0x8108, 0xa182, 0x00ff, 0x0048, 0x4103, + 0xa00e, 0x7007, 0x0002, 0x7112, 0x007c, 0x7014, 0x2060, 0x127e, + 0x2091, 0x8000, 0x6014, 0xa005, 0x0040, 0x4134, 0x8001, 0x6016, + 0x00c0, 0x4134, 0x611c, 0xa186, 0x0003, 0x0040, 0x411b, 0xa186, + 0x0006, 0x00c0, 0x4132, 0x6010, 0x2068, 0x6854, 0xa08a, 0x199a, + 0x0048, 0x4132, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a, 0x0048, + 0x412b, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, + 0x0078, 0x4134, 0x1078, 0x5fea, 0x127f, 0xac88, 0x0008, 0x7116, + 0x2001, 0x6d16, 0x2004, 0xa102, 0x0048, 0x4142, 0x7017, 0x7400, + 0x7007, 0x0000, 0x007c, 0x0e7e, 0x2071, 0x6f23, 0x7027, 0x07d0, + 0x7023, 0x0009, 0x0e7f, 0x007c, 0x2001, 0x6f2c, 0x2003, 0x0000, + 0x007c, 0x0e7e, 0x2071, 0x6f23, 0x7033, 0x07d0, 0x702f, 0x0009, + 0x0e7f, 0x007c, 0x2011, 0x6f2f, 0x2013, 0x0000, 0x007c, 0x0e7e, + 0x2071, 0x6f23, 0x711a, 0x721e, 0x700b, 0x0009, 0x0e7f, 0x007c, + 0x0c7e, 0x2061, 0x6fb2, 0x0c7f, 0x007c, 0xa184, 0x000f, 0x8003, + 0x8003, 0x8003, 0xa080, 0x6fb2, 0x2060, 0x007c, 0x684c, 0xa08c, + 0x00c0, 0xa18e, 0x00c0, 0x0040, 0x41ac, 0xd0b4, 0x00c0, 0x4188, + 0xd0bc, 0x00c0, 0x419a, 0x2009, 0x0006, 0x1078, 0x41cf, 0x007c, + 0xd0fc, 0x0040, 0x4195, 0xa084, 0x0003, 0xa08e, 0x0003, 0x0040, + 0x41c8, 0xa08e, 0x0000, 0x00c0, 0x41c8, 0x2009, 0x0043, 0x1078, + 0x5591, 0x007c, 0xd0fc, 0x0040, 0x41a7, 0xa084, 0x0003, 0xa08e, + 0x0003, 0x0040, 0x41c8, 0xa08e, 0x0000, 0x00c0, 0x41c8, 0x2009, + 0x0042, 0x1078, 0x5591, 0x007c, 0xd0fc, 0x0040, 0x41be, 0xa084, + 0x0003, 0xa08e, 0x0003, 0x0040, 0x41c8, 0xa08e, 0x0002, 0x0040, + 0x41c2, 0x2009, 0x0041, 0x1078, 0x5591, 0x007c, 0x1078, 0x41cd, + 0x0078, 0x41bd, 0x2009, 0x0043, 0x1078, 0x5591, 0x0078, 0x41bd, + 0x2009, 0x0004, 0x1078, 0x41cf, 0x007c, 0x2009, 0x0001, 0x6010, + 0xa0ec, 0xf000, 0x0040, 0x41f3, 0x2068, 0x6952, 0x6800, 0x6012, + 0xa186, 0x0001, 0x00c0, 0x41ed, 0x694c, 0xa18c, 0x8100, 0xa18e, + 0x8100, 0x00c0, 0x41ed, 0x0c7e, 0x6944, 0x1078, 0x416d, 0x6204, + 0x8210, 0x0048, 0x41ec, 0x6206, 0x0c7f, 0x1078, 0x36a1, 0x6010, + 0xa06d, 0x10c0, 0x4176, 0x007c, 0x157e, 0x0c7e, 0x20a9, 0x0010, + 0x2061, 0x6fb2, 0x6000, 0x81ff, 0x0040, 0x4201, 0xa205, 0x0078, + 0x4202, 0xa204, 0x6002, 0xace0, 0x0008, 0x00f0, 0x41fa, 0x0c7f, + 0x157f, 0x007c, 0x6808, 0xa005, 0x0040, 0x4212, 0x8001, 0x680a, + 0xa085, 0x0001, 0x007c, 0x127e, 0x2091, 0x2200, 0x2079, 0x6f10, + 0x127f, 0x0d7e, 0x2069, 0x6f10, 0x6803, 0x0005, 0x2069, 0x0004, + 0x2d04, 0xa085, 0x8001, 0x206a, 0x0d7f, 0x007c, 0x0c7e, 0x6027, + 0x0001, 0x7804, 0xa084, 0x0007, 0x0079, 0x422e, 0x4238, 0x425d, + 0x428e, 0x423e, 0x425d, 0x4236, 0x4236, 0x4236, 0x1078, 0x12b7, + 0x1078, 0x414c, 0x1078, 0x476a, 0x0c7f, 0x007c, 0x62c0, 0x82ff, + 0x00c0, 0x4244, 0x0c7f, 0x007c, 0x2011, 0x318e, 0x1078, 0x40d1, + 0x7828, 0xa092, 0x0002, 0x00c8, 0x4253, 0x8000, 0x782a, 0x1078, + 0x31c2, 0x0078, 0x4242, 0x1078, 0x318e, 0x7807, 0x0003, 0x7827, + 0x0000, 0x782b, 0x0000, 0x0078, 0x4242, 0x1078, 0x414c, 0x62c0, + 0x82ff, 0x00c0, 0x426f, 0x782b, 0x0000, 0x7824, 0xa065, 0x1040, + 0x12b7, 0x2009, 0x0013, 0x1078, 0x5591, 0x0c7f, 0x007c, 0x0c7e, + 0x7824, 0xa065, 0x1040, 0x12b7, 0x7804, 0xa086, 0x0004, 0x0040, + 0x42cc, 0x7828, 0xa092, 0x2710, 0x00c8, 0x4285, 0x8000, 0x782a, + 0x0c7f, 0x1078, 0x4fd7, 0x0078, 0x426d, 0x1078, 0x6c76, 0x2009, + 0x0014, 0x1078, 0x5591, 0x0c7f, 0x0078, 0x426d, 0x2001, 0x6f2c, + 0x2003, 0x0000, 0x62c0, 0x82ff, 0x00c0, 0x42a2, 0x782b, 0x0000, + 0x7824, 0xa065, 0x1040, 0x12b7, 0x2009, 0x0013, 0x1078, 0x55df, + 0x0c7f, 0x007c, 0x0c7e, 0x0d7e, 0x7824, 0xa005, 0x1040, 0x12b7, + 0x781c, 0xa06d, 0x1040, 0x12b7, 0x6800, 0xc0dc, 0x6802, 0x7924, + 0x2160, 0x1078, 0x556a, 0x693c, 0x81ff, 0x1040, 0x12b7, 0x8109, + 0x693e, 0x6854, 0xa015, 0x0040, 0x42c0, 0x7a1e, 0x0078, 0x42c2, + 0x7918, 0x791e, 0x7807, 0x0000, 0x7827, 0x0000, 0x0d7f, 0x0c7f, + 0x1078, 0x476a, 0x0078, 0x42a0, 0x6104, 0xa186, 0x0002, 0x0040, + 0x42d7, 0xa186, 0x0004, 0x0040, 0x42d7, 0x0078, 0x4279, 0x7808, + 0xac06, 0x0040, 0x4279, 0x1078, 0x4671, 0x1078, 0x4376, 0x0c7f, + 0x1078, 0x476a, 0x0078, 0x426d, 0x0c7e, 0x6027, 0x0002, 0x2011, + 0x6f2f, 0x2013, 0x0000, 0x62c8, 0x82ff, 0x00c0, 0x42fe, 0x62c4, + 0x82ff, 0x00c0, 0x42fe, 0x793c, 0xa1e5, 0x0000, 0x0040, 0x42fc, + 0x2009, 0x0049, 0x1078, 0x5591, 0x0c7f, 0x007c, 0x6017, 0x0010, + 0x793c, 0x81ff, 0x0040, 0x42fc, 0x7944, 0xa192, 0x2710, 0x00c8, + 0x431d, 0x8108, 0x7946, 0x1078, 0x4151, 0x793c, 0xa188, 0x0007, + 0x210c, 0xa18e, 0x0006, 0x00c0, 0x4319, 0x6017, 0x0012, 0x0078, + 0x42fc, 0x6017, 0x0016, 0x0078, 0x42fc, 0x1078, 0x6c76, 0x793c, + 0x2160, 0x2009, 0x004a, 0x1078, 0x5591, 0x0078, 0x42fc, 0x007e, + 0x017e, 0x0c7e, 0x127e, 0x600f, 0x0000, 0x2c08, 0x2061, 0x6f10, + 0x2091, 0x8000, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005, 0x0040, + 0x4342, 0xa080, 0x0003, 0x2102, 0x6112, 0x127f, 0x0c7f, 0x017f, + 0x007f, 0x007c, 0x6116, 0x6112, 0x0078, 0x433d, 0x0d7e, 0x2069, + 0x6f10, 0x6000, 0xd0d4, 0x0040, 0x435d, 0x6820, 0x8000, 0x6822, + 0xa086, 0x0001, 0x00c0, 0x4356, 0x2c00, 0x681e, 0x6804, 0xa084, + 0x0007, 0x0079, 0x4772, 0x0d7f, 0x007c, 0xc0d5, 0x6002, 0x6818, + 0xa005, 0x0040, 0x436f, 0x6056, 0x605b, 0x0000, 0x007e, 0x2c00, + 0x681a, 0x0d7f, 0x685a, 0x2069, 0x6f10, 0x0078, 0x434d, 0x6056, + 0x605a, 0x2c00, 0x681a, 0x681e, 0x0078, 0x434d, 0x007e, 0x017e, + 0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, + 0x6f10, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040, 0x4391, + 0xa080, 0x0003, 0x2102, 0x610a, 0x127f, 0x0c7f, 0x017f, 0x007f, + 0x007c, 0x610e, 0x610a, 0x0078, 0x438c, 0x0c7e, 0x600f, 0x0000, + 0x2c08, 0x2061, 0x6f10, 0x6034, 0xa005, 0x0040, 0x43a5, 0xa080, + 0x0003, 0x2102, 0x6136, 0x0c7f, 0x007c, 0x613a, 0x6136, 0x0078, + 0x43a3, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x007e, + 0x127e, 0x2071, 0x6f10, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, + 0x8cff, 0x0040, 0x4405, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, + 0x00c0, 0x4400, 0x703c, 0xac06, 0x00c0, 0x43cb, 0x6003, 0x000a, + 0x630a, 0x0078, 0x4400, 0x7038, 0xac36, 0x00c0, 0x43d1, 0x660c, + 0x763a, 0x7034, 0xac36, 0x00c0, 0x43df, 0x2c00, 0xaf36, 0x0040, + 0x43dd, 0x2f00, 0x7036, 0x0078, 0x43df, 0x7037, 0x0000, 0x660c, + 0x067e, 0x2c00, 0xaf06, 0x0040, 0x43e8, 0x7e0e, 0x0078, 0x43e9, + 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, + 0x00c0, 0x440e, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, + 0x36a1, 0x1078, 0x6276, 0x1078, 0x6283, 0x0c7f, 0x0078, 0x43b8, + 0x2c78, 0x600c, 0x2060, 0x0078, 0x43b8, 0x127f, 0x007f, 0x027f, + 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086, + 0x0006, 0x00c0, 0x43f2, 0x1078, 0x6bb3, 0x0078, 0x43fb, 0x007e, + 0x067e, 0x0c7e, 0x0d7e, 0x0f7e, 0x2031, 0x0000, 0x127e, 0x2091, + 0x8000, 0x2079, 0x6f10, 0x7838, 0xa065, 0x0040, 0x444a, 0x600c, + 0x007e, 0x600f, 0x0000, 0x783c, 0xac06, 0x00c0, 0x4435, 0x6003, + 0x000a, 0x630a, 0x2c30, 0x0078, 0x4447, 0x6010, 0x2068, 0x601c, + 0xa086, 0x0003, 0x00c0, 0x4453, 0x6837, 0x0103, 0x6b4a, 0x6847, + 0x0000, 0x1078, 0x36a1, 0x1078, 0x6276, 0x1078, 0x6283, 0x007f, + 0x0078, 0x4424, 0x7e3a, 0x7e36, 0x127f, 0x0f7f, 0x0d7f, 0x0c7f, + 0x067f, 0x007f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x443c, + 0x1078, 0x6bb3, 0x0078, 0x4445, 0x027e, 0x1078, 0x4470, 0x1078, + 0x4507, 0x027f, 0x007c, 0x0f7e, 0x127e, 0x2079, 0x6f10, 0x2091, + 0x8000, 0x1078, 0x4599, 0x1078, 0x4601, 0x127f, 0x0f7f, 0x007c, + 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e, 0x127e, 0x2091, + 0x8000, 0x2071, 0x6f10, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0040, + 0x44f6, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x44f1, + 0x7024, 0xac06, 0x00c0, 0x44b6, 0x2069, 0x0100, 0x68c0, 0xa005, + 0x0040, 0x44b1, 0x1078, 0x4fe5, 0x68c3, 0x0000, 0x1078, 0x54a4, + 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, + 0x0040, 0x44a6, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, + 0x6824, 0xd084, 0x0040, 0x44ae, 0x6827, 0x0001, 0x037f, 0x0078, + 0x44b6, 0x6003, 0x0009, 0x630a, 0x0078, 0x44f1, 0x7014, 0xac36, + 0x00c0, 0x44bc, 0x660c, 0x7616, 0x7010, 0xac36, 0x00c0, 0x44ca, + 0x2c00, 0xaf36, 0x0040, 0x44c8, 0x2f00, 0x7012, 0x0078, 0x44ca, + 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x44d3, + 0x7e0e, 0x0078, 0x44d4, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, + 0x1078, 0x6120, 0x0040, 0x44ea, 0x601c, 0xa086, 0x0003, 0x00c0, + 0x44fe, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x36a1, + 0x1078, 0x6276, 0x1078, 0x6283, 0x1078, 0x5374, 0x0c7f, 0x0078, + 0x447e, 0x2c78, 0x600c, 0x2060, 0x0078, 0x447e, 0x127f, 0x007f, + 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086, + 0x0006, 0x00c0, 0x44e1, 0x1078, 0x6bb3, 0x0078, 0x44ea, 0x0c7e, + 0x007e, 0x127e, 0x2091, 0x8000, 0xa280, 0x6e00, 0x2004, 0xa065, + 0x0040, 0x4595, 0x0f7e, 0x0e7e, 0x0d7e, 0x067e, 0x2071, 0x6f10, + 0x6654, 0x7018, 0xac06, 0x00c0, 0x451e, 0x761a, 0x701c, 0xac06, + 0x00c0, 0x452a, 0x86ff, 0x00c0, 0x4529, 0x7018, 0x701e, 0x0078, + 0x452a, 0x761e, 0x6058, 0xa07d, 0x0040, 0x452f, 0x7e56, 0xa6ed, + 0x0000, 0x0040, 0x4535, 0x2f00, 0x685a, 0x6057, 0x0000, 0x605b, + 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x33c4, 0x0040, + 0x4591, 0x7624, 0x86ff, 0x0040, 0x4586, 0xa680, 0x0004, 0x2004, + 0xad06, 0x00c0, 0x4586, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005, + 0x0040, 0x457d, 0x1078, 0x4fe5, 0x68c3, 0x0000, 0x1078, 0x54a4, + 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, + 0x0040, 0x4566, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, + 0x6824, 0xd084, 0x0040, 0x456e, 0x6827, 0x0001, 0x037f, 0x0d7f, + 0x0c7e, 0x603c, 0xa005, 0x0040, 0x4577, 0x8001, 0x603e, 0x2660, + 0x1078, 0x6283, 0x0c7f, 0x0078, 0x4586, 0x0d7f, 0x0c7e, 0x2660, + 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x453d, 0x6837, 0x0103, + 0x6b4a, 0x6847, 0x0000, 0x1078, 0x36a1, 0x1078, 0x5374, 0x0078, + 0x453d, 0x067f, 0x0d7f, 0x0e7f, 0x0f7f, 0x127f, 0x007f, 0x0c7f, + 0x007c, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x2031, 0x0000, 0x7814, + 0xa065, 0x0040, 0x45f1, 0x600c, 0x007e, 0x600f, 0x0000, 0x7824, + 0xac06, 0x00c0, 0x45d6, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, + 0x45d0, 0x1078, 0x4fe5, 0x68c3, 0x0000, 0x1078, 0x54a4, 0x7827, + 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, + 0x45c5, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, + 0xd084, 0x0040, 0x45cd, 0x6827, 0x0001, 0x037f, 0x0078, 0x45d6, + 0x6003, 0x0009, 0x630a, 0x2c30, 0x0078, 0x45ee, 0x6010, 0x2068, + 0x1078, 0x6120, 0x0040, 0x45ea, 0x601c, 0xa086, 0x0003, 0x00c0, + 0x45f8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x36a1, + 0x1078, 0x6276, 0x1078, 0x6283, 0x1078, 0x5374, 0x007f, 0x0078, + 0x45a0, 0x7e16, 0x7e12, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, + 0x601c, 0xa086, 0x0006, 0x00c0, 0x45e1, 0x1078, 0x6bb3, 0x0078, + 0x45ea, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x7818, 0xa065, 0x0040, + 0x466a, 0x6054, 0x007e, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, + 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x33c4, 0x0040, 0x4667, 0x7e24, + 0x86ff, 0x0040, 0x465c, 0xa680, 0x0004, 0x2004, 0xad06, 0x00c0, + 0x465c, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x4653, + 0x1078, 0x4fe5, 0x68c3, 0x0000, 0x1078, 0x54a4, 0x7827, 0x0000, + 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x463c, + 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0040, 0x4644, 0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c, + 0xa005, 0x0040, 0x464d, 0x8001, 0x603e, 0x2660, 0x1078, 0x6283, + 0x0c7f, 0x0078, 0x465c, 0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009, + 0x630a, 0x0c7f, 0x0078, 0x4613, 0x6837, 0x0103, 0x6b4a, 0x6847, + 0x0000, 0x1078, 0x36a1, 0x1078, 0x5374, 0x0078, 0x4613, 0x007f, + 0x0078, 0x4606, 0x781e, 0x781a, 0x0d7f, 0x0c7f, 0x067f, 0x007f, + 0x007c, 0x0e7e, 0x0c7e, 0x2071, 0x6f10, 0x7004, 0xa084, 0x0007, + 0x0079, 0x467a, 0x4684, 0x4687, 0x46a0, 0x46bc, 0x4701, 0x4684, + 0x4682, 0x4682, 0x1078, 0x12b7, 0x0c7f, 0x0e7f, 0x007c, 0x7024, + 0xa065, 0x0040, 0x4695, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015, + 0x0040, 0x469c, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, + 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7216, 0x7212, 0x0078, 0x4695, + 0x6018, 0x2060, 0x1078, 0x33c4, 0x6000, 0xc0dc, 0x6002, 0x7020, + 0x8001, 0x7022, 0x0040, 0x46b1, 0x6054, 0xa015, 0x0040, 0x46b8, + 0x721e, 0x7007, 0x0000, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, + 0x7218, 0x721e, 0x0078, 0x46b1, 0x7024, 0xa065, 0x0040, 0x46fe, + 0x700c, 0xac06, 0x00c0, 0x46d3, 0x1078, 0x5374, 0x600c, 0xa015, + 0x0040, 0x46cf, 0x720e, 0x600f, 0x0000, 0x0078, 0x46fc, 0x720e, + 0x720a, 0x0078, 0x46fc, 0x7014, 0xac06, 0x00c0, 0x46e6, 0x1078, + 0x5374, 0x600c, 0xa015, 0x0040, 0x46e2, 0x7216, 0x600f, 0x0000, + 0x0078, 0x46fc, 0x7216, 0x7212, 0x0078, 0x46fc, 0x6018, 0x2060, + 0x1078, 0x33c4, 0x6000, 0xc0dc, 0x6002, 0x1078, 0x5374, 0x701c, + 0xa065, 0x0040, 0x46fc, 0x6054, 0xa015, 0x0040, 0x46fa, 0x721e, + 0x0078, 0x46fc, 0x7218, 0x721e, 0x7027, 0x0000, 0x0c7f, 0x0e7f, + 0x007c, 0x7024, 0xa065, 0x0040, 0x470e, 0x1078, 0x5374, 0x600c, + 0xa015, 0x0040, 0x4715, 0x720e, 0x600f, 0x0000, 0x1078, 0x54a4, + 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x720e, 0x720a, 0x0078, + 0x470e, 0x0d7e, 0x2069, 0x6f10, 0x6830, 0xa084, 0x0003, 0x0079, + 0x4721, 0x4727, 0x4729, 0x474f, 0x4725, 0x1078, 0x12b7, 0x0d7f, + 0x007c, 0x0c7e, 0x6840, 0xa086, 0x0001, 0x0040, 0x4745, 0x683c, + 0xa065, 0x0040, 0x473a, 0x600c, 0xa015, 0x0040, 0x4741, 0x6a3a, + 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c7f, 0x0d7f, + 0x007c, 0x683a, 0x6836, 0x0078, 0x473a, 0x6843, 0x0000, 0x6838, + 0xa065, 0x0040, 0x473a, 0x6003, 0x0003, 0x0078, 0x473a, 0x0c7e, + 0x6843, 0x0000, 0x6847, 0x0000, 0x683c, 0xa065, 0x0040, 0x4767, + 0x600c, 0xa015, 0x0040, 0x4763, 0x6a3a, 0x600f, 0x0000, 0x683f, + 0x0000, 0x0078, 0x4767, 0x683f, 0x0000, 0x683a, 0x6836, 0x0c7f, + 0x0d7f, 0x007c, 0x0d7e, 0x2069, 0x6f10, 0x6804, 0xa084, 0x0007, + 0x0079, 0x4772, 0x477c, 0x4810, 0x4810, 0x4810, 0x4810, 0x4812, + 0x477a, 0x477a, 0x1078, 0x12b7, 0x6820, 0xa005, 0x00c0, 0x4782, + 0x0d7f, 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, 0x4791, 0x6807, + 0x0004, 0x6826, 0x682b, 0x0000, 0x1078, 0x4858, 0x0c7f, 0x0d7f, + 0x007c, 0x6814, 0xa065, 0x0040, 0x479f, 0x6807, 0x0001, 0x6826, + 0x682b, 0x0000, 0x1078, 0x4858, 0x0c7f, 0x0d7f, 0x007c, 0x0e7e, + 0x037e, 0x6a1c, 0xa2f5, 0x0000, 0x0040, 0x480b, 0x704c, 0xa00d, + 0x0040, 0x47ae, 0x7088, 0xa005, 0x0040, 0x47c6, 0x7054, 0xa075, + 0x0040, 0x47b7, 0xa20e, 0x0040, 0x480b, 0x0078, 0x47bc, 0x6818, + 0xa20e, 0x0040, 0x480b, 0x2070, 0x704c, 0xa00d, 0x0040, 0x47ae, + 0x7088, 0xa005, 0x00c0, 0x47ae, 0x2e00, 0x681e, 0x733c, 0x7038, + 0xa302, 0x00c8, 0x47ae, 0x1078, 0x5539, 0x0040, 0x480b, 0x8318, + 0x733e, 0x6112, 0x2e10, 0x621a, 0xa180, 0x0015, 0x2004, 0xa08a, + 0x199a, 0x0048, 0x47dd, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b, + 0xa318, 0x6316, 0x037f, 0x0f7e, 0x2c78, 0x71a0, 0xd1bc, 0x0040, + 0x47ed, 0x2009, 0x0000, 0x0078, 0x47f2, 0xa1e0, 0x2091, 0x2c0c, + 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0x1078, 0x4c44, 0x7300, + 0xc3dd, 0x7302, 0x6807, 0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000, + 0x781f, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040, 0x0f7f, 0x0e7f, + 0x0c7f, 0x0d7f, 0x007c, 0x037f, 0x0e7f, 0x0c7f, 0x0078, 0x4809, + 0x0d7f, 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, 0x481e, 0x6807, + 0x0004, 0x6826, 0x682b, 0x0000, 0x1078, 0x4858, 0x0c7f, 0x0d7f, + 0x007c, 0x0f7e, 0x0d7e, 0x2069, 0x6f10, 0x6830, 0xa086, 0x0000, + 0x00c0, 0x483f, 0x6838, 0xa07d, 0x0040, 0x483f, 0x6833, 0x0001, + 0x683e, 0x6847, 0x0000, 0x127e, 0x0f7e, 0x2091, 0x2200, 0x027f, + 0x1078, 0x1838, 0x00c0, 0x4842, 0x127f, 0x1078, 0x4ed5, 0x0d7f, + 0x0f7f, 0x007c, 0x127f, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, + 0xa015, 0x0040, 0x4854, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, + 0x683f, 0x0000, 0x0078, 0x483f, 0x683a, 0x6836, 0x0078, 0x484e, + 0x601c, 0xa084, 0x000f, 0x1079, 0x485e, 0x007c, 0x4867, 0x4869, + 0x4b33, 0x4c15, 0x4869, 0x4b33, 0x4c15, 0x4867, 0x4869, 0x1078, + 0x12b7, 0x157e, 0x137e, 0x147e, 0x0c7e, 0x0f7e, 0x6004, 0xa08a, + 0x0024, 0x10c8, 0x12b7, 0x6118, 0x2178, 0x79a0, 0xa1f8, 0x2091, + 0x2f0c, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0x1079, + 0x4887, 0x0f7f, 0x0c7f, 0x147f, 0x137f, 0x157f, 0x007c, 0x48ad, + 0x48ec, 0x4904, 0x494c, 0x4979, 0x4981, 0x49a2, 0x49b3, 0x49c4, + 0x49cc, 0x49dd, 0x49cc, 0x4a25, 0x49b3, 0x4a55, 0x4a5d, 0x49c4, + 0x4a5d, 0x4a6e, 0x48ab, 0x48ab, 0x48ab, 0x48ab, 0x48ab, 0x48ab, + 0x48ab, 0x48ab, 0x48ab, 0x48ab, 0x48ab, 0x48ab, 0x50b8, 0x50cd, + 0x50f0, 0x5114, 0x49a2, 0x1078, 0x12b7, 0x20a1, 0x020b, 0x1078, + 0x4a83, 0x20a3, 0x5200, 0x20a3, 0x0000, 0x0d7e, 0x2069, 0x6d51, + 0x6804, 0xd084, 0x0040, 0x48ce, 0x6828, 0x017e, 0x2069, 0x6d00, + 0x694c, 0xa106, 0x017f, 0x00c0, 0x48ce, 0x20a3, 0x0000, 0x6030, + 0xa084, 0x00ff, 0x20a2, 0x0d7f, 0x0078, 0x48d3, 0x0d7f, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0x6d05, 0x53a6, + 0x20a9, 0x0004, 0x2099, 0x6d01, 0x53a6, 0x20a3, 0x0000, 0x6030, + 0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, + 0x001c, 0x1078, 0x4fd1, 0x007c, 0x20a1, 0x020b, 0x1078, 0x4a83, + 0x20a3, 0x0500, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x6030, 0xa084, + 0x00ff, 0x20a2, 0x20a9, 0x0004, 0x2099, 0x6d05, 0x53a6, 0x60c3, + 0x0010, 0x1078, 0x4fd1, 0x007c, 0x20a1, 0x020b, 0x1078, 0x4a83, + 0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, 0x4917, + 0x20a3, 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0078, 0x4919, 0x20a3, + 0x0300, 0x20a3, 0x0000, 0x2099, 0x6f00, 0x20a9, 0x0008, 0x53a6, + 0x20a9, 0x0004, 0x2099, 0x6d05, 0x53a6, 0x20a9, 0x0004, 0x2099, + 0x6d01, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x492c, + 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x4932, 0x2099, 0x6f08, + 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, + 0x493d, 0x20a9, 0x000a, 0x20a3, 0x0000, 0x00f0, 0x4943, 0x60c3, + 0x0074, 0x1078, 0x4fd1, 0x007c, 0x20a1, 0x020b, 0x1078, 0x4a83, + 0x20a3, 0x2010, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000, + 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e, 0x2079, + 0x6d51, 0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x4968, 0xa085, 0x0020, + 0xd1a4, 0x0040, 0x496d, 0xa085, 0x0010, 0xa085, 0x0002, 0x20a2, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4fd1, + 0x007c, 0x20a1, 0x020b, 0x1078, 0x4a83, 0x20a3, 0x5000, 0x0078, + 0x4919, 0x20a1, 0x020b, 0x1078, 0x4a83, 0x20a3, 0x2110, 0x20a3, + 0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0022, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, + 0x4fd1, 0x007c, 0x20a1, 0x020b, 0x1078, 0x4afa, 0x20a3, 0x0200, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004, + 0x1078, 0x4fd1, 0x007c, 0x20a1, 0x020b, 0x1078, 0x4afa, 0x20a3, + 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, + 0x0008, 0x1078, 0x4fd1, 0x007c, 0x20a1, 0x020b, 0x1078, 0x4afa, + 0x20a3, 0x0200, 0x0078, 0x4919, 0x20a1, 0x020b, 0x1078, 0x4afa, + 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x7810, 0x20a2, + 0x60c3, 0x0008, 0x1078, 0x4fd1, 0x007c, 0x0d7e, 0x20a1, 0x020b, + 0x1078, 0x4afa, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0800, + 0x7818, 0x2068, 0x6894, 0xa086, 0x0014, 0x00c0, 0x4a03, 0x6998, + 0xa184, 0xc000, 0x00c0, 0x49ff, 0xd1ec, 0x0040, 0x49fb, 0x20a3, + 0x2100, 0x0078, 0x4a05, 0x20a3, 0x0100, 0x0078, 0x4a05, 0x20a3, + 0x0400, 0x0078, 0x4a05, 0x20a3, 0x0700, 0xa006, 0x20a2, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x0f7e, 0x2079, 0x6d51, 0x7904, 0x0f7f, + 0xd1ac, 0x00c0, 0x4a15, 0xa085, 0x0020, 0xd1a4, 0x0040, 0x4a1a, + 0xa085, 0x0010, 0xa085, 0x0002, 0x20a2, 0x20a2, 0x20a2, 0x60c3, + 0x0014, 0x1078, 0x4fd1, 0x0d7f, 0x007c, 0x20a1, 0x020b, 0x1078, + 0x4afa, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x6018, + 0x0d7e, 0x2068, 0x6804, 0x0d7f, 0xa084, 0x00ff, 0xa086, 0x0006, + 0x0040, 0x4a3e, 0x20a3, 0x0400, 0x0078, 0x4a40, 0x20a3, 0x0100, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0014, 0x1078, 0x4fd1, 0x007c, 0x20a1, 0x020b, 0x1078, + 0x4afa, 0x20a3, 0x0200, 0x0078, 0x48b3, 0x20a1, 0x020b, 0x1078, + 0x4afa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, + 0x2a00, 0x60c3, 0x0008, 0x1078, 0x4fd1, 0x007c, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x20a1, 0x020b, 0x1078, 0x4afa, 0x20a3, 0x0100, + 0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3, 0x0000, 0x60c3, 0x0008, + 0x1078, 0x4fd1, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, + 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x00c0, 0x4a96, + 0x20a3, 0x22ff, 0x20a3, 0xfffe, 0x0078, 0x4ac4, 0xa286, 0x007f, + 0x00c0, 0x4aa1, 0x0d7e, 0x20a3, 0x22ff, 0x20a3, 0xfffd, 0x0078, + 0x4ab8, 0xd2bc, 0x0040, 0x4ac0, 0xa286, 0x0080, 0x0d7e, 0x00c0, + 0x4aaf, 0x20a3, 0x22ff, 0x20a3, 0xfffc, 0x0078, 0x4ab8, 0xa2e8, + 0x6e00, 0x2d6c, 0x6810, 0xa085, 0x2200, 0x20a2, 0x6814, 0x20a2, + 0x2069, 0x6d19, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x4ac8, + 0x20a3, 0x2200, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, + 0x20a3, 0x0129, 0x20a3, 0x0000, 0x1078, 0x4fc0, 0x22a2, 0x20a3, + 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x027f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, + 0x02ff, 0x2011, 0xfffc, 0x22a2, 0x0d7e, 0x2069, 0x6d19, 0x2da6, + 0x8d68, 0x2da6, 0x0d7f, 0x20a3, 0x2029, 0x20a3, 0x0000, 0x0078, + 0x4acc, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, + 0x0000, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, + 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x4b19, 0x0d7e, + 0xa0e8, 0x6e00, 0x2d6c, 0x6810, 0xa085, 0x2300, 0x20a2, 0x6814, + 0x20a2, 0x2069, 0x6d19, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, + 0x4b21, 0x20a3, 0x2300, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, + 0x22a2, 0x20a3, 0x0198, 0x20a3, 0x0000, 0x1078, 0x4fc0, 0x22a2, + 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x027f, 0x007c, 0x0c7e, 0x0f7e, 0x6004, 0xa08a, 0x0025, + 0x1048, 0x12b7, 0xa08a, 0x002c, 0x10c8, 0x12b7, 0x6118, 0x2178, + 0x79a0, 0xa1f8, 0x2091, 0x2f0c, 0xa18c, 0x00ff, 0x2c78, 0x2061, + 0x0100, 0x619a, 0xa082, 0x0025, 0x1079, 0x4b51, 0x0f7f, 0x0c7f, + 0x007c, 0x4b5a, 0x4b65, 0x4b7f, 0x4b58, 0x4b58, 0x4b58, 0x4b5a, + 0x1078, 0x12b7, 0x147e, 0x20a1, 0x020b, 0x1078, 0x4b8e, 0x60c3, + 0x0000, 0x1078, 0x4fd1, 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, + 0x1078, 0x4bbb, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, + 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x60c3, 0x000c, 0x1078, 0x4fd1, 0x147f, 0x007c, 0x147e, + 0x20a1, 0x020b, 0x1078, 0x4be8, 0x20a3, 0x0003, 0x20a3, 0x0300, + 0x60c3, 0x0004, 0x1078, 0x4fd1, 0x147f, 0x007c, 0x027e, 0x20e1, + 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, + 0x007e, 0x0048, 0x4bad, 0x0d7e, 0xa0e8, 0x6e00, 0x2d6c, 0x6810, + 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x6d19, 0x2da6, + 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x4bb5, 0x20a3, 0x8100, 0x6298, + 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0009, 0x20a3, + 0x0000, 0x0078, 0x4acc, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, + 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x4bda, + 0x0d7e, 0xa0e8, 0x6e00, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2, + 0x6814, 0x20a2, 0x2069, 0x6d19, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, + 0x0078, 0x4be2, 0x20a3, 0x8400, 0x6298, 0x22a2, 0x20a3, 0x0000, + 0x6230, 0x22a2, 0x20a3, 0x00d1, 0x20a3, 0x0000, 0x0078, 0x4b25, + 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, + 0x2004, 0xa092, 0x007e, 0x0048, 0x4c07, 0x0d7e, 0xa0e8, 0x6e00, + 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x2069, + 0x6d19, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x4c0f, 0x20a3, + 0x8500, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, + 0x00d1, 0x20a3, 0x0000, 0x0078, 0x4b25, 0x0c7e, 0x0f7e, 0x2c78, + 0x7804, 0xa08a, 0x0040, 0x1048, 0x12b7, 0xa08a, 0x004f, 0x10c8, + 0x12b7, 0x7918, 0x2160, 0x61a0, 0xa1e0, 0x2091, 0x2c0c, 0xa18c, + 0x00ff, 0x2061, 0x0100, 0x619a, 0xa082, 0x0040, 0x1079, 0x4c33, + 0x0f7f, 0x0c7f, 0x007c, 0x4c44, 0x4d28, 0x4cd0, 0x4e50, 0x4c42, + 0x4c42, 0x4c42, 0x4c42, 0x4c42, 0x4c42, 0x4c42, 0x528d, 0x529e, + 0x52af, 0x52c0, 0x1078, 0x12b7, 0x0d7e, 0x157e, 0x147e, 0x20a1, + 0x020b, 0x1078, 0x4c93, 0x7910, 0x2168, 0x6944, 0xa18c, 0x00ff, + 0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184, 0x0006, + 0x8004, 0x20a2, 0xd1ac, 0x0040, 0x4c61, 0x20a3, 0x0002, 0x0078, + 0x4c6d, 0xd1b4, 0x0040, 0x4c68, 0x20a3, 0x0001, 0x0078, 0x4c6d, + 0x20a3, 0x0000, 0x2230, 0x0078, 0x4c6f, 0x6a80, 0x6e7c, 0x20a9, + 0x0008, 0xad80, 0x0017, 0x200c, 0x810f, 0x21a2, 0x8000, 0x00f0, + 0x4c73, 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, 0x6014, + 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0x6f2c, 0x2003, + 0x07d0, 0x2001, 0x6f2b, 0x2003, 0x0009, 0x1078, 0x14e4, 0x147f, + 0x157f, 0x0d7f, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7a18, + 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, + 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x4cb9, 0x0d7e, + 0xa0e8, 0x6e00, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, + 0x20a2, 0x2069, 0x6d19, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, + 0x4cc1, 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, 0x4cf0, + 0x7810, 0x2068, 0x6860, 0x20a2, 0x685c, 0x20a2, 0x6880, 0x20a2, + 0x687c, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x60c3, + 0x000c, 0x1078, 0x4fd1, 0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c, + 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, + 0x2004, 0xd0bc, 0x0040, 0x4d0e, 0x0d7e, 0xa0e8, 0x6e00, 0x2d6c, + 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x6d19, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x4d16, 0x20a3, 0x0500, + 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0889, + 0x20a3, 0x0000, 0x1078, 0x4fc0, 0x22a2, 0x20a3, 0x0000, 0x7a08, + 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, + 0x0d7e, 0x157e, 0x137e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x4e18, + 0x7810, 0x2068, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, + 0x7810, 0xa084, 0xf000, 0x00c0, 0x4d45, 0x7810, 0xa084, 0x0700, + 0x8007, 0x1079, 0x4d4d, 0x0078, 0x4d48, 0xa006, 0x1079, 0x4d4d, + 0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c, 0x4d57, 0x4db9, 0x4dbd, + 0x4de0, 0x4ded, 0x4dff, 0x4e03, 0x4d55, 0x1078, 0x12b7, 0x017e, + 0x037e, 0x694c, 0xa18c, 0x0003, 0xa186, 0x0000, 0x00c0, 0x4d6a, + 0x6b78, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x037f, 0x017f, + 0x0078, 0x4de4, 0xa186, 0x0001, 0x00c0, 0x4db4, 0x6b78, 0x23a2, + 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2, 0x6874, 0x20a2, 0x22a2, + 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384, 0x0300, 0x0040, 0x4db3, + 0xd3c4, 0x0040, 0x4d85, 0x687c, 0xa108, 0xd3cc, 0x0040, 0x4d8a, + 0x6874, 0xa108, 0x157e, 0x20a9, 0x000d, 0xad80, 0x0020, 0x201c, + 0x831f, 0x23a2, 0x8000, 0x00f0, 0x4d8f, 0x157f, 0x22a2, 0x22a2, + 0x22a2, 0xa184, 0x0003, 0x0040, 0x4db3, 0x20a1, 0x020b, 0x20e1, + 0x9080, 0x20e1, 0x4000, 0x20a3, 0x0700, 0x6298, 0x22a2, 0x20a3, + 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0898, 0x20a2, 0x1078, 0x4fc0, + 0x22a2, 0x20a3, 0x0000, 0x61c2, 0x037f, 0x017f, 0x1078, 0x4fd1, + 0x007c, 0x20a3, 0x0008, 0x0078, 0x4de2, 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, 0x4fd1, 0x007c, + 0x20a3, 0x0028, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, + 0x60c3, 0x0018, 0x1078, 0x4fd1, 0x007c, 0x20a3, 0x0100, 0x22a2, + 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0008, 0x22a2, 0x22a2, + 0x22a2, 0x22a2, 0x60c3, 0x0020, 0x1078, 0x4fd1, 0x007c, 0x20a3, + 0x0008, 0x0078, 0x4de2, 0x037e, 0x7b10, 0xa384, 0xff00, 0x7812, + 0xa384, 0x00ff, 0x8001, 0x00c0, 0x4e11, 0x22a2, 0x037f, 0x0078, + 0x4de2, 0x20a3, 0x0800, 0x22a2, 0x20a2, 0x037f, 0x0078, 0x4de4, + 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, + 0x2004, 0xd0bc, 0x0040, 0x4e36, 0x0d7e, 0xa0e8, 0x6e00, 0x2d6c, + 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x6d19, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x4e3e, 0x20a3, 0x0700, + 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0898, + 0x20a3, 0x0000, 0x1078, 0x4fc0, 0x22a2, 0x20a3, 0x0000, 0x7a08, + 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, + 0x0d7e, 0x157e, 0x137e, 0x147e, 0x017e, 0x037e, 0x7810, 0xa084, + 0x0700, 0x8007, 0x1079, 0x4e63, 0x037f, 0x017f, 0x147f, 0x137f, + 0x157f, 0x0d7f, 0x007c, 0x4e6b, 0x4e6b, 0x4e6d, 0x4e6b, 0x4e6b, + 0x4e6b, 0x4e92, 0x4e6b, 0x1078, 0x12b7, 0x7910, 0xa18c, 0xf8ff, + 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078, + 0x4e9c, 0x0d7e, 0x2069, 0x6d51, 0x6804, 0xd0bc, 0x0040, 0x4e87, + 0x682c, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x0078, 0x4e89, 0x20a3, + 0x3f00, 0x0d7f, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, 0x1078, + 0x4fd1, 0x007c, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078, 0x4e9c, + 0x20a3, 0x7f00, 0x0078, 0x4e8a, 0x027e, 0x20e1, 0x9080, 0x20e1, + 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x4eba, + 0x0d7e, 0xa0e8, 0x6e00, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2, + 0x6814, 0x20a2, 0x2069, 0x6d19, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, + 0x0078, 0x4ec2, 0x20a3, 0x0100, 0x6298, 0x22a2, 0x20a3, 0x0000, + 0x6230, 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x1078, + 0x4fc0, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x0c7e, + 0x057e, 0x047e, 0x037e, 0x2061, 0x0100, 0x2071, 0x6d00, 0x6130, + 0x7818, 0x2068, 0x68a0, 0x2028, 0xd0bc, 0x00c0, 0x4eee, 0xa080, + 0x2091, 0x2014, 0xa294, 0x00ff, 0x0078, 0x4ef2, 0x6910, 0x6a14, + 0x7364, 0x7468, 0x781c, 0xa086, 0x0006, 0x0040, 0x4f3d, 0xd5bc, + 0x0040, 0x4f02, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, + 0x0078, 0x4f08, 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, 0x4f31, 0x2011, + 0x0000, 0x629e, 0x6017, 0x0016, 0x1078, 0x4151, 0x037f, 0x047f, + 0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7810, 0x2070, 0x704c, + 0xa084, 0x0003, 0xa086, 0x0002, 0x0040, 0x4f83, 0xd5bc, 0x0040, + 0x4f51, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, + 0x4f57, 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, 0x4f7e, 0x2011, 0x0000, 0x629e, 0x6017, + 0x0012, 0x0078, 0x4f34, 0xd5bc, 0x0040, 0x4f8e, 0xa185, 0x0700, + 0x20a2, 0x6266, 0x636a, 0x646e, 0x0078, 0x4f94, 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, + 0x4fbb, 0x2011, 0x0000, 0x629e, 0x6017, 0x0016, 0x0078, 0x4f34, + 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, + 0x8217, 0x007c, 0x0d7e, 0x2069, 0x6f10, 0x6843, 0x0001, 0x0d7f, + 0x007c, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x1078, + 0x4fdc, 0x1078, 0x4143, 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, 0x414c, + 0x2061, 0x0100, 0x2069, 0x0140, 0x6904, 0xa194, 0x4000, 0x0040, + 0x503a, 0x1078, 0x4fe5, 0x6803, 0x1000, 0x6803, 0x0000, 0x0c7e, + 0x2061, 0x6f10, 0x6128, 0xa192, 0x0002, 0x00c8, 0x5027, 0x8108, + 0x612a, 0x613c, 0x0c7f, 0x81ff, 0x0040, 0x5035, 0x1078, 0x4143, + 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0, 0x5023, 0x6017, + 0x0012, 0x0078, 0x5035, 0x1078, 0x4fdc, 0x0078, 0x5035, 0x6124, + 0xa1e5, 0x0000, 0x0040, 0x5032, 0x1078, 0x6c76, 0x2009, 0x0014, + 0x1078, 0x5591, 0x0c7f, 0x0078, 0x5035, 0x027f, 0x017f, 0x0d7f, + 0x0c7f, 0x007c, 0x1078, 0x31cb, 0x0078, 0x5035, 0x0c7e, 0x0d7e, + 0x0e7e, 0x017e, 0x027e, 0x1078, 0x415a, 0x2071, 0x6f10, 0x713c, + 0x81ff, 0x0040, 0x5079, 0x2061, 0x0100, 0x2069, 0x0140, 0x6904, + 0x017e, 0x017f, 0xa194, 0x4000, 0x0040, 0x507f, 0x6017, 0x0010, + 0x7144, 0xa192, 0x0002, 0x00c8, 0x5071, 0x8108, 0x7146, 0x1078, + 0x4151, 0x713c, 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0, + 0x506d, 0x6017, 0x0012, 0x0078, 0x5079, 0x6017, 0x0016, 0x0078, + 0x5079, 0x1078, 0x6c76, 0x2009, 0x004a, 0x1078, 0x5591, 0x0078, + 0x5079, 0x027f, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c, 0x1078, + 0x4151, 0x0078, 0x5079, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x057e, + 0x047e, 0x007e, 0x127e, 0x2091, 0x8000, 0x6018, 0x2068, 0x6ca0, + 0x2071, 0x6f10, 0x7018, 0x2068, 0x8dff, 0x0040, 0x50af, 0x68a0, + 0xa406, 0x0040, 0x509f, 0x6854, 0x2068, 0x0078, 0x5094, 0x6010, + 0x2060, 0x643c, 0x6540, 0x6644, 0xa6b4, 0x000f, 0x2d60, 0x1078, + 0x3522, 0x0040, 0x50af, 0x1078, 0x5374, 0xa085, 0x0001, 0x127f, + 0x007f, 0x047f, 0x057f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, + 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x4a83, 0x20a3, 0x0f00, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, 0x60c3, 0x0008, + 0x1078, 0x4fd1, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1, + 0x020b, 0x1078, 0x4afa, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a9, + 0x0006, 0x2011, 0x6d40, 0x2019, 0x6d40, 0x23a6, 0x22a6, 0xa398, + 0x0002, 0xa290, 0x0002, 0x00f0, 0x50dd, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x60c3, 0x001c, 0x1078, 0x4fd1, 0x147f, 0x157f, 0x007c, + 0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b, 0x1078, 0x4ada, + 0x1078, 0x4af1, 0x7810, 0x007e, 0xa080, 0x0015, 0x2098, 0x7808, + 0xa088, 0x0002, 0x21a8, 0x53a6, 0xa080, 0x0004, 0x8003, 0x60c2, + 0x007f, 0xa080, 0x0001, 0x2004, 0x7812, 0x1078, 0x4fd1, 0x027f, + 0x017f, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, + 0x1078, 0x4a83, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x7808, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x4fd1, 0x147f, 0x157f, + 0x007c, 0x0e7e, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, + 0x6f10, 0x700c, 0x2060, 0x8cff, 0x0040, 0x513f, 0x600c, 0x007e, + 0x1078, 0x556a, 0x1078, 0x5374, 0x0c7f, 0x0078, 0x5133, 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, + 0x6f10, 0x7024, 0x2060, 0x8cff, 0x0040, 0x5198, 0x1078, 0x4fe5, + 0x68c3, 0x0000, 0x1078, 0x414c, 0x2009, 0x0013, 0x1078, 0x5591, + 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040, 0x517b, 0x6827, 0x0004, + 0x7804, 0xa084, 0x4000, 0x0040, 0x518d, 0x7803, 0x1000, 0x7803, + 0x0000, 0x0078, 0x518d, 0xd084, 0x0040, 0x5182, 0x6827, 0x0001, + 0x0078, 0x5184, 0x00f0, 0x516a, 0x7804, 0xa084, 0x1000, 0x0040, + 0x518d, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x007f, 0x017f, + 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c, + 0x2001, 0x6d00, 0x2004, 0xa096, 0x0001, 0x0040, 0x51d0, 0xa096, + 0x0004, 0x0040, 0x51d0, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, + 0x318e, 0x1078, 0x40d1, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040, + 0x51be, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x51d0, + 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0x51d0, 0xd084, 0x0040, + 0x51c5, 0x6827, 0x0001, 0x0078, 0x51c7, 0x00f0, 0x51ad, 0x7804, + 0xa084, 0x1000, 0x0040, 0x51d0, 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, 0x6f10, 0x703c, 0x2060, 0x8cff, 0x0040, 0x5228, + 0x6817, 0x0010, 0x68cb, 0x0000, 0x68c7, 0x0000, 0x1078, 0x415a, + 0x1078, 0x1a20, 0xa39d, 0x0000, 0x00c0, 0x5202, 0x2009, 0x0049, + 0x1078, 0x5591, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0040, 0x5215, + 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x5227, 0x7803, + 0x1000, 0x7803, 0x0000, 0x0078, 0x5227, 0xd094, 0x0040, 0x521c, + 0x6827, 0x0002, 0x0078, 0x521e, 0x00f0, 0x5204, 0x7804, 0xa084, + 0x1000, 0x0040, 0x5227, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, + 0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, + 0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0x6f10, + 0x6a06, 0x127f, 0x0d7f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, + 0x2069, 0x6f10, 0x6a32, 0x127f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, + 0x0c7e, 0x067e, 0x007e, 0x127e, 0x2071, 0x6f10, 0x7614, 0x2660, + 0x2678, 0x2091, 0x8000, 0x8cff, 0x0040, 0x5286, 0x601c, 0xa206, + 0x00c0, 0x5281, 0x7014, 0xac36, 0x00c0, 0x5260, 0x660c, 0x7616, + 0x7010, 0xac36, 0x00c0, 0x526e, 0x2c00, 0xaf36, 0x0040, 0x526c, + 0x2f00, 0x7012, 0x0078, 0x526e, 0x7013, 0x0000, 0x660c, 0x067e, + 0x2c00, 0xaf06, 0x0040, 0x5277, 0x7e0e, 0x0078, 0x5278, 0x2678, + 0x600f, 0x0000, 0x1078, 0x6283, 0x1078, 0x5374, 0x0c7f, 0x0078, + 0x5253, 0x2c78, 0x600c, 0x2060, 0x0078, 0x5253, 0x127f, 0x007f, + 0x067f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x157e, 0x147e, 0x20a1, + 0x020b, 0x1078, 0x4c93, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, + 0x20a2, 0x20a2, 0x20a3, 0x4000, 0x0078, 0x52cf, 0x157e, 0x147e, + 0x20a1, 0x020b, 0x1078, 0x4c93, 0x7810, 0x20a2, 0xa006, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000, 0x0078, 0x52cf, 0x157e, + 0x147e, 0x20a1, 0x020b, 0x1078, 0x4c93, 0x7810, 0x20a2, 0xa006, + 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078, 0x52cf, + 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x4c93, 0x7810, 0x20a2, + 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200, 0x1078, + 0x537f, 0x60c3, 0x0020, 0x1078, 0x4fd1, 0x147f, 0x157f, 0x007c, + 0x127e, 0x0c7e, 0x2091, 0x8000, 0x2061, 0x0100, 0x6120, 0xd1b4, + 0x00c0, 0x52e7, 0xd1bc, 0x00c0, 0x5331, 0x0078, 0x5371, 0x2009, + 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069, 0x0140, + 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000, 0x0040, + 0x5328, 0x6020, 0xd0b4, 0x0040, 0x5328, 0x6024, 0xd094, 0x00c0, + 0x5328, 0x2104, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x5328, + 0x00f0, 0x52f4, 0x027e, 0x6198, 0xa18c, 0x00ff, 0x8107, 0x6130, + 0xa18c, 0x00ff, 0xa10d, 0x6088, 0x628c, 0x618e, 0x608b, 0xbc91, + 0x6043, 0x0001, 0x6043, 0x0000, 0x608a, 0x628e, 0x6024, 0xd094, + 0x00c0, 0x5327, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x531e, 0x027f, + 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000, 0x0078, + 0x5371, 0x2009, 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, + 0x2069, 0x0140, 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, + 0x4000, 0x0040, 0x536a, 0x6020, 0xd0bc, 0x0040, 0x536a, 0x2104, + 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x536a, 0x00f0, 0x533e, + 0x027e, 0x6164, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c, 0x00ff, + 0xa10d, 0x6088, 0x628c, 0x608b, 0xbc91, 0x618e, 0x6043, 0x0001, + 0x6043, 0x0000, 0x608a, 0x628e, 0x6a04, 0xa294, 0x4000, 0x00c0, + 0x5364, 0x027f, 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, + 0x0000, 0x0c7f, 0x127f, 0x007c, 0x0e7e, 0x2071, 0x6f10, 0x7020, + 0xa005, 0x0040, 0x537d, 0x8001, 0x7022, 0x0e7f, 0x007c, 0x20a9, + 0x0008, 0x20a2, 0x00f0, 0x5381, 0x20a2, 0x20a2, 0x007c, 0x0f7e, + 0x0e7e, 0x0d7e, 0x0c7e, 0x077e, 0x067e, 0x007e, 0x127e, 0x2091, + 0x8000, 0x2071, 0x6f10, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001, + 0x87ff, 0x0040, 0x5417, 0x8cff, 0x0040, 0x5417, 0x601c, 0xa086, + 0x0006, 0x00c0, 0x5412, 0x88ff, 0x0040, 0x53ae, 0x2800, 0xac06, + 0x00c0, 0x5412, 0x2039, 0x0000, 0x0078, 0x53b2, 0x6018, 0xa206, + 0x00c0, 0x5412, 0x7024, 0xac06, 0x00c0, 0x53e0, 0x2069, 0x0100, + 0x68c0, 0xa005, 0x0040, 0x53db, 0x6817, 0x0008, 0x68c3, 0x0000, + 0x1078, 0x54a4, 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, + 0xa384, 0x1000, 0x0040, 0x53d0, 0x6803, 0x0100, 0x6803, 0x0000, + 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x53d8, 0x6827, 0x0001, + 0x037f, 0x0078, 0x53e0, 0x6003, 0x0009, 0x630a, 0x0078, 0x5412, + 0x7014, 0xac36, 0x00c0, 0x53e6, 0x660c, 0x7616, 0x7010, 0xac36, + 0x00c0, 0x53f4, 0x2c00, 0xaf36, 0x0040, 0x53f2, 0x2f00, 0x7012, + 0x0078, 0x53f4, 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, + 0x0040, 0x53fd, 0x7e0e, 0x0078, 0x53fe, 0x2678, 0x600f, 0x0000, + 0x6010, 0x2068, 0x1078, 0x6120, 0x0040, 0x5408, 0x1078, 0x6bb3, + 0x1078, 0x6283, 0x1078, 0x5374, 0x88ff, 0x00c0, 0x5421, 0x0c7f, + 0x0078, 0x5398, 0x2c78, 0x600c, 0x2060, 0x0078, 0x5398, 0xa006, + 0x127f, 0x007f, 0x067f, 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, + 0x007c, 0x6017, 0x0000, 0x0c7f, 0xa8c5, 0x0001, 0x0078, 0x5418, + 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x007e, 0x127e, + 0x2091, 0x8000, 0x2071, 0x6f10, 0x7638, 0x2660, 0x2678, 0x8cff, + 0x0040, 0x5493, 0x601c, 0xa086, 0x0006, 0x00c0, 0x548e, 0x88ff, + 0x0040, 0x5448, 0x2800, 0xac06, 0x00c0, 0x548e, 0x0078, 0x544c, + 0x6018, 0xa206, 0x00c0, 0x548e, 0x703c, 0xac06, 0x00c0, 0x545e, + 0x037e, 0x2019, 0x0001, 0x1078, 0x51da, 0x7033, 0x0000, 0x703f, + 0x0000, 0x7043, 0x0000, 0x7047, 0x0000, 0x037f, 0x7038, 0xac36, + 0x00c0, 0x5464, 0x660c, 0x763a, 0x7034, 0xac36, 0x00c0, 0x5472, + 0x2c00, 0xaf36, 0x0040, 0x5470, 0x2f00, 0x7036, 0x0078, 0x5472, + 0x7037, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x547b, + 0x7e0e, 0x0078, 0x547c, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, + 0x1078, 0x6120, 0x0040, 0x5486, 0x1078, 0x6bb3, 0x1078, 0x6283, + 0x88ff, 0x00c0, 0x549d, 0x0c7f, 0x0078, 0x5437, 0x2c78, 0x600c, + 0x2060, 0x0078, 0x5437, 0xa006, 0x127f, 0x007f, 0x027f, 0x067f, + 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x6017, 0x0000, 0x0c7f, + 0xa8c5, 0x0001, 0x0078, 0x5494, 0x0e7e, 0x2071, 0x6f10, 0x2001, + 0x6d00, 0x2004, 0xa086, 0x0002, 0x00c0, 0x54b2, 0x7007, 0x0005, + 0x0078, 0x54b4, 0x7007, 0x0000, 0x0e7f, 0x007c, 0x0f7e, 0x0e7e, + 0x0c7e, 0x067e, 0x027e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, + 0x6f10, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0040, 0x54f4, + 0x2200, 0xac06, 0x00c0, 0x54ef, 0x7038, 0xac36, 0x00c0, 0x54d2, + 0x660c, 0x763a, 0x7034, 0xac36, 0x00c0, 0x54e0, 0x2c00, 0xaf36, + 0x0040, 0x54de, 0x2f00, 0x7036, 0x0078, 0x54e0, 0x7037, 0x0000, + 0x660c, 0x2c00, 0xaf06, 0x0040, 0x54e8, 0x7e0e, 0x0078, 0x54e9, + 0x2678, 0x600f, 0x0000, 0xa085, 0x0001, 0x0078, 0x54f4, 0x2c78, + 0x600c, 0x2060, 0x0078, 0x54c5, 0x127f, 0x007f, 0x027f, 0x067f, + 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x2061, 0x7400, 0x2a70, 0x7060, + 0x7046, 0x704b, 0x7400, 0x007c, 0x0e7e, 0x127e, 0x2071, 0x6d00, + 0x2091, 0x8000, 0x7544, 0xa582, 0x0001, 0x0048, 0x5536, 0x7048, + 0x2060, 0x6000, 0xa086, 0x0000, 0x0040, 0x5522, 0xace0, 0x0008, + 0x7054, 0xac02, 0x00c8, 0x551e, 0x0078, 0x5511, 0x2061, 0x7400, + 0x0078, 0x5511, 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8, 0x0008, + 0x7054, 0xa502, 0x00c8, 0x5532, 0x754a, 0xa085, 0x0001, 0x127f, + 0x0e7f, 0x007c, 0x704b, 0x7400, 0x0078, 0x552d, 0xa006, 0x0078, + 0x552f, 0x0e7e, 0x2071, 0x6d00, 0x7544, 0xa582, 0x0001, 0x0048, + 0x5567, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040, 0x5554, + 0xace0, 0x0008, 0x7054, 0xac02, 0x00c8, 0x5550, 0x0078, 0x5543, + 0x2061, 0x7400, 0x0078, 0x5543, 0x6003, 0x0008, 0x8529, 0x7546, + 0xaca8, 0x0008, 0x7054, 0xa502, 0x00c8, 0x5563, 0x754a, 0xa085, + 0x0001, 0x0e7f, 0x007c, 0x704b, 0x7400, 0x0078, 0x555f, 0xa006, + 0x0078, 0x5561, 0xac82, 0x7400, 0x1048, 0x12b7, 0x2001, 0x6d15, + 0x2004, 0xac02, 0x10c8, 0x12b7, 0xa006, 0x6006, 0x600a, 0x600e, + 0x6012, 0x6016, 0x601a, 0x601f, 0x0000, 0x6003, 0x0000, 0x2061, + 0x6d00, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0040, 0x5589, + 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x476a, 0x127f, 0x0078, + 0x5588, 0x601c, 0xa084, 0x000f, 0x0079, 0x5596, 0x559f, 0x55a7, + 0x55c3, 0x55df, 0x629a, 0x62b6, 0x62d2, 0x559f, 0x55a7, 0xa18e, + 0x0047, 0x00c0, 0x55a6, 0xa016, 0x1078, 0x1532, 0x007c, 0x067e, + 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12b7, 0x1079, 0x55b1, 0x067f, + 0x007c, 0x55c1, 0x5698, 0x5792, 0x55c1, 0x57d7, 0x55c1, 0x55c1, + 0x55c1, 0x5653, 0x5a4d, 0x55c1, 0x55c1, 0x55c1, 0x55c1, 0x55c1, + 0x55c1, 0x1078, 0x12b7, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, + 0x12b7, 0x1079, 0x55cd, 0x067f, 0x007c, 0x55dd, 0x55dd, 0x55dd, + 0x55dd, 0x55dd, 0x55dd, 0x55dd, 0x55dd, 0x5e10, 0x5edd, 0x55dd, + 0x5e29, 0x5e8f, 0x5e29, 0x5e8f, 0x55dd, 0x1078, 0x12b7, 0x067e, + 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12b7, 0x1079, 0x55e9, 0x067f, + 0x007c, 0x55f9, 0x5a96, 0x5b05, 0x5bbb, 0x5cd2, 0x55f9, 0x55f9, + 0x55f9, 0x5a75, 0x5dc6, 0x5dca, 0x55f9, 0x55f9, 0x55f9, 0x55f9, + 0x5df0, 0x1078, 0x12b7, 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, 0x5609, 0x0e7e, 0x6010, 0x2070, + 0x7007, 0x0000, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x556a, 0x007c, + 0x0d7e, 0x037e, 0x7330, 0xa386, 0x0200, 0x00c0, 0x562d, 0x6018, + 0x2068, 0x6813, 0x00ff, 0x6817, 0xfffd, 0x6010, 0xa005, 0x0040, + 0x5637, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6b32, 0x1078, + 0x556a, 0x037f, 0x0d7f, 0x007c, 0x0d7e, 0x20a9, 0x000e, 0x2e98, + 0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x00c0, 0x5650, 0x6018, + 0x2068, 0x7038, 0x680a, 0x703c, 0x680e, 0x6800, 0xc08d, 0x6802, + 0x0d7f, 0x0078, 0x5615, 0x2100, 0xa1b2, 0x0024, 0x10c8, 0x12b7, + 0x0079, 0x565a, 0x5680, 0x568c, 0x5680, 0x5680, 0x5680, 0x5680, + 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, + 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, + 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, 0x567e, + 0x567e, 0x5680, 0x567e, 0x5680, 0x5680, 0x567e, 0x1078, 0x12b7, + 0x6003, 0x0001, 0x6106, 0x1078, 0x4376, 0x127e, 0x2091, 0x8000, + 0x1078, 0x476a, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078, + 0x4376, 0x127e, 0x2091, 0x8000, 0x1078, 0x476a, 0x127f, 0x007c, + 0x6004, 0xa0b2, 0x0024, 0x10c8, 0x12b7, 0xa1b6, 0x0013, 0x00c0, + 0x56a4, 0x2008, 0x0079, 0x5706, 0xa1b6, 0x0014, 0x00c0, 0x56fd, + 0x1078, 0x4671, 0x6004, 0xa08e, 0x0000, 0x0040, 0x56fe, 0xa08e, + 0x0002, 0x0040, 0x56c9, 0xa08e, 0x0003, 0x0040, 0x56c9, 0xa08e, + 0x0004, 0x0040, 0x56c9, 0xa08e, 0x001f, 0x0040, 0x56fe, 0xa08e, + 0x0021, 0x0040, 0x5702, 0xa08e, 0x0022, 0x0040, 0x56fe, 0x0078, + 0x56f9, 0x1078, 0x206f, 0x2001, 0x0007, 0x1078, 0x33f3, 0x6018, + 0xa080, 0x0028, 0x200c, 0x1078, 0x5778, 0xa186, 0x007e, 0x00c0, + 0x56df, 0x2001, 0x6d2f, 0x2014, 0xa295, 0x0001, 0x2202, 0x017e, + 0x027e, 0x037e, 0x2110, 0x2019, 0x0028, 0x1078, 0x445c, 0x1078, + 0x43a9, 0x0c7e, 0x6018, 0xa065, 0x0040, 0x56f0, 0x1078, 0x35cf, + 0x0c7f, 0x2c08, 0x1078, 0x6a57, 0x037f, 0x027f, 0x017f, 0x1078, + 0x342f, 0x1078, 0x556a, 0x1078, 0x476a, 0x007c, 0x1078, 0x5778, + 0x0078, 0x56f9, 0x1078, 0x5786, 0x0078, 0x56f9, 0x572c, 0x572e, + 0x5732, 0x5736, 0x573a, 0x573e, 0x572a, 0x572a, 0x572a, 0x572a, + 0x572a, 0x572a, 0x572a, 0x572a, 0x572a, 0x572a, 0x572a, 0x572a, + 0x572a, 0x572a, 0x572a, 0x572a, 0x572a, 0x572a, 0x572a, 0x572a, + 0x572a, 0x572a, 0x572a, 0x572a, 0x5742, 0x5748, 0x572a, 0x5752, + 0x5748, 0x572a, 0x1078, 0x12b7, 0x0078, 0x5748, 0x2001, 0x000b, + 0x0078, 0x575b, 0x2001, 0x0003, 0x0078, 0x575b, 0x2001, 0x0005, + 0x0078, 0x575b, 0x2001, 0x0001, 0x0078, 0x575b, 0x2001, 0x0009, + 0x0078, 0x575b, 0x1078, 0x12b7, 0x0078, 0x575a, 0x1078, 0x33f3, + 0x1078, 0x4671, 0x6003, 0x0002, 0x6017, 0x0028, 0x1078, 0x476a, + 0x0078, 0x575a, 0x1078, 0x4671, 0x6003, 0x0004, 0x6017, 0x0028, + 0x1078, 0x476a, 0x007c, 0x1078, 0x33f3, 0x1078, 0x4671, 0x6003, + 0x0002, 0x037e, 0x2019, 0x6d5c, 0x2304, 0xa084, 0xff00, 0x00c0, + 0x576d, 0x2019, 0x0028, 0x0078, 0x5772, 0x8007, 0x8003, 0x801b, + 0x831b, 0xa318, 0x6316, 0x037f, 0x1078, 0x476a, 0x0078, 0x575a, + 0x0e7e, 0x6010, 0xa005, 0x0040, 0x5784, 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, 0x12b7, 0x6604, 0xa6b6, 0x001f, + 0x00c0, 0x57a6, 0x1078, 0x55fb, 0x0078, 0x57c6, 0x6604, 0xa6b6, + 0x0000, 0x00c0, 0x57af, 0x1078, 0x563c, 0x0078, 0x57c6, 0x6604, + 0xa6b6, 0x0022, 0x00c0, 0x57b8, 0x1078, 0x5620, 0x0078, 0x57c6, + 0xa1b6, 0x0015, 0x00c0, 0x57c0, 0x1079, 0x57cb, 0x0078, 0x57c6, + 0xa1b6, 0x0016, 0x00c0, 0x57c7, 0x1079, 0x58f6, 0x007c, 0x1078, + 0x559f, 0x0078, 0x57c6, 0x57ef, 0x57f2, 0x57ef, 0x5833, 0x57ef, + 0x5892, 0x57ef, 0x57ef, 0x57ef, 0x58ce, 0x57ef, 0x58e4, 0xa1b6, + 0x0048, 0x0040, 0x57e3, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, + 0x1078, 0x1532, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000, + 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x556a, 0x007c, 0x0005, + 0x0005, 0x007c, 0x0e7e, 0x2071, 0x6d00, 0x7078, 0xa086, 0x0074, + 0x00c0, 0x581c, 0x1078, 0x6a2b, 0x00c0, 0x580e, 0x0d7e, 0x6018, + 0x2068, 0x1078, 0x5820, 0x0d7f, 0x2001, 0x0006, 0x1078, 0x33f3, + 0x1078, 0x206f, 0x1078, 0x556a, 0x0078, 0x581e, 0x2001, 0x000a, + 0x1078, 0x33f3, 0x1078, 0x206f, 0x6003, 0x0001, 0x6007, 0x0001, + 0x1078, 0x4376, 0x0078, 0x581e, 0x1078, 0x5889, 0x0e7f, 0x007c, + 0x6800, 0xd084, 0x0040, 0x5832, 0x2001, 0x0000, 0x1078, 0x33df, + 0x2069, 0x6d51, 0x6804, 0xd0a4, 0x0040, 0x5832, 0x2001, 0x0006, + 0x1078, 0x3401, 0x007c, 0x0d7e, 0x2011, 0x6d1e, 0x2204, 0xa086, + 0x0074, 0x00c0, 0x5885, 0x1078, 0x599f, 0x6018, 0x2068, 0xa080, + 0x0028, 0x2014, 0xa286, 0x007e, 0x0040, 0x5850, 0xa286, 0x0080, + 0x00c0, 0x5879, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x0078, 0x586f, + 0x0e7e, 0x0f7e, 0x6813, 0x00ff, 0x6817, 0xfffe, 0x2071, 0x6d2f, + 0x2e04, 0xa085, 0x0003, 0x2072, 0x2071, 0x7280, 0x2079, 0x0100, + 0x2e04, 0xa084, 0x00ff, 0x2069, 0x6d19, 0x206a, 0x78e6, 0x8e70, + 0x2e04, 0x2069, 0x6d1a, 0x206a, 0x78ea, 0x0f7f, 0x0e7f, 0x2001, + 0x0006, 0x1078, 0x33f3, 0x1078, 0x206f, 0x1078, 0x556a, 0x0078, + 0x5887, 0x2001, 0x0004, 0x1078, 0x33f3, 0x6003, 0x0001, 0x6007, + 0x0003, 0x1078, 0x4376, 0x0078, 0x5887, 0x1078, 0x5889, 0x0d7f, + 0x007c, 0x2001, 0x0007, 0x1078, 0x33f3, 0x1078, 0x206f, 0x1078, + 0x556a, 0x007c, 0x0e7e, 0x2071, 0x6d00, 0x7078, 0xa086, 0x0014, + 0x00c0, 0x58c8, 0x7000, 0xa086, 0x0003, 0x00c0, 0x58a5, 0x6010, + 0xa005, 0x00c0, 0x58a5, 0x1078, 0x2ad1, 0x0d7e, 0x6018, 0x2068, + 0x1078, 0x34ca, 0x1078, 0x5820, 0x0d7f, 0x1078, 0x59a9, 0x00c0, + 0x58c8, 0x2001, 0x0006, 0x1078, 0x33f3, 0x0e7e, 0x6010, 0xa005, + 0x0040, 0x58c1, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103, 0x7033, + 0x0200, 0x0e7f, 0x1078, 0x206f, 0x1078, 0x556a, 0x0078, 0x58cc, + 0x1078, 0x5778, 0x1078, 0x5889, 0x0e7f, 0x007c, 0x2011, 0x6d1e, + 0x2204, 0xa086, 0x0014, 0x00c0, 0x58e1, 0x2001, 0x0002, 0x1078, + 0x33f3, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x4376, 0x0078, + 0x58e3, 0x1078, 0x5889, 0x007c, 0x2011, 0x6d1e, 0x2204, 0xa086, + 0x0004, 0x00c0, 0x58f3, 0x2001, 0x0007, 0x1078, 0x33f3, 0x1078, + 0x556a, 0x0078, 0x58f5, 0x1078, 0x5889, 0x007c, 0x57ef, 0x5902, + 0x57ef, 0x5928, 0x57ef, 0x5952, 0x57ef, 0x57ef, 0x57ef, 0x5967, + 0x57ef, 0x597a, 0x0c7e, 0x1078, 0x598d, 0x00c0, 0x5917, 0x2001, + 0x0000, 0x1078, 0x33df, 0x2001, 0x0002, 0x1078, 0x33f3, 0x6003, + 0x0001, 0x6007, 0x0002, 0x1078, 0x4376, 0x0078, 0x5926, 0x2009, + 0x728f, 0x2104, 0xa084, 0xff00, 0xa086, 0x1900, 0x00c0, 0x5924, + 0x1078, 0x556a, 0x0078, 0x5926, 0x1078, 0x5889, 0x0c7f, 0x007c, + 0x1078, 0x599c, 0x00c0, 0x593c, 0x2001, 0x0000, 0x1078, 0x33df, + 0x2001, 0x0002, 0x1078, 0x33f3, 0x6003, 0x0001, 0x6007, 0x0002, + 0x1078, 0x4376, 0x0078, 0x5951, 0x1078, 0x5778, 0x2009, 0x728f, + 0x2104, 0xa084, 0xff00, 0xa086, 0x1900, 0x00c0, 0x594f, 0x2001, + 0x0004, 0x1078, 0x33f3, 0x1078, 0x556a, 0x0078, 0x5951, 0x1078, + 0x5889, 0x007c, 0x1078, 0x599c, 0x00c0, 0x5962, 0x2001, 0x0004, + 0x1078, 0x33f3, 0x6003, 0x0001, 0x6007, 0x0003, 0x1078, 0x4376, + 0x0078, 0x5966, 0x1078, 0x5778, 0x1078, 0x5889, 0x007c, 0x1078, + 0x599c, 0x00c0, 0x5977, 0x2001, 0x0008, 0x1078, 0x33f3, 0x6003, + 0x0001, 0x6007, 0x0005, 0x1078, 0x4376, 0x0078, 0x5979, 0x1078, + 0x5889, 0x007c, 0x1078, 0x599c, 0x00c0, 0x598a, 0x2001, 0x000a, + 0x1078, 0x33f3, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x4376, + 0x0078, 0x598c, 0x1078, 0x5889, 0x007c, 0x2009, 0x728e, 0x2104, + 0xa086, 0x0003, 0x00c0, 0x599b, 0x2009, 0x728f, 0x2104, 0xa084, + 0xff00, 0xa086, 0x2a00, 0x007c, 0xa085, 0x0001, 0x007c, 0x0c7e, + 0x017e, 0xac88, 0x0006, 0x2164, 0x1078, 0x3459, 0x017f, 0x0c7f, + 0x007c, 0x0e7e, 0x2071, 0x728c, 0x7004, 0xa086, 0x0014, 0x00c0, + 0x59cc, 0x7008, 0xa086, 0x0800, 0x00c0, 0x59cc, 0x700c, 0xd0ec, + 0x0040, 0x59ca, 0xa084, 0x0f00, 0xa086, 0x0100, 0x00c0, 0x59ca, + 0x7024, 0xd0a4, 0x0040, 0x59ca, 0xd08c, 0x0040, 0x59ca, 0xa006, + 0x0078, 0x59cc, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x0e7e, 0x0d7e, + 0x0c7e, 0x077e, 0x057e, 0x047e, 0x027e, 0x007e, 0x127e, 0x2091, + 0x8000, 0x2029, 0x6f19, 0x252c, 0x2021, 0x6f1f, 0x2424, 0x2061, + 0x7400, 0x2071, 0x6d00, 0x7244, 0x7060, 0xa202, 0x00c8, 0x5a23, + 0x1078, 0x6c0f, 0x0040, 0x5a1b, 0x671c, 0xa786, 0x0001, 0x0040, + 0x5a1b, 0xa786, 0x0007, 0x0040, 0x5a1b, 0x2500, 0xac06, 0x0040, + 0x5a1b, 0x2400, 0xac06, 0x0040, 0x5a1b, 0x0c7e, 0x6010, 0x2068, + 0x1078, 0x6120, 0x0040, 0x5a11, 0xa786, 0x0003, 0x00c0, 0x5a2d, + 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x36a1, 0x1078, + 0x6276, 0x6000, 0xa086, 0x0004, 0x00c0, 0x5a18, 0x1078, 0x15f2, + 0x1078, 0x6283, 0x0c7f, 0xace0, 0x0008, 0x7054, 0xac02, 0x00c8, + 0x5a23, 0x0078, 0x59e3, 0x127f, 0x007f, 0x027f, 0x047f, 0x057f, + 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0, + 0x5a08, 0x1078, 0x6bb3, 0x0078, 0x5a11, 0x220c, 0x2304, 0xa106, + 0x00c0, 0x5a40, 0x8210, 0x8318, 0x00f0, 0x5a35, 0xa006, 0x007c, + 0x2304, 0xa102, 0x0048, 0x5a48, 0x2001, 0x0001, 0x0078, 0x5a4a, + 0x2001, 0x0000, 0xa18d, 0x0001, 0x007c, 0x6004, 0xa08a, 0x0024, + 0x10c8, 0x12b7, 0xa08e, 0x0000, 0x0040, 0x5a71, 0xa08e, 0x0002, + 0x0040, 0x5a68, 0xa08e, 0x0003, 0x0040, 0x5a68, 0xa08e, 0x0004, + 0x0040, 0x5a68, 0xa08e, 0x001f, 0x0040, 0x5a71, 0x0078, 0x5a6a, + 0x1078, 0x206f, 0x1078, 0x4671, 0x1078, 0x556a, 0x1078, 0x476a, + 0x007c, 0x1078, 0x5778, 0x0078, 0x5a6a, 0xa182, 0x0040, 0x0079, + 0x5a79, 0x5a88, 0x5a88, 0x5a88, 0x5a88, 0x5a88, 0x5a88, 0x5a88, + 0x5a88, 0x5a88, 0x5a88, 0x5a88, 0x5a8a, 0x5a8a, 0x5a8a, 0x5a8a, + 0x1078, 0x12b7, 0x6003, 0x0001, 0x6106, 0x1078, 0x4327, 0x127e, + 0x2091, 0x8000, 0x1078, 0x476a, 0x127f, 0x007c, 0xa186, 0x0013, + 0x00c0, 0x5a9f, 0x6004, 0xa082, 0x0040, 0x0079, 0x5adf, 0xa186, + 0x0014, 0x10c0, 0x12b7, 0x6004, 0xa082, 0x0040, 0x0079, 0x5aa8, + 0x5ab9, 0x5ab7, 0x5ab7, 0x5ab7, 0x5ab7, 0x5ab7, 0x5ab7, 0x5ab7, + 0x5ab7, 0x5ab7, 0x5ab7, 0x5ad4, 0x5ad4, 0x5ad4, 0x5ad4, 0x1078, + 0x12b7, 0x2001, 0x0007, 0x1078, 0x33f3, 0x1078, 0x4671, 0x0d7e, + 0x6110, 0x2168, 0x1078, 0x6120, 0x0040, 0x5ace, 0x6837, 0x0103, + 0x684b, 0x0028, 0x1078, 0x36a1, 0x1078, 0x6276, 0x0d7f, 0x1078, + 0x556a, 0x1078, 0x476a, 0x007c, 0x2001, 0x0007, 0x1078, 0x33f3, + 0x1078, 0x4671, 0x1078, 0x556a, 0x1078, 0x476a, 0x007c, 0x5af0, + 0x5aee, 0x5aee, 0x5aee, 0x5aee, 0x5aee, 0x5aee, 0x5aee, 0x5aee, + 0x5aee, 0x5aee, 0x5afe, 0x5afe, 0x5afe, 0x5afe, 0x1078, 0x12b7, + 0x1078, 0x4671, 0x6003, 0x0002, 0x1078, 0x476a, 0x6010, 0xa088, + 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x007c, 0x1078, 0x4671, + 0x6003, 0x000f, 0x1078, 0x476a, 0x007c, 0xa182, 0x0040, 0x0079, + 0x5b09, 0x5b18, 0x5b18, 0x5b18, 0x5b18, 0x5b18, 0x5b1a, 0x5b98, + 0x5bb0, 0x5b18, 0x5b18, 0x5b18, 0x5b18, 0x5b18, 0x5b18, 0x5b18, + 0x1078, 0x12b7, 0x0e7e, 0x0d7e, 0x2071, 0x728c, 0x6110, 0x2168, + 0x7614, 0xa6b4, 0x0fff, 0x86ff, 0x0040, 0x5b87, 0xa68c, 0x00ff, + 0xa186, 0x0002, 0x0040, 0x5b4c, 0xa186, 0x0028, 0x00c0, 0x5b36, + 0x1078, 0x628a, 0x684b, 0x001c, 0x0078, 0x5b4e, 0xd6dc, 0x0040, + 0x5b41, 0x684b, 0x0015, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0x0078, + 0x5b4e, 0xd6d4, 0x0040, 0x5b4c, 0x684b, 0x0007, 0x7318, 0x6b62, + 0x731c, 0x6b5e, 0x0078, 0x5b4e, 0x684b, 0x0000, 0x6837, 0x0103, + 0x6e46, 0xa01e, 0xd6c4, 0x0040, 0x5b61, 0x7328, 0x732c, 0x6b56, + 0x037e, 0x2308, 0x2019, 0x7298, 0xad90, 0x0019, 0x1078, 0x5f4c, + 0x037f, 0xd6cc, 0x0040, 0x5b8c, 0x7124, 0x695a, 0xa192, 0x0021, + 0x00c8, 0x5b75, 0x2071, 0x7298, 0x831c, 0x2300, 0xae18, 0xad90, + 0x001d, 0x1078, 0x5f4c, 0x0078, 0x5b8c, 0x6838, 0xd0fc, 0x0040, + 0x5b7e, 0x2009, 0x0020, 0x695a, 0x0078, 0x5b6a, 0x0f7e, 0x2d78, + 0x1078, 0x5ee4, 0x0f7f, 0x1078, 0x5f39, 0x0078, 0x5b8e, 0x684b, + 0x0000, 0x6837, 0x0103, 0x6e46, 0x1078, 0x36a1, 0x6218, 0x2268, + 0x6a3c, 0x8211, 0x6a3e, 0x0d7f, 0x0e7f, 0x1078, 0x556a, 0x007c, + 0x0f7e, 0x6003, 0x0003, 0x2079, 0x728c, 0x7c04, 0x7b00, 0x7e0c, + 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x0f7f, + 0x2c10, 0x1078, 0x17de, 0x1078, 0x4395, 0x1078, 0x4821, 0x007c, + 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, + 0x1078, 0x1532, 0x007c, 0xa182, 0x0040, 0x0079, 0x5bbf, 0x5bce, + 0x5bce, 0x5bce, 0x5bce, 0x5bce, 0x5bd0, 0x5c5e, 0x5bce, 0x5bce, + 0x5c74, 0x5cb4, 0x5bce, 0x5bce, 0x5bce, 0x5bce, 0x1078, 0x12b7, + 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071, 0x728c, 0x6110, 0x2178, + 0x7614, 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, + 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x5c59, 0xa694, + 0xff00, 0xa284, 0x0c00, 0x0040, 0x5bf1, 0x7018, 0x7862, 0x701c, + 0x785e, 0xa284, 0x0300, 0x0040, 0x5c59, 0x1078, 0x130f, 0x1040, + 0x12b7, 0x2d00, 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, + 0x7838, 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, + 0x00ff, 0xa186, 0x0002, 0x0040, 0x5c2b, 0xa186, 0x0028, 0x00c0, + 0x5c15, 0x684b, 0x001c, 0x0078, 0x5c2d, 0xd6dc, 0x0040, 0x5c20, + 0x684b, 0x0015, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0x0078, 0x5c2d, + 0xd6d4, 0x0040, 0x5c2b, 0x684b, 0x0007, 0x7318, 0x6b62, 0x731c, + 0x6b5e, 0x0078, 0x5c2d, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, + 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x5c42, 0x7328, 0x732c, + 0x6b56, 0x037e, 0x2308, 0x2019, 0x7298, 0xad90, 0x0019, 0x1078, + 0x5f4c, 0x037f, 0xd6cc, 0x0040, 0x5c59, 0x7124, 0x695a, 0xa192, + 0x0021, 0x00c8, 0x5c56, 0x2071, 0x7298, 0x831c, 0x2300, 0xae18, + 0xad90, 0x001d, 0x1078, 0x5f4c, 0x0078, 0x5c59, 0x2d78, 0x1078, + 0x5ee4, 0x0d7f, 0x0e7f, 0x0f7f, 0x077f, 0x007c, 0x0f7e, 0x6003, + 0x0003, 0x2079, 0x728c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, + 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x0f7f, 0x2c10, 0x1078, + 0x17de, 0x1078, 0x4fca, 0x007c, 0x0d7e, 0x6003, 0x0002, 0x1078, + 0x4719, 0x1078, 0x4821, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040, + 0x5cb2, 0xd1cc, 0x0040, 0x5c8d, 0x6948, 0x017e, 0x1078, 0x1338, + 0x0d7f, 0x1078, 0x5f39, 0x0078, 0x5cb0, 0x6837, 0x0103, 0x6944, + 0xa184, 0x00ff, 0xa186, 0x0002, 0x0040, 0x5cac, 0xa086, 0x0028, + 0x00c0, 0x5c9e, 0x684b, 0x001c, 0x0078, 0x5cae, 0xd1dc, 0x0040, + 0x5ca5, 0x684b, 0x0015, 0x0078, 0x5cae, 0xd1d4, 0x0040, 0x5cac, + 0x684b, 0x0007, 0x0078, 0x5cae, 0x684b, 0x0000, 0x1078, 0x36a1, + 0x1078, 0x556a, 0x0d7f, 0x007c, 0x2001, 0x0007, 0x1078, 0x33f3, + 0x1078, 0x4719, 0x0f7e, 0x0d7e, 0x6110, 0x2178, 0x1078, 0x6120, + 0x0040, 0x5ccb, 0x7837, 0x0103, 0x784b, 0x0028, 0x2f68, 0x1078, + 0x36a1, 0x1078, 0x6276, 0x0d7f, 0x0f7f, 0x1078, 0x556a, 0x1078, + 0x4821, 0x007c, 0xa182, 0x0040, 0x0079, 0x5cd6, 0x5ce5, 0x5ce5, + 0x5ce5, 0x5ce5, 0x5ce5, 0x5ce7, 0x5ce5, 0x5d82, 0x5d8a, 0x5ce5, + 0x5ce5, 0x5ce5, 0x5ce5, 0x5ce5, 0x5ce5, 0x1078, 0x12b7, 0x077e, + 0x0f7e, 0x0e7e, 0x0d7e, 0x2071, 0x728c, 0x6110, 0x2178, 0x7614, + 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, + 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x5d74, 0xa694, 0xff00, + 0xa284, 0x0c00, 0x0040, 0x5d08, 0x7018, 0x7862, 0x701c, 0x785e, + 0xa284, 0x0300, 0x0040, 0x5d71, 0x1078, 0x130f, 0x1040, 0x12b7, + 0x2d00, 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, + 0x7838, 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, + 0x00ff, 0xa186, 0x0002, 0x0040, 0x5d43, 0xa186, 0x0028, 0x00c0, + 0x5d2d, 0x684b, 0x001c, 0x0078, 0x5d45, 0xd6dc, 0x0040, 0x5d38, + 0x684b, 0x0015, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0x0078, 0x5d45, + 0xd6d4, 0x0040, 0x5d43, 0x684b, 0x0007, 0x7318, 0x6b62, 0x731c, + 0x6b5e, 0x0078, 0x5d45, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, + 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x5d5a, 0x7328, 0x732c, + 0x6b56, 0x037e, 0x2308, 0x2019, 0x7298, 0xad90, 0x0019, 0x1078, + 0x5f4c, 0x037f, 0xd6cc, 0x0040, 0x5d71, 0x7124, 0x695a, 0xa192, + 0x0021, 0x00c8, 0x5d6e, 0x2071, 0x7298, 0x831c, 0x2300, 0xae18, + 0xad90, 0x001d, 0x1078, 0x5f4c, 0x0078, 0x5d71, 0x2d78, 0x1078, + 0x5ee4, 0xd6dc, 0x00c0, 0x5d77, 0xa006, 0x0078, 0x5d7b, 0x2001, + 0x0001, 0x7218, 0x731c, 0x1078, 0x156f, 0x0d7f, 0x0e7f, 0x0f7f, + 0x077f, 0x007c, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, + 0x1532, 0x007c, 0x0d7e, 0x6003, 0x0002, 0x6110, 0x2168, 0x694c, + 0xd1e4, 0x0040, 0x5dc4, 0xd1cc, 0x0040, 0x5d9f, 0x6948, 0x017e, + 0x1078, 0x1338, 0x0d7f, 0x1078, 0x5f39, 0x0078, 0x5dc2, 0x6837, + 0x0103, 0x6944, 0xa184, 0x00ff, 0xa186, 0x0002, 0x0040, 0x5dbe, + 0xa086, 0x0028, 0x00c0, 0x5db0, 0x684b, 0x001c, 0x0078, 0x5dc0, + 0xd1dc, 0x0040, 0x5db7, 0x684b, 0x0015, 0x0078, 0x5dc0, 0xd1d4, + 0x0040, 0x5dbe, 0x684b, 0x0007, 0x0078, 0x5dc0, 0x684b, 0x0000, + 0x1078, 0x36a1, 0x1078, 0x556a, 0x0d7f, 0x007c, 0x1078, 0x4671, + 0x0078, 0x5dcc, 0x1078, 0x4719, 0x1078, 0x6120, 0x0040, 0x5de3, + 0x0d7e, 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0x6d0c, 0x210c, + 0xd18c, 0x00c0, 0x5dec, 0xd184, 0x00c0, 0x5de8, 0x6108, 0x694a, + 0x1078, 0x36a1, 0x0d7f, 0x1078, 0x556a, 0x1078, 0x476a, 0x007c, + 0x684b, 0x0004, 0x0078, 0x5de0, 0x684b, 0x0004, 0x0078, 0x5de0, + 0xa182, 0x0040, 0x0079, 0x5df4, 0x5e03, 0x5e03, 0x5e03, 0x5e03, + 0x5e03, 0x5e05, 0x5e03, 0x5e08, 0x5e03, 0x5e03, 0x5e03, 0x5e03, + 0x5e03, 0x5e03, 0x5e03, 0x1078, 0x12b7, 0x1078, 0x556a, 0x007c, + 0x007e, 0x027e, 0xa016, 0x1078, 0x1532, 0x027f, 0x007f, 0x007c, + 0xa182, 0x0025, 0x0079, 0x5e14, 0x5e1d, 0x5e1b, 0x5e1b, 0x5e1b, + 0x5e1b, 0x5e1b, 0x5e1b, 0x1078, 0x12b7, 0x6003, 0x0001, 0x6106, + 0x1078, 0x4327, 0x127e, 0x2091, 0x8000, 0x1078, 0x476a, 0x127f, + 0x007c, 0xa186, 0x0013, 0x00c0, 0x5e33, 0x6004, 0xa082, 0x0025, + 0x2008, 0x0079, 0x5e74, 0xa186, 0x0014, 0x00c0, 0x5e70, 0x1078, + 0x4671, 0x2001, 0x0007, 0x1078, 0x33f3, 0x6018, 0xa080, 0x0028, + 0x200c, 0x017e, 0x027e, 0x037e, 0x2110, 0x2019, 0x0028, 0x1078, + 0x445c, 0x1078, 0x43a9, 0x0c7e, 0x6018, 0xa065, 0x0040, 0x5e52, + 0x1078, 0x35cf, 0x0c7f, 0x2c08, 0x1078, 0x6a57, 0x037f, 0x027f, + 0x017f, 0x1078, 0x342f, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x6120, + 0x0040, 0x5e6a, 0x6837, 0x0103, 0x684b, 0x0006, 0x1078, 0x36a1, + 0x1078, 0x6276, 0x0d7f, 0x1078, 0x556a, 0x1078, 0x476a, 0x007c, + 0x1078, 0x559f, 0x0078, 0x5e6f, 0x5e7d, 0x5e7b, 0x5e7b, 0x5e7b, + 0x5e7b, 0x5e7b, 0x5e86, 0x1078, 0x12b7, 0x1078, 0x4671, 0x6017, + 0x0014, 0x6003, 0x000c, 0x1078, 0x476a, 0x007c, 0x1078, 0x4671, + 0x6017, 0x0014, 0x6003, 0x000e, 0x1078, 0x476a, 0x007c, 0xa182, + 0x002c, 0x00c8, 0x5e99, 0xa182, 0x0025, 0x0048, 0x5e99, 0x0079, + 0x5e9c, 0x1078, 0x559f, 0x007c, 0x5ea3, 0x5ea3, 0x5ea3, 0x5ea3, + 0x5ea5, 0x5ebf, 0x5ea3, 0x1078, 0x12b7, 0x0d7e, 0x1078, 0x6276, + 0x6010, 0x2068, 0x6837, 0x0103, 0x6850, 0xa084, 0x0040, 0x0040, + 0x5eb5, 0x684b, 0x0006, 0x0078, 0x5eb7, 0x684b, 0x0005, 0x6847, + 0x0000, 0x1078, 0x36a1, 0x1078, 0x556a, 0x0d7f, 0x007c, 0x0d7e, + 0x6010, 0x2068, 0x1078, 0x6120, 0x0040, 0x5ed9, 0x6837, 0x0103, + 0x6850, 0xa084, 0x0040, 0x0040, 0x5ed1, 0x684b, 0x0006, 0x0078, + 0x5ed3, 0x684b, 0x0005, 0x6847, 0x0000, 0x1078, 0x36a1, 0x1078, + 0x6276, 0x0d7f, 0x1078, 0x556a, 0x007c, 0x1078, 0x4671, 0x1078, + 0x556a, 0x1078, 0x476a, 0x007c, 0x057e, 0x067e, 0x0d7e, 0x0f7e, + 0x2029, 0x0001, 0xa182, 0x0101, 0x00c8, 0x5ef0, 0x0078, 0x5ef2, + 0x2009, 0x0100, 0x2130, 0x2069, 0x7298, 0x831c, 0x2300, 0xad18, + 0x2009, 0x0020, 0xaf90, 0x001d, 0x1078, 0x5f4c, 0xa6b2, 0x0020, + 0x7804, 0xa06d, 0x0040, 0x5f06, 0x1078, 0x1338, 0x1078, 0x130f, + 0x0040, 0x5f30, 0x8528, 0x6837, 0x0110, 0x683b, 0x0000, 0x2d20, + 0x7c06, 0xa68a, 0x003d, 0x00c8, 0x5f1c, 0x2608, 0xad90, 0x000f, + 0x1078, 0x5f4c, 0x0078, 0x5f30, 0xa6b2, 0x003c, 0x2009, 0x003c, + 0x2d78, 0xad90, 0x000f, 0x1078, 0x5f4c, 0x0078, 0x5f06, 0x0f7f, + 0x852f, 0xa5ad, 0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0078, 0x5f35, + 0x0f7f, 0x852f, 0xa5ad, 0x0003, 0x7d36, 0x0d7f, 0x067f, 0x057f, + 0x007c, 0x0f7e, 0x8dff, 0x0040, 0x5f4a, 0x6804, 0xa07d, 0x0040, + 0x5f48, 0x6807, 0x0000, 0x1078, 0x36a1, 0x2f68, 0x0078, 0x5f3d, + 0x1078, 0x36a1, 0x0f7f, 0x007c, 0x157e, 0xa184, 0x0001, 0x0040, + 0x5f52, 0x8108, 0x810c, 0x21a8, 0x2304, 0x8007, 0x2012, 0x8318, + 0x8210, 0x00f0, 0x5f54, 0x157f, 0x007c, 0x127e, 0x2091, 0x8000, + 0x601c, 0xa084, 0x000f, 0x1079, 0x5f67, 0x127f, 0x007c, 0x5f76, + 0x5f6f, 0x5f71, 0x5f8d, 0x5f6f, 0x5f71, 0x5f71, 0x5f71, 0x1078, + 0x12b7, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0x0d7e, 0x6010, + 0x2068, 0x1078, 0x6120, 0x0040, 0x5f8a, 0xa00e, 0x2001, 0x0005, + 0x1078, 0x372d, 0x1078, 0x36a1, 0x1078, 0x556a, 0xa085, 0x0001, + 0x0d7f, 0x007c, 0xa006, 0x0078, 0x5f88, 0x6000, 0xa08a, 0x0010, + 0x10c8, 0x12b7, 0x1079, 0x5f95, 0x007c, 0x5fa5, 0x5fc4, 0x5fa7, + 0x5fd5, 0x5fc0, 0x5fa5, 0x5f71, 0x5f76, 0x5f76, 0x5f71, 0x5f71, + 0x5f71, 0x5f71, 0x5f71, 0x5f71, 0x5f71, 0x1078, 0x12b7, 0x0d7e, + 0x6010, 0x2068, 0x1078, 0x6120, 0x0040, 0x5fb2, 0x6850, 0xa085, + 0x0005, 0x6852, 0x0d7f, 0x6007, 0x0025, 0x6003, 0x000b, 0x601f, + 0x0002, 0x1078, 0x4327, 0x1078, 0x476a, 0xa085, 0x0001, 0x007c, + 0x1078, 0x15f2, 0x0078, 0x5fa7, 0x0e7e, 0x2071, 0x6f10, 0x7024, + 0xac06, 0x00c0, 0x5fcd, 0x1078, 0x5148, 0x1078, 0x5083, 0x0e7f, + 0x00c0, 0x5fa7, 0x1078, 0x5f71, 0x007c, 0x037e, 0x0e7e, 0x2071, + 0x6f10, 0x703c, 0xac06, 0x00c0, 0x5fe1, 0x2019, 0x0000, 0x1078, + 0x51da, 0x1078, 0x54b6, 0x0e7f, 0x037f, 0x00c0, 0x5fa7, 0x1078, + 0x5f71, 0x007c, 0x0c7e, 0x601c, 0xa084, 0x000f, 0x1079, 0x5ff2, + 0x0c7f, 0x007c, 0x5ffb, 0x605b, 0x60c8, 0x5fff, 0x5ffb, 0x5ffb, + 0x5ffb, 0x556a, 0x605b, 0x007c, 0x6017, 0x0001, 0x007c, 0x6000, + 0xa08a, 0x0010, 0x10c8, 0x12b7, 0x1079, 0x6007, 0x007c, 0x6017, + 0x6019, 0x603a, 0x604d, 0x604d, 0x6017, 0x5ffb, 0x5ffb, 0x5ffb, + 0x604d, 0x604d, 0x6017, 0x6017, 0x6017, 0x6017, 0x6058, 0x1078, + 0x12b7, 0x0e7e, 0x6010, 0x2070, 0x7050, 0xa085, 0x0040, 0x7052, + 0x2071, 0x6f10, 0x7024, 0xac06, 0x0040, 0x6036, 0x1078, 0x5083, + 0x6007, 0x0025, 0x6003, 0x000b, 0x601f, 0x0002, 0x6017, 0x0014, + 0x1078, 0x4327, 0x1078, 0x476a, 0x0e7f, 0x007c, 0x6017, 0x0001, + 0x0078, 0x6034, 0x0d7e, 0x6010, 0x2068, 0x6850, 0xa085, 0x0040, + 0x6852, 0x0d7f, 0x6007, 0x0025, 0x6003, 0x000b, 0x601f, 0x0002, + 0x1078, 0x4327, 0x1078, 0x476a, 0x007c, 0x0d7e, 0x6017, 0x0001, + 0x6010, 0x2068, 0x6850, 0xa085, 0x0040, 0x6852, 0x0d7f, 0x007c, + 0x1078, 0x556a, 0x007c, 0x6000, 0xa08a, 0x0010, 0x10c8, 0x12b7, + 0x1079, 0x6063, 0x007c, 0x6073, 0x5ffc, 0x6075, 0x6073, 0x6075, + 0x6073, 0x6073, 0x6073, 0x5ffb, 0x5ffb, 0x6073, 0x6073, 0x6073, + 0x6073, 0x6073, 0x6073, 0x1078, 0x12b7, 0x0d7e, 0x6018, 0x2068, + 0x6804, 0xa084, 0x00ff, 0x0d7f, 0xa08a, 0x000c, 0x10c8, 0x12b7, + 0x1079, 0x6083, 0x007c, 0x608f, 0x60b1, 0x608f, 0x60b1, 0x608f, + 0x60b1, 0x6091, 0x609a, 0x608f, 0x60b1, 0x608f, 0x60aa, 0x1078, + 0x12b7, 0x6004, 0xa08e, 0x0004, 0x0040, 0x60ac, 0xa08e, 0x0002, + 0x0040, 0x60ac, 0xa08e, 0x0000, 0x0040, 0x60c0, 0xa08e, 0x001f, + 0x0040, 0x60c0, 0xa08e, 0x0021, 0x0040, 0x60c4, 0xa08e, 0x0022, + 0x0040, 0x60c0, 0x1078, 0x2051, 0x1078, 0x5778, 0x1078, 0x556a, + 0x007c, 0x1078, 0x5778, 0x1078, 0x2051, 0x0e7e, 0x127e, 0x2091, + 0x8000, 0x1078, 0x206f, 0x127f, 0x0e7f, 0x1078, 0x556a, 0x007c, + 0x1078, 0x5778, 0x0078, 0x60ac, 0x1078, 0x5786, 0x0078, 0x60ac, + 0x6000, 0xa08a, 0x0010, 0x10c8, 0x12b7, 0x1079, 0x60d0, 0x007c, + 0x60e0, 0x60e0, 0x60e0, 0x60e0, 0x60e0, 0x60e0, 0x60e0, 0x60e0, + 0x60e0, 0x5ffb, 0x60e0, 0x5ffc, 0x60e2, 0x5ffc, 0x60eb, 0x60e0, + 0x1078, 0x12b7, 0x6007, 0x002b, 0x6003, 0x000d, 0x1078, 0x4327, + 0x1078, 0x476a, 0x007c, 0x1078, 0x6276, 0x1078, 0x6120, 0x0040, + 0x6109, 0x1078, 0x2051, 0x0d7e, 0x6010, 0x2068, 0x6837, 0x0103, + 0x684b, 0x0006, 0x1078, 0x36a1, 0x0d7f, 0x601f, 0x0001, 0x6007, + 0x0001, 0x6003, 0x0001, 0x1078, 0x4376, 0x1078, 0x476a, 0x0078, + 0x610b, 0x1078, 0x556a, 0x007c, 0xa284, 0x0007, 0x00c0, 0x611d, + 0xa282, 0x7400, 0x0048, 0x611d, 0x2001, 0x6d15, 0x2004, 0xa202, + 0x00c8, 0x611d, 0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x611c, + 0x027e, 0x0e7e, 0x2071, 0x6d00, 0x6210, 0x7058, 0xa202, 0x0048, + 0x6132, 0x705c, 0xa202, 0x00c8, 0x6132, 0xa085, 0x0001, 0x0e7f, + 0x027f, 0x007c, 0xa006, 0x0078, 0x612f, 0x0e7e, 0x0c7e, 0x037e, + 0x007e, 0x127e, 0x2091, 0x8000, 0x2061, 0x7400, 0x2071, 0x6d00, + 0x7344, 0x7060, 0xa302, 0x00c8, 0x6155, 0x601c, 0xa206, 0x00c0, + 0x614d, 0x0c7e, 0x1078, 0x556a, 0x0c7f, 0xace0, 0x0008, 0x7054, + 0xac02, 0x00c8, 0x6155, 0x0078, 0x6140, 0x127f, 0x007f, 0x037f, + 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e, 0x017e, 0x127e, 0x2091, + 0x8000, 0xa188, 0x6e00, 0x210c, 0x81ff, 0x0040, 0x6182, 0x2061, + 0x7400, 0x2071, 0x6d00, 0x7344, 0x7060, 0xa302, 0x00c8, 0x6182, + 0x6018, 0xa106, 0x00c0, 0x617c, 0x1078, 0x2051, 0x017e, 0x0c7e, + 0x1078, 0x556a, 0x0c7f, 0x017f, 0xace0, 0x0008, 0x7054, 0xac02, + 0x0048, 0x6170, 0x127f, 0x017f, 0x0c7f, 0x0e7f, 0x007c, 0x0c7e, + 0x057e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x5504, 0x057f, + 0x0040, 0x61a0, 0x6612, 0x651a, 0x601f, 0x0003, 0x2009, 0x004b, + 0x1078, 0x5591, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c, + 0xa006, 0x0078, 0x619c, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, + 0x62a0, 0x0c7e, 0x1078, 0x5504, 0x057f, 0x0040, 0x61ca, 0x6013, + 0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e, 0x2560, 0x1078, 0x35cf, + 0x0c7f, 0x1078, 0x445c, 0x1078, 0x43a9, 0x2c08, 0x1078, 0x6a57, + 0x2009, 0x004c, 0x1078, 0x5591, 0xa085, 0x0001, 0x127f, 0x057f, + 0x0c7f, 0x007c, 0xa006, 0x0078, 0x61c6, 0x0c7e, 0x057e, 0x127e, + 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078, 0x5504, 0x057f, 0x0040, + 0x61f5, 0x6612, 0x651a, 0x601f, 0x0003, 0x2019, 0x0005, 0x0c7e, + 0x2560, 0x1078, 0x35cf, 0x0c7f, 0x1078, 0x445c, 0x1078, 0x43a9, + 0x2c08, 0x1078, 0x6a57, 0x2009, 0x004d, 0x1078, 0x5591, 0xa085, + 0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x61f1, + 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078, + 0x5504, 0x057f, 0x0040, 0x6220, 0x6612, 0x651a, 0x601f, 0x0003, + 0x2019, 0x0005, 0x0c7e, 0x2560, 0x1078, 0x35cf, 0x0c7f, 0x1078, + 0x445c, 0x1078, 0x43a9, 0x2c08, 0x1078, 0x6a57, 0x2009, 0x004e, + 0x1078, 0x5591, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c, + 0xa006, 0x0078, 0x621c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, + 0x1078, 0x5504, 0x017f, 0x0040, 0x623c, 0x660a, 0x611a, 0x601f, + 0x0001, 0x2d00, 0x6012, 0x2009, 0x001f, 0x1078, 0x5591, 0xa085, + 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6239, 0x0c7e, + 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x5504, 0x017f, 0x0040, + 0x6258, 0x660a, 0x611a, 0x601f, 0x0008, 0x2d00, 0x6012, 0x2009, + 0x0021, 0x1078, 0x5591, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, + 0xa006, 0x0078, 0x6255, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, + 0x1078, 0x5504, 0x017f, 0x0040, 0x6273, 0x611a, 0x601f, 0x0001, + 0x2d00, 0x6012, 0x2009, 0x0000, 0x1078, 0x5591, 0xa085, 0x0001, + 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6270, 0x027e, 0x0d7e, + 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0040, 0x6280, 0x8211, 0x6a3e, + 0x0d7f, 0x027f, 0x007c, 0x6013, 0x0000, 0x601f, 0x0007, 0x6017, + 0x0014, 0x007c, 0x067e, 0x0c7e, 0x2031, 0x6d52, 0x2634, 0xd6e4, + 0x0040, 0x6297, 0x6618, 0x2660, 0x6e44, 0x1078, 0x3507, 0x0c7f, + 0x067f, 0x007c, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12b7, + 0x1079, 0x62a4, 0x067f, 0x007c, 0x62b4, 0x640b, 0x64d4, 0x62b4, + 0x62b4, 0x62b4, 0x62b4, 0x62b4, 0x62ee, 0x6542, 0x62b4, 0x62b4, + 0x62b4, 0x62b4, 0x62b4, 0x62b4, 0x1078, 0x12b7, 0x067e, 0x6000, + 0xa0b2, 0x0010, 0x10c8, 0x12b7, 0x1079, 0x62c0, 0x067f, 0x007c, + 0x62d0, 0x6837, 0x62d0, 0x62d0, 0x62d0, 0x62d0, 0x62d0, 0x62d0, + 0x6812, 0x687d, 0x62d0, 0x62d0, 0x62d0, 0x62d0, 0x62d0, 0x62d0, + 0x1078, 0x12b7, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12b7, + 0x1079, 0x62dc, 0x067f, 0x007c, 0x62ec, 0x668f, 0x66fb, 0x671c, + 0x6769, 0x62ec, 0x62ec, 0x67be, 0x654e, 0x67fa, 0x67fe, 0x62ec, + 0x62ec, 0x62ec, 0x62ec, 0x62ec, 0x1078, 0x12b7, 0xa1b2, 0x0024, + 0x10c8, 0x12b7, 0x2100, 0x0079, 0x62f5, 0x6319, 0x63f5, 0x6319, + 0x6319, 0x6319, 0x6319, 0x6319, 0x6319, 0x6319, 0x6319, 0x6319, + 0x6319, 0x6319, 0x6319, 0x6319, 0x6319, 0x6319, 0x6319, 0x6319, + 0x6319, 0x6319, 0x6319, 0x6319, 0x631b, 0x634a, 0x6354, 0x637c, + 0x6382, 0x63b6, 0x63ee, 0x6319, 0x6319, 0x63fd, 0x6319, 0x6319, + 0x6404, 0x1078, 0x12b7, 0x1078, 0x364d, 0x6618, 0x0c7e, 0x2660, + 0x1078, 0x3459, 0x0c7f, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, + 0xa082, 0x0006, 0x0048, 0x633c, 0x1078, 0x6993, 0x00c0, 0x6376, + 0x1078, 0x6931, 0x00c0, 0x6338, 0x6007, 0x0008, 0x0078, 0x63f0, + 0x6007, 0x0009, 0x0078, 0x63f0, 0x1078, 0x6b02, 0x0040, 0x6346, + 0x1078, 0x6993, 0x0040, 0x6330, 0x0078, 0x6376, 0x6013, 0x1900, + 0x0078, 0x6338, 0x1078, 0x68b7, 0x6007, 0x0006, 0x0078, 0x63f0, + 0x6007, 0x0007, 0x0078, 0x63f0, 0x0d7e, 0x6618, 0x2668, 0x6e04, + 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x6366, 0xa686, + 0x0004, 0x0040, 0x6366, 0x0d7f, 0x0078, 0x6376, 0x1078, 0x69f1, + 0x00c0, 0x6371, 0x1078, 0x34ca, 0x6007, 0x000a, 0x0d7f, 0x0078, + 0x63f0, 0x6007, 0x000b, 0x0d7f, 0x0078, 0x63f0, 0x1078, 0x2051, + 0x6007, 0x0001, 0x0078, 0x63f0, 0x1078, 0x2051, 0x6007, 0x000c, + 0x0078, 0x63f0, 0x1078, 0x364d, 0x6618, 0xa6b0, 0x0001, 0x2634, + 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x63a3, 0xa6b4, 0xff00, + 0x8637, 0xa686, 0x0006, 0x00c0, 0x6376, 0x1078, 0x6a00, 0x00c0, + 0x639d, 0x6007, 0x000e, 0x0078, 0x63f0, 0x1078, 0x2051, 0x6007, + 0x000f, 0x0078, 0x63f0, 0x1078, 0x6b02, 0x0040, 0x63b0, 0xa6b4, + 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x6395, 0x0078, 0x6376, + 0x6013, 0x1900, 0x6007, 0x0009, 0x0078, 0x63f0, 0x1078, 0x364d, + 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, + 0x0048, 0x63db, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x00c0, + 0x6376, 0x1078, 0x6a2b, 0x00c0, 0x63d5, 0x1078, 0x6931, 0x00c0, + 0x63d5, 0x6007, 0x0010, 0x0078, 0x63f0, 0x1078, 0x2051, 0x6007, + 0x0011, 0x0078, 0x63f0, 0x1078, 0x6b02, 0x0040, 0x63e8, 0xa6b4, + 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x63c9, 0x0078, 0x6376, + 0x6013, 0x1900, 0x6007, 0x0009, 0x0078, 0x63f0, 0x6007, 0x0012, + 0x6003, 0x0001, 0x1078, 0x4376, 0x007c, 0x6007, 0x0001, 0x6003, + 0x0001, 0x1078, 0x4376, 0x0078, 0x63f4, 0x6007, 0x0020, 0x6003, + 0x0001, 0x1078, 0x4376, 0x007c, 0x6007, 0x0023, 0x6003, 0x0001, + 0x1078, 0x4376, 0x007c, 0x6004, 0xa0b2, 0x0024, 0x10c8, 0x12b7, + 0xa1b6, 0x0013, 0x00c0, 0x6417, 0x2008, 0x0079, 0x6426, 0xa1b6, + 0x0014, 0x10c0, 0x12b7, 0x2001, 0x0007, 0x1078, 0x3401, 0x1078, + 0x4671, 0x1078, 0x6283, 0x1078, 0x476a, 0x007c, 0x644a, 0x644c, + 0x644a, 0x644a, 0x644a, 0x644c, 0x6454, 0x64af, 0x6472, 0x64af, + 0x6486, 0x64af, 0x6454, 0x64af, 0x64a7, 0x64af, 0x64a7, 0x64af, + 0x64af, 0x644a, 0x644a, 0x644a, 0x644a, 0x644a, 0x644a, 0x644a, + 0x644a, 0x644a, 0x644a, 0x644a, 0x644a, 0x644a, 0x64af, 0x644a, + 0x644a, 0x64af, 0x1078, 0x12b7, 0x1078, 0x4671, 0x6003, 0x0002, + 0x1078, 0x476a, 0x0078, 0x64b5, 0x0f7e, 0x2079, 0x6d51, 0x7804, + 0x0f7f, 0xd0ac, 0x00c0, 0x64af, 0x2001, 0x0000, 0x1078, 0x33df, + 0x2001, 0x0002, 0x1078, 0x33f3, 0x1078, 0x4671, 0x601f, 0x0001, + 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x4376, 0x1078, 0x476a, + 0x0078, 0x64b5, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, + 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x64af, 0xa686, 0x0004, + 0x0040, 0x64af, 0x2001, 0x0004, 0x0078, 0x64ad, 0x2001, 0x6d00, + 0x2004, 0xa086, 0x0003, 0x00c0, 0x648f, 0x1078, 0x2ad1, 0x2001, + 0x0006, 0x1078, 0x64b6, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, + 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x64af, 0x2001, + 0x0006, 0x0078, 0x64ad, 0x2001, 0x0004, 0x0078, 0x64ad, 0x2001, + 0x0006, 0x1078, 0x64b6, 0x0078, 0x64af, 0x1078, 0x3401, 0x1078, + 0x4671, 0x1078, 0x556a, 0x1078, 0x476a, 0x007c, 0x017e, 0x0d7e, + 0x6118, 0x2168, 0x6900, 0xd184, 0x0040, 0x64d1, 0x6104, 0xa18e, + 0x000a, 0x00c0, 0x64c9, 0x699c, 0xd1a4, 0x00c0, 0x64c9, 0x2001, + 0x0007, 0x1078, 0x33f3, 0x2001, 0x0000, 0x1078, 0x33df, 0x1078, + 0x206f, 0x0d7f, 0x017f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, + 0xa084, 0xff00, 0x8007, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x12b7, + 0xa1b6, 0x0015, 0x00c0, 0x64e8, 0x1079, 0x64ef, 0x0078, 0x64ee, + 0xa1b6, 0x0016, 0x10c0, 0x12b7, 0x1079, 0x6527, 0x007c, 0x57ef, + 0x57ef, 0x57ef, 0x57ef, 0x57ef, 0x57ef, 0x57ef, 0x64fb, 0x57ef, + 0x57ef, 0x57ef, 0x57ef, 0x0f7e, 0x2079, 0x6d51, 0x7804, 0x0f7f, + 0xd0ac, 0x00c0, 0x6517, 0x2001, 0x0000, 0x1078, 0x33df, 0x2001, + 0x0002, 0x1078, 0x33f3, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, + 0x0002, 0x1078, 0x4376, 0x1078, 0x476a, 0x0078, 0x6526, 0x2011, + 0x7283, 0x220c, 0x017e, 0x0c7e, 0x1078, 0x3447, 0x00c0, 0x6526, + 0x1078, 0x3256, 0x0c7f, 0x017f, 0x1078, 0x556a, 0x007c, 0x57ef, + 0x57ef, 0x57ef, 0x57ef, 0x57ef, 0x57ef, 0x57ef, 0x6533, 0x57ef, + 0x57ef, 0x57ef, 0x57ef, 0x1078, 0x599c, 0x00c0, 0x653f, 0x6003, + 0x0001, 0x6007, 0x0001, 0x1078, 0x4376, 0x0078, 0x6541, 0x1078, + 0x556a, 0x007c, 0x6004, 0xa08a, 0x0024, 0x10c8, 0x12b7, 0x1078, + 0x4671, 0x1078, 0x6283, 0x1078, 0x476a, 0x007c, 0xa182, 0x0040, + 0x0079, 0x6552, 0x6561, 0x6561, 0x6561, 0x6561, 0x6563, 0x6561, + 0x6561, 0x6561, 0x6561, 0x6561, 0x6561, 0x6561, 0x6561, 0x6561, + 0x6561, 0x1078, 0x12b7, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e, + 0x027e, 0x2071, 0x7280, 0x7444, 0xa4a4, 0xe600, 0x0040, 0x65d4, + 0xa486, 0x2000, 0x0040, 0x6592, 0xa486, 0x0400, 0x0040, 0x6592, + 0x7130, 0xa18c, 0x00ff, 0xa182, 0x0010, 0x00c8, 0x6663, 0x0c7e, + 0x1078, 0x416d, 0x2c68, 0x0c7f, 0x6a00, 0xa284, 0x0001, 0x0040, + 0x6644, 0x1078, 0x420a, 0x0040, 0x666f, 0xa295, 0x0200, 0x6a02, + 0x0078, 0x6598, 0x2009, 0x0001, 0x2011, 0x0200, 0x1078, 0x41f4, + 0x1078, 0x130f, 0x1040, 0x12b7, 0x6003, 0x0007, 0x6106, 0x2d00, + 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, + 0x685e, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0xa18c, 0x00ff, + 0xa10d, 0x6946, 0x684f, 0x0000, 0x6857, 0x0036, 0x1078, 0x36a1, + 0xa486, 0x2000, 0x00c0, 0x65c2, 0x2019, 0x0017, 0x1078, 0x6b8f, + 0x0078, 0x6631, 0xa486, 0x0400, 0x00c0, 0x65cc, 0x2019, 0x0002, + 0x1078, 0x6b8f, 0x0078, 0x6631, 0xa486, 0x0200, 0x00c0, 0x65d2, + 0x1078, 0x6b80, 0x0078, 0x6631, 0x7130, 0xa18c, 0x00ff, 0xa182, + 0x0010, 0x00c8, 0x6687, 0x0c7e, 0x1078, 0x416d, 0x2c68, 0x0c7f, + 0x6a00, 0xa284, 0x0001, 0x0040, 0x668b, 0xa284, 0x0300, 0x00c0, + 0x6683, 0x6804, 0xa005, 0x0040, 0x666f, 0x8001, 0x6806, 0x6003, + 0x0007, 0x6106, 0x1078, 0x12f4, 0x0040, 0x6638, 0x6013, 0x0000, + 0x6803, 0x0000, 0x6837, 0x0116, 0x683b, 0x0000, 0x2c00, 0x684a, + 0x6018, 0x2078, 0x78a0, 0x8007, 0xa10d, 0x6946, 0x6853, 0x003d, + 0x7044, 0xa084, 0x0003, 0xa086, 0x0002, 0x00c0, 0x6613, 0x684f, + 0x0040, 0x0078, 0x661d, 0xa086, 0x0001, 0x00c0, 0x661b, 0x684f, + 0x0080, 0x0078, 0x661d, 0x684f, 0x0000, 0x20a9, 0x000a, 0x2001, + 0x7290, 0xad90, 0x0015, 0x200c, 0x810f, 0x2112, 0x8000, 0x8210, + 0x00f0, 0x6623, 0x200c, 0x6982, 0x8000, 0x200c, 0x697e, 0x1078, + 0x36a1, 0x027f, 0x047f, 0x157f, 0x0f7f, 0x0e7f, 0x0d7f, 0x007c, + 0x6013, 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x4327, + 0x1078, 0x476a, 0x0078, 0x6631, 0x2069, 0x7292, 0x2d04, 0xa084, + 0xff00, 0xa086, 0x1200, 0x00c0, 0x6663, 0x2069, 0x7280, 0x686c, + 0xa084, 0x00ff, 0x017e, 0x6110, 0xa18c, 0x0700, 0xa10d, 0x6112, + 0x017f, 0x6003, 0x0001, 0x6007, 0x0043, 0x1078, 0x4327, 0x1078, + 0x476a, 0x0078, 0x6631, 0x6013, 0x0200, 0x6003, 0x0001, 0x6007, + 0x0041, 0x1078, 0x4327, 0x1078, 0x476a, 0x0078, 0x6631, 0xa284, + 0x0004, 0x00c0, 0x6677, 0x6013, 0x0300, 0x0078, 0x6679, 0x6013, + 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x4327, 0x1078, + 0x476a, 0x0078, 0x6631, 0x6013, 0x0500, 0x0078, 0x6679, 0x6013, + 0x0600, 0x0078, 0x6644, 0x6013, 0x0200, 0x0078, 0x6644, 0xa186, + 0x0013, 0x00c0, 0x66a1, 0x6004, 0xa08a, 0x0040, 0x1048, 0x12b7, + 0xa08a, 0x004f, 0x10c8, 0x12b7, 0xa082, 0x0040, 0x2008, 0x0079, + 0x66cd, 0xa186, 0x0047, 0x00c0, 0x66a7, 0x0078, 0x66fb, 0xa186, + 0x0014, 0x10c0, 0x12b7, 0x6004, 0xa082, 0x0040, 0x2008, 0x0079, + 0x66b1, 0x66c0, 0x66c2, 0x66c2, 0x66c0, 0x66c0, 0x66c0, 0x66c0, + 0x66c0, 0x66c0, 0x66c0, 0x66c0, 0x66c0, 0x66c0, 0x66c0, 0x66c0, + 0x1078, 0x12b7, 0x2001, 0x0007, 0x1078, 0x3401, 0x1078, 0x4671, + 0x1078, 0x6283, 0x1078, 0x476a, 0x007c, 0x66dc, 0x66ec, 0x66e5, + 0x66f5, 0x66dc, 0x66dc, 0x66dc, 0x66dc, 0x66dc, 0x66dc, 0x66dc, + 0x66dc, 0x66dc, 0x66dc, 0x66dc, 0x1078, 0x12b7, 0x6010, 0xa088, + 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x1078, 0x4671, 0x6003, + 0x0002, 0x1078, 0x476a, 0x007c, 0x1078, 0x4671, 0x1078, 0x41cd, + 0x1078, 0x556a, 0x1078, 0x476a, 0x007c, 0x1078, 0x4671, 0x2009, + 0x0041, 0x0078, 0x67be, 0xa182, 0x0040, 0x0079, 0x66ff, 0x670e, + 0x6710, 0x670e, 0x670e, 0x670e, 0x670e, 0x670e, 0x6711, 0x670e, + 0x670e, 0x670e, 0x670e, 0x670e, 0x670e, 0x670e, 0x1078, 0x12b7, + 0x007c, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, + 0x2c10, 0x1078, 0x1532, 0x007c, 0xa182, 0x0040, 0x0079, 0x6720, + 0x672f, 0x672f, 0x672f, 0x672f, 0x672f, 0x672f, 0x672f, 0x672f, + 0x672f, 0x6731, 0x6754, 0x672f, 0x672f, 0x672f, 0x672f, 0x1078, + 0x12b7, 0x1078, 0x4719, 0x1078, 0x4821, 0x6010, 0x0d7e, 0x2068, + 0x684c, 0xd0fc, 0x0040, 0x6747, 0xa08c, 0x0003, 0xa18e, 0x0002, + 0x0040, 0x674d, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x67be, 0x6003, + 0x0007, 0x1078, 0x41cd, 0x0d7f, 0x007c, 0x1078, 0x41cd, 0x1078, + 0x556a, 0x0d7f, 0x0078, 0x674c, 0x2001, 0x0007, 0x1078, 0x3401, + 0x1078, 0x4719, 0x1078, 0x4821, 0x6010, 0x0d7e, 0x2068, 0x037e, + 0x2019, 0x0004, 0x1078, 0x6bb3, 0x037f, 0x1078, 0x6283, 0x0d7f, + 0x007c, 0xa186, 0x0013, 0x00c0, 0x6777, 0x6004, 0xa086, 0x0042, + 0x10c0, 0x12b7, 0x1078, 0x4671, 0x1078, 0x476a, 0x007c, 0xa186, + 0x0014, 0x00c0, 0x678b, 0x6004, 0xa086, 0x0042, 0x10c0, 0x12b7, + 0x2001, 0x0007, 0x1078, 0x3401, 0x1078, 0x4671, 0x1078, 0x6283, + 0x1078, 0x476a, 0x007c, 0xa182, 0x0040, 0x0079, 0x678f, 0x679e, + 0x679e, 0x679e, 0x679e, 0x679e, 0x679e, 0x679e, 0x67a0, 0x67ac, + 0x679e, 0x679e, 0x679e, 0x679e, 0x679e, 0x679e, 0x1078, 0x12b7, + 0x037e, 0x047e, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, + 0x1532, 0x047f, 0x037f, 0x007c, 0x6010, 0x0d7e, 0x2068, 0x684c, + 0xd0fc, 0x0040, 0x67b8, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x67be, + 0x6003, 0x0007, 0x1078, 0x41cd, 0x0d7f, 0x007c, 0xa182, 0x0040, + 0x0079, 0x67c2, 0x67d1, 0x67d3, 0x67df, 0x67eb, 0x67d1, 0x67d1, + 0x67d1, 0x67d1, 0x67d1, 0x67d1, 0x67d1, 0x67d1, 0x67d1, 0x67d1, + 0x67d1, 0x1078, 0x12b7, 0x6003, 0x0001, 0x6106, 0x1078, 0x4327, + 0x127e, 0x2091, 0x8000, 0x1078, 0x476a, 0x127f, 0x007c, 0x6003, + 0x0001, 0x6106, 0x1078, 0x4327, 0x127e, 0x2091, 0x8000, 0x1078, + 0x476a, 0x127f, 0x007c, 0x6003, 0x0003, 0x6106, 0x2c10, 0x1078, + 0x17de, 0x127e, 0x2091, 0x8000, 0x1078, 0x4395, 0x1078, 0x4821, + 0x127f, 0x007c, 0x1078, 0x4671, 0x0078, 0x6800, 0x1078, 0x4719, + 0x6110, 0x81ff, 0x0040, 0x680d, 0x0d7e, 0x2168, 0x037e, 0x2019, + 0x0029, 0x1078, 0x6bb3, 0x037f, 0x0d7f, 0x1078, 0x6283, 0x1078, + 0x476a, 0x007c, 0xa182, 0x0025, 0x0079, 0x6816, 0x681d, 0x681d, + 0x681d, 0x681f, 0x681d, 0x681d, 0x681d, 0x1078, 0x12b7, 0x027e, + 0x0e7e, 0x2071, 0x7280, 0x7220, 0x1078, 0x6ad1, 0x0040, 0x682c, + 0x6007, 0x0026, 0x0078, 0x682e, 0x6007, 0x0027, 0x6003, 0x0001, + 0x1078, 0x4327, 0x1078, 0x476a, 0x0e7f, 0x027f, 0x007c, 0xa186, + 0x0013, 0x00c0, 0x6848, 0x6004, 0xa08a, 0x0025, 0x1048, 0x12b7, + 0xa08a, 0x002c, 0x10c8, 0x12b7, 0xa082, 0x0025, 0x0079, 0x6857, + 0xa186, 0x0014, 0x10c0, 0x12b7, 0x2001, 0x0007, 0x1078, 0x3401, + 0x1078, 0x4671, 0x1078, 0x6283, 0x1078, 0x476a, 0x007c, 0x685e, + 0x6860, 0x6860, 0x685e, 0x685e, 0x685e, 0x685e, 0x1078, 0x12b7, + 0x1078, 0x4671, 0x1078, 0x556a, 0x1078, 0x476a, 0x007c, 0xa182, + 0x0025, 0x1048, 0x12b7, 0xa182, 0x002c, 0x10c8, 0x12b7, 0xa182, + 0x0025, 0x0079, 0x6873, 0x687a, 0x687a, 0x687a, 0x687c, 0x687a, + 0x687a, 0x687a, 0x1078, 0x12b7, 0x007c, 0x1078, 0x4671, 0x1078, + 0x6283, 0x1078, 0x476a, 0x007c, 0x127e, 0x037e, 0x087e, 0x2091, + 0x8000, 0x2c40, 0x2019, 0x0002, 0x1078, 0x5387, 0x00c0, 0x68b3, + 0x1078, 0x5428, 0x00c0, 0x68b3, 0x6000, 0xa086, 0x0000, 0x0040, + 0x68b3, 0x601c, 0xa086, 0x0007, 0x0040, 0x68b3, 0x0d7e, 0x6010, + 0x2068, 0x1078, 0x6120, 0x0040, 0x68a7, 0x1078, 0x6bb3, 0x0d7f, + 0x6000, 0xa086, 0x0004, 0x00c0, 0x68af, 0x1078, 0x15f2, 0x6013, + 0x0000, 0x601f, 0x0007, 0x087f, 0x037f, 0x127f, 0x007c, 0x0f7e, + 0x0c7e, 0x037e, 0x157e, 0x2079, 0x7280, 0x7938, 0x783c, 0x1078, + 0x1e1b, 0x00c0, 0x68e8, 0x017e, 0x0c7e, 0x1078, 0x3447, 0x00c0, + 0x68e8, 0x2011, 0x7290, 0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, + 0x5a35, 0x00c0, 0x68e8, 0x017f, 0x027f, 0x027e, 0x017e, 0x2019, + 0x0029, 0x1078, 0x445c, 0x1078, 0x43a9, 0x017f, 0x1078, 0x6a57, + 0x1078, 0x35cf, 0x017f, 0x1078, 0x3256, 0xa006, 0x0078, 0x68ea, + 0x0c7f, 0x017f, 0x157f, 0x037f, 0x0c7f, 0x0f7f, 0x007c, 0x0e7e, + 0x0d7e, 0x0c7e, 0x047e, 0x037e, 0x027e, 0x2061, 0x7400, 0x2071, + 0x6d00, 0x7444, 0x7060, 0x8001, 0xa402, 0x00c8, 0x6929, 0x2100, + 0xac06, 0x0040, 0x691b, 0x6000, 0xa086, 0x0000, 0x0040, 0x691b, + 0x6018, 0x2068, 0x68a0, 0xa206, 0x00c0, 0x691b, 0x631c, 0xa386, + 0x0004, 0x0040, 0x6925, 0xa386, 0x0005, 0x0040, 0x6925, 0xa386, + 0x0006, 0x0040, 0x6925, 0xace0, 0x0008, 0x2001, 0x6d15, 0x2004, + 0xac02, 0x00c8, 0x6929, 0x0078, 0x68f7, 0xa085, 0x0001, 0x0078, + 0x692a, 0xa006, 0x027f, 0x037f, 0x047f, 0x0c7f, 0x0d7f, 0x0e7f, + 0x007c, 0x0c7e, 0x0d7e, 0x017e, 0x2009, 0x6d1e, 0x2104, 0xa086, + 0x0074, 0x00c0, 0x6988, 0x2069, 0x728e, 0x690c, 0xa182, 0x0100, + 0x0048, 0x6978, 0x6908, 0xa184, 0x8000, 0x0040, 0x6984, 0xa184, + 0x0800, 0x0040, 0x6984, 0x6910, 0xa18a, 0x0001, 0x0048, 0x697c, + 0x6914, 0x2069, 0x72ae, 0x6904, 0x81ff, 0x00c0, 0x6970, 0x690c, + 0xa182, 0x0100, 0x0048, 0x6978, 0x6908, 0x81ff, 0x00c0, 0x6974, + 0x6910, 0xa18a, 0x0001, 0x0048, 0x697c, 0x6918, 0xa18a, 0x0001, + 0x0048, 0x6984, 0x0078, 0x698e, 0x6013, 0x0100, 0x0078, 0x698a, + 0x6013, 0x0300, 0x0078, 0x698a, 0x6013, 0x0500, 0x0078, 0x698a, + 0x6013, 0x0700, 0x0078, 0x698a, 0x6013, 0x0900, 0x0078, 0x698a, + 0x6013, 0x0b00, 0x0078, 0x698a, 0x6013, 0x0f00, 0x0078, 0x698a, + 0x6013, 0x2d00, 0xa085, 0x0001, 0x0078, 0x698f, 0xa006, 0x017f, + 0x0d7f, 0x0c7f, 0x007c, 0x0c7e, 0x0d7e, 0x027e, 0x037e, 0x157e, + 0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff, 0xa286, 0x0006, 0x0040, + 0x69b7, 0xa286, 0x0004, 0x0040, 0x69b7, 0xa394, 0xff00, 0x8217, + 0xa286, 0x0006, 0x0040, 0x69b7, 0xa286, 0x0004, 0x0040, 0x69b7, + 0x0c7e, 0x2d60, 0x1078, 0x3459, 0x0c7f, 0x0078, 0x69ea, 0x2011, + 0x7296, 0xad98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x5a35, 0x00c0, + 0x69eb, 0x2011, 0x729a, 0xad98, 0x0006, 0x20a9, 0x0004, 0x1078, + 0x5a35, 0x00c0, 0x69eb, 0x047e, 0x017e, 0x6aa0, 0xa294, 0x00ff, + 0x8227, 0xa006, 0x2009, 0x6d52, 0x210c, 0xd1a4, 0x0040, 0x69df, + 0x2009, 0x0029, 0x1078, 0x6bf7, 0x6800, 0xc0e5, 0x6802, 0x2019, + 0x0029, 0x1078, 0x445c, 0x1078, 0x43a9, 0x2c08, 0x1078, 0x6a57, + 0x017f, 0x047f, 0xa006, 0x157f, 0x037f, 0x027f, 0x0d7f, 0x0c7f, + 0x007c, 0x0d7e, 0x2069, 0x728e, 0x6800, 0xa086, 0x0800, 0x0040, + 0x69fd, 0x6013, 0x0000, 0x0078, 0x69fe, 0xa006, 0x0d7f, 0x007c, + 0x0c7e, 0x0f7e, 0x017e, 0x027e, 0x037e, 0x157e, 0x2079, 0x728c, + 0x7930, 0x7834, 0x1078, 0x1e1b, 0x00c0, 0x6a24, 0x1078, 0x3447, + 0x00c0, 0x6a24, 0x2011, 0x7290, 0xac98, 0x000a, 0x20a9, 0x0004, + 0x1078, 0x5a35, 0x00c0, 0x6a24, 0x2011, 0x7294, 0xac98, 0x0006, + 0x20a9, 0x0004, 0x1078, 0x5a35, 0x157f, 0x037f, 0x027f, 0x017f, + 0x0f7f, 0x0c7f, 0x007c, 0x0c7e, 0x007e, 0x017e, 0x027e, 0x037e, + 0x157e, 0x2011, 0x7283, 0x2204, 0x8211, 0x220c, 0x1078, 0x1e1b, + 0x00c0, 0x6a50, 0x1078, 0x3447, 0x00c0, 0x6a50, 0x2011, 0x7296, + 0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x5a35, 0x00c0, 0x6a50, + 0x2011, 0x729a, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078, 0x5a35, + 0x157f, 0x037f, 0x027f, 0x017f, 0x007f, 0x0c7f, 0x007c, 0x0e7e, + 0x0c7e, 0x077e, 0x067e, 0x057e, 0x047e, 0x027e, 0x127e, 0x2091, + 0x8000, 0x2029, 0x6f19, 0x252c, 0x2021, 0x6f1f, 0x2424, 0x2061, + 0x7400, 0x2071, 0x6d00, 0x7644, 0x7060, 0x8001, 0xa602, 0x00c8, + 0x6abc, 0x2100, 0xac06, 0x0040, 0x6ab2, 0x1078, 0x6c0f, 0x0040, + 0x6ab2, 0x671c, 0xa786, 0x0001, 0x0040, 0x6ab2, 0xa786, 0x0007, + 0x0040, 0x6ab2, 0x2500, 0xac06, 0x0040, 0x6ab2, 0x2400, 0xac06, + 0x0040, 0x6ab2, 0x6018, 0x2070, 0x70a0, 0xa206, 0x00c0, 0x6ab2, + 0x0d7e, 0x6010, 0x2068, 0x1078, 0x6120, 0x0040, 0x6aa6, 0xa786, + 0x0003, 0x00c0, 0x6ac5, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, + 0x017e, 0x1078, 0x36a1, 0x017f, 0x1078, 0x6276, 0x0d7f, 0x6000, + 0xa086, 0x0004, 0x00c0, 0x6ab0, 0x017e, 0x1078, 0x15f2, 0x017f, + 0x1078, 0x6283, 0xace0, 0x0008, 0x2001, 0x6d15, 0x2004, 0xac02, + 0x00c8, 0x6abc, 0x0078, 0x6a69, 0x127f, 0x027f, 0x047f, 0x057f, + 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0, + 0x6a9b, 0xa386, 0x0005, 0x0040, 0x6ab2, 0x1078, 0x6bb3, 0x0078, + 0x6aa6, 0x0c7e, 0x0e7e, 0x017e, 0x2c08, 0x2170, 0x1078, 0x6bca, + 0x017f, 0x0040, 0x6ae0, 0x601c, 0xa084, 0x000f, 0x1079, 0x6ae3, + 0x0e7f, 0x0c7f, 0x007c, 0x6aeb, 0x6aeb, 0x6aeb, 0x6aeb, 0x6aeb, + 0x6aeb, 0x6aed, 0x6aeb, 0xa006, 0x007c, 0x047e, 0x017e, 0x7018, + 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, 0x2009, + 0x0020, 0x1078, 0x6bf7, 0x017f, 0x047f, 0x1078, 0x6884, 0xa085, + 0x0001, 0x007c, 0x2001, 0x0001, 0x1078, 0x33df, 0x157e, 0x017e, + 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019, 0x6d05, 0x2011, 0x7296, + 0x1078, 0x5a35, 0x037f, 0x027f, 0x017f, 0x157f, 0xa005, 0x007c, + 0x0f7e, 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x027e, 0x127e, 0x2091, + 0x8000, 0x2061, 0x7400, 0x2079, 0x0001, 0x8fff, 0x0040, 0x6b73, + 0x2071, 0x6d00, 0x7644, 0x7060, 0x8001, 0xa602, 0x00c8, 0x6b73, + 0x88ff, 0x0040, 0x6b39, 0x2800, 0xac06, 0x00c0, 0x6b69, 0x2079, + 0x0000, 0x1078, 0x6c0f, 0x0040, 0x6b69, 0x2400, 0xac06, 0x0040, + 0x6b69, 0x671c, 0xa786, 0x0006, 0x00c0, 0x6b69, 0xa786, 0x0007, + 0x0040, 0x6b69, 0x88ff, 0x00c0, 0x6b51, 0x6018, 0xa206, 0x00c0, + 0x6b69, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x6120, 0x0040, 0x6b5c, + 0x047e, 0x1078, 0x6bb3, 0x047f, 0x0d7f, 0x6000, 0xa086, 0x0004, + 0x00c0, 0x6b64, 0x1078, 0x15f2, 0x1078, 0x6283, 0x88ff, 0x00c0, + 0x6b7c, 0xace0, 0x0008, 0x2001, 0x6d15, 0x2004, 0xac02, 0x00c8, + 0x6b73, 0x0078, 0x6b25, 0xa006, 0x127f, 0x027f, 0x067f, 0x077f, + 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0xa8c5, 0x0001, 0x0078, 0x6b74, + 0x087e, 0x2041, 0x0000, 0x2c20, 0x2019, 0x0002, 0x6218, 0x1078, + 0x5387, 0x1078, 0x5428, 0x1078, 0x6b18, 0x087f, 0x007c, 0x027e, + 0x047e, 0x087e, 0x0c7e, 0x157e, 0x2c20, 0x20a9, 0x007f, 0x2009, + 0x0000, 0x017e, 0x037e, 0x1078, 0x3447, 0x00c0, 0x6ba8, 0x2c10, + 0x2041, 0x0000, 0x1078, 0x5387, 0x1078, 0x5428, 0x1078, 0x6b18, + 0x037f, 0x017f, 0x8108, 0x00f0, 0x6b99, 0x157f, 0x0c7f, 0x087f, + 0x047f, 0x027f, 0x007c, 0x017e, 0x0f7e, 0x8dff, 0x0040, 0x6bc7, + 0x6800, 0xa07d, 0x0040, 0x6bc4, 0x6803, 0x0000, 0x6b52, 0x1078, + 0x36a1, 0x2f68, 0x0078, 0x6bb8, 0x6b52, 0x1078, 0x36a1, 0x0f7f, + 0x017f, 0x007c, 0x0e7e, 0x047e, 0x037e, 0x2061, 0x7400, 0x2071, + 0x6d00, 0x7444, 0x7060, 0x8001, 0xa402, 0x00c8, 0x6bf2, 0x2100, + 0xac06, 0x0040, 0x6be4, 0x6000, 0xa086, 0x0000, 0x0040, 0x6be4, + 0x6008, 0xa206, 0x0040, 0x6bee, 0xace0, 0x0008, 0x2001, 0x6d15, + 0x2004, 0xac02, 0x00c8, 0x6bf2, 0x0078, 0x6bcf, 0xa085, 0x0001, + 0x0078, 0x6bf3, 0xa006, 0x037f, 0x047f, 0x0e7f, 0x007c, 0x0d7e, + 0x007e, 0x1078, 0x130f, 0x007f, 0x1040, 0x12b7, 0x6837, 0x010d, + 0x6803, 0x0000, 0x683b, 0x0000, 0x685b, 0x0000, 0x685e, 0x6956, + 0x6c46, 0x684f, 0x0000, 0x1078, 0x36a1, 0x0d7f, 0x007c, 0x6700, + 0xa786, 0x0000, 0x0040, 0x6c22, 0xa786, 0x0001, 0x0040, 0x6c22, + 0xa786, 0x000a, 0x0040, 0x6c22, 0xa786, 0x0009, 0x0040, 0x6c22, + 0xa085, 0x0001, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, + 0x2071, 0x6d00, 0xd5a4, 0x0040, 0x6c30, 0x7034, 0x8000, 0x7036, + 0xd5b4, 0x0040, 0x6c36, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0040, + 0x6c3d, 0x2071, 0x6d0a, 0x1078, 0x6c6c, 0x0e7f, 0x007f, 0x127f, + 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x6d00, + 0xd5a4, 0x0040, 0x6c4e, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, + 0x6c54, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0040, 0x6c5b, 0x2071, + 0x6d0a, 0x1078, 0x6c6c, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, + 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x6d02, 0x1078, 0x6c6c, + 0x0e7f, 0x007f, 0x127f, 0x007c, 0x2e04, 0x8000, 0x2072, 0x00c8, + 0x6c75, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x007c, 0x0e7e, 0x2071, + 0x6d00, 0x1078, 0x6c6c, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0x6d04, + 0x1078, 0x6c6c, 0x0e7f, 0x007c, 0x0001, 0x0002, 0x0004, 0x0008, + 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, + 0x1000, 0x2000, 0x4000, 0x8000, 0x614c +}; +unsigned short risc_code_length01 = 0x5c95; + diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/scsi_error.c linux/drivers/scsi/scsi_error.c --- v2.2.2/linux/drivers/scsi/scsi_error.c Fri Jan 8 22:36:10 1999 +++ linux/drivers/scsi/scsi_error.c Wed Feb 24 16:27:54 1999 @@ -563,6 +563,7 @@ struct semaphore sem = MUTEX_LOCKED; struct timer_list timer; + init_timer(&timer); timer.data = (unsigned long) &sem; timer.expires = jiffies + timeout; timer.function = (void (*)(unsigned long))scsi_sleep_done; diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/sd_ioctl.c linux/drivers/scsi/sd_ioctl.c --- v2.2.2/linux/drivers/scsi/sd_ioctl.c Fri Oct 23 22:01:21 1998 +++ linux/drivers/scsi/sd_ioctl.c Wed Feb 24 16:27:54 1999 @@ -108,6 +108,11 @@ return -EACCES; return revalidate_scsidisk(dev, 1); + case BLKSSZGET: + /* Block size of media */ + return put_user(blksize_size[MAJOR(dev)][MINOR(dev)&0x0F], + (int *)arg); + RO_IOCTLS(dev, arg); default: diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c --- v2.2.2/linux/drivers/scsi/sr_ioctl.c Wed Sep 9 14:51:09 1998 +++ linux/drivers/scsi/sr_ioctl.c Wed Feb 24 16:27:54 1999 @@ -872,6 +872,11 @@ read_ahead[MAJOR(cdi->dev)] = arg; return 0; + case BLKSSZGET: + /* Block size of media */ + return put_user(blksize_size[MAJOR(cdi->dev)][MINOR(cdi->dev)], + (int *)arg); + RO_IOCTLS(cdi->dev,arg); case BLKFLSBUF: diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/st.c linux/drivers/scsi/st.c --- v2.2.2/linux/drivers/scsi/st.c Mon Dec 28 15:00:52 1998 +++ linux/drivers/scsi/st.c Sun Mar 7 15:20:26 1999 @@ -8,10 +8,10 @@ order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale. - Copyright 1992 - 1998 Kai Makisara + Copyright 1992 - 1999 Kai Makisara email Kai.Makisara@metla.fi - Last modified: Thu Dec 3 20:27:46 1998 by makisara@home + Last modified: Sun Mar 7 09:03:17 1999 by makisara@home Some small formal changes - aeb, 950809 */ @@ -1094,8 +1094,11 @@ #endif /* Write must be integral number of blocks */ - if (STp->block_size != 0 && (count % STp->block_size) != 0) + if (STp->block_size != 0 && (count % STp->block_size) != 0) { + printk(KERN_WARNING "st%d: Write not multiple of tape block size.\n", + dev); return (-EIO); + } if (STp->can_partitions && (retval = update_partition(inode)) < 0) diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/sym53c416.c linux/drivers/scsi/sym53c416.c --- v2.2.2/linux/drivers/scsi/sym53c416.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/sym53c416.c Wed Feb 24 16:28:43 1999 @@ -0,0 +1,806 @@ +/* + * sym53c416.c + * Low-level SCSI driver for sym53c416 chip. + * Copyright (C) 1998 Lieven Willems (lw_linux@hotmail.com) + * + * LILO command line usage: sym53c416=[,] + * + * 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, 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "scsi.h" +#include "hosts.h" +#include "sd.h" +#include "sym53c416.h" + +#define VERSION_STRING "Version 1.0.0" + +#define TC_LOW 0x00 /* Transfer counter low */ +#define TC_MID 0x01 /* Transfer counter mid */ +#define SCSI_FIFO 0x02 /* SCSI FIFO register */ +#define COMMAND_REG 0x03 /* Command Register */ +#define STATUS_REG 0x04 /* Status Register (READ) */ +#define DEST_BUS_ID 0x04 /* Destination Bus ID (WRITE) */ +#define INT_REG 0x05 /* Interrupt Register (READ) */ +#define TOM 0x05 /* Time out multiplier (WRITE) */ +#define STP 0x06 /* Synchronous Transfer period */ +#define SYNC_OFFSET 0x07 /* Synchronous Offset */ +#define CONF_REG_1 0x08 /* Configuration register 1 */ +#define CONF_REG_2 0x0B /* Configuration register 2 */ +#define CONF_REG_3 0x0C /* Configuration register 3 */ +#define CONF_REG_4 0x0D /* Configuration register 4 */ +#define TC_HIGH 0x0E /* Transfer counter high */ +#define PIO_FIFO_1 0x10 /* PIO FIFO register 1 */ +#define PIO_FIFO_2 0x11 /* PIO FIFO register 2 */ +#define PIO_FIFO_3 0x12 /* PIO FIFO register 3 */ +#define PIO_FIFO_4 0x13 /* PIO FIFO register 4 */ +#define PIO_FIFO_CNT 0x14 /* PIO FIFO count */ +#define PIO_INT_REG 0x15 /* PIO interrupt register */ +#define CONF_REG_5 0x16 /* Configuration register 5 */ +#define FEATURE_EN 0x1D /* Feature Enable register */ + +/* Configuration register 1 entries: */ +/* Bits 2-0: SCSI ID of host adapter */ +#define SCM 0x80 /* Slow Cable Mode */ +#define SRID 0x40 /* SCSI Reset Interrupt Disable */ +#define PTM 0x20 /* Parity Test Mode */ +#define EPC 0x10 /* Enable Parity Checking */ +#define CTME 0x08 /* Special Test Mode */ + +/* Configuration register 2 entries: */ +#define FE 0x40 /* Features Enable */ +#define SCSI2 0x08 /* SCSI 2 Enable */ +#define TBPA 0x04 /* Target Bad Parity Abort */ + +/* Configuration register 3 entries: */ +#define IDMRC 0x80 /* ID Message Reserved Check */ +#define QTE 0x40 /* Queue Tag Enable */ +#define CDB10 0x20 /* Command Descriptor Block 10 */ +#define FSCSI 0x10 /* FastSCSI */ +#define FCLK 0x08 /* FastClock */ + +/* Configuration register 4 entries: */ +#define RBS 0x08 /* Register bank select */ +#define EAN 0x04 /* Enable Active Negotiation */ + +/* Configuration register 5 entries: */ +#define LPSR 0x80 /* Lower Power SCSI Reset */ +#define IE 0x20 /* Interrupt Enable */ +#define LPM 0x02 /* Low Power Mode */ +#define WSE0 0x01 /* 0WS Enable */ + +/* Interrupt register entries: */ +#define SRST 0x80 /* SCSI Reset */ +#define ILCMD 0x40 /* Illegal Command */ +#define DIS 0x20 /* Disconnect */ +#define BS 0x10 /* Bus Service */ +#define FC 0x08 /* Function Complete */ +#define RESEL 0x04 /* Reselected */ +#define SI 0x03 /* Selection Interrupt */ + +/* Status Register Entries: */ +#define SCI 0x80 /* SCSI Core Int */ +#define GE 0x40 /* Gross Error */ +#define PE 0x20 /* Parity Error */ +#define TC 0x10 /* Terminal Count */ +#define VGC 0x08 /* Valid Group Code */ +#define PHBITS 0x07 /* Phase bits */ + +/* PIO Interrupt Register Entries: */ +#define SCI 0x80 /* SCSI Core Int */ +#define PFI 0x40 /* PIO FIFO Interrupt */ +#define FULL 0x20 /* PIO FIFO Full */ +#define EMPTY 0x10 /* PIO FIFO Empty */ +#define CE 0x08 /* Collision Error */ +#define OUE 0x04 /* Overflow / Underflow error */ +#define FIE 0x02 /* Full Interrupt Enable */ +#define EIE 0x01 /* Empty Interrupt Enable */ + +/* SYM53C416 SCSI phases (lower 3 bits of SYM53C416_STATUS_REG) */ +#define PHASE_DATA_OUT 0x00 +#define PHASE_DATA_IN 0x01 +#define PHASE_COMMAND 0x02 +#define PHASE_STATUS 0x03 +#define PHASE_RESERVED_1 0x04 +#define PHASE_RESERVED_2 0x05 +#define PHASE_MESSAGE_OUT 0x06 +#define PHASE_MESSAGE_IN 0x07 + +/* SYM53C416 core commands */ +#define NOOP 0x00 +#define FLUSH_FIFO 0x01 +#define RESET_CHIP 0x02 +#define RESET_SCSI_BUS 0x03 +#define DISABLE_SEL_RESEL 0x45 +#define RESEL_SEQ 0x40 +#define SEL_WITHOUT_ATN_SEQ 0x41 +#define SEL_WITH_ATN_SEQ 0x42 +#define SEL_WITH_ATN_AND_STOP_SEQ 0x43 +#define ENABLE_SEL_RESEL 0x44 +#define SEL_WITH_ATN3_SEQ 0x46 +#define RESEL3_SEQ 0x47 +#define SND_MSG 0x20 +#define SND_STAT 0x21 +#define SND_DATA 0x22 +#define DISCONNECT_SEQ 0x23 +#define TERMINATE_SEQ 0x24 +#define TARGET_COMM_COMPLETE_SEQ 0x25 +#define DISCONN 0x27 +#define RECV_MSG_SEQ 0x28 +#define RECV_CMD 0x29 +#define RECV_DATA 0x2A +#define RECV_CMD_SEQ 0x2B +#define TARGET_ABORT_PIO 0x04 +#define TRANSFER_INFORMATION 0x10 +#define INIT_COMM_COMPLETE_SEQ 0x11 +#define MSG_ACCEPTED 0x12 +#define TRANSFER_PAD 0x18 +#define SET_ATN 0x1A +#define RESET_ATN 0x1B +#define ILLEGAL 0xFF + +#define PIO_MODE 0x80 + +#define IO_RANGE 0x20 /* 0x00 - 0x1F */ +#define ID "sym53c416" +#define PIO_SIZE 128 /* Size of PIO fifo is 128 bytes */ + +#define READ_TIMEOUT 150 +#define WRITE_TIMEOUT 150 + +#ifdef MODULE + +#define sym53c416_base sym53c416 +#define sym53c416_base_1 sym53c416_1 +#define sym53c416_base_2 sym53c416_2 +#define sym53c416_base_3 sym53c416_3 + +static unsigned short sym53c416_base = 0; +static unsigned int sym53c416_irq = 0; +static unsigned short sym53c416_base_1 = 0; +static unsigned int sym53c416_irq_1 = 0; +static unsigned short sym53c416_base_2 = 0; +static unsigned int sym53c416_irq_2 = 0; +static unsigned short sym53c416_base_3 = 0; +static unsigned int sym53c416_irq_3 = 0; + +#endif + +/* #define DEBUG */ + +/* Macro for debugging purposes */ + +#ifdef DEBUG +#define DEB(x) x +#else +#define DEB(x) +#endif + +#define MAXHOSTS 4 + +enum phases + { + idle, + data_out, + data_in, + command_ph, + status_ph, + message_out, + message_in + }; + +typedef struct + { + int base; + int irq; + int scsi_id; + } host; + +host hosts[MAXHOSTS] = { + {0, 0, SYM53C416_SCSI_ID}, + {0, 0, SYM53C416_SCSI_ID}, + {0, 0, SYM53C416_SCSI_ID}, + {0, 0, SYM53C416_SCSI_ID} + }; + +static int host_index = 0; + +static char info[120]; + +static Scsi_Cmnd *current_command = NULL; + +struct proc_dir_entry proc_scsi_sym53c416 = {PROC_SCSI_SYM53C416, 7, ID, S_IFDIR | S_IRUGO | S_IXUGO, 2}; + +int fastpio = 1; + +int probeaddrs[] = {0x200, 0x220, 0x240, 0}; + +static void sym53c416_set_transfer_counter(int base, unsigned int len) + { + /* Program Transfer Counter */ + outb(len & 0x0000FF, base + TC_LOW); + outb((len & 0x00FF00) >> 8, base + TC_MID); + outb((len & 0xFF0000) >> 16, base + TC_HIGH); + } + +/* Returns the number of bytes read */ +static __inline__ unsigned int sym53c416_read(int base, unsigned char *buffer, unsigned int len) + { + unsigned int orig_len = len; + unsigned long flags = 0; + unsigned int bytes_left; + int i; + int timeout = READ_TIMEOUT; + + /* Do transfer */ + save_flags(flags); + cli(); + while(len && timeout) + { + bytes_left = inb(base + PIO_FIFO_CNT); /* Number of bytes in the PIO FIFO */ + if(fastpio && bytes_left > 3) + { + insl(base + PIO_FIFO_1, buffer, bytes_left >> 2); + buffer += bytes_left & 0xFC; + len -= bytes_left & 0xFC; + } + else if(bytes_left > 0) + { + len -= bytes_left; + for(; bytes_left > 0; bytes_left--) + *(buffer++) = inb(base + PIO_FIFO_1); + } + else + { + i = jiffies + timeout; + restore_flags(flags); + while(jiffies < i && (inb(base + PIO_INT_REG) & EMPTY) && timeout) + if(inb(base + PIO_INT_REG) & SCI) + timeout = 0; + save_flags(flags); + cli(); + if(inb(base + PIO_INT_REG) & EMPTY) + timeout = 0; + } + } + restore_flags(flags); + return orig_len - len; + } + +/* Returns the number of bytes written */ +static __inline__ unsigned int sym53c416_write(int base, unsigned char *buffer, unsigned int len) + { + unsigned int orig_len = len; + unsigned long flags = 0; + unsigned int bufferfree; + unsigned int i; + unsigned int timeout = WRITE_TIMEOUT; + + /* Do transfer */ + save_flags(flags); + cli(); + while(len && timeout) + { + bufferfree = PIO_SIZE - inb(base + PIO_FIFO_CNT); + if(bufferfree > len) + bufferfree = len; + if(fastpio && bufferfree > 3) + { + outsl(base + PIO_FIFO_1, buffer, bufferfree >> 2); + buffer += bufferfree & 0xFC; + len -= bufferfree & 0xFC; + } + else if(bufferfree > 0) + { + len -= bufferfree; + for(; bufferfree > 0; bufferfree--) + outb(*(buffer++), base + PIO_FIFO_1); + } + else + { + i = jiffies + timeout; + restore_flags(flags); + while(jiffies < i && (inb(base + PIO_INT_REG) & FULL) && timeout) + ; + save_flags(flags); + cli(); + if(inb(base + PIO_INT_REG) & FULL) + timeout = 0; + } + } + restore_flags(flags); + return orig_len - len; + } + +static void sym53c416_intr_handle(int irq, void *dev_id, struct pt_regs *regs) + { + int base = 0; + int i; + unsigned long flags = 0; + unsigned char status_reg, pio_int_reg, int_reg; + struct scatterlist *sglist; + unsigned int sgcount; + unsigned int tot_trans = 0; + + /* We search the base address of the host adapter which caused the interrupt */ + for(i = 0; i < host_index && !base; i++) + if(irq == hosts[i].irq) + base = hosts[i].base; + /* If no adapter found, we cannot handle the interrupt. Leave a message */ + /* and continue. This should never happen... */ + if(!base) + { + printk("sym53c416: No host adapter defined for interrupt %d\n", irq); + return; + } + /* Now we have the base address and we can start handling the interrupt */ + save_flags(flags); + cli(); + status_reg = inb(base + STATUS_REG); + pio_int_reg = inb(base + PIO_INT_REG); + int_reg = inb(base + INT_REG); + restore_flags(flags); + + /* First, we handle error conditions */ + if(int_reg & SCI) /* SCSI Reset */ + { + printk("sym53c416: Warning: Reset received\n"); + current_command->SCp.phase = idle; + current_command->result = DID_RESET << 16; + current_command->scsi_done(current_command); + return; + } + if(int_reg & ILCMD) /* Illegal Command */ + { + printk("sym53c416: Warning: Illegal Command: 0x%02x\n", inb(base + COMMAND_REG)); + current_command->SCp.phase = idle; + current_command->result = DID_ERROR << 16; + current_command->scsi_done(current_command); + return; + } + if(status_reg & GE) /* Gross Error */ + { + printk("sym53c416: Warning: Gross Error\n"); + current_command->SCp.phase = idle; + current_command->result = DID_ERROR << 16; + current_command->scsi_done(current_command); + return; + } + if(status_reg & PE) /* Parity Error */ + { + printk("sym53c416: Warning: Parity Error\n"); + current_command->SCp.phase = idle; + current_command->result = DID_PARITY << 16; + current_command->scsi_done(current_command); + return; + } + if(pio_int_reg & (CE | OUE)) + { + printk("sym53c416: Warning: PIO Interrupt Error\n"); + current_command->SCp.phase = idle; + current_command->result = DID_ERROR << 16; + current_command->scsi_done(current_command); + return; + } + if(int_reg & DIS) /* Disconnect */ + { + if(current_command->SCp.phase != message_in) + current_command->result = DID_NO_CONNECT << 16; + else + current_command->result = (current_command->SCp.Status & 0xFF) | ((current_command->SCp.Message & 0xFF) << 8) | (DID_OK << 16); + current_command->SCp.phase = idle; + current_command->scsi_done(current_command); + return; + } + /* Now we handle SCSI phases */ + switch(status_reg & PHBITS) /* Filter SCSI phase out of status reg */ + { + case PHASE_DATA_OUT: + { + if(int_reg & BS) + { + current_command->SCp.phase = data_out; + outb(FLUSH_FIFO, base + COMMAND_REG); + sym53c416_set_transfer_counter(base, current_command->request_bufflen); + outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG); + if(!current_command->use_sg) + tot_trans = sym53c416_write(base, current_command->request_buffer, current_command->request_bufflen); + else + { + sgcount = current_command->use_sg; + sglist = current_command->request_buffer; + while(sgcount--) + { + tot_trans += sym53c416_write(base, sglist->address, sglist->length); + sglist++; + } + } + if(tot_trans < current_command->underflow) + printk("sym53c416: Warning: underflow, wrote %d bytes, request for %d bytes\n", tot_trans, current_command->underflow); + } + break; + } + case PHASE_DATA_IN: + { + if(int_reg & BS) + { + current_command->SCp.phase = data_in; + outb(FLUSH_FIFO, base + COMMAND_REG); + sym53c416_set_transfer_counter(base, current_command->request_bufflen); + outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG); + if(!current_command->use_sg) + tot_trans = sym53c416_read(base, current_command->request_buffer, current_command->request_bufflen); + else + { + sgcount = current_command->use_sg; + sglist = current_command->request_buffer; + while(sgcount--) + { + tot_trans += sym53c416_read(base, sglist->address, sglist->length); + sglist++; + } + } + if(tot_trans < current_command->underflow) + printk("sym53c416: Warning: underflow, read %d bytes, request for %d bytes\n", tot_trans, current_command->underflow); + } + break; + } + case PHASE_COMMAND: + { + current_command->SCp.phase = command_ph; + printk("sym53c416: Warning: Unknown interrupt in command phase\n"); + break; + } + case PHASE_STATUS: + { + current_command->SCp.phase = status_ph; + outb(FLUSH_FIFO, base + COMMAND_REG); + outb(INIT_COMM_COMPLETE_SEQ, base + COMMAND_REG); + break; + } + case PHASE_RESERVED_1: + case PHASE_RESERVED_2: + { + printk("sym53c416: Warning: Reserved phase\n"); + break; + } + case PHASE_MESSAGE_OUT: + { + current_command->SCp.phase = message_out; + outb(SET_ATN, base + COMMAND_REG); + outb(MSG_ACCEPTED, base + COMMAND_REG); + break; + } + case PHASE_MESSAGE_IN: + { + current_command->SCp.phase = message_in; + current_command->SCp.Status = inb(base + SCSI_FIFO); + current_command->SCp.Message = inb(base + SCSI_FIFO); + if(current_command->SCp.Message == SAVE_POINTERS || current_command->SCp.Message == DISCONNECT) + outb(SET_ATN, base + COMMAND_REG); + outb(MSG_ACCEPTED, base + COMMAND_REG); + break; + } + } + } + +static void sym53c416_init(int base, int scsi_id) + { + outb(RESET_CHIP, base + COMMAND_REG); + outb(NOOP, base + COMMAND_REG); + outb(0x99, base + TOM); /* Time out of 250 ms */ + outb(0x05, base + STP); + outb(0x00, base + SYNC_OFFSET); + outb(EPC | scsi_id, base + CONF_REG_1); + outb(FE | SCSI2 | TBPA, base + CONF_REG_2); + outb(IDMRC | QTE | CDB10 | FSCSI | FCLK, base + CONF_REG_3); + outb(0x83 | EAN, base + CONF_REG_4); + outb(IE | WSE0, base + CONF_REG_5); + outb(0, base + FEATURE_EN); + } + +static int sym53c416_probeirq(int base, int scsi_id) + { + int irq, irqs, i; + + /* Clear interrupt register */ + inb(base + INT_REG); + /* Start probing for irq's */ + irqs = probe_irq_on(); + /* Reinit chip */ + sym53c416_init(base, scsi_id); + /* Cause interrupt */ + outb(NOOP, base + COMMAND_REG); + outb(ILLEGAL, base + COMMAND_REG); + outb(0x07, base + DEST_BUS_ID); + outb(0x00, base + DEST_BUS_ID); + /* Wait for interrupt to occur */ + i = jiffies + 20; + while(i > jiffies && !(inb(base + STATUS_REG) & SCI)) + barrier(); + if(i <= jiffies) /* timed out */ + return 0; + /* Get occurred irq */ + irq = probe_irq_off(irqs); + sym53c416_init(base, scsi_id); + return irq; + } + +/* Setup: sym53c416=base,irq */ +void sym53c416_setup(char *str, int *ints) + { + int i; + + if(host_index >= MAXHOSTS) + { + printk("sym53c416.c: Too many hosts defined\n"); + } + else + { + if(ints[0] < 1 || ints[0] > 2) + { + printk("sym53c416.c: Wrong number of parameters:\n"); + printk("sym53c416.c: usage: sym53c416=[,]\n"); + } + else + { + for(i = 0; i < host_index && i >= 0; i++) + if(hosts[i].base == ints[1]) + i = -2; + if(i >= 0) + { + hosts[host_index].base = ints[1]; + hosts[host_index].irq = (ints[0] == 2)? ints[2] : 0; + host_index++; + } + } + } + } + +static int sym53c416_test(int base) + { + outb(RESET_CHIP, base + COMMAND_REG); + outb(NOOP, base + COMMAND_REG); + if(inb(base + COMMAND_REG) != NOOP) + return 0; + if(!inb(base + TC_HIGH) || inb(base + TC_HIGH) == 0xFF) + return 0; + if((inb(base + PIO_INT_REG) & (FULL | EMPTY | CE | OUE | FIE | EIE)) != EMPTY) + return 0; + return 1; + } + +void sym53c416_probe(void) + { + int *base = probeaddrs; + int ints[2]; + + ints[0] = 1; + for(; *base; base++) + if(!check_region(*base, IO_RANGE) && sym53c416_test(*base)) + { + ints[1] = *base; + sym53c416_setup(NULL, ints); + } + } + +int sym53c416_detect(Scsi_Host_Template *tpnt) + { + unsigned long flags; + struct Scsi_Host * shpnt = NULL; + int i; + int count; + +#ifdef MODULE + int ints[3]; + + ints[0] = 2; + if(sym53c416_base) + { + ints[1] = sym53c416_base; + ints[2] = sym53c416_irq; + sym53c416_setup(NULL, ints); + } + if(sym53c416_base_1) + { + ints[1] = sym53c416_base_1; + ints[2] = sym53c416_irq_1; + sym53c416_setup(NULL, ints); + } + if(sym53c416_base_2) + { + ints[1] = sym53c416_base_2; + ints[2] = sym53c416_irq_2; + sym53c416_setup(NULL, ints); + } + if(sym53c416_base_3) + { + ints[1] = sym53c416_base_3; + ints[2] = sym53c416_irq_3; + sym53c416_setup(NULL, ints); + } +#endif + + printk("sym53c416.c: %s\n", VERSION_STRING); + + sym53c416_probe(); + + /* Now we register and set up each host adapter found... */ + for(count = 0, i = 0; i < host_index; i++) + if(!sym53c416_test(hosts[i].base)) + printk("No sym53c416 found at address 0x%03x\n", hosts[i].base); + else + { + if(hosts[i].irq == 0) + /* We don't have an irq yet, so we should probe for one */ + if((hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id)) == 0) + printk("irq autoprobing failed for sym53c416 at address 0x%03x\n", hosts[i].base); + if(hosts[i].irq && !check_region(hosts[i].base, IO_RANGE)) + { + shpnt = scsi_register(tpnt, 0); + save_flags(flags); + cli(); + /* Request for specified IRQ */ + if(request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, NULL)) + { + restore_flags(flags); + printk("Unable to assign IRQ %d\n", hosts[i].irq); + scsi_unregister(shpnt); + } + else + { + /* Inform the kernel of our IO range */ + request_region(hosts[i].base, IO_RANGE, ID); + shpnt->unique_id = hosts[i].base; + shpnt->io_port = hosts[i].base; + shpnt->n_io_port = IO_RANGE; + shpnt->irq = hosts[i].irq; + shpnt->this_id = hosts[i].scsi_id; + sym53c416_init(hosts[i].base, hosts[i].scsi_id); + count++; + restore_flags(flags); + } + } + } + return count; + } + +const char *sym53c416_info(struct Scsi_Host *SChost) + { + int i; + int base = SChost->io_port; + int irq = SChost->irq; + int scsi_id = 0; + int rev = inb(base + TC_HIGH); + + for(i = 0; i < host_index; i++) + if(hosts[i].base == base) + scsi_id = hosts[i].scsi_id; + sprintf(info, "Symbios Logic 53c416 (rev. %d) at 0x%03x, irq %d, SCSI-ID %d, %s pio", rev, base, irq, scsi_id, (fastpio)? "fast" : "slow"); + return info; + } + +int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) + { + int base; + unsigned long flags = 0; + int i; + + /* Store base register as we can have more than one controller in the system */ + base = SCpnt->host->io_port; + current_command = SCpnt; /* set current command */ + current_command->scsi_done = done; /* set ptr to done function */ + current_command->SCp.phase = command_ph; /* currect phase is the command phase */ + current_command->SCp.Status = 0; + current_command->SCp.Message = 0; + + save_flags(flags); + cli(); + outb(SCpnt->target, base + DEST_BUS_ID); /* Set scsi id target */ + outb(FLUSH_FIFO, base + COMMAND_REG); /* Flush SCSI and PIO FIFO's */ + /* Write SCSI command into the SCSI fifo */ + for(i = 0; i < SCpnt->cmd_len; i++) + outb(SCpnt->cmnd[i], base + SCSI_FIFO); + /* Start selection sequence */ + outb(SEL_WITHOUT_ATN_SEQ, base + COMMAND_REG); + /* Now an interrupt will be generated which we will catch in out interrupt routine */ + restore_flags(flags); + return 0; + } + +static void internal_done(Scsi_Cmnd *SCpnt) + { + SCpnt->SCp.Status++; + } + +int sym53c416_command(Scsi_Cmnd *SCpnt) + { + sym53c416_queuecommand(SCpnt, internal_done); + SCpnt->SCp.Status = 0; + while(!SCpnt->SCp.Status) + barrier(); + return SCpnt->result; + } + +int sym53c416_abort(Scsi_Cmnd *SCpnt) + { + printk("sym53c416_abort\n"); + + /* We don't know how to abort for the moment */ + return SCSI_ABORT_SNOOZE; + } + +int sym53c416_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags) + { + int base; + int scsi_id = -1; + int i; + + printk("sym53c416_reset\n"); + base = SCpnt->host->io_port; + /* search scsi_id */ + for(i = 0; i < host_index && scsi_id != -1; i++) + if(hosts[i].base == base) + scsi_id = hosts[i].scsi_id; + outb(RESET_CHIP, base + COMMAND_REG); + outb(NOOP | PIO_MODE, base + COMMAND_REG); + outb(RESET_SCSI_BUS, base + COMMAND_REG); + sym53c416_init(base, scsi_id); + return SCSI_RESET_PENDING; + } + +int sym53c416_bios_param(Disk *disk, kdev_t dev, int *ip) + { + int size; + + size = disk->capacity; + ip[0] = 64; /* heads */ + ip[1] = 32; /* sectors */ + if((ip[2] = size >> 11) > 1024) /* cylinders, test for big disk */ + { + ip[0] = 255; /* heads */ + ip[1] = 63; /* sectors */ + ip[2] = size / (255 * 63); /* cylinders */ + } + return 0; + } + +/* Loadable module support */ +#ifdef MODULE + +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,26) +MODULE_AUTHOR("Lieven Willems"); +MODULE_PARM(sym53c416, "1-2i"); +MODULE_PARM(sym53c416_1, "1-2i"); +MODULE_PARM(sym53c416_2, "1-2i"); +MODULE_PARM(sym53c416_3, "1-2i"); +#endif + +Scsi_Host_Template driver_template = SYM53C416; + +#include "scsi_module.c" +#endif diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/sym53c416.h linux/drivers/scsi/sym53c416.h --- v2.2.2/linux/drivers/scsi/sym53c416.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/sym53c416.h Mon Mar 8 15:52:16 1999 @@ -0,0 +1,91 @@ +/* + * sym53c416.h + * + * Copyright (C) 1998 Lieven Willems (lw_linux@hotmail.com) + * + * 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, 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. + * + */ + +#ifndef _SYM53C416_H +#define _SYM53C416_H + +#if !defined(LINUX_VERSION_CODE) +#include +#endif + +#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) + +#include +#include + +#define SYM53C416_SCSI_ID 7 + +extern struct proc_dir_entry proc_scsi_sym53c416; + +extern int sym53c416_detect(Scsi_Host_Template *); +extern const char *sym53c416_info(struct Scsi_Host *); +extern int sym53c416_command(Scsi_Cmnd *); +extern int sym53c416_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +extern int sym53c416_abort(Scsi_Cmnd *); +extern int sym53c416_reset(Scsi_Cmnd *, unsigned int); +extern int sym53c416_bios_param(Disk *, kdev_t, int *); +extern void sym53c416_setup(char *str, int *ints); + +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,75) + +#define SYM53C416 { \ + proc_dir: &proc_scsi_sym53c416, \ + name: "Symbios Logic 53c416", \ + detect: sym53c416_detect, \ + info: sym53c416_info, \ + command: sym53c416_command, \ + queuecommand: sym53c416_queuecommand, \ + abort: sym53c416_abort, \ + reset: sym53c416_reset, \ + bios_param: sym53c416_bios_param, \ + can_queue: 1, \ + this_id: SYM53C416_SCSI_ID, \ + sg_tablesize: 32, \ + cmd_per_lun: 1, \ + unchecked_isa_dma: 1, \ + use_clustering: ENABLE_CLUSTERING \ + } + +#else + +#define SYM53C416 { \ + NULL, \ + NULL, \ + &proc_scsi_sym53c416, \ + NULL, \ + "Symbios Logic 53c416", \ + sym53c416_detect, \ + NULL, \ + sym53c416_info, \ + sym53c416_command, \ + sym53c416_queuecommand, \ + sym53c416_abort, \ + sym53c416_reset, \ + NULL, \ + sym53c416_bios_param, \ + 1, \ + SYM53C416_SCSI_ID, \ + 32, /* ???? */ \ + 1, \ + 0, \ + 1, \ + ENABLE_CLUSTERING \ + } + +#endif + +#endif diff -u --recursive --new-file v2.2.2/linux/drivers/sound/Config.in linux/drivers/sound/Config.in --- v2.2.2/linux/drivers/sound/Config.in Tue Jan 19 11:32:51 1999 +++ linux/drivers/sound/Config.in Sun Mar 7 15:22:06 1999 @@ -12,7 +12,7 @@ dep_tristate 'Ensoniq AudioPCI (ES1370)' CONFIG_SOUND_ES1370 $CONFIG_SOUND if [ "$CONFIG_SOUND_ES1370" = "y" ]; then bool 'Joystick support at boot time' CONFIG_SOUND_ES1370_JOYPORT_BOOT -fi +fi dep_tristate 'Creative Ensoniq AudioPCI 97 (ES1371)' CONFIG_SOUND_ES1371 $CONFIG_SOUND if [ "$CONFIG_SOUND_ES1371" = "y" ]; then bool 'Joystick support at boot time' CONFIG_SOUND_ES1371_JOYPORT_BOOT @@ -75,6 +75,10 @@ dep_tristate 'OSS sound modules' CONFIG_SOUND_OSS $CONFIG_SOUND if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then + if [ "$CONFIG_SOUND_OSS" = "y" ]; then + bool 'Persistent DMA buffers' CONFIG_SOUND_DMAP + fi + dep_tristate 'ProAudioSpectrum 16 support' CONFIG_SOUND_PAS $CONFIG_SOUND_OSS if [ "$CONFIG_SOUND_PAS" = "y" ]; then int 'PAS16 IRQ 3, 4, 5, 7, 9, 10, 11, 12, 14 or 15' CONFIG_PAS_IRQ 10 @@ -138,6 +142,7 @@ dep_tristate 'Microsoft Sound System support' CONFIG_SOUND_MSS $CONFIG_SOUND_OSS if [ "$CONFIG_SOUND_MSS" = "y" ]; then + bool 'Enable support for the SoundPro mixer' CONFIG_SOUND_SPRO hex 'MSS/WSS I/O base 530, 604, E80 or F40' CONFIG_MSS_BASE 530 int 'MSS/WSS IRQ 7, 9, 10 or 11' CONFIG_MSS_IRQ 11 int 'MSS/WSS DMA 0, 1 or 3' CONFIG_MSS_DMA 3 diff -u --recursive --new-file v2.2.2/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c --- v2.2.2/linux/drivers/sound/ad1848.c Wed Jan 20 23:14:06 1999 +++ linux/drivers/sound/ad1848.c Sun Mar 7 15:22:06 1999 @@ -100,6 +100,11 @@ static int nr_ad1848_devs = 0; int deskpro_xl = 0; +#ifdef CONFIG_SOUND_SPRO +int soundpro = 1; +#else +int soundpro = 0; +#endif static volatile char irq2dev[17] = { -1, -1, -1, -1, -1, -1, -1, -1, @@ -312,22 +317,21 @@ if (mask & (1 << i)) n++; - if (n == 0) - mask = SOUND_MASK_MIC; - else if (n != 1) /* Too many devices selected */ - { - mask &= ~devc->recmask; /* Filter out active settings */ + if (!soundpro) { + if (n == 0) + mask = SOUND_MASK_MIC; + else if (n != 1) { /* Too many devices selected */ + mask &= ~devc->recmask; /* Filter out active settings */ - n = 0; - for (i = 0; i < 32; i++) /* Count selected device bits */ - if (mask & (1 << i)) - n++; + n = 0; + for (i = 0; i < 32; i++) /* Count selected device bits */ + if (mask & (1 << i)) + n++; - if (n != 1) - mask = SOUND_MASK_MIC; - } - switch (mask) - { + if (n != 1) + mask = SOUND_MASK_MIC; + } + switch (mask) { case SOUND_MASK_MIC: recdev = 2; break; @@ -349,11 +353,38 @@ default: mask = SOUND_MASK_MIC; recdev = 2; - } + } + + recdev <<= 6; + ad_write(devc, 0, (ad_read(devc, 0) & 0x3f) | recdev); + ad_write(devc, 1, (ad_read(devc, 1) & 0x3f) | recdev); + } else { /* soundpro */ + unsigned char val; + int set_rec_bit; + int j; + + for (i = 0; i < 32; i++) { /* For each bit */ + if ((devc->supported_rec_devices & (1 << i)) == 0) + continue; /* Device not supported */ + + for (j = LEFT_CHN; j <= RIGHT_CHN; j++) { + if (devc->mix_devices[i][j].nbits == 0) /* Inexistent channel */ + continue; + + /* + * This is tricky: + * set_rec_bit becomes 1 if the corresponding bit in mask is set + * then it gets flipped if the polarity is inverse + */ + set_rec_bit = ((mask & (1 << i)) != 0) ^ devc->mix_devices[i][j].recpol; - recdev <<= 6; - ad_write(devc, 0, (ad_read(devc, 0) & 0x3f) | recdev); - ad_write(devc, 1, (ad_read(devc, 1) & 0x3f) | recdev); + val = ad_read(devc, devc->mix_devices[i][j].recreg); + val &= ~(1 << devc->mix_devices[i][j].recpos); + val |= (set_rec_bit << devc->mix_devices[i][j].recpos); + ad_write(devc, devc->mix_devices[i][j].recreg, val); + } + } + } /* Rename the mixer bits back if necessary */ for (i = 0; i < 32; i++) @@ -371,7 +402,8 @@ return mask; } -static void change_bits(ad1848_info * devc, unsigned char *regval, int dev, int chn, int newval) +static void change_bits(ad1848_info * devc, unsigned char *regval, + unsigned char *muteval, int dev, int chn, int newval) { unsigned char mask; int shift; @@ -379,7 +411,7 @@ int mutemask; int set_mute_bit; - set_mute_bit = (newval == 0); + set_mute_bit = (newval == 0) ^ devc->mix_devices[dev][chn].mutepol; if (devc->mix_devices[dev][chn].polarity == 1) /* Reverse */ newval = 100 - newval; @@ -399,8 +431,11 @@ } newval = (int) ((newval * mask) + 50) / 100; /* Scale it */ - *regval &= (~(mask << shift)) & (mutemask); /* Clear bits */ - *regval |= ((newval & mask) << shift) | mute; /* Set new value */ + *regval &= ~(mask << shift); /* Clear bits */ + *regval |= (newval & mask) << shift; /* Set new value */ + + *muteval &= mutemask; + *muteval |= mute; } static int ad1848_mixer_get(ad1848_info * devc, int dev) @@ -413,15 +448,36 @@ return devc->levels[dev]; } +static void ad1848_mixer_set_channel(ad1848_info *devc, int dev, int value, int channel) +{ + int regoffs, muteregoffs; + unsigned char val, muteval; + + regoffs = devc->mix_devices[dev][channel].regno; + muteregoffs = devc->mix_devices[dev][channel].mutereg; + val = ad_read(devc, regoffs); + + if (muteregoffs != regoffs) { + muteval = ad_read(devc, muteregoffs); + change_bits(devc, &val, &muteval, dev, channel, value); + } + else + change_bits(devc, &val, &val, dev, channel, value); + + ad_write(devc, regoffs, val); + devc->saved_regs[regoffs] = val; + if (muteregoffs != regoffs) { + ad_write(devc, muteregoffs, muteval); + devc->saved_regs[muteregoffs] = muteval; + } +} + static int ad1848_mixer_set(ad1848_info * devc, int dev, int value) { int left = value & 0x000000ff; int right = (value & 0x0000ff00) >> 8; int retvol; - int regoffs; - unsigned char val; - if (dev > 31) return -EINVAL; @@ -430,6 +486,9 @@ dev = devc->mixer_reroute[dev]; + if (devc->mix_devices[dev][LEFT_CHN].nbits == 0) + return -EINVAL; + if (left > 100) left = 100; if (right > 100) @@ -444,34 +503,21 @@ left = mix_cvt[left]; right = mix_cvt[right]; - if (devc->mix_devices[dev][LEFT_CHN].nbits == 0) - return -EINVAL; - devc->levels[dev] = retvol; /* * Set the left channel */ - - regoffs = devc->mix_devices[dev][LEFT_CHN].regno; - val = ad_read(devc, regoffs); - change_bits(devc, &val, dev, LEFT_CHN, left); - ad_write(devc, regoffs, val); - devc->saved_regs[regoffs] = val; + ad1848_mixer_set_channel(devc, dev, left, LEFT_CHN); /* * Set the right channel */ - if (devc->mix_devices[dev][RIGHT_CHN].nbits == 0) - return retvol; /* Was just a mono channel */ - - regoffs = devc->mix_devices[dev][RIGHT_CHN].regno; - val = ad_read(devc, regoffs); - change_bits(devc, &val, dev, RIGHT_CHN, right); - ad_write(devc, regoffs, val); - devc->saved_regs[regoffs] = val; + goto out; + ad1848_mixer_set_channel(devc, dev, right, RIGHT_CHN); + out: return retvol; } @@ -487,6 +533,8 @@ for (i = 0; i < 32; i++) devc->mixer_reroute[i] = i; + devc->supported_rec_devices = MODE1_REC_DEVICES; + switch (devc->model) { case MD_4231: @@ -509,11 +557,18 @@ devc->supported_devices = MODE3_MIXER_DEVICES; break; + case MD_1848: + if (soundpro) { + devc->supported_devices = SPRO_MIXER_DEVICES; + devc->supported_rec_devices = SPRO_REC_DEVICES; + devc->mix_devices = &(spro_mix_devices[0]); + break; + } + default: devc->supported_devices = MODE1_MIXER_DEVICES; } - devc->supported_rec_devices = MODE1_REC_DEVICES; devc->orig_devices = devc->supported_devices; devc->orig_rec_devices = devc->supported_rec_devices; @@ -528,10 +583,20 @@ ad1848_set_recmask(devc, SOUND_MASK_MIC); devc->mixer_output_port = devc->levels[31] | AUDIO_HEADPHONE | AUDIO_LINE_OUT; - if (devc->mixer_output_port & AUDIO_SPEAKER) - ad_write(devc, 26, ad_read(devc, 26) & ~0x40); /* Unmute mono out */ - else - ad_write(devc, 26, ad_read(devc, 26) | 0x40); /* Mute mono out */ + + if (!soundpro) { + if (devc->mixer_output_port & AUDIO_SPEAKER) + ad_write(devc, 26, ad_read(devc, 26) & ~0x40); /* Unmute mono out */ + else + ad_write(devc, 26, ad_read(devc, 26) | 0x40); /* Mute mono out */ + } else { + /* + * From the "wouldn't it be nice if the mixer API had (better) + * support for custom stuff" category + */ + /* Enable surround mode and SB16 mixer */ + ad_write(devc, 16, 0x60); + } } static int ad1848_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg) @@ -1357,6 +1422,8 @@ { devc->audio_flags &= ~DMA_DUPLEX; ad_write(devc, 9, ad_read(devc, 9) | 0x04); /* Single DMA mode */ + if (soundpro) + ad_write(devc, 12, ad_read(devc, 12) | 0x40); /* Mode2 = enabled */ } outb((0), io_Status(devc)); /* Clear pending interrupts */ @@ -1706,7 +1773,27 @@ DDB(printk("ad1848_detect() - step K\n")); } + } else if (tmp1 == 0x0a) { + /* + * Is it perhaps a SoundPro CMI8330? + * If so, then we should be able to change indirect registers + * greater than I15 after activating MODE2, even though reading + * back I12 does not show it. + */ + + /* + * Let's try comparing register values + */ + for (i = 0; i < 16; i++) { + if ((tmp1 = ad_read(devc, i)) != (tmp2 = ad_read(devc, i + 16))) { + DDB(printk("ad1848 detect step H(%d/%x/%x) - SoundPro chip?\n", i, tmp1, tmp2)); + soundpro = 1; + devc->chip_name = "SoundPro CMI 8330"; + break; + } + } } + DDB(printk("ad1848_detect() - step L\n")); if (ad_flags) { @@ -2302,7 +2389,8 @@ (hw_config->irq != 7) && (hw_config->irq != 9) && (hw_config->irq != 10) && - (hw_config->irq != 11)) + (hw_config->irq != 11) && + (hw_config->irq != 12)) { printk(KERN_ERR "MSS: Bad IRQ %d\n", hw_config->irq); return 0; @@ -2555,6 +2643,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(soundpro, "i"); /* More special magic for SoundPro chips */ int io = -1; int irq = -1; diff -u --recursive --new-file v2.2.2/linux/drivers/sound/ad1848_mixer.h linux/drivers/sound/ad1848_mixer.h --- v2.2.2/linux/drivers/sound/ad1848_mixer.h Fri Oct 23 22:01:21 1998 +++ linux/drivers/sound/ad1848_mixer.h Sun Mar 7 15:22:06 1999 @@ -24,7 +24,10 @@ * solution). */ #define MODE1_REC_DEVICES (SOUND_MASK_LINE3 | SOUND_MASK_MIC | \ - SOUND_MASK_LINE1|SOUND_MASK_IMIX) + SOUND_MASK_LINE1 | SOUND_MASK_IMIX) + +#define SPRO_REC_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | \ + SOUND_MASK_CD | SOUND_MASK_LINE1) #define MODE1_MIXER_DEVICES (SOUND_MASK_LINE1 | SOUND_MASK_MIC | \ SOUND_MASK_LINE2 | \ @@ -47,16 +50,27 @@ SOUND_MASK_LINE3 | \ SOUND_MASK_IGAIN | SOUND_MASK_PCM) +#define SPRO_MIXER_DEVICES (SOUND_MASK_VOLUME | SOUND_MASK_PCM | \ + SOUND_MASK_LINE | SOUND_MASK_SYNTH | \ + SOUND_MASK_CD | SOUND_MASK_MIC | \ + SOUND_MASK_SPEAKER | SOUND_MASK_LINE1 | \ + SOUND_MASK_OGAIN) + struct mixer_def { - unsigned int regno: 5; - unsigned int polarity:1; /* 0=normal, 1=reversed */ - unsigned int bitpos:3; - unsigned int nbits:3; - unsigned int mutepos:4; + unsigned int regno:5; /* register number for volume */ + unsigned int polarity:1; /* volume polarity: 0=normal, 1=reversed */ + unsigned int bitpos:3; /* position of bits in register for volume */ + unsigned int nbits:3; /* number of bits in register for volume */ + unsigned int mutereg:5; /* register number for mute bit */ + unsigned int mutepol:1; /* mute polarity: 0=normal, 1=reversed */ + unsigned int mutepos:4; /* position of mute bit in register */ + unsigned int recreg:5; /* register number for recording bit */ + unsigned int recpol:1; /* recording polarity: 0=normal, 1=reversed */ + unsigned int recpos:4; /* position of recording bit in register */ }; static char mix_cvt[101] = { - 0, 0,3,7,10,13,16,19,21,23,26,28,30,32,34,35,37,39,40,42, + 0, 0, 3, 7,10,13,16,19,21,23,26,28,30,32,34,35,37,39,40,42, 43,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,64,65, 65,66,67,68,69,70,70,71,72,73,73,74,75,75,76,77,77,78,79,79, 80,81,81,82,82,83,84,84,85,85,86,86,87,87,88,88,89,89,90,90, @@ -77,7 +91,17 @@ */ #define MIX_ENT(name, reg_l, pola_l, pos_l, len_l, reg_r, pola_r, pos_r, len_r, mute_bit) \ - {{reg_l, pola_l, pos_l, len_l, mute_bit}, {reg_r, pola_r, pos_r, len_r, mute_bit}} + [name] = {{reg_l, pola_l, pos_l, len_l, reg_l, 0, mute_bit, 0, 0, 8}, \ + {reg_r, pola_r, pos_r, len_r, reg_r, 0, mute_bit, 0, 0, 8}} + +#define MIX_ENT2(name, reg_l, pola_l, pos_l, len_l, mute_reg_l, mute_pola_l, mute_pos_l, \ + rec_reg_l, rec_pola_l, rec_pos_l, \ + reg_r, pola_r, pos_r, len_r, mute_reg_r, mute_pola_r, mute_pos_r, \ + rec_reg_r, rec_pola_r, rec_pos_r) \ + [name] = {{reg_l, pola_l, pos_l, len_l, mute_reg_l, mute_pola_l, mute_pos_l, \ + rec_reg_l, rec_pola_l, rec_pos_l}, \ + {reg_r, pola_r, pos_r, len_r, mute_reg_r, mute_pola_r, mute_pos_r, \ + rec_reg_r, rec_pola_r, rec_pos_r}} static mixer_ents ad1848_mix_devices[32] = { MIX_ENT(SOUND_MIXER_VOLUME, 27, 1, 0, 4, 29, 1, 0, 4, 8), @@ -142,6 +166,30 @@ MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 1, 4, 3, 1, 1, 4, 7), MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 1, 4, 5, 1, 1, 4, 7), MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 1, 4, 19, 1, 1, 4, 7) +}; + +static mixer_ents spro_mix_devices[32] = { +MIX_ENT (SOUND_MIXER_VOLUME, 19, 0, 4, 4, 19, 0, 0, 4, 8), +MIX_ENT (SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8), +MIX_ENT (SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8), +MIX_ENT2(SOUND_MIXER_SYNTH, 4, 1, 1, 4, 23, 0, 3, 0, 0, 8, + 5, 1, 1, 4, 23, 0, 3, 0, 0, 8), +MIX_ENT (SOUND_MIXER_PCM, 6, 1, 1, 4, 7, 1, 1, 4, 8), +MIX_ENT (SOUND_MIXER_SPEAKER, 18, 0, 3, 2, 0, 0, 0, 0, 8), +MIX_ENT2(SOUND_MIXER_LINE, 20, 0, 4, 4, 17, 1, 4, 16, 0, 2, + 20, 0, 0, 4, 17, 1, 3, 16, 0, 1), +MIX_ENT2(SOUND_MIXER_MIC, 18, 0, 0, 3, 17, 1, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +MIX_ENT2(SOUND_MIXER_CD, 21, 0, 4, 4, 17, 1, 2, 16, 0, 4, + 21, 0, 0, 4, 17, 1, 1, 16, 0, 3), +MIX_ENT (SOUND_MIXER_IMIX, 0, 0, 0, 0, 0, 0, 0, 0, 8), +MIX_ENT (SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8), +MIX_ENT (SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8), +MIX_ENT (SOUND_MIXER_IGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8), +MIX_ENT (SOUND_MIXER_OGAIN, 17, 1, 6, 1, 0, 0, 0, 0, 8), +/* This is external wavetable */ +MIX_ENT2(SOUND_MIXER_LINE1, 22, 0, 4, 4, 23, 1, 1, 23, 0, 4, + 22, 0, 0, 4, 23, 1, 0, 23, 0, 5), }; static int default_mixer_levels[32] = diff -u --recursive --new-file v2.2.2/linux/drivers/sound/es1370.c linux/drivers/sound/es1370.c --- v2.2.2/linux/drivers/sound/es1370.c Fri Jan 8 22:36:10 1999 +++ linux/drivers/sound/es1370.c Sun Mar 7 15:22:06 1999 @@ -1228,8 +1228,6 @@ if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) return -EAGAIN; db->mapped = 1; - vma->vm_file = file; - file->f_count++; return 0; } @@ -1597,6 +1595,7 @@ down(&s->open_sem); if (file->f_mode & FMODE_WRITE) { stop_dac2(s); + synchronize_irq(); dealloc_dmabuf(&s->dma_dac2); } if (file->f_mode & FMODE_READ) { @@ -1725,8 +1724,6 @@ if (remap_page_range(vma->vm_start, virt_to_phys(s->dma_dac1.rawbuf), size, vma->vm_page_prot)) return -EAGAIN; s->dma_dac1.mapped = 1; - vma->vm_file = file; - file->f_count++; return 0; } diff -u --recursive --new-file v2.2.2/linux/drivers/sound/es1371.c linux/drivers/sound/es1371.c --- v2.2.2/linux/drivers/sound/es1371.c Fri Jan 8 22:36:10 1999 +++ linux/drivers/sound/es1371.c Sun Mar 7 10:37:40 1999 @@ -1675,8 +1675,6 @@ if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) return -EAGAIN; db->mapped = 1; - vma->vm_file = file; - file->f_count++; return 0; } @@ -2172,8 +2170,6 @@ if (remap_page_range(vma->vm_start, virt_to_phys(s->dma_dac1.rawbuf), size, vma->vm_page_prot)) return -EAGAIN; s->dma_dac1.mapped = 1; - vma->vm_file = file; - file->f_count++; return 0; } diff -u --recursive --new-file v2.2.2/linux/drivers/sound/lowlevel/awe_compat.h linux/drivers/sound/lowlevel/awe_compat.h --- v2.2.2/linux/drivers/sound/lowlevel/awe_compat.h Fri Jan 8 22:36:11 1999 +++ linux/drivers/sound/lowlevel/awe_compat.h Sun Mar 7 15:22:06 1999 @@ -54,7 +54,7 @@ #include "../soundvers.h" #endif -#if SOUND_INTERNAL_VERSION >= 0x30803 +#if defined(SOUND_INTERNAL_VERSION) && SOUND_INTERNAL_VERSION >= 0x30803 /* OSS/Free-3.8 */ #define AWE_NO_PATCHMGR #define AWE_OSS38 @@ -151,18 +151,9 @@ #define my_malloc_memptr() _mem_start #define my_free(ptr) /* do nothing */ -static void *my_malloc(int size) -{ - char *ptr; - PERMANENT_MALLOC(ptr, char*, size, _mem_start); - return (void*)ptr; -} -#define my_kmalloc(size) my_malloc(size) -#define kfree(ptr) /* do nothing */ - /* allocate buffer only once */ #define INIT_TABLE(buffer,index,nums,type) {\ -buffer = my_malloc(sizeof(type) * (nums)); index = (nums);\ +PERMANENT_MALLOC(buffer, char*, size, _mem_start); index = (nums);\ } #else @@ -173,8 +164,6 @@ #define my_malloc_memptr() 0 #define my_malloc(size) vmalloc(size) #define my_free(ptr) if (ptr) {vfree(ptr);} -#define my_kmalloc(size) kmalloc(size,GFP_KERNEL) -#define my_kfree(ptr) kfree(ptr) /* do not allocate buffer at beginning */ #define INIT_TABLE(buffer,index,nums,type) {buffer=NULL; index=0;} @@ -254,6 +243,14 @@ #define sound_unload_mididev(dev) /**/ #endif /* AWE_MODULE_SUPPORT */ + +#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0) +inline static void interruptible_sleep_on_timeout(struct wait_queue **q, unsigned long timeout) +{ + current->timeout = jiffies + timeout; + interruptible_sleep_on(q); +} +#endif #endif /* CONFIG_AWE32_SYNTH */ diff -u --recursive --new-file v2.2.2/linux/drivers/sound/lowlevel/awe_wave.c linux/drivers/sound/lowlevel/awe_wave.c --- v2.2.2/linux/drivers/sound/lowlevel/awe_wave.c Tue Dec 22 14:16:56 1998 +++ linux/drivers/sound/lowlevel/awe_wave.c Sun Mar 7 15:22:06 1999 @@ -2,9 +2,9 @@ * sound/awe_wave.c * * The low level driver for the AWE32/SB32/AWE64 wave table synth. - * version 0.4.3; Nov. 1, 1998 + * version 0.4.3; Feb. 1, 1999 * - * Copyright (C) 1996-1998 Takashi Iwai + * Copyright (C) 1996-1999 Takashi Iwai * * 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 @@ -204,16 +204,20 @@ #if defined(AWE_MODULE_SUPPORT) && defined(MODULE) /* replace awe_port variable with exported variable */ #define awe_port io -#define BASEVAR_DECL /**/ +#define awe_mem_size memsize +int io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */ +int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */ +#ifdef MODULE_PARM +MODULE_PARM(io, "i"); +MODULE_PARM_DESC(io, "base i/o port of Emu8000"); +MODULE_PARM(memsize, "i"); +MODULE_PARM_DESC(memsize, "onboard DRAM size in Kbytes"); +#endif #else -#define BASEVAR_DECL static +static int awe_port = AWE_DEFAULT_BASE_ADDR; +static int awe_mem_size = AWE_DEFAULT_MEM_SIZE; #endif /* module */ -/* awe32 base address (overwritten at initialization) */ -BASEVAR_DECL int awe_port = AWE_DEFAULT_BASE_ADDR; -/* memory byte size */ -BASEVAR_DECL int memsize = AWE_DEFAULT_MEM_SIZE; /* for module option */ -static int awe_mem_size = -1; /* DRAM start offset */ static int awe_mem_start = AWE_DRAM_OFFSET; @@ -669,7 +673,7 @@ #include -BASEVAR_DECL int pnp = 1; /* use PnP as default */ +static int pnp = 1; /* use PnP as default */ #define AWE_NUM_CHIPS 3 static unsigned int pnp_ids[AWE_NUM_CHIPS] = { @@ -812,6 +816,7 @@ } #ifdef MODULE_PARM +EXPORT_NO_SYMBOLS; MODULE_AUTHOR("Takashi Iwai "); MODULE_DESCRIPTION("SB AWE32/64 WaveTable driver"); MODULE_SUPPORTED_DEVICE("sound"); @@ -975,23 +980,9 @@ #else static struct wait_queue *awe_sleeper = NULL; -static void awe_wakeup(unsigned long dummy) -{ - wake_up(&awe_sleeper); -} - -static struct timer_list awe_timer = -{NULL, NULL, 0, 0, awe_wakeup}; - static void awe_wait(unsigned short delay) { - unsigned long flags; - awe_timer.expires = jiffies + (HZ * (unsigned long)delay + 44099) / 44100; - add_timer(&awe_timer); - save_flags (flags); - cli(); - sleep_on(&awe_sleeper); - restore_flags(flags); + interruptible_sleep_on_timeout(&awe_sleeper, (HZ * (unsigned long)delay + 44099) / 44100); } #endif /* wait by loop */ @@ -1553,7 +1544,7 @@ vp->parm.moddcysus)); if (parm->volatk >= 0x80 && parm->voldelay >= 0x8000) { - awe_poke(AWE_ENVVAL(voice), 0xBFFF); + awe_poke(AWE_ENVVOL(voice), 0xBFFF); vtarget = voltarget[voices[voice].avol%0x10]>>(voices[voice].avol>>4); } else { awe_poke(AWE_ENVVOL(voice), @@ -3268,7 +3259,7 @@ sf_list *sf; /* search for all sharing lists */ - for (sf_id = rec->v.sf_id; sf_id > 0; sf_id = sf->shared) { + for (sf_id = rec->v.sf_id; sf_id > 0 && sf_id <= current_sf_id; sf_id = sf->shared) { sf = &sflists[sf_id - 1]; for (j = sf->infos; j >= 0; j = infos[j].next) { awe_voice_list *p = &infos[j]; @@ -4201,7 +4192,7 @@ if (id1 < id2) { /* make sure id1 > id2 */ int tmp; tmp = id1; id1 = id2; id2 = tmp; } - for (i = sflists[id1-1].shared; i > 0; i = sflists[i-1].shared) { + for (i = sflists[id1-1].shared; i > 0 && i <= current_sf_id; i = sflists[i-1].shared) { if (i == id2) return TRUE; } @@ -4223,10 +4214,10 @@ return i; } #ifdef AWE_ALLOW_SAMPLE_SHARING - if (sflists[sf-1].shared) { /* search recursively */ + if ((i = sflists[sf-1].shared) > 0 && i <= current_sf_id) { /* search recursively */ if (level > current_sf_id) return -1; /* strange sharing loop.. quit */ - return search_sample_index(sflists[sf-1].shared, sample, level + 1); + return search_sample_index(i, sample, level + 1); } #endif return -1; @@ -4272,10 +4263,12 @@ note <= infos[rec].v.high && velocity >= infos[rec].v.vellow && velocity <= infos[rec].v.velhigh) { - vlist[nvoices] = &infos[rec].v; - if (infos[rec].type == V_ST_MAPPED) /* mapper */ + if (infos[rec].type == V_ST_MAPPED) { + /* mapper */ + vlist[0] = &infos[rec].v; return -1; - nvoices++; + } + vlist[nvoices++] = &infos[rec].v; if (nvoices >= AWE_MAX_VOICES) break; } @@ -5009,8 +5002,6 @@ DEBUG(0,printk("AWE32 not found\n")); return 0; } - if (memsize >= 0) /* given by config file or module option */ - awe_mem_size = memsize * 1024; /* convert to Kbytes */ return 1; } @@ -5028,8 +5019,13 @@ static void awe_check_dram(void) { - if (awe_mem_size >= 0) /* already initialized */ + if (awe_present) /* already initialized */ return; + + if (awe_mem_size >= 0) { /* given by config file or module option */ + awe_mem_size *= 1024; /* convert to Kbytes */ + return; + } awe_open_dram_for_check(); diff -u --recursive --new-file v2.2.2/linux/drivers/sound/mad16.c linux/drivers/sound/mad16.c --- v2.2.2/linux/drivers/sound/mad16.c Fri Jan 8 22:36:11 1999 +++ linux/drivers/sound/mad16.c Sun Mar 7 15:22:06 1999 @@ -800,7 +800,7 @@ mad_write(MC3_PORT, tmp | 0x04); hw_config->driver_use_1 = SB_MIDI_ONLY; - return sb_dsp_detect(hw_config); + return sb_dsp_detect(hw_config, 0, 0); #else return 0; #endif diff -u --recursive --new-file v2.2.2/linux/drivers/sound/sb.h linux/drivers/sound/sb.h --- v2.2.2/linux/drivers/sound/sb.h Tue Feb 23 15:21:34 1999 +++ linux/drivers/sound/sb.h Sun Mar 7 15:22:06 1999 @@ -47,11 +47,13 @@ #define MDL_AZTECH 13 /* Aztech Sound Galaxy family */ #define MDL_ES1868MIDI 14 /* MIDI port of ESS1868 */ #define MDL_AEDSP 15 /* Audio Excel DSP 16 */ +#define MDL_ESSPCI 16 /* ESS PCI card */ #define SUBMDL_ALS007 42 /* ALS-007 differs from SB16 only in mixer */ /* register assignment */ #define SUBMDL_ALS100 43 /* ALS-100 allows sampling rates of up */ /* to 48kHz */ + /* * Config flags */ @@ -60,6 +62,7 @@ #define SB_NO_AUDIO 0x00000004 #define SB_NO_RECORDING 0x00000008 /* No audio recording */ #define SB_MIDI_ONLY (SB_NO_AUDIO|SB_NO_MIXER) +#define SB_PCI_IRQ 0x00000010 /* PCI shared IRQ */ struct mixer_def { unsigned int regno: 8; @@ -86,6 +89,8 @@ int base; int irq; int dma8, dma16; + + int pcibase; /* For ESS Maestro etc */ /* State variables */ int opened; @@ -128,13 +133,24 @@ void (*midi_input_intr) (int dev, unsigned char data); void *midi_irq_cookie; /* IRQ cookie for the midi */ } sb_devc; + +/* + * PCI card types + */ +#define SB_PCI_ESSMAESTRO 1 /* ESS Maestro Legacy */ +#define SB_PCI_YAMAHA 2 /* Yamaha Legacy */ + +/* + * Functions + */ + int sb_dsp_command (sb_devc *devc, unsigned char val); int sb_dsp_get_byte(sb_devc * devc); int sb_dsp_reset (sb_devc *devc); void sb_setmixer (sb_devc *devc, unsigned int port, unsigned int value); unsigned int sb_getmixer (sb_devc *devc, unsigned int port); -int sb_dsp_detect (struct address_info *hw_config); +int sb_dsp_detect (struct address_info *hw_config, int pci, int pciio); int sb_dsp_init (struct address_info *hw_config); void sb_dsp_unload(struct address_info *hw_config, int sbmpu); int sb_mixer_init(sb_devc *devc); diff -u --recursive --new-file v2.2.2/linux/drivers/sound/sb_card.c linux/drivers/sound/sb_card.c --- v2.2.2/linux/drivers/sound/sb_card.c Tue Feb 23 15:21:34 1999 +++ linux/drivers/sound/sb_card.c Sun Mar 7 15:22:06 1999 @@ -103,7 +103,7 @@ printk(KERN_ERR "sb_card: I/O port %x is already in use\n\n", hw_config->io_base); return 0; } - return sb_dsp_detect(hw_config); + return sb_dsp_detect(hw_config, 0, 0); } void unload_sb(struct address_info *hw_config) @@ -135,6 +135,7 @@ int mad16 = 0; /* Set mad16=1 to load this as support for mad16 */ int trix = 0; /* Set trix=1 to load this as support for trix */ int pas2 = 0; /* Set pas2=1 to load this as support for pas2 */ +int support = 0; /* Set support to load this as a support module */ int sm_games = 0; /* Mixer - see sb_mixer.c */ int acer = 0; /* Do acer notebook init */ @@ -145,6 +146,7 @@ MODULE_PARM(mpu_io, "i"); MODULE_PARM(type, "i"); MODULE_PARM(mad16, "i"); +MODULE_PARM(support, "i"); MODULE_PARM(trix, "i"); MODULE_PARM(pas2, "i"); MODULE_PARM(sm_games, "i"); @@ -156,7 +158,7 @@ { printk(KERN_INFO "Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996\n"); - if (mad16 == 0 && trix == 0 && pas2 == 0) + if (mad16 == 0 && trix == 0 && pas2 == 0 && support == 0) { if (io == -1 || dma == -1 || irq == -1) { @@ -191,7 +193,7 @@ { if (smw_free) vfree(smw_free); - if (!mad16 && !trix && !pas2) + if (!mad16 && !trix && !pas2 && !support) unload_sb(&config); if (sbmpu) unload_sbmpu(&config_mpu); diff -u --recursive --new-file v2.2.2/linux/drivers/sound/sb_common.c linux/drivers/sound/sb_common.c --- v2.2.2/linux/drivers/sound/sb_common.c Mon Jan 25 17:44:34 1999 +++ linux/drivers/sound/sb_common.c Sun Mar 7 15:22:06 1999 @@ -179,13 +179,25 @@ status = inb(DSP_DATA_AVL16); } +static void pci_intr(sb_devc *devc) +{ + int src = inb(devc->pcibase+0x1A); + src&=3; + if(src) + sb_intr(devc); +} + static void sbintr(int irq, void *dev_id, struct pt_regs *dummy) { - sb_devc *devc = dev_id; + sb_devc *devc = dev_id; devc->irq_ok = 1; switch (devc->model) { + case MDL_ESSPCI: + pci_intr (devc); + break; + case MDL_ESS: ess_intr (devc); break; @@ -478,7 +490,7 @@ #endif } -int sb_dsp_detect(struct address_info *hw_config) +int sb_dsp_detect(struct address_info *hw_config, int pci, int pciio) { sb_devc sb_info; sb_devc *devc = &sb_info; @@ -508,7 +520,22 @@ devc->dma8 = hw_config->dma; devc->dma16 = -1; - + devc->pcibase = pciio; + + if(pci == SB_PCI_ESSMAESTRO) + { + devc->model = MDL_ESSPCI; + devc->caps |= SB_PCI_IRQ; + hw_config->driver_use_1 |= SB_PCI_IRQ; + hw_config->card_subtype = MDL_ESSPCI; + } + + if(pci == SB_PCI_YAMAHA) + { + devc->caps |= SB_PCI_IRQ; + hw_config->driver_use_1 |= SB_PCI_IRQ; + } + if (acer) { cli(); @@ -569,6 +596,10 @@ } } } + + if(devc->type == MDL_ESSPCI) + devc->model = MDL_ESSPCI; + /* * Save device information for sb_dsp_init() */ @@ -619,7 +650,15 @@ if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI) && hw_config->irq > 0) { /* IRQ setup */ - if (request_irq(hw_config->irq, sbintr, 0, "soundblaster", devc) < 0) + + /* + * ESS PCI cards do shared PCI IRQ stuff. Since they + * will get shared PCI irq lines we must cope. + */ + + int i=(devc->caps&SB_PCI_IRQ)?SA_SHIRQ:0; + + if (request_irq(hw_config->irq, sbintr, i, "soundblaster", devc) < 0) { printk(KERN_ERR "SB: Can't allocate IRQ%d\n", hw_config->irq); return 0; diff -u --recursive --new-file v2.2.2/linux/drivers/sound/sb_mixer.c linux/drivers/sound/sb_mixer.c --- v2.2.2/linux/drivers/sound/sb_mixer.c Mon Jan 25 17:44:34 1999 +++ linux/drivers/sound/sb_mixer.c Sun Mar 7 15:22:06 1999 @@ -673,6 +673,7 @@ switch (devc->model) { + case MDL_ESSPCI: case MDL_SBPRO: case MDL_AZTECH: case MDL_JAZZ: diff -u --recursive --new-file v2.2.2/linux/drivers/sound/sequencer.c linux/drivers/sound/sequencer.c --- v2.2.2/linux/drivers/sound/sequencer.c Tue Jan 19 11:32:52 1999 +++ linux/drivers/sound/sequencer.c Sun Mar 7 15:22:06 1999 @@ -1105,7 +1105,7 @@ */ for (i = 0; i < max_mididev; i++) - if (!midi_opened[i]) + if (!midi_opened[i] && midi_devs[i]) { if ((retval = midi_devs[i]->open(i, mode, sequencer_midi_input, sequencer_midi_output)) >= 0) @@ -1411,7 +1411,7 @@ case SNDCTL_SEQ_TESTMIDI: if (__get_user(midi_dev, (int *)arg)) return -EFAULT; - if (midi_dev < 0 || midi_dev >= max_mididev) + if (midi_dev < 0 || midi_dev >= max_mididev || !midi_devs[midi_dev]) return -ENXIO; if (!midi_opened[midi_dev] && @@ -1529,7 +1529,7 @@ case SNDCTL_MIDI_INFO: if (get_user(dev, (int *)(&(((struct midi_info *)arg)->device)))) return -EFAULT; - if (dev < 0 || dev >= max_mididev) + if (dev < 0 || dev >= max_mididev || !midi_devs[dev]) return -ENXIO; midi_devs[dev]->info.device = dev; return copy_to_user(arg, &midi_devs[dev]->info, sizeof(struct midi_info))?-EFAULT:0; diff -u --recursive --new-file v2.2.2/linux/drivers/sound/sonicvibes.c linux/drivers/sound/sonicvibes.c --- v2.2.2/linux/drivers/sound/sonicvibes.c Fri Jan 8 22:36:12 1999 +++ linux/drivers/sound/sonicvibes.c Sun Mar 7 10:37:54 1999 @@ -1431,8 +1431,6 @@ if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) return -EAGAIN; db->mapped = 1; - vma->vm_file = file; - file->f_count++; return 0; } diff -u --recursive --new-file v2.2.2/linux/drivers/sound/sound_core.c linux/drivers/sound/sound_core.c --- v2.2.2/linux/drivers/sound/sound_core.c Tue Feb 23 15:21:34 1999 +++ linux/drivers/sound/sound_core.c Sun Mar 7 15:22:06 1999 @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff -u --recursive --new-file v2.2.2/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c --- v2.2.2/linux/drivers/sound/soundcard.c Tue Jan 19 11:32:52 1999 +++ linux/drivers/sound/soundcard.c Sun Mar 7 15:22:06 1999 @@ -67,7 +67,11 @@ int sound_nblocks = 0; /* Persistent DMA buffers */ -int sound_dmap_flag = 0; /* Off by default */ +#ifdef CONFIG_SOUND_DMAP +int sound_dmap_flag = 1; +#else +int sound_dmap_flag = 0; +#endif static int soundcard_configured = 0; @@ -751,9 +755,6 @@ vma->vm_page_prot)) return -EAGAIN; - vma->vm_file = file; - file->f_count++; - dmap->mapping_flags |= DMA_MAP_MAPPED; if( audio_devs[dev]->d->mmap) @@ -802,13 +803,6 @@ return -1; } -static void destroy_special_devices(void) -{ - unregister_sound_special(6); - unregister_sound_special(1); - unregister_sound_special(8); -} - #ifdef MODULE static void #else @@ -849,11 +843,18 @@ #endif } +#ifdef MODULE + +static void destroy_special_devices(void) +{ + unregister_sound_special(6); + unregister_sound_special(1); + unregister_sound_special(8); +} + static int sound[20] = { 0 }; - -#ifdef MODULE int traceinit = 0; static int dmabuf = 0; diff -u --recursive --new-file v2.2.2/linux/drivers/sound/trix.c linux/drivers/sound/trix.c --- v2.2.2/linux/drivers/sound/trix.c Mon Dec 28 15:00:52 1998 +++ linux/drivers/sound/trix.c Sun Mar 7 15:22:06 1999 @@ -323,7 +323,7 @@ hw_config->name = "AudioTrix SB"; #ifdef CONFIG_SBDSP - return sb_dsp_detect(hw_config); + return sb_dsp_detect(hw_config, 0, 0); #else return 0; #endif diff -u --recursive --new-file v2.2.2/linux/drivers/video/Config.in linux/drivers/video/Config.in --- v2.2.2/linux/drivers/video/Config.in Wed Jan 20 23:14:06 1999 +++ linux/drivers/video/Config.in Thu Feb 25 10:02:12 1999 @@ -4,12 +4,17 @@ if [ "$CONFIG_FB" = "y" ]; then define_bool CONFIG_DUMMY_CONSOLE y - if [ "$CONFIG_APUS" = "y" ]; then - bool 'Permedia2 support' CONFIG_FB_PM2 - if [ "$CONFIG_FB_PM2" = "y" ]; then - bool ' enable FIFO disconnect feature' CONFIG_FB_PM2_FIFO_DISCONNECT - if [ "$CONFIG_APUS" = "y" ]; then - bool ' Phase5 CVisionPPC/BVisionPPC support' CONFIG_FB_PM2_CVPPC + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_PCI" = "y" ]; then + bool 'Permedia2 support (experimental)' CONFIG_FB_PM2 + if [ "$CONFIG_FB_PM2" = "y" ]; then + if [ "$CONFIG_PCI" = "y" ]; then + bool ' enable FIFO disconnect feature' CONFIG_FB_PM2_FIFO_DISCONNECT + bool ' generic Permedia2 PCI board support' CONFIG_FB_PM2_PCI + fi + if [ "$CONFIG_AMIGA" = "y" ]; then + bool ' Phase5 CVisionPPC/BVisionPPC support' CONFIG_FB_PM2_CVPPC + fi fi fi fi @@ -19,6 +24,9 @@ if [ "$CONFIG_APOLLO" = "y" ]; then define_bool CONFIG_FB_APOLLO y fi + if [ "$CONFIG_Q40" = "y" ]; then + define_bool CONFIG_FB_Q40 y + fi if [ "$CONFIG_AMIGA" = "y" ]; then bool 'Amiga native chipset support' CONFIG_FB_AMIGA if [ "$CONFIG_FB_AMIGA" != "n" ]; then @@ -33,6 +41,7 @@ bool 'Amiga CyberVision3D support (experimental)' CONFIG_FB_VIRGE tristate 'Amiga RetinaZ3 support' CONFIG_FB_RETINAZ3 tristate 'Amiga CLgen driver' CONFIG_FB_CLGEN + bool 'Amiga FrameMaster II/Rainbow II support (experimental)' CONFIG_FB_FM2 fi fi if [ "$CONFIG_ATARI" = "y" ]; then @@ -185,6 +194,7 @@ if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \ "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VESA" = "y" -o \ "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \ + "$CONFIG_FB_Q40" = "y" -o \ "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ @@ -195,6 +205,7 @@ if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \ "$CONFIG_FB_VIRTUAL" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \ + "$CONFIG_FB_Q40" = "m" -o \ "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ @@ -218,7 +229,8 @@ "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ - "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" ]; then + "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ + "$CONFIG_FB_FM2" = "y" ]; then define_bool CONFIG_FBCON_CFB32 y else if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ diff -u --recursive --new-file v2.2.2/linux/drivers/video/Makefile linux/drivers/video/Makefile --- v2.2.2/linux/drivers/video/Makefile Wed Jan 20 23:14:06 1999 +++ linux/drivers/video/Makefile Thu Feb 25 10:02:12 1999 @@ -88,6 +88,10 @@ L_OBJS += dnfb.o endif +ifeq ($(CONFIG_FB_Q40),y) +L_OBJS += q40fb.o +endif + ifeq ($(CONFIG_FB_ATARI),y) L_OBJS += atafb.o else @@ -192,6 +196,10 @@ ifdef CONFIG_FB_G364 L_OBJS := $(L_OBJS) g364fb.o +endif + +ifdef CONFIG_FB_FM2 +L_OBJS := $(L_OBJS) fm2fb.o endif ifeq ($(CONFIG_FB_SBUS),y) diff -u --recursive --new-file v2.2.2/linux/drivers/video/atafb.c linux/drivers/video/atafb.c --- v2.2.2/linux/drivers/video/atafb.c Wed Jan 20 23:14:06 1999 +++ linux/drivers/video/atafb.c Thu Feb 25 10:02:11 1999 @@ -103,7 +103,7 @@ static int ovsc_offset=0, ovsc_addlen=0; static struct atafb_par { - unsigned long screen_base; + void *screen_base; int yres_virtual; #if defined ATAFB_TT || defined ATAFB_STE union { @@ -167,8 +167,8 @@ static struct fb_info fb_info; -static unsigned long screen_base; /* base address of screen */ -static unsigned long real_screen_base; /* (only for Overscan) */ +static void *screen_base; /* base address of screen */ +static void *real_screen_base; /* (only for Overscan) */ static int screen_len; @@ -193,7 +193,7 @@ static unsigned external_depth; static int external_pmode; -static unsigned long external_addr = 0; +static void *external_addr = 0; static unsigned long external_len; static unsigned long external_vgaiobase = 0; static unsigned int external_bitspercol = 6; @@ -299,7 +299,7 @@ * Read a single color register and split it into * colors/transparent. Return != 0 for invalid regno. * - * void (*set_screen_base)( unsigned long s_base ) + * void (*set_screen_base)(void *s_base) * Set the base address of the displayed frame buffer. Only called * if yres_virtual > yres or xres_virtual > xres. * @@ -328,7 +328,7 @@ int (*setcolreg)( unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info ); - void (*set_screen_base)( unsigned long s_base ); + void (*set_screen_base)(void *s_base); int (*blank)( int blank_mode ); int (*pan_display)( struct fb_var_screeninfo *var, struct atafb_par *par); @@ -464,7 +464,7 @@ int mode; strcpy(fix->id,"Atari Builtin"); - fix->smem_start = (char *)real_screen_base; + fix->smem_start = real_screen_base; fix->smem_len = screen_len; fix->type=FB_TYPE_INTERLEAVED_PLANES; fix->type_aux=2; @@ -797,7 +797,7 @@ struct atafb_par *par ) { strcpy(fix->id, "Atari Builtin"); - fix->smem_start = (char *)real_screen_base; + fix->smem_start = real_screen_base; fix->smem_len = screen_len; fix->type = FB_TYPE_INTERLEAVED_PLANES; fix->type_aux = 2; @@ -1760,7 +1760,7 @@ int mode; strcpy(fix->id,"Atari Builtin"); - fix->smem_start = (char *)real_screen_base; + fix->smem_start = real_screen_base; fix->smem_len = screen_len; fix->type = FB_TYPE_INTERLEAVED_PLANES; fix->type_aux = 2; @@ -2024,7 +2024,7 @@ return 1; } -static void stste_set_screen_base(unsigned long s_base) +static void stste_set_screen_base(void *s_base) { unsigned long addr; addr= virt_to_phys(s_base); @@ -2104,8 +2104,8 @@ { strcpy(fix->id,"Unknown Extern"); - fix->smem_start=(char *)external_addr; - fix->smem_len=(external_len + PAGE_SIZE -1) & PAGE_MASK; + fix->smem_start=external_addr; + fix->smem_len = PAGE_ALIGN(external_len); if (external_depth == 1) { fix->type = FB_TYPE_PACKED_PIXELS; /* The letters 'n' and 'i' in the "atavideo=external:" stand @@ -2295,7 +2295,7 @@ /* ------ This is the same for most hardware types -------- */ -static void set_screen_base(unsigned long s_base) +static void set_screen_base(void *s_base) { unsigned long addr; addr= virt_to_phys(s_base); @@ -2804,15 +2804,13 @@ #ifdef ATAFB_EXT if (!external_addr) { #endif /* ATAFB_EXT */ - mem_req = default_mem_req + ovsc_offset + - ovsc_addlen; - mem_req = ((mem_req + PAGE_SIZE - 1) & PAGE_MASK) + PAGE_SIZE; - screen_base = (unsigned long)atari_stram_alloc(mem_req, NULL, - "atafb"); + mem_req = default_mem_req + ovsc_offset + ovsc_addlen; + mem_req = PAGE_ALIGN(mem_req) + PAGE_SIZE; + screen_base = atari_stram_alloc(mem_req, NULL, "atafb"); if (!screen_base) panic("Cannot allocate screen memory"); - memset((char *) screen_base, 0, mem_req); - pad = ((screen_base + PAGE_SIZE-1) & PAGE_MASK) - screen_base; + memset(screen_base, 0, mem_req); + pad = -(unsigned long)screen_base & (PAGE_SIZE-1); screen_base+=pad; real_screen_base=screen_base+ovsc_offset; screen_len = (mem_req - pad - ovsc_offset) & PAGE_MASK; @@ -2820,9 +2818,9 @@ if (CPU_IS_040_OR_060) { /* On a '040+, the cache mode of video RAM must be set to * write-through also for internal video hardware! */ - cache_push( virt_to_phys(screen_base), screen_len ); - kernel_set_cachemode( screen_base, screen_len, - IOMAP_WRITETHROUGH ); + cache_push(virt_to_phys(screen_base), screen_len); + kernel_set_cachemode(screen_base, screen_len, + IOMAP_WRITETHROUGH); } #ifdef ATAFB_EXT } @@ -2836,7 +2834,7 @@ screen_base = real_screen_base = external_addr; screen_len = external_len & PAGE_MASK; - memset ((char *) screen_base, 0, external_len); + memset (screen_base, 0, external_len); } #endif /* ATAFB_EXT */ diff -u --recursive --new-file v2.2.2/linux/drivers/video/atyfb.c linux/drivers/video/atyfb.c --- v2.2.2/linux/drivers/video/atyfb.c Wed Jan 20 23:14:06 1999 +++ linux/drivers/video/atyfb.c Sun Mar 7 10:38:37 1999 @@ -1,4 +1,4 @@ -/* $Id: atyfb.c,v 1.98 1999/01/14 08:50:53 geert Exp $ +/* $Id: atyfb.c,v 1.102 1999/01/21 22:44:42 geert Exp $ * linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64 * * Copyright (C) 1997-1998 Geert Uytterhoeven @@ -66,6 +66,8 @@ #include #include #include