diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/Documentation/Configure.help linux.ac/Documentation/Configure.help
--- linux.vanilla/Documentation/Configure.help Sun Jan 24 19:55:29 1999
+++ linux.ac/Documentation/Configure.help Sun Jan 24 20:19:27 1999
@@ -1749,6 +1749,18 @@
except that your Apollo won't be able to boot from it (because the
code in the ROM will be for a PC).
+Apollo support
+CONFIG_APOLLO
+ Say Y here if you want to run Linux on an MC680x0-based Apollo
+ Domain workstation such as the DN3500.
+
+Apollo 3c505 support
+CONFIG_APOLLO_ELPLUS
+ Say Y or M here if your Apollo has a 3Com 3c505 ISA Ethernet card.
+ If you don't have one made for Apollos, you can use one from a PC,
+ except that your Apollo won't be able to boot from it (because the
+ code in the ROM will be for a PC).
+
Atari native chipset support
CONFIG_FB_ATARI
This is the frame buffer device driver for the builtin graphics
@@ -4176,6 +4188,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
@@ -4366,6 +4389,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
@@ -5206,27 +5246,6 @@
up to 256Kbits. It supports both PPP and Cisco HDLC
At this point, the driver can only be compiled as a module.
-COSA/SRP sync serial boards support
-CONFIG_COSA
- This is a driver for COSA and SRP synchronous serial boards.
- These boards enable to connect synchronous serial devices (for
- example base-band modems, or any other device with the X.21, V.24,
- V.35 or V.36 interface) to your Linux box. The cards can work
- as the character device, synchronous PPP network device, or the Cisco
- HDLC network device.
-
- To actually use the COSA or SRP board, you will need user-space
- utilities for downloading the firmware to the cards and to set
- them up. Look at the http://www.fi.muni.cz/~kas/cosa/ for more
- information about the cards (including the pointer to the user-space
- utilities). You can also read the comment at the top of the
- drivers/net/cosa.c for details about the cards and the driver itself.
-
- The driver will be compiled as a module ( = code which can be
- inserted in and removed from the running kernel whenever you want).
- The module will be called cosa.o. For general information about
- modules read Documentation/modules.txt.
-
WAN Drivers
CONFIG_WAN_DRIVERS
Say Y to this option if your Linux box contains a WAN card and you
@@ -9353,6 +9372,11 @@
ISDN subsystem
CONFIG_ISDN
+ CAUTION: the ISDN driver shipped with this kernel distribution
+ is outdated and might not work without problems. An updated driver
+ is available for download. Please read http://www.isdn4linux.de
+ on the WWW for a list of servers.
+
ISDN ("Integrated Services Digital Networks", called RNIS in France)
is a special type of fully digital telephone service; it's mostly
used to connect to your Internet service provider (with SLIP or
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/Documentation/filesystems/dcache.txt linux.ac/Documentation/filesystems/dcache.txt
--- linux.vanilla/Documentation/filesystems/dcache.txt Thu Jan 1 01:00:00 1970
+++ linux.ac/Documentation/filesystems/dcache.txt Thu Jan 14 04:02:58 1999
@@ -0,0 +1,173 @@
+Some dcache details
+
+A traditional Unix system has inodes (`index nodes') as in-core
+descriptors of files. An inode refers to the actual file, not
+to a directory entry naming it. Linux v2.1.43 introduced dentries
+(`directory entries') as in-core descriptors of file names.
+
+The entire purpose of dentries is to make the map
+filename -> inode fast. An interesting side effect
+is that the kernel knows what name was used to open a file
+and that a system call getcwd() is possible.
+
+Thus, the central part of the dcache code are the lines
+ dentry = reserved_lookup(base, &this);
+ if (!dentry) {
+ dentry = cached_lookup(base, &this);
+ if (!dentry)
+ dentry = real_lookup(base, &this);
+ }
+in namei.c. The reserved_lookup() takes care of . and ..;
+the cached_lookup() is what we have the dcache for,
+and the real_lookup() goes to the filesystem.
+
+The cached_lookup() returns the value of d_lookup(),
+but does a d_revalidate() before returning, and if that fails
+and the dentry has no children, it returns NULL.
+ [This is a rather obscure part. The d_revalidate()
+ is allowed to fail for any reason - for example,
+ autofs uses a timeout to make d_revalidate fail -
+ which means that the final dentry we come up with
+ need not be the dentry that d_lookup() found.
+ This causes bugs in the vfat filesystem.
+ Moreover, if d_revalidate(D) fails but D still has
+ children, then D is used anyway.
+ This also causes bugs in the vfat filesystem.
+ I think also nfs has problems.]
+
+
+
+
+A struct dentry has five members of type struct list_head:
+ struct list_head d_hash; /* lookup hash list */
+ struct list_head d_lru; /* d_count = 0 LRU list */
+ struct list_head d_child; /* child of parent list */
+ struct list_head d_subdirs; /* our children */
+ struct list_head d_alias; /* inode alias list */
+
+ [Some of these names were very badly chosen, and lead
+ to confusion all the time. We should do a global replace
+ changing d_subdirs into d_children and d_child into d_sister.]
+
+
+
+1. d_hash
+
+The d_hash field of a dentry links the dentry into
+the list of dentries for filenames with a given hash value
+with list head dentry_hashtable[hashvalue] defined in dcache.c.
+This list is used in d_lookup() to find a dentry with given name
+and parent. It is used in d_validate() to find a dentry with
+known hash and parent.
+ [The present code takes the parent into account when
+ computing a hash. Not doing this would make the code
+ simpler and faster, possibly at the expense of a few
+ more collisions. Has anyone investigated this?]
+The d_hash field is an empty list when the file is a mount point
+(cf. d_validate) or has been deleted, or when the dentry was
+dropped for some other reason.
+
+
+d_add(D,I) will put D into its hash chain and provide it
+with the inode I. It is called by all filesystem lookup routines.
+
+d_drop(D) will remove D from its hash chain. A dentry is called
+`unhashed' when its d_hash field is an empty list.
+Sometimes dentries are dropped temporarily to make sure
+no lookup will find them. The general routine vfs_rmdir(I,D)
+will drop D if d_count=2, so that all filesystem rmdir()
+routines can return -EBUSY when D still occurs in the hash list.
+The filesystem routines for unlink and rmdir call d_delete()
+which again calls d_drop().
+
+[The d_hash field is referred to in many places that should
+not know about its existence, in the phrase
+ if (list_empty(&dentry->d_hash)) ...
+No doubt there should be a line
+ #define unhashed(d) (list_empty(&(d)->d_hash))
+in dcache.h, together with a comment describing the semantics
+of being unhashed. Then all these occurrences of d_hash can
+be removed. Next, d_drop() should be renamed d_unhash().]
+
+The dentry for the root of a mounted filesystem is returned by
+d_alloc_root() and is unhashed.
+
+
+
+2. d_lru
+The simplest list is the one joining the d_lru fields of
+dentries that had d_count = 0 at some point in time.
+The list head is the variable dentry_unused defined in dcache.c.
+The number of elements in this list is dentry_stat.nr_unused.
+There are no references to the d_lru field outside dcache.[ch].
+
+Note that d_count is incremented by dget(), invoked by d_lookup(),
+without removing the dentry from the LRU list. Thus, anyone hoping
+to find unused dentries on this list must first check d_count.
+If a dentry is not on the LRU list, its d_lru field is an
+empty list (initialized by d_alloc()).
+
+dput(D) tries to get rid of D altogether when d_count = 0, but
+puts D at the head of the LRU list if it is still on the hash list.
+Thus, every D with d_count = 0 will be on the LRU list.
+
+select_dcache(ict,pct) removes D with d_count > 0 from the
+LRU list, and moves D that are ready to be sacrificed for memory
+to the end of the list. (If ict and/or pct is given, then we are
+satisfied when the selected D's involve ict inodes or pct pages.)
+
+prune_dcache(ct) removes D with d_count > 0 from the LRU list,
+and frees unused D, stopping when ct of them have been freed.
+
+shrink_dcache_sb(sb) removes all unused D with given superblock
+from the LRU list.
+
+select_parent(D) move all unused descendants of D to the end
+of the LRU list.
+
+
+
+3. d_child and d_subdirs
+As already noted, the names are terrible. The d_child field
+does not refer to a child but to a sibling, and the d_subdirs
+field does not refer to a subdirectory but to a child, directory
+or not. These two fields form a threaded tree: the d_subdirs field
+points to the first child, and the d_child field is member of the
+circularly linked list of all children of one parent.
+
+To be more precise: this circularly linked list of all children
+of one parent P passes through the d_child fields of all children
+and through the d_subdirs field of the parent P.
+
+
+
+4. d_alias
+Somewhat similar to the above, where we had a circularly linked list
+with one special element, we here have a circularly linked list
+passing through the d_alias field of all dentries that are aliases
+of one inode, and through the i_dentry field of the inode.
+
+The dentry is added to this list by d_instantiate().
+It is removed again by dentry_iput() which is called by dput()
+and d_delete().
+
+
+
+
+So far about the lists in the dentry structure.
+Some of the routines in dcache.c have been mentioned already.
+Let me describe one of the more obscure ones.
+
+d_move(D,T) is the routine called by the filesystem code
+just before finishing the rename(D,T) call. Since both
+dentries D and T may be busy we cannot just throw one away.
+Instead they are partially interchanged:
+D and T interchange names, and D is put into T's hash queue,
+and T is unhashed; D and T interchange parents, and are put
+on the list of children of their new parent.
+The result is that the file D that got renamed is now in perfect
+shape again - it has been renamed. T, if it existed, lost its
+name string, if it was short, but perhaps this is harmless -
+let us hope no-one will ever ask for T's name anymore.
+
+
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/Documentation/sound/OPL3-SA linux.ac/Documentation/sound/OPL3-SA
--- linux.vanilla/Documentation/sound/OPL3-SA Sun Nov 8 15:08:50 1998
+++ linux.ac/Documentation/sound/OPL3-SA Tue Jan 26 10:06:26 1999
@@ -2,8 +2,7 @@
---
Note: This howto only describes how to setup the OPL3-SA1 chip; this info
-does not apply to the SA2, SA3, or SA4. Contact hannu@opensound.com for
-the support details of these other SAx chips.
+does not apply to the SA2, SA3, or SA4.
---
The Yamaha OPL3-SA1 sound chip is usually found built into motherboards, and
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/MAINTAINERS linux.ac/MAINTAINERS
--- linux.vanilla/MAINTAINERS Sun Jan 24 19:55:29 1999
+++ linux.ac/MAINTAINERS Sun Jan 24 20:19:52 1999
@@ -672,9 +672,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 --new-file --recursive --exclude-from ../exclude linux.vanilla/Makefile linux.ac/Makefile
--- linux.vanilla/Makefile Thu Jan 28 22:00:13 1999
+++ linux.ac/Makefile Thu Jan 28 22:01:38 1999
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 2
SUBLEVEL = 1
-EXTRAVERSION =
+EXTRAVERSION = -ac1
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
@@ -397,7 +397,7 @@
sums:
find . -type f -print | sort | xargs sum > .SUMS
-dep-files: scripts/mkdep archdep include/linux/version.h
+dep-files: scripts/mkdep archdep include/linux/version.h new-genksyms
scripts/mkdep init/*.c > .depend
scripts/mkdep `find $(FINDHPATH) -follow -name \*.h ! -name modversions.h -print` > .hdepend
# set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i fastdep ;done
@@ -407,7 +407,19 @@
MODVERFILE :=
ifdef CONFIG_MODVERSIONS
+
MODVERFILE := $(TOPDIR)/include/linux/modversions.h
+
+new-genksyms:
+ @$(GENKSYMS) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) /dev/null || ( echo -e "\nYou need a new version of the genksyms\
+ program, which is part of\nthe modutils package. Please read the file\
+ Documentation/Changes\nfor more information.\n"; exit 1 )
+
+else
+
+new-genksyms:
+
endif
depend dep: dep-files $(MODVERFILE)
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/alpha/kernel/process.c linux.ac/arch/alpha/kernel/process.c
--- linux.vanilla/arch/alpha/kernel/process.c Sun Jan 24 19:55:29 1999
+++ linux.ac/arch/alpha/kernel/process.c Sun Jan 24 20:20:25 1999
@@ -55,7 +55,6 @@
unsigned long init_user_stack[1024] = { STACK_MAGIC, };
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
-static struct file * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/Makefile linux.ac/arch/arm/Makefile
--- linux.vanilla/arch/arm/Makefile Tue Dec 22 23:19:25 1998
+++ linux.ac/arch/arm/Makefile Sun Jan 24 21:11:30 1999
@@ -15,9 +15,8 @@
CFLAGS_PROC :=
ASFLAGS_PROC :=
-# All processors get `-mshort-load-bytes' for now, to work around alignment
-# problems. This is more of a hack that just happens to work than a real fix
-# but it will do for now.
+# GCC 2.7 uses different options to later compilers; sort out which we have
+CONFIG_BINUTILS_NEW := $(shell if $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; then echo n; else echo y; fi)
ifeq ($(CONFIG_CPU_26),y)
PROCESSOR = armo
@@ -103,7 +102,7 @@
ZRELADDR = 0x00008000
endif
-ifeq ($(CONFIG_ARCH_EBSA285),y)
+ifeq ($(CONFIG_HOST_FOOTBRIDGE),y)
MACHINE = ebsa285
ARCHDIR = ebsa285
ZTEXTADDR = 0x00008000
@@ -119,19 +118,6 @@
COMPRESSED_HEAD = head-nexuspci.o
endif
-ifeq ($(CONFIG_ARCH_VNC),y)
-TEXTADDR = 0xC000C000
-MACHINE = vnc
-ARCHDIR = vnc
-endif
-
-ifeq ($(CONFIG_ARCH_TBOX),y)
-MACHINE = tbox
-ARCHDIR = tbox
-ZTEXTADDR = 0x80008000
-ZRELDIR = 0x80008000
-endif
-
PERL = perl
ifeq ($(CONFIG_BINUTILS_NEW),y)
LD = $(CROSS_COMPILE)ld -m elf32arm
@@ -143,7 +129,6 @@
CPP = $(CC) -E
ARCHCC := $(word 1,$(CC))
GCCLIB := `$(CC) $(CFLAGS_PROC) --print-libgcc-file-name`
-#GCCARCH := -B/usr/bin/arm-linuxelf-
HOSTCFLAGS := $(CFLAGS:-fomit-frame-pointer=)
ifeq ($(CONFIG_FRAME_POINTER),y)
CFLAGS := $(CFLAGS:-fomit-frame-pointer=)
@@ -153,6 +138,15 @@
LINKFLAGS = -T $(TOPDIR)/arch/arm/vmlinux-$(PROCESSOR).lds -e stext -Ttext $(TEXTADDR)
ZLINKFLAGS = -Ttext $(ZTEXTADDR)
+# If we're intending to debug the kernel, make sure it has line number
+# information. This gets stripped out when building (z)Image so it doesn't
+# add anything to the footprint of the running kernel.
+# Only do this on new binutils - old binutils run out of memory on the
+# final link
+ifeq ($(CONFIG_DEBUG_INFO),y)
+CFLAGS += -g
+endif
+
SUBDIRS := $(SUBDIRS:drivers=arch/arm/drivers) arch/arm/lib arch/arm/kernel arch/arm/mm
HEAD := arch/arm/kernel/head-$(PROCESSOR).o arch/arm/kernel/init_task.o
CORE_FILES := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
@@ -161,10 +155,10 @@
BLOCK_DRIVERS := drivers/block/block.a
CDROM_DRIVERS := drivers/cdrom/cdrom.a
ifeq ($(CONFIG_FB),y)
-CHAR_DRIVERS := arch/arm/drivers/char1/char1.a drivers/char/char.a arch/arm/drivers/char1/char1.a
+CHAR_DRIVERS := arch/arm/drivers/char1/char1.a drivers/char/char.a
else
ifeq ($(CONFIG_VGA_CONSOLE),y)
-CHAR_DRIVERS := arch/arm/drivers/char1/char1.a drivers/char/char.a arch/arm/drivers/char1/char1.a
+CHAR_DRIVERS := arch/arm/drivers/char1/char1.a drivers/char/char.a
else
CHAR_DRIVERS := arch/arm/drivers/char/char.a
endif
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/config.in linux.ac/arch/arm/config.in
--- linux.vanilla/arch/arm/config.in Tue Jan 19 02:57:23 1999
+++ linux.ac/arch/arm/config.in Sun Jan 24 21:11:30 1999
@@ -14,18 +14,22 @@
A5000 CONFIG_ARCH_A5K \
RiscPC CONFIG_ARCH_RPC \
EBSA-110 CONFIG_ARCH_EBSA110 \
- EBSA-285 CONFIG_ARCH_EBSA285 \
- NexusPCI CONFIG_ARCH_NEXUSPCI \
- Corel-VNC CONFIG_ARCH_VNC \
- Tbox CONFIG_ARCH_TBOX" RiscPC
+ DC21285-based-machines CONFIG_FOOTBRIDGE" RiscPC
-if [ "$CONFIG_ARCH_EBSA285" = "y" ]; then
- bool ' Include support for CATS boards' CONFIG_CATS
+if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
+ choice 'DC21285 FootBridge mode' \
+ "HostBridge CONFIG_HOST_FOOTBRIDGE \
+ Add-in CONFIG_ADDIN_FOOTBRIDGE" HostBridge
+fi
+
+if [ "$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then
+ bool ' Include support for Intel EBSA285' CONFIG_ARCH_EBSA285
+ bool ' Include support for Chalice CATS boards' CONFIG_CATS
+ bool ' Include support for Corel NetWinder' CONFIG_ARCH_NETWINDER
fi
# Select various configuration options depending on the machine type
# Easy check for Acorn-style architectures
-
if [ "$CONFIG_ARCH_ARC" = "y" -o \
"$CONFIG_ARCH_A5K" = "y" -o \
"$CONFIG_ARCH_RPC" = "y" ]; then
@@ -39,18 +43,14 @@
fi
# These machines always have PCI
-
if [ "$CONFIG_ARCH_NEXUSPCI" = "y" -o \
- "$CONFIG_ARCH_VNC" = "y" ]; then
+ "$CONFIG_FOOTBRIDGE" = "y" ]; then
define_bool CONFIG_PCI y
fi
-if [ "$CONFIG_ARCH_EBSA285" = "y" ]; then
- bool "PCI support" CONFIG_PCI
-fi
# These machines have ISA-DMA
if [ "$CONFIG_CATS" = "y" -o \
- "$CONFIG_ARCH_VNC" = "y" ]; then
+ "$CONFIG_ARCH_NETWINDER" = "y" ]; then
define_bool CONFIG_ISA_DMA y
else
define_bool CONFIG_ISA_DMA n
@@ -59,7 +59,6 @@
# Figure out whether this system uses 26-bit or 32-bit CPUs. Nobody has
# ever built a machine that can take both, and now that ARM3 is obsolete
# nobody is likely to either.
-
if [ "$CONFIG_ARCH_ARC" = "y" -o \
"$CONFIG_ARCH_A5K" = "y" ]; then
define_bool CONFIG_CPU_32 n
@@ -71,7 +70,6 @@
# Now allow the user to choose a more precise CPU. This is only used to set
# the flags we pass to GCC, not in any code.
-
choice 'Optimise for CPU' \
"ARM2 CONFIG_CPU_ARM2 \
ARM3 CONFIG_CPU_ARM3 \
@@ -80,10 +78,8 @@
SA110 CONFIG_CPU_SA110" ARM6
if [ "$CONFIG_CPU_26" = "y" ]; then
-
# For 26-bit CPUs, the page size changes with the amount of physical RAM!
# The default is 4MB but if the user has less they have to own up to it here.
-
choice 'Physical memory size' \
"4MB+ CONFIG_PAGESIZE_32 \
2MB CONFIG_PAGESIZE_16 \
@@ -94,8 +90,10 @@
mainmenu_option next_comment
comment 'Code maturity level options'
bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
-bool 'Use new compilation options (for GCC 2.8)' CONFIG_BINUTILS_NEW
-bool 'Compile kernel with frame pointer (for useful debugging)' CONFIG_FRAME_POINTER
+if [ "$CONFIG_CPU_32" = "y" ]; then
+ bool 'Enable kernel-mode alignment trap handler (EXPERIMENTAL)' CONFIG_ALIGNMENT_TRAP
+fi
+bool 'Split text into discardable sections' CONFIG_TEXT_SECTIONS
endmenu
mainmenu_option next_comment
@@ -119,7 +117,9 @@
tristate 'Parallel port support' CONFIG_PARPORT
if [ "$CONFIG_PARPORT" != "n" ]; then
- dep_tristate ' Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT
+ if [ "$CONFIG_ARCH_ARC" = "y" ]; then
+ dep_tristate ' Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT
+ fi
dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT
# If exactly one hardware type is selected then parport will optimise away
# support for loading any others. Defeat this if the user is keen.
@@ -129,11 +129,22 @@
fi
fi
fi
-if [ "$CONFIG_ARCH_EBSA285" = "y" -o \
- "$CONFIG_ARCH_EBSA110" = "y" -o \
- "$CONFIG_ARCH_VNC" = "y" ]; then
+if [ "$CONFIG_ARCH_EBSA110" = "y" -o \
+ "$CONFIG_ARCH_NETWINDER" = "y" ]; then
string 'Initial kernel command string' CONFIG_CMDLINE
fi
+if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \
+ "$CONFIG_ARCH_EBSA110" = "y" -o \
+ "$CONFIG_ARCH_EBSA285" = "y" ]; then
+ bool 'Timer and CPU usage LEDs' CONFIG_LEDS
+ if [ "$CONFIG_LEDS" = "y" ]; then
+ if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \
+ "$CONFIG_ARCH_EBSA285" = "y" ]; then
+ bool 'Timer LED' CONFIG_LEDS_TIMER
+ bool 'CPU usage LED' CONFIG_LEDS_CPU
+ fi
+ fi
+fi
endmenu
source drivers/pnp/Config.in
@@ -150,7 +161,13 @@
source drivers/char/Config.in
fi
if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
- source drivers/acorn/char/Config.in
+ if [ "$CONFIG_MOUSE" = "y" ]; then
+ if [ "$CONFIG_ARCH_RPC" != "y" ]; then
+ define_bool CONFIG_KBDMOUSE y
+ else
+ define_bool CONFIG_RPCMOUSE y
+ fi
+ fi
fi
if [ "$CONFIG_VT" = "y" ]; then
@@ -166,9 +183,11 @@
if [ "$CONFIG_NET" = "y" ]; then
source net/Config.in
-fi
-if [ "$CONFIG_NET" = "y" ]; then
+ source net/ax25/Config.in
+
+ source net/irda/Config.in
+
mainmenu_option next_comment
comment 'Network device support'
@@ -179,6 +198,15 @@
endmenu
fi
+# mainmenu_option next_comment
+# comment 'ISDN subsystem'
+#
+# tristate 'ISDN support' CONFIG_ISDN
+# if [ "$CONFIG_ISDN" != "n" ]; then
+# source drivers/isdn/Config.in
+# fi
+# endmenu
+
mainmenu_option next_comment
comment 'SCSI support'
@@ -200,21 +228,21 @@
endmenu
fi
-# mainmenu_option next_comment
-# comment 'ISDN subsystem'
-#
-# tristate 'ISDN support' CONFIG_ISDN
-# if [ "$CONFIG_ISDN" != "n" ]; then
-# source drivers/isdn/Config.in
-# fi
-# endmenu
-
source fs/Config.in
mainmenu_option next_comment
comment 'Kernel hacking'
-bool 'Debug kernel errors' CONFIG_DEBUG_ERRORS
+bool 'Compile kernel with frame pointer (for useful debugging)' CONFIG_FRAME_POINTER
+bool 'Verbose kernel error messages' CONFIG_DEBUG_ERRORS
+bool 'Verbose user fault messages' CONFIG_DEBUG_USER
+bool 'Include debugging information in kernel binary' CONFIG_DEBUG_INFO
#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+if [ "$CONFIG_CPU_26" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ bool 'Disable pgtable cache (EXPERIMENTAL)' CONFIG_NO_PGT_CACHE
+fi
+if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_CPU_32" = "y" ]; then
+ tristate 'RISC OS personality' CONFIG_ARTHUR
+fi
endmenu
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/defconfig linux.ac/arch/arm/defconfig
--- linux.vanilla/arch/arm/defconfig Sun Nov 8 15:08:43 1998
+++ linux.ac/arch/arm/defconfig Sun Jan 24 21:11:30 1999
@@ -4,47 +4,72 @@
CONFIG_ARM=y
#
+# System and processor type
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_EBSA110 is not set
+CONFIG_FOOTBRIDGE=y
+CONFIG_HOST_FOOTBRIDGE=y
+# CONFIG_ADDIN_FOOTBRIDGE is not set
+CONFIG_ARCH_EBSA285=y
+# CONFIG_CATS is not set
+CONFIG_ARCH_NETWINDER=y
+# CONFIG_ARCH_ACORN is not set
+CONFIG_PCI=y
+CONFIG_ISA_DMA=y
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM2 is not set
+# CONFIG_CPU_ARM3 is not set
+# CONFIG_CPU_ARM6 is not set
+# CONFIG_CPU_ARM7 is not set
+CONFIG_CPU_SA110=y
+# CONFIG_PAGESIZE_32 is not set
+# CONFIG_PAGESIZE_16 is not set
+# CONFIG_PAGESIZE_8 is not set
+
+#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
+# CONFIG_ALIGNMENT_TRAP is not set
+# CONFIG_TEXT_SECTIONS is not set
#
# Loadable module support
#
CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
+# CONFIG_MODVERSIONS is not set
CONFIG_KMOD=y
#
# General setup
#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-CONFIG_ARCH_RPC=y
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_NEXUSPCI is not set
-CONFIG_ARCH_ACORN=y
-# CONFIG_PCI is not set
-# CONFIG_CPU_ARM2 is not set
-# CONFIG_CPU_ARM3 is not set
-# CONFIG_CPU_ARM6 is not set
-CONFIG_CPU_SA110=y
-CONFIG_FRAME_POINTER=y
-# CONFIG_BINUTILS_NEW is not set
-CONFIG_DEBUG_ERRORS=y
CONFIG_NET=y
CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_ELF=m
-# CONFIG_BINFMT_JAVA is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
+CONFIG_CMDLINE="root=/dev/hda2 ro mem=32M parport=0x378,23 ide0=autotune"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+# CONFIG_LEDS_CPU is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
#
-# Floppy, IDE, and other block devices
+# Block devices
#
-CONFIG_BLK_DEV_FD=y
+# CONFIG_BLK_DEV_FD is not set
CONFIG_BLK_DEV_IDE=y
#
@@ -52,47 +77,186 @@
#
# CONFIG_BLK_DEV_HD_IDE is not set
CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_BLK_DEV_IDE_PCMCIA is not set
-CONFIG_BLK_DEV_IDE_CARDS=y
-CONFIG_BLK_DEV_IDE_ICSIDE=y
-# CONFIG_BLK_DEV_IDE_RAPIDE is not set
-# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_BLK_DEV_OFFBOARD=y
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_VIA82C586 is not set
+# CONFIG_BLK_DEV_CMD646 is not set
+CONFIG_BLK_DEV_SL82C105=y
+# CONFIG_IDE_CHIPSETS is not set
#
# Additional Block Devices
#
CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_STRIPED=m
+CONFIG_MD_MIRRORING=m
+CONFIG_MD_RAID5=m
CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_XD is not set
CONFIG_PARIDE_PARPORT=y
-# CONFIG_PARIDE is not set
-CONFIG_BLK_DEV_PART=y
+CONFIG_PARIDE=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
# CONFIG_BLK_DEV_HD is not set
#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+CONFIG_PRINTER=m
+CONFIG_PRINTER_READBACK=y
+CONFIG_MOUSE=y
+
+#
+# Mice
+#
+# CONFIG_ATIXL_BUSMOUSE is not set
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MS_BUSMOUSE is not set
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+CONFIG_DS1620=y
+# CONFIG_QIC02_TAPE is not set
+CONFIG_WATCHDOG=y
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+# CONFIG_WDT is not set
+CONFIG_SOFT_WATCHDOG=y
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_ACQUIRE_WDT is not set
+CONFIG_DS1620=y
+# CONFIG_NVRAM is not set
+CONFIG_NWBUTTON=y
+CONFIG_NWBUTTON_REBOOT=y
+CONFIG_RTC=y
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_FT_NORMAL_DEBUG is not set
+# CONFIG_FT_FULL_DEBUG is not set
+# CONFIG_FT_NO_TRACE is not set
+# CONFIG_FT_NO_TRACE_AT_ALL is not set
+# CONFIG_FT_STD_FDC is not set
+# CONFIG_FT_MACH2 is not set
+# CONFIG_FT_PROBE_FC10 is not set
+# CONFIG_FT_ALT_FDC is not set
+
+#
+# Console drivers
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FB_CYBER2000=y
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+CONFIG_FBCON_VGA=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+CONFIG_FBCON_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+CONFIG_FONT_ACORN_8x8=y
+
+#
# Networking options
#
-# CONFIG_PACKET is not set
+CONFIG_PACKET=y
# CONFIG_NETLINK is not set
# CONFIG_FIREWALL is not set
-# CONFIG_NET_ALIAS is not set
+CONFIG_NET_ALIAS=y
# CONFIG_FILTER is not set
CONFIG_UNIX=y
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_IP_ACCT is not set
-# CONFIG_IP_MASQUERADE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
# CONFIG_IP_ROUTER is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_ALIAS is not set
+CONFIG_IP_ALIAS=y
# CONFIG_SYN_COOKIES is not set
#
@@ -100,7 +264,7 @@
#
# CONFIG_INET_RARP is not set
CONFIG_IP_NOSR=y
-# CONFIG_SKB_LARGE is not set
+CONFIG_SKB_LARGE=y
# CONFIG_IPV6 is not set
#
@@ -112,155 +276,228 @@
# CONFIG_LAPB is not set
# CONFIG_BRIDGE is not set
# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
# CONFIG_CPU_IS_SLOW is not set
+
+#
+# QoS and/or fair queueing
+#
# CONFIG_NET_SCHED is not set
-# CONFIG_NET_PROFILE is not set
#
-# SCSI support
+# Amateur Radio support
#
-CONFIG_SCSI=y
+# CONFIG_HAMRADIO is not set
#
-# SCSI support type (disk, tape, CD-ROM)
+# IrDA subsystem support
#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-CONFIG_BLK_DEV_SR=y
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-# CONFIG_CHR_DEV_SG is not set
+# CONFIG_IRDA is not set
#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+# Network device support
#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
+CONFIG_NETDEVICES=y
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+CONFIG_NET_VENDOR_3COM=y
+# CONFIG_EL1 is not set
+# CONFIG_EL2 is not set
+# CONFIG_ELPLUS is not set
+# CONFIG_EL16 is not set
+# CONFIG_EL3 is not set
+# CONFIG_3C515 is not set
+CONFIG_VORTEX=y
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_RTL8139 is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_EISA=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_DE4X5 is not set
+CONFIG_DEC_ELCP=m
+# CONFIG_DGRS is not set
+# CONFIG_EEXPRESS_PRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_NE3210 is not set
+CONFIG_NE2K_PCI=y
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_ES3210 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_ZNET is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_DLCI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
#
-# SCSI low-level drivers
+# CCP compressors for PPP are only built as modules.
#
-CONFIG_SCSI_ACORNSCSI_3=m
-CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE=y
-CONFIG_SCSI_ACORNSCSI_SYNC=y
-CONFIG_SCSI_CUMANA_2=m
-CONFIG_SCSI_POWERTECSCSI=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_NET_RADIO is not set
+# CONFIG_TR is not set
+# CONFIG_SHAPER is not set
+# CONFIG_HOSTESS_SV11 is not set
+# CONFIG_COSA is not set
+# CONFIG_RCPCI is not set
#
-# The following drives are not fully supported
+# SCSI support
#
-CONFIG_SCSI_CUMANA_1=m
-CONFIG_SCSI_OAK1=m
-CONFIG_SCSI_PPA=m
-CONFIG_SCSI_PPA_HAVE_PEDANTIC=2
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_G_NCR5380_PORT is not set
+# CONFIG_SCSI_G_NCR5380_MEM is not set
#
-# Network device support
+# Sound
#
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_PPP=m
+CONFIG_SOUND=m
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+CONFIG_SOUND_OSS=m
+# CONFIG_SOUND_PAS is not set
+# CONFIG_SOUND_SB is not set
+CONFIG_SOUND_ADLIB=m
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+# CONFIG_SOUND_CS4232 is not set
+CONFIG_SOUND_OPL3SA2=m
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_SOFTOSS is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_VIDC is not set
+CONFIG_SOUND_WAVEARTIST=m
+CONFIG_WAVEARTIST_BASE=250
+CONFIG_WAVEARTIST_IRQ=28
+CONFIG_WAVEARTIST_DMA=5
+CONFIG_WAVEARTIST_DMA2=9
#
-# CCP compressors for PPP are only built as modules.
+# Additional low level sound drivers
#
-# CONFIG_SLIP is not set
-CONFIG_ETHER1=m
-CONFIG_ETHER3=m
-CONFIG_ETHERH=m
+# CONFIG_LOWLEVEL_SOUND is not set
#
# Filesystems
#
# CONFIG_QUOTA is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_EXT2_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
-CONFIG_PROC_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFSD=y
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-# CONFIG_CODA_FS is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_SYSV_FS is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_ADFS_FS=y
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_QNX4FS_FS is not set
# CONFIG_ROMFS_FS is not set
-# CONFIG_AUTOFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-CONFIG_ADFS_FS=y
-CONFIG_ADFS_FS=y
-# CONFIG_MAC_PARTITION is not set
-CONFIG_NLS=y
#
-# Native Language Support
+# Network File Systems
#
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_KOI8_R is not set
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+# CONFIG_NFSD_SUN is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
#
-# Character devices
+# Partition Types
#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
-# CONFIG_SERIAL_EXTENDED is not set
-CONFIG_ATOMWIDE_SERIAL=y
-CONFIG_DUALSP_SERIAL=y
-CONFIG_MOUSE=y
-CONFIG_PRINTER=m
-CONFIG_PRINTER_READBACK=y
-# CONFIG_UMISC is not set
-# CONFIG_WATCHDOG is not set
-CONFIG_RPCMOUSE=y
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+CONFIG_ACORN_PARTITION=y
+CONFIG_ACORN_PARTITION_ADFS=y
+# CONFIG_ACORN_PARTITION_ICS is not set
+# CONFIG_ACORN_PARTITION_POWERTEC is not set
+# CONFIG_ACORN_PARTITION_RISCIX is not set
+CONFIG_NLS=y
#
-# Sound
+# Native Language Support
#
-CONFIG_SOUND=m
-CONFIG_VIDC=y
-CONFIG_AUDIO=y
-DSP_BUFFSIZE=65536
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_ISO8859_9=m
+# CONFIG_NLS_ISO8859_15 is not set
+CONFIG_NLS_KOI8_R=m
#
# Kernel hacking
#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_USER is not set
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_ARTHUR is not set
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/Makefile linux.ac/arch/arm/kernel/Makefile
--- linux.vanilla/arch/arm/kernel/Makefile Tue Dec 22 23:19:26 1998
+++ linux.ac/arch/arm/kernel/Makefile Sun Jan 24 21:11:30 1999
@@ -9,31 +9,39 @@
ENTRY_OBJ = entry-$(PROCESSOR).o
O_TARGET := kernel.o
-O_OBJS := $(ENTRY_OBJ) ioport.o irq.o process.o ptrace.o setup.o \
+O_OBJS := $(ENTRY_OBJ) irq.o process.o ptrace.o setup.o \
signal.o sys_arm.o time.o traps.o
-DMA_OBJS_arc = dma-arc.o
-DMA_OBJS_a5k = dma-a5k.o
-DMA_OBJS_rpc = dma-rpc.o
-DMA_OBJS_ebsa110 = dma-dummy.o
-DMA_OBJS_ebsa285 = dma-ebsa285.o
-DMA_OBJS_nexuspci =
-DMA_OBJS_vnc = dma-vnc.o
-
-O_OBJS_arc = ecard.o iic.o fiq.o oldlatches.o
-O_OBJS_a5k = ecard.o iic.o fiq.o
-O_OBJS_rpc = ecard.o iic.o fiq.o
-O_OBJS_ebsa110 = leds-ebsa110.o
-O_OBJS_ebsa285 = leds-ebsa285.o hw-ebsa285.o
-O_OBJS_nexuspci =
-O_OBJS_vnc = leds-ebsa285.o hw-vnc.o
+ifeq ($(CONFIG_ISA_DMA),y)
+ ISA_DMA_OBJS += dma-isa.o
+endif
+
+O_OBJS_arc = dma-arc.o iic.o fiq.o oldlatches.o
+O_OBJS_a5k = dma-a5k.o iic.o fiq.o
+O_OBJS_rpc = dma-rpc.o iic.o fiq.o
+O_OBJS_ebsa110 = dma-dummy.o
+O_OBJS_ebsa285 = dma-ebsa285.o $(ISA_DMA_OBJS)
+O_OBJS_nexuspci = dma-dummy.o
+O_OBJS_co285 = dma-ebsa285.o $(ISA_DMA_OBJS)
+
+OX_OBJS_arc = dma.o
+OX_OBJS_a5k = dma.o
+OX_OBJS_rpc = dma.o
+OX_OBJS_ebsa110 =
+OX_OBJS_ebsa285 = dma.o hw-ebsa285.o
+OX_OBJS_nexuspci =
+OX_OBJS_co285 = dma.o
all: lib kernel.o $(HEAD_OBJ) init_task.o
+O_OBJS += $(O_OBJS_$(MACHINE))
+
ifeq ($(CONFIG_MODULES),y)
OX_OBJS = armksyms.o
-else
- O_OBJS += armksyms.o
+endif
+
+ifeq ($(CONFIG_ARCH_ACORN),y)
+ OX_OBJS += ecard.o
endif
ifeq ($(MACHINE),nexuspci)
@@ -46,17 +54,23 @@
endif
endif
-ifneq ($(DMA_OBJS_$(MACHINE)),)
- OX_OBJS += dma.o
- O_OBJS += $(DMA_OBJS_$(MACHINE))
- ifeq ($(CONFIG_ISA_DMA),y)
- O_OBJS += dma-isa.o
- endif
+ifdef CONFIG_LEDS
+ O_OBJS += leds-$(MACHINE).o
+endif
+
+ifeq ($(CONFIG_MODULES),y)
+ OX_OBJS += $(OX_OBJS_$(MACHINE))
else
- O_OBJS += dma-dummy.o
+ O_OBJS += $(OX_OBJS_$(MACHINE))
endif
-O_OBJS += $(O_OBJS_$(MACHINE))
+ifeq ($(CONFIG_ARTHUR),y)
+ O_OBJS += arthur.o
+else
+ ifeq ($(CONFIG_ARTHUR),m)
+ M_OBJS += arthur.o
+ endif
+endif
$(HEAD_OBJ): $(HEAD_OBJ:.o=.S)
$(CC) -D__ASSEMBLY__ -DTEXTADDR=$(TEXTADDR) -traditional -c $(HEAD_OBJ:.o=.S) -o $@
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/armksyms.c linux.ac/arch/arm/kernel/armksyms.c
--- linux.vanilla/arch/arm/kernel/armksyms.c Sun Nov 8 15:08:43 1998
+++ linux.ac/arch/arm/kernel/armksyms.c Sun Jan 24 21:11:30 1999
@@ -7,11 +7,11 @@
#include
#include
-#include
#include
#include
#include
#include
+#include
#include
#include
@@ -20,6 +20,19 @@
extern void inswb(unsigned int port, void *to, int len);
extern void outswb(unsigned int port, const void *to, int len);
+extern unsigned int local_bh_count[NR_CPUS];
+extern unsigned int local_irq_count[NR_CPUS];
+
+/*
+ * syscalls
+ */
+extern int sys_write(int, const char *, int);
+extern int sys_read(int, char *, int);
+extern int sys_lseek(int, off_t, int);
+extern int sys_open(const char *, int, int);
+extern int sys_exit(int);
+extern int sys_wait4(int, int *, int, struct rusage *);
+
/*
* libgcc functions - functions that are used internally by the
* compiler... (prototypes are not correct though, but that
@@ -62,14 +75,8 @@
EXPORT_SYMBOL(dump_fpu);
EXPORT_SYMBOL(udelay);
EXPORT_SYMBOL(xchg_str);
-
- /* expansion card support */
-#ifdef CONFIG_ARCH_ACORN
-EXPORT_SYMBOL(ecard_startfind);
-EXPORT_SYMBOL(ecard_find);
-EXPORT_SYMBOL(ecard_readchunk);
-EXPORT_SYMBOL(ecard_address);
-#endif
+EXPORT_SYMBOL(local_bh_count);
+EXPORT_SYMBOL(local_irq_count);
EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq);
@@ -167,3 +174,17 @@
EXPORT_SYMBOL(armidlist);
EXPORT_SYMBOL(armidindex);
EXPORT_SYMBOL(elf_platform);
+
+ /* syscalls */
+EXPORT_SYMBOL(sys_write);
+EXPORT_SYMBOL(sys_read);
+EXPORT_SYMBOL(sys_lseek);
+EXPORT_SYMBOL(sys_open);
+EXPORT_SYMBOL(sys_exit);
+EXPORT_SYMBOL(sys_wait4);
+
+ /* semaphores */
+EXPORT_SYMBOL_NOVERS(__down_failed);
+EXPORT_SYMBOL_NOVERS(__down_interruptible_failed);
+EXPORT_SYMBOL_NOVERS(__up_wakeup);
+
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/arthur.c linux.ac/arch/arm/kernel/arthur.c
--- linux.vanilla/arch/arm/kernel/arthur.c Thu Jan 1 01:00:00 1970
+++ linux.ac/arch/arm/kernel/arthur.c Sun Jan 24 21:11:30 1999
@@ -0,0 +1,88 @@
+/*
+ * Arthur personality
+ * Copyright (C) 1998 Philip Blundell
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+/* RISC OS doesn't have many signals, and a lot of those that it does
+ have don't map easily to any Linux equivalent. Never mind. */
+
+#define RISCOS_SIGABRT 1
+#define RISCOS_SIGFPE 2
+#define RISCOS_SIGILL 3
+#define RISCOS_SIGINT 4
+#define RISCOS_SIGSEGV 5
+#define RISCOS_SIGTERM 6
+#define RISCOS_SIGSTAK 7
+#define RISCOS_SIGUSR1 8
+#define RISCOS_SIGUSR2 9
+#define RISCOS_SIGOSERROR 10
+
+static unsigned long riscos_to_linux_signals[32] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31
+};
+
+static unsigned long linux_to_riscos_signals[32] = {
+ 0, -1, RISCOS_SIGINT, -1,
+ RISCOS_SIGILL, 5, RISCOS_SIGABRT, 7,
+ RISCOS_SIGFPE, 9, RISCOS_SIGUSR1, RISCOS_SIGSEGV,
+ RISCOS_SIGUSR2, 13, 14, RISCOS_SIGTERM,
+ 16, 17, 18, 19,
+ 20, 21, 22, 23,
+ 24, 25, 26, 27,
+ 28, 29, 30, 31
+};
+
+static void arthur_lcall7(int nr, struct pt_regs *regs)
+{
+ struct siginfo info;
+ info.si_signo = SIGSWI;
+ info.si_code = nr;
+ /* Bounce it to the emulator */
+ send_sig_info(SIGSWI, &info, current);
+}
+
+static struct exec_domain riscos_exec_domain = {
+ "Arthur", /* name */
+ (lcall7_func)arthur_lcall7,
+ PER_RISCOS, PER_RISCOS,
+ riscos_to_linux_signals,
+ linux_to_riscos_signals,
+#ifdef MODULE
+ &__this_module, /* No usage counter. */
+#else
+ NULL,
+#endif
+ NULL /* Nothing after this in the list. */
+};
+
+/*
+ * We could do with some locking to stop Arthur being removed while
+ * processes are using it.
+ */
+
+#ifdef MODULE
+int init_module(void)
+#else
+int initialise_arthur(void)
+#endif
+{
+ return register_exec_domain(&riscos_exec_domain);
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+ unregister_exec_domain(&riscos_exec_domain);
+}
+#endif
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/calls.S linux.ac/arch/arm/kernel/calls.S
--- linux.vanilla/arch/arm/kernel/calls.S Tue Dec 22 23:19:26 1998
+++ linux.ac/arch/arm/kernel/calls.S Sun Jan 24 21:11:30 1999
@@ -110,7 +110,7 @@
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_profil */
.long SYMBOL_NAME(sys_statfs)
/* 100 */ .long SYMBOL_NAME(sys_fstatfs)
- .long SYMBOL_NAME(sys_ni_syscall) /* .long _sys_ioperm */
+ .long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_socketcall)
.long SYMBOL_NAME(sys_syslog)
.long SYMBOL_NAME(sys_setitimer)
@@ -119,7 +119,7 @@
.long SYMBOL_NAME(sys_newlstat)
.long SYMBOL_NAME(sys_newfstat)
.long SYMBOL_NAME(sys_uname)
-/* 110 */ .long SYMBOL_NAME(sys_iopl)
+/* 110 */ .long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_vhangup)
.long SYMBOL_NAME(sys_idle)
.long SYMBOL_NAME(sys_syscall) /* call a syscall */
@@ -196,6 +196,10 @@
.long SYMBOL_NAME(sys_capget)
/* 185 */ .long SYMBOL_NAME(sys_capset)
.long SYMBOL_NAME(sys_sigaltstack_wrapper)
+ .long SYMBOL_NAME(sys_sendfile)
+ .long SYMBOL_NAME(sys_ni_syscall)
+ .long SYMBOL_NAME(sys_ni_syscall)
+/* 190 */ .long SYMBOL_NAME(sys_vfork_wrapper)
.rept NR_syscalls-186
.long SYMBOL_NAME(sys_ni_syscall)
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/dec21285.c linux.ac/arch/arm/kernel/dec21285.c
--- linux.vanilla/arch/arm/kernel/dec21285.c Tue Dec 22 23:19:26 1998
+++ linux.ac/arch/arm/kernel/dec21285.c Sun Jan 24 21:11:30 1999
@@ -17,8 +17,6 @@
extern void pcibios_fixup_ebsa285(struct pci_dev *dev);
extern void pcibios_init_ebsa285(void);
-extern void pcibios_fixup_vnc(struct pci_dev *dev);
-extern void pcibios_init_vnc(void);
int
pcibios_present(void)
@@ -151,10 +149,7 @@
struct pci_dev *dev;
for (dev = pci_devices; dev; dev = dev->next) {
- if (machine_is_ebsa285() || machine_is_cats())
- pcibios_fixup_ebsa285(dev);
- if (machine_is_netwinder())
- pcibios_fixup_vnc(dev);
+ pcibios_fixup_ebsa285(dev);
pcibios_write_config_byte(dev->bus->number, dev->devfn,
PCI_INTERRUPT_LINE, dev->irq);
@@ -164,18 +159,18 @@
dev->bus->number, dev->devfn,
dev->vendor, dev->device, dev->irq);
}
+ /*
+ * this ought to have a better home
+ */
if (machine_is_netwinder())
hw_init();
}
__initfunc(void pcibios_init(void))
{
- if (machine_is_ebsa285() || machine_is_cats())
- pcibios_init_ebsa285();
- if (machine_is_netwinder())
- pcibios_init_vnc();
+ pcibios_init_ebsa285();
- printk("DEC21285 PCI revision %02X\n", *(unsigned char *)0xfe000008);
+ printk(KERN_DEBUG "PCI: DEC21285 revision %02X\n", *(unsigned char *)0xfe000008);
}
__initfunc(void pcibios_fixup_bus(struct pci_bus *bus))
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/dma-arc.c linux.ac/arch/arm/kernel/dma-arc.c
--- linux.vanilla/arch/arm/kernel/dma-arc.c Sun Nov 8 15:08:43 1998
+++ linux.ac/arch/arm/kernel/dma-arc.c Sun Jan 24 21:11:31 1999
@@ -14,7 +14,7 @@
#include "dma.h"
-int arch_request_dma(dmach_t channel, dma_t *dma)
+int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_id)
{
if (channel == DMA_VIRTUAL_FLOPPY0 ||
channel == DMA_VIRTUAL_FLOPPY1)
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/dma-ebsa285.c linux.ac/arch/arm/kernel/dma-ebsa285.c
--- linux.vanilla/arch/arm/kernel/dma-ebsa285.c Tue Dec 22 23:19:26 1998
+++ linux.ac/arch/arm/kernel/dma-ebsa285.c Sun Jan 24 21:11:31 1999
@@ -30,10 +30,11 @@
case 0:
case 1: /* 21285 internal channels */
return 0;
-
+#ifdef CONFIG_ISA_DMA
case 2 ... 9:
- if (machine_is_cats())
+ if (machine_is_cats() || machine_is_netwinder())
return isa_request_dma(channel - 2, dma, dev_name);
+#endif
}
return -EINVAL;
@@ -52,10 +53,9 @@
case 0:
case 1:
break;
-#ifdef CONFIG_CATS
+#ifdef CONFIG_ISA_DMA
case 2 ... 9:
- if (machine_is_cats())
- residue = isa_get_dma_residue(channel - 2);
+ residue = isa_get_dma_residue(channel - 2, dma);
#endif
}
return residue;
@@ -70,10 +70,9 @@
* Not yet implemented
*/
break;
-#ifdef CONFIG_CATS
+#ifdef CONFIG_ISA_DMA
case 2 ... 9:
- if (machine_is_cats())
- isa_enable_dma(channel - 2, dma);
+ isa_enable_dma(channel - 2, dma);
#endif
}
}
@@ -87,15 +86,17 @@
* Not yet implemented
*/
break;
-#ifdef CONFIG_CATS
+#ifdef CONFIG_ISA_DMA
case 2 ... 9:
- if (machine_is_cats())
- isa_disable_dma(channel - 2, dma);
+ isa_disable_dma(channel - 2, dma);
#endif
}
}
__initfunc(void arch_dma_init(dma_t *dma))
{
- /* Nothing to do */
+#ifdef CONFIG_ISA_DMA
+ if (machine_is_cats() || machine_is_netwinder())
+ isa_init_dma();
+#endif
}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/dma-isa.c linux.ac/arch/arm/kernel/dma-isa.c
--- linux.vanilla/arch/arm/kernel/dma-isa.c Tue Dec 22 23:19:26 1998
+++ linux.ac/arch/arm/kernel/dma-isa.c Sun Jan 24 21:11:31 1999
@@ -11,6 +11,7 @@
* Copyright (C) 1998 Phil Blundell
*/
#include
+#include
#include
#include
@@ -18,6 +19,10 @@
#include "dma.h"
#include "dma-isa.h"
+#define ISA_DMA_MODE_READ 0x44
+#define ISA_DMA_MODE_WRITE 0x48
+#define ISA_DMA_AUTOINIT 0x10
+
#define ISA_DMA_MASK 0
#define ISA_DMA_MODE 1
#define ISA_DMA_CLRFF 2
@@ -56,25 +61,27 @@
unsigned int io_port = isa_dma_port[channel][ISA_DMA_COUNT];
int count;
- count = 1 + inb(io_port) + (inb(io_port) << 8);
+ count = 1 + inb(io_port);
+ count |= inb(io_port) << 8;
return channel < 4 ? count : (count << 1);
}
void isa_enable_dma(int channel, dma_t *dma)
{
- unsigned long address, length;
-
if (dma->invalid) {
+ unsigned long address, length;
+ unsigned int mode;
+
address = dma->buf.address;
length = dma->buf.length - 1;
- outb(address >> 24, isa_dma_port[channel][ISA_DMA_PGHI]);
outb(address >> 16, isa_dma_port[channel][ISA_DMA_PGLO]);
+ outb(address >> 24, isa_dma_port[channel][ISA_DMA_PGHI]);
if (channel >= 4) {
address >>= 1;
- length = (length >> 1) & 0xfe; /* why &0xfe? */
+ length >>= 1;
}
outb(0, isa_dma_port[channel][ISA_DMA_CLRFF]);
@@ -85,17 +92,27 @@
outb(length, isa_dma_port[channel][ISA_DMA_COUNT]);
outb(length >> 8, isa_dma_port[channel][ISA_DMA_COUNT]);
- outb(dma->dma_mode | (channel & 3), isa_dma_port[channel][ISA_DMA_MODE]);
+ mode = channel & 3;
- switch (dma->dma_mode) {
+ switch (dma->dma_mode & DMA_MODE_MASK) {
case DMA_MODE_READ:
+ mode |= ISA_DMA_MODE_READ;
dma_cache_inv(__bus_to_virt(dma->buf.address), dma->buf.length);
break;
case DMA_MODE_WRITE:
+ mode |= ISA_DMA_MODE_WRITE;
dma_cache_wback(__bus_to_virt(dma->buf.address), dma->buf.length);
break;
+
+ default:
+ break;
}
+
+ if (dma->dma_mode & DMA_AUTOINIT)
+ mode |= ISA_DMA_AUTOINIT;
+
+ outb(mode, isa_dma_port[channel][ISA_DMA_MODE]);
dma->invalid = 0;
}
outb(channel & 3, isa_dma_port[channel][ISA_DMA_MASK]);
@@ -104,4 +121,39 @@
void isa_disable_dma(int channel, dma_t *dma)
{
outb(channel | 4, isa_dma_port[channel][ISA_DMA_MASK]);
+}
+
+__initfunc(void isa_init_dma(void))
+{
+ int channel;
+
+ outb(0xff, 0x0d);
+ outb(0xff, 0xda);
+
+ for (channel = 0; channel < 8; channel++)
+ isa_disable_dma(channel, NULL);
+
+ outb(0x40, 0x0b);
+ outb(0x41, 0x0b);
+ outb(0x42, 0x0b);
+ outb(0x43, 0x0b);
+
+ outb(0xc0, 0xd6);
+ outb(0x41, 0xd6);
+ outb(0x42, 0xd6);
+ outb(0x43, 0xd6);
+
+ outb(0, 0xd4);
+
+ outb(0x10, 0x08);
+ outb(0x10, 0xd0);
+
+ outb(0x30, 0x40b);
+ outb(0x31, 0x40b);
+ outb(0x32, 0x40b);
+ outb(0x33, 0x40b);
+
+ outb(0x31, 0x4d6);
+ outb(0x32, 0x4d6);
+ outb(0x33, 0x4d6);
}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/dma-isa.h linux.ac/arch/arm/kernel/dma-isa.h
--- linux.vanilla/arch/arm/kernel/dma-isa.h Tue Dec 22 23:19:26 1998
+++ linux.ac/arch/arm/kernel/dma-isa.h Sun Jan 24 21:11:31 1999
@@ -23,3 +23,7 @@
*/
void isa_disable_dma(int channel, dma_t *dma);
+/*
+ * Initialise DMA
+ */
+void isa_init_dma(void);
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/dma-rpc.c linux.ac/arch/arm/kernel/dma-rpc.c
--- linux.vanilla/arch/arm/kernel/dma-rpc.c Sun Nov 8 15:08:43 1998
+++ linux.ac/arch/arm/kernel/dma-rpc.c Sun Jan 24 21:11:31 1999
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
#include
#include
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/dma-vnc.c linux.ac/arch/arm/kernel/dma-vnc.c
--- linux.vanilla/arch/arm/kernel/dma-vnc.c Tue Dec 22 23:19:26 1998
+++ linux.ac/arch/arm/kernel/dma-vnc.c Thu Jan 1 01:00:00 1970
@@ -1,51 +0,0 @@
-/*
- * arch/arm/kernel/dma-vnc.c
- *
- * Copyright (C) 1998 Russell King
- */
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-#include "dma.h"
-#include "dma-isa.h"
-
-int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_name)
-{
- if (channel < 8)
- return isa_request_dma(channel, dma, dev_name);
- return -EINVAL;
-}
-
-void arch_free_dma(dmach_t channel, dma_t *dma)
-{
- isa_free_dma(channel, dma);
-}
-
-int arch_get_dma_residue(dmach_t channel, dma_t *dma)
-{
- return isa_get_dma_residue(channel, dma);
-}
-
-void arch_enable_dma(dmach_t channel, dma_t *dma)
-{
- isa_enable_dma(channel, dma);
-}
-
-void arch_disable_dma(dmach_t channel, dma_t *dma)
-{
- isa_disable_dma(channel, dma);
-}
-
-__initfunc(void arch_dma_init(dma_t *dma))
-{
- /* Nothing to do */
-}
-
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/ecard.c linux.ac/arch/arm/kernel/ecard.c
--- linux.vanilla/arch/arm/kernel/ecard.c Mon Dec 28 23:09:40 1998
+++ linux.ac/arch/arm/kernel/ecard.c Sun Jan 24 21:11:31 1999
@@ -7,32 +7,41 @@
*
* Created from information from Acorns RiscOS3 PRMs
*
- * 08-Dec-1996 RMK Added code for the 9'th expansion card - the ether podule slot.
+ * 08-Dec-1996 RMK Added code for the 9'th expansion card - the ether
+ * podule slot.
* 06-May-1997 RMK Added blacklist for cards whose loader doesn't work.
- * 12-Sep-1997 RMK Created new handling of interrupt enables/disables - cards can
- * now register their own routine to control interrupts (recommended).
- * 29-Sep-1997 RMK Expansion card interrupt hardware not being re-enabled on reset from
- * Linux. (Caused cards not to respond under RiscOS without hard reset).
+ * 12-Sep-1997 RMK Created new handling of interrupt enables/disables
+ * - cards can now register their own routine to control
+ * interrupts (recommended).
+ * 29-Sep-1997 RMK Expansion card interrupt hardware not being re-enabled
+ * on reset from Linux. (Caused cards not to respond
+ * under RiscOS without hard reset).
* 15-Feb-1998 RMK Added DMA support
* 12-Sep-1998 RMK Added EASI support
+ * 10-Jan-1999 RMK Run loaders in a simulated RISC OS environment.
*/
#define ECARD_C
+#define __KERNEL_SYSCALLS__
#include
+#include
#include
#include
#include
#include
#include
#include
+#include
+#include
#include
-#include
-#include
+#include
#include
+#include
+#include
#include
-#include
+#include
#ifdef CONFIG_ARCH_ARC
#include
@@ -40,45 +49,418 @@
#define oldlatch_init()
#endif
-#define BLACKLIST_NAME(m,p,s) { m, p, NULL, s }
-#define BLACKLIST_LOADER(m,p,l) { m, p, l, NULL }
-#define BLACKLIST_NOLOADER(m,p) { m, p, noloader, blacklisted_str }
-#define BUS_ADDR(x) ((((unsigned long)(x)) << 2) + IO_BASE)
+enum req {
+ req_readbytes,
+ req_reset
+};
-extern unsigned long atomwide_serial_loader[], oak_scsi_loader[], noloader[];
-static const char blacklisted_str[] = "*loader s/w is not 32-bit compliant*";
+struct ecard_request {
+ enum req req;
+ ecard_t *ec;
+ unsigned int address;
+ unsigned int length;
+ unsigned int use_loader;
+ void *buffer;
+};
-static const struct expcard_blacklist {
+struct expcard_blacklist {
unsigned short manufacturer;
unsigned short product;
- const loader_t loader;
const char *type;
-} blacklist[] = {
-/* Cards without names */
- BLACKLIST_NAME(MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1"),
-
-/* Cards with corrected loader */
- BLACKLIST_LOADER(MANU_ATOMWIDE, PROD_ATOMWIDE_3PSERIAL, atomwide_serial_loader),
- BLACKLIST_LOADER(MANU_OAK, PROD_OAK_SCSI, oak_scsi_loader),
+};
-/* Supported cards with broken loader */
- { MANU_ALSYSTEMS, PROD_ALSYS_SCSIATAPI, noloader, "AlSystems PowerTec SCSI" },
+static pid_t ecard_pid;
+static struct wait_queue *ecard_wait;
+static struct wait_queue *ecard_done;
+static struct ecard_request *ecard_req;
+static struct task_struct *ecard_tsk;
+static ecard_t *cards;
+static ecard_t *slot_to_expcard[MAX_ECARDS];
+#ifdef HAS_EXPMASK
+static unsigned int have_expmask;
+#endif
-/* Unsupported cards with no loader */
- BLACKLIST_NOLOADER(MANU_MCS, PROD_MCS_CONNECT32)
+/* List of descriptions of cards which don't have an extended
+ * identification, or chunk directories containing a description.
+ */
+static const struct expcard_blacklist blacklist[] = {
+ { MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" }
};
+asmlinkage extern int ecard_loader_reset(volatile unsigned char *pa,
+ loader_t loader);
+asmlinkage extern int ecard_loader_read(int off, volatile unsigned char *pa,
+ loader_t loader);
extern int setup_arm_irq(int, struct irqaction *);
+extern void do_ecard_IRQ(int, struct pt_regs *);
+
+
+static void
+ecard_irq_noexpmask(int intr_no, void *dev_id, struct pt_regs *regs);
+
+static struct irqaction irqexpansioncard = {
+ ecard_irq_noexpmask, SA_INTERRUPT, 0, "expansion cards", NULL, NULL
+};
+
+static inline unsigned short
+ecard_getu16(unsigned char *v)
+{
+ return v[0] | v[1] << 8;
+}
+
+static inline signed long
+ecard_gets24(unsigned char *v)
+{
+ return v[0] | v[1] << 8 | v[2] << 16 | ((v[2] & 0x80) ? 0xff000000 : 0);
+}
+
+static inline ecard_t *
+slot_to_ecard(unsigned int slot)
+{
+ return slot < MAX_ECARDS ? slot_to_expcard[slot] : NULL;
+}
+/* ===================== Expansion card daemon ======================== */
/*
- * from linux/arch/arm/kernel/irq.c
+ * Since the loader programs on the expansion cards need to be run
+ * in a specific environment, create a separate task with this
+ * environment up, and pass requests to this task as and when we
+ * need to.
+ *
+ * This should allow 99% of loaders to be called from Linux.
+ *
+ * From a security standpoint, we trust the card vendors. This
+ * may be a misplaced trust.
*/
-extern void do_ecard_IRQ(int irq, struct pt_regs *);
+#define BUS_ADDR(x) ((((unsigned long)(x)) << 2) + IO_BASE)
+#define POD_INT_ADDR(x) ((volatile unsigned char *)\
+ ((BUS_ADDR((x)) - IO_BASE) + IO_START))
-static ecard_t expcard[MAX_ECARDS];
-static signed char irqno_to_expcard[16];
-static unsigned int ecard_numcards, ecard_numirqcards;
-static unsigned int have_expmask;
+static void
+ecard_task_reset(struct ecard_request *req)
+{
+ if (req->ec == NULL) {
+ ecard_t *ec;
+
+ for (ec = cards; ec; ec = ec->next) {
+ printk(KERN_DEBUG "Resetting card %d\n",
+ ec->slot_no);
+
+ if (ec->loader)
+ ecard_loader_reset(POD_INT_ADDR(ec->podaddr),
+ ec->loader);
+ }
+ printk(KERN_DEBUG "All cards reset\n");
+ } else if (req->ec->loader)
+ ecard_loader_reset(POD_INT_ADDR(req->ec->podaddr),
+ req->ec->loader);
+}
+
+static void
+ecard_task_readbytes(struct ecard_request *req)
+{
+ unsigned char *buf = (unsigned char *)req->buffer;
+ volatile unsigned char *base_addr =
+ (volatile unsigned char *)POD_INT_ADDR(req->ec->podaddr);
+ unsigned int len = req->length;
+
+ if (req->ec->slot_no == 8) {
+ /*
+ * The card maintains an index which
+ * increments the address into a 4096-byte
+ * page on each access. We need to keep
+ * track of the counter.
+ */
+ static unsigned int index;
+ unsigned int offset, page;
+ unsigned char byte = 0; /* keep gcc quiet */
+
+ offset = req->address & 4095;
+ page = req->address >> 12;
+
+ if (page > 256)
+ return;
+
+ page *= 4;
+
+ if (offset == 0 || index > offset) {
+ /*
+ * We need to reset the index counter.
+ */
+ *base_addr = 0;
+ index = 0;
+ }
+
+ while (index <= offset) {
+ byte = base_addr[page];
+ index += 1;
+ }
+
+ while (len--) {
+ *buf++ = byte;
+ if (len) {
+ byte = base_addr[page];
+ index += 1;
+ }
+ }
+ } else {
+ unsigned int off = req->address;
+
+ if (!req->use_loader || !req->ec->loader) {
+ off *= 4;
+ while (len--) {
+ *buf++ = base_addr[off];
+ off += 4;
+ }
+ } else {
+ while(len--) {
+ /*
+ * The following is required by some
+ * expansion card loader programs.
+ */
+ *(unsigned long *)0x108 = 0;
+ *buf++ = ecard_loader_read(off++, base_addr,
+ req->ec->loader);
+ }
+ }
+ }
+
+}
+
+#ifdef CONFIG_CPU_32
+/*
+ * Set up the expansion card daemon's environment.
+ */
+static void
+ecard_init_task(void)
+{
+ /* We want to set up the page tables for the following mapping:
+ * Virtual Physical
+ * 0x03000000 0x03000000
+ * 0x03010000 unmapped
+ * 0x03210000 0x03210000
+ * 0x03400000 unmapped
+ * 0x08000000 0x08000000
+ * 0x10000000 unmapped
+ *
+ * FIXME: we don't follow this 100% yet.
+ */
+ pgd_t *src_pgd, *dst_pgd;
+ unsigned int dst_addr = IO_START;
+
+ src_pgd = pgd_offset(current->mm, IO_BASE);
+ dst_pgd = pgd_offset(current->mm, dst_addr);
+
+ while (dst_addr < IO_START + IO_SIZE) {
+ *dst_pgd++ = *src_pgd++;
+ dst_addr += PGDIR_SIZE;
+ }
+
+ flush_tlb_range(current->mm, IO_START, IO_START + IO_SIZE);
+
+ dst_addr = EASI_START;
+ src_pgd = pgd_offset(current->mm, EASI_BASE);
+ dst_pgd = pgd_offset(current->mm, dst_addr);
+
+ while (dst_addr < EASI_START + EASI_SIZE) {
+ *dst_pgd++ = *src_pgd++;
+ dst_addr += PGDIR_SIZE;
+ }
+
+ flush_tlb_range(current->mm, EASI_START, EASI_START + EASI_SIZE);
+}
+
+static int
+ecard_task(void * unused)
+{
+ ecard_tsk = current;
+
+ current->session = 1;
+ current->pgrp = 1;
+
+ /*
+ * We don't want /any/ signals, not even SIGKILL
+ */
+ sigfillset(¤t->blocked);
+ sigemptyset(¤t->signal);
+
+ strcpy(current->comm, "kecardd");
+
+ /*
+ * Set up the environment
+ */
+ ecard_init_task();
+
+ while (1) {
+ struct ecard_request *req;
+
+ do {
+ req = xchg(&ecard_req, NULL);
+
+ if (req == NULL) {
+ sigemptyset(¤t->signal);
+ interruptible_sleep_on(&ecard_wait);
+ }
+ } while (req == NULL);
+
+ switch (req->req) {
+ case req_readbytes:
+ ecard_task_readbytes(req);
+ break;
+
+ case req_reset:
+ ecard_task_reset(req);
+ break;
+ }
+ wake_up(&ecard_done);
+ }
+}
+
+/*
+ * Wake the expansion card daemon to action our request.
+ *
+ * FIXME: The test here is not sufficient to detect if the
+ * kcardd is running.
+ */
+static inline void
+ecard_call(struct ecard_request *req)
+{
+ /*
+ * If we're called from task 0, or from an
+ * interrupt (will be keyboard interrupt),
+ * we forcefully set up the memory map, and
+ * call the loader. We can't schedule, or
+ * sleep for this call.
+ */
+ if ((current == task[0] || in_interrupt()) &&
+ req->req == req_reset && req->ec == NULL) {
+ ecard_init_task();
+ ecard_task_reset(req);
+ } else {
+ if (ecard_pid <= 0)
+ ecard_pid = kernel_thread(ecard_task, NULL, 0);
+
+ ecard_req = req;
+
+ wake_up(&ecard_wait);
+
+ sleep_on(&ecard_done);
+ }
+}
+#else
+/*
+ * On 26-bit processors, we don't need the kcardd thread to access the
+ * expansion card loaders. We do it directly.
+ */
+static inline void
+ecard_call(struct ecard_request *req)
+{
+ if (req->req == req_reset)
+ ecard_task_reset(req);
+ else
+ ecard_task_readbytes(req);
+}
+#endif
+
+/* ======================= Mid-level card control ===================== */
+/*
+ * This is called to reset the loaders for each expansion card on reboot.
+ *
+ * This is required to make sure that the card is in the correct state
+ * that RiscOS expects it to be.
+ */
+void
+ecard_reset(int slot)
+{
+ struct ecard_request req;
+
+ req.req = req_reset;
+
+ if (slot < 0)
+ req.ec = NULL;
+ else
+ req.ec = slot_to_ecard(slot);
+
+ ecard_call(&req);
+
+#ifdef HAS_EXPMASK
+ if (have_expmask && slot < 0) {
+ have_expmask |= ~0;
+ EXPMASK_ENABLE = have_expmask;
+ }
+#endif
+}
+
+static void
+ecard_readbytes(void *addr, ecard_t *ec, int off, int len, int useld)
+{
+ struct ecard_request req;
+
+ req.req = req_readbytes;
+ req.ec = ec;
+ req.address = off;
+ req.length = len;
+ req.use_loader = useld;
+ req.buffer = addr;
+
+ ecard_call(&req);
+}
+
+int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
+{
+ struct ex_chunk_dir excd;
+ int index = 16;
+ int useld = 0;
+
+ if (!ec->cid.cd)
+ return 0;
+
+ while(1) {
+ ecard_readbytes(&excd, ec, index, 8, useld);
+ index += 8;
+ if (c_id(&excd) == 0) {
+ if (!useld && ec->loader) {
+ useld = 1;
+ index = 0;
+ continue;
+ }
+ return 0;
+ }
+ if (c_id(&excd) == 0xf0) { /* link */
+ index = c_start(&excd);
+ continue;
+ }
+ if (c_id(&excd) == 0x80) { /* loader */
+ if (!ec->loader) {
+ ec->loader = (loader_t)kmalloc(c_len(&excd),
+ GFP_KERNEL);
+ ecard_readbytes(ec->loader, ec,
+ (int)c_start(&excd),
+ c_len(&excd), useld);
+ }
+ continue;
+ }
+ if (c_id(&excd) == id && num-- == 0)
+ break;
+ }
+
+ if (c_id(&excd) & 0x80) {
+ switch (c_id(&excd) & 0x70) {
+ case 0x70:
+ ecard_readbytes((unsigned char *)excd.d.string, ec,
+ (int)c_start(&excd), c_len(&excd),
+ useld);
+ break;
+ case 0x00:
+ break;
+ }
+ }
+ cd->start_offset = c_start(&excd);
+ memcpy(cd->d.string, excd.d.string, 256);
+ return 1;
+}
+
+/* ======================= Interrupt control ============================ */
static void ecard_def_irq_enable(ecard_t *ec, int irqnr)
{
@@ -100,6 +482,11 @@
#endif
}
+static int ecard_def_irq_pending(ecard_t *ec)
+{
+ return !ec->irqmask || ec->irqaddr[0] & ec->irqmask;
+}
+
static void ecard_def_fiq_enable(ecard_t *ec, int fiqnr)
{
panic("ecard_def_fiq_enable called - impossible");
@@ -110,11 +497,18 @@
panic("ecard_def_fiq_disable called - impossible");
}
+static int ecard_def_fiq_pending(ecard_t *ec)
+{
+ return !ec->fiqmask || ec->fiqaddr[0] & ec->fiqmask;
+}
+
static expansioncard_ops_t ecard_default_ops = {
ecard_def_irq_enable,
ecard_def_irq_disable,
+ ecard_def_irq_pending,
ecard_def_fiq_enable,
- ecard_def_fiq_disable
+ ecard_def_fiq_disable,
+ ecard_def_fiq_pending
};
/*
@@ -125,10 +519,9 @@
*/
void ecard_enableirq(unsigned int irqnr)
{
- irqnr &= 7;
- if (irqnr < MAX_ECARDS && irqno_to_expcard[irqnr] != -1) {
- ecard_t *ec = expcard + irqno_to_expcard[irqnr];
+ ecard_t *ec = slot_to_ecard(irqnr);
+ if (ec) {
if (!ec->ops)
ec->ops = &ecard_default_ops;
@@ -142,10 +535,9 @@
void ecard_disableirq(unsigned int irqnr)
{
- irqnr &= 7;
- if (irqnr < MAX_ECARDS && irqno_to_expcard[irqnr] != -1) {
- ecard_t *ec = expcard + irqno_to_expcard[irqnr];
+ ecard_t *ec = slot_to_ecard(irqnr);
+ if (ec) {
if (!ec->ops)
ec->ops = &ecard_default_ops;
@@ -156,10 +548,9 @@
void ecard_enablefiq(unsigned int fiqnr)
{
- fiqnr &= 7;
- if (fiqnr < MAX_ECARDS && irqno_to_expcard[fiqnr] != -1) {
- ecard_t *ec = expcard + irqno_to_expcard[fiqnr];
+ ecard_t *ec = slot_to_ecard(fiqnr);
+ if (ec) {
if (!ec->ops)
ec->ops = &ecard_default_ops;
@@ -173,10 +564,9 @@
void ecard_disablefiq(unsigned int fiqnr)
{
- fiqnr &= 7;
- if (fiqnr < MAX_ECARDS && irqno_to_expcard[fiqnr] != -1) {
- ecard_t *ec = expcard + irqno_to_expcard[fiqnr];
+ ecard_t *ec = slot_to_ecard(fiqnr);
+ if (ec) {
if (!ec->ops)
ec->ops = &ecard_default_ops;
@@ -185,41 +575,89 @@
}
}
-static void ecard_irq_noexpmask(int intr_no, void *dev_id, struct pt_regs *regs)
+static void
+ecard_dump_irq_state(ecard_t *ec)
{
- const int num_cards = ecard_numirqcards;
- int i, called = 0;
+ printk(" %d: %sclaimed, ",
+ ec->slot_no,
+ ec->claimed ? "" : "not ");
+
+ if (ec->ops && ec->ops->irqpending &&
+ ec->ops != &ecard_default_ops)
+ printk("irq %spending\n",
+ ec->ops->irqpending(ec) ? "" : "not ");
+ else
+ printk("irqaddr %p, mask = %02X, status = %02X\n",
+ ec->irqaddr, ec->irqmask, *ec->irqaddr);
+}
- for (i = 0; i < num_cards; i++) {
- if (expcard[i].claimed && expcard[i].irq &&
- (!expcard[i].irqmask ||
- expcard[i].irqaddr[0] & expcard[i].irqmask)) {
- do_ecard_IRQ(expcard[i].irq, regs);
- called ++;
+static void
+ecard_check_lockup(void)
+{
+ static int last, lockup;
+ ecard_t *ec;
+
+ /*
+ * If the timer interrupt has not run since the last million
+ * unrecognised expansion card interrupts, then there is
+ * something seriously wrong. Disable the expansion card
+ * interrupts so at least we can continue.
+ *
+ * Maybe we ought to start a timer to re-enable them some time
+ * later?
+ */
+ if (last == jiffies) {
+ lockup += 1;
+ if (lockup > 1000000) {
+ printk(KERN_ERR "\nInterrupt lockup detected - "
+ "disabling all expansion card interrupts\n");
+
+ disable_irq(IRQ_EXPANSIONCARD);
+
+ printk("Expansion card IRQ state:\n");
+
+ for (ec = cards; ec; ec = ec->next)
+ ecard_dump_irq_state(ec);
}
+ } else
+ lockup = 0;
+
+ /*
+ * If we did not recognise the source of this interrupt,
+ * warn the user, but don't flood the user with these messages.
+ */
+ if (!last || time_after(jiffies, last + 5*HZ)) {
+ last = jiffies;
+ printk(KERN_WARNING "Unrecognised interrupt from backplane\n");
}
- cli();
- if (called == 0) {
- static int last, lockup;
+}
- if (last == jiffies) {
- lockup += 1;
- if (lockup > 1000000) {
- printk(KERN_ERR "\nInterrupt lockup detected - disabling expansion card IRQs\n");
- disable_irq(intr_no);
- printk("Expansion card IRQ state:\n");
- for (i = 0; i < num_cards; i++)
- printk(" %d: %sclaimed, irqaddr = %p, irqmask = %X, status=%X\n", expcard[i].irq - 32,
- expcard[i].claimed ? "" : "not", expcard[i].irqaddr, expcard[i].irqmask, *expcard[i].irqaddr);
- }
- } else
- lockup = 0;
+static void
+ecard_irq_noexpmask(int intr_no, void *dev_id, struct pt_regs *regs)
+{
+ ecard_t *ec;
+ int called = 0;
+
+ for (ec = cards; ec; ec = ec->next) {
+ int pending;
+
+ if (!ec->claimed || ec->irq == NO_IRQ || ec->slot_no == 8)
+ continue;
- if (!last || time_after(jiffies, last + 5*HZ)) {
- last = jiffies;
- printk(KERN_ERR "\nUnrecognised interrupt from backplane\n");
+ if (ec->ops && ec->ops->irqpending)
+ pending = ec->ops->irqpending(ec);
+ else
+ pending = ecard_default_ops.irqpending(ec);
+
+ if (pending) {
+ do_ecard_IRQ(ec->irq, regs);
+ called ++;
}
}
+ cli();
+
+ if (called == 0)
+ ecard_check_lockup();
}
#ifdef HAS_EXPMASK
@@ -234,31 +672,35 @@
0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00
};
-static void ecard_irq_expmask(int intr_no, void *dev_id, struct pt_regs *regs)
+static void
+ecard_irq_expmask(int intr_no, void *dev_id, struct pt_regs *regs)
{
const unsigned int statusmask = 15;
unsigned int status;
status = EXPMASK_STATUS & statusmask;
if (status) {
- unsigned int irqno;
+ unsigned int slot;
ecard_t *ec;
again:
- irqno = first_set[status];
- ec = expcard + irqno_to_expcard[irqno];
+ slot = first_set[status];
+ ec = slot_to_ecard(slot);
if (ec->claimed) {
unsigned int oldexpmask;
/*
- * this ugly code is so that we can operate a prioritorising system.
+ * this ugly code is so that we can operate a
+ * prioritorising system:
+ *
* Card 0 highest priority
* Card 1
* Card 2
* Card 3 lowest priority
+ *
* Serial cards should go in 0/1, ethernet/scsi in 2/3
* otherwise you will lose serial data at high speeds!
*/
oldexpmask = have_expmask;
- EXPMASK_ENABLE = (have_expmask &= priority_masks[irqno]);
+ EXPMASK_ENABLE = (have_expmask &= priority_masks[slot]);
sti();
do_ecard_IRQ(ec->irq, regs);
cli();
@@ -267,15 +709,18 @@
if (status)
goto again;
} else {
- printk(KERN_WARNING "card%d: interrupt from unclaimed card???\n", irqno);
- EXPMASK_ENABLE = (have_expmask &= ~(1 << irqno));
+ printk(KERN_WARNING "card%d: interrupt from unclaimed "
+ "card???\n", slot);
+ EXPMASK_ENABLE = (have_expmask &= ~(1 << slot));
}
} else
printk(KERN_WARNING "Wild interrupt from backplane (masks)\n");
}
-static int ecard_checkirqhw(void)
+static void
+ecard_probeirqhw(void)
{
+ ecard_t *ec;
int found;
EXPMASK_ENABLE = 0x00;
@@ -283,62 +728,75 @@
found = ((EXPMASK_STATUS & 15) == 0);
EXPMASK_ENABLE = 0xff;
- return found;
+ if (!found)
+ return;
+
+ printk(KERN_DEBUG "Expansion card interrupt "
+ "management hardware found\n");
+
+ irqexpansioncard.handler = ecard_irq_expmask;
+
+ /* for each card present, set a bit to '1' */
+ have_expmask = 0x80000000;
+
+ for (ec = cards; ec; ec = ec->next)
+ have_expmask |= 1 << ec->slot_no;
+
+ EXPMASK_ENABLE = have_expmask;
}
+#else
+#define ecard_probeirqhw()
#endif
-static void ecard_readbytes(void *addr, ecard_t *ec, int off, int len, int useld)
+unsigned int ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
{
- extern int ecard_loader_read(int off, volatile unsigned int pa, loader_t loader);
- unsigned char *a = (unsigned char *)addr;
-
- if (ec->slot_no == 8) {
- static unsigned int lowaddress;
- unsigned int laddr, haddr;
- unsigned char byte = 0; /* keep gcc quiet */
-
- laddr = off & 4095; /* number of bytes to read from offset + base addr */
- haddr = off >> 12; /* offset into card from base addr */
+ switch (ec->slot_no) {
+ case 0 ... 3:
+ switch (type) {
+ case ECARD_MEMC:
+ return IO_EC_MEMC_BASE + (ec->slot_no << 12);
- if (haddr > 256)
- return;
+ case ECARD_IOC:
+ return IO_EC_IOC_BASE + (speed << 17) +
+ (ec->slot_no << 12);
- /*
- * If we require a low address or address 0, then reset, and start again...
- */
- if (!off || lowaddress > laddr) {
- outb(0, ec->podaddr);
- lowaddress = 0;
- }
- while (lowaddress <= laddr) {
- byte = inb(ec->podaddr + haddr);
- lowaddress += 1;
- }
- while (len--) {
- *a++ = byte;
- if (len) {
- byte = inb(ec->podaddr + haddr);
- lowaddress += 1;
- }
+#ifdef IO_EC_EASI_BASE
+ case ECARD_EASI:
+ return IO_EC_EASI_BASE + (ec->slot_no << 22);
+#endif
}
- } else {
- if (!useld || !ec->loader) {
- while(len--)
- *a++ = inb(ec->podaddr + (off++));
- } else {
- while(len--) {
- *(unsigned long *)0x108 = 0; /* hack for some loaders!!! */
- *a++ = ecard_loader_read(off++, BUS_ADDR(ec->podaddr), ec->loader);
- }
+ break;
+
+ case 4 ... 7:
+ switch (type) {
+#ifdef IO_EC_IOC4_BASE
+ case ECARD_IOC:
+ return IO_EC_IOC4_BASE + (speed << 17) +
+ ((ec->slot_no - 4) << 12);
+#endif
+#ifdef IO_EC_EASI_BASE
+ case ECARD_EASI:
+ return IO_EC_EASI_BASE + (ec->slot_no << 22);
+#endif
+ default:
+ break;
}
+ break;
+
+#ifdef IO_EC_MEMC8_BASE
+ case 8:
+ return IO_EC_MEMC8_BASE;
+#endif
}
+ return 0;
}
static int ecard_prints(char *buffer, ecard_t *ec)
{
char *start = buffer;
- buffer += sprintf(buffer, "\n %d: ", ec->slot_no);
+ buffer += sprintf(buffer, " %d: %s ", ec->slot_no,
+ ec->type == ECARD_EASI ? "EASI" : " ");
if (ec->cid.id == 0) {
struct in_chunk_dir incd;
@@ -346,63 +804,59 @@
buffer += sprintf(buffer, "[%04X:%04X] ",
ec->cid.manufacturer, ec->cid.product);
- if (!ec->card_desc && ec->cid.is && ec->cid.cd &&
+ if (!ec->card_desc && ec->cid.cd &&
ecard_readchunk(&incd, ec, 0xf5, 0))
ec->card_desc = incd.d.string;
if (!ec->card_desc)
ec->card_desc = "*unknown*";
- buffer += sprintf(buffer, "%s", ec->card_desc);
+ buffer += sprintf(buffer, "%s\n", ec->card_desc);
} else
- buffer += sprintf(buffer, "Simple card %d", ec->cid.id);
+ buffer += sprintf(buffer, "Simple card %d\n", ec->cid.id);
return buffer - start;
}
-static inline unsigned short ecard_getu16(unsigned char *v)
-{
- return v[0] | v[1] << 8;
-}
-
-static inline signed long ecard_gets24(unsigned char *v)
-{
- return v[0] | v[1] << 8 | v[2] << 16 | ((v[2] & 0x80) ? 0xff000000 : 0);
-}
-
/*
* Probe for an expansion card.
*
* If bit 1 of the first byte of the card is set, then the
* card does not exist.
*/
-__initfunc(static int ecard_probe(int card, int freeslot, card_type_t type))
+__initfunc(static int
+ecard_probe(int slot, card_type_t type))
{
- ecard_t *ec = expcard + freeslot;
+ ecard_t **ecp;
+ ecard_t *ec;
struct ex_ecid cid;
char buffer[200];
- int i;
+ int i, rc = -ENOMEM;
+
+ ec = kmalloc(sizeof(ecard_t), GFP_KERNEL);
- irqno_to_expcard[card] = -1;
+ if (!ec)
+ goto nodev;
- ec->slot_no = card;
+ memset(ec, 0, sizeof(ecard_t));
+
+ ec->slot_no = slot;
+ ec->type = type;
ec->irq = NO_IRQ;
ec->fiq = NO_IRQ;
ec->dma = NO_DMA;
ec->card_desc = NULL;
ec->ops = &ecard_default_ops;
+ rc = -ENODEV;
if ((ec->podaddr = ecard_address(ec, type, ECARD_SYNC)) == 0)
- return 0;
+ goto nodev;
cid.r_zero = 1;
ecard_readbytes(&cid, ec, 0, 16, 0);
if (cid.r_zero)
- return 0;
-
- irqno_to_expcard[card] = freeslot;
+ goto nodev;
- ec->type = type;
ec->cid.id = cid.r_id;
ec->cid.cd = cid.r_cd;
ec->cid.is = cid.r_is;
@@ -415,9 +869,9 @@
ec->cid.fiqmask = cid.r_fiqmask;
ec->cid.fiqoff = ecard_gets24(cid.r_fiqoff);
ec->fiqaddr =
- ec->irqaddr = (unsigned char *)BUS_ADDR(ec->podaddr);
+ ec->irqaddr = (unsigned char *)ioaddr(ec->podaddr);
- if (ec->cid.cd && ec->cid.is) {
+ if (ec->cid.is) {
ec->irqmask = ec->cid.irqmask;
ec->irqaddr += ec->cid.irqoff;
ec->fiqmask = ec->cid.fiqmask;
@@ -430,88 +884,69 @@
for (i = 0; i < sizeof(blacklist) / sizeof(*blacklist); i++)
if (blacklist[i].manufacturer == ec->cid.manufacturer &&
blacklist[i].product == ec->cid.product) {
- ec->loader = blacklist[i].loader;
ec->card_desc = blacklist[i].type;
break;
}
- ecard_prints(buffer, ec);
- printk("%s", buffer);
-
- ec->irq = 32 + card;
+ ec->irq = 32 + slot;
#ifdef IO_EC_MEMC8_BASE
- if (card == 8)
+ if (slot == 8)
ec->irq = 11;
#endif
#ifdef CONFIG_ARCH_RPC
/* On RiscPC, only first two slots have DMA capability */
- if (card < 2)
- ec->dma = 2 + card;
+ if (slot < 2)
+ ec->dma = 2 + slot;
#endif
#if 0 /* We don't support FIQs on expansion cards at the moment */
- ec->fiq = 96 + card;
+ ec->fiq = 96 + slot;
#endif
- return 1;
-}
+ rc = 0;
-/*
- * This is called to reset the loaders for each expansion card on reboot.
- *
- * This is required to make sure that the card is in the correct state
- * that RiscOS expects it to be.
- */
-void ecard_reset(int card)
-{
- extern int ecard_loader_reset(volatile unsigned int pa, loader_t loader);
+ for (ecp = &cards; *ecp; ecp = &(*ecp)->next);
- if (card >= ecard_numcards)
- return;
-
- if (card < 0) {
- for (card = 0; card < ecard_numcards; card++)
- if (expcard[card].loader)
- ecard_loader_reset(BUS_ADDR(expcard[card].podaddr),
- expcard[card].loader);
- } else
- if (expcard[card].loader)
- ecard_loader_reset(BUS_ADDR(expcard[card].podaddr),
- expcard[card].loader);
+ *ecp = ec;
-#ifdef HAS_EXPMASK
- if (have_expmask) {
- have_expmask |= ~0;
- EXPMASK_ENABLE = have_expmask;
+nodev:
+ if (rc && ec)
+ kfree(ec);
+ else {
+ slot_to_expcard[slot] = ec;
+
+ ecard_prints(buffer, ec);
+ printk("%s", buffer);
}
-#endif
+ return rc;
}
-static unsigned int ecard_startcard;
+static ecard_t *finding_pos;
void ecard_startfind(void)
{
- ecard_startcard = 0;
+ finding_pos = NULL;
}
ecard_t *ecard_find(int cid, const card_ids *cids)
{
- int card;
+ if (!finding_pos)
+ finding_pos = cards;
+ else
+ finding_pos = finding_pos->next;
+
+ for (; finding_pos; finding_pos = finding_pos->next) {
+ if (finding_pos->claimed)
+ continue;
- if (!cids) {
- for (card = ecard_startcard; card < ecard_numcards; card++)
- if (!expcard[card].claimed &&
- (expcard[card].cid.id ^ cid) == 0)
+ if (!cids) {
+ if ((finding_pos->cid.id ^ cid) == 0)
break;
- } else {
- for (card = ecard_startcard; card < ecard_numcards; card++) {
+ } else {
unsigned int manufacturer, product;
int i;
- if (expcard[card].claimed)
- continue;
-
- manufacturer = expcard[card].cid.manufacturer;
- product = expcard[card].cid.product;
+ manufacturer = finding_pos->cid.manufacturer;
+ product = finding_pos->cid.product;
for (i = 0; cids[i].manufacturer != 65535; i++)
if (manufacturer == cids[i].manufacturer &&
@@ -523,111 +958,24 @@
}
}
- ecard_startcard = card + 1;
-
- return card < ecard_numcards ? &expcard[card] : NULL;
+ return finding_pos;
}
-int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
+__initfunc(static void ecard_free_all(void))
{
- struct ex_chunk_dir excd;
- int index = 16;
- int useld = 0;
+ ecard_t *ec, *ecn;
- if (!ec->cid.is || !ec->cid.cd)
- return 0;
-
- while(1) {
- ecard_readbytes(&excd, ec, index, 8, useld);
- index += 8;
- if (c_id(&excd) == 0) {
- if (!useld && ec->loader) {
- useld = 1;
- index = 0;
- continue;
- }
- return 0;
- }
- if (c_id(&excd) == 0xf0) { /* link */
- index = c_start(&excd);
- continue;
- }
- if (c_id(&excd) == 0x80) { /* loader */
- if (!ec->loader) {
- ec->loader = (loader_t)kmalloc(c_len(&excd), GFP_KERNEL);
- ecard_readbytes(ec->loader, ec, (int)c_start(&excd), c_len(&excd), useld);
- }
- continue;
- }
- if (c_id(&excd) == id && num-- == 0)
- break;
- }
+ for (ec = cards; ec; ec = ecn) {
+ ecn = ec->next;
- if (c_id(&excd) & 0x80) {
- switch (c_id(&excd) & 0x70) {
- case 0x70:
- ecard_readbytes((unsigned char *)excd.d.string, ec,
- (int)c_start(&excd), c_len(&excd), useld);
- break;
- case 0x00:
- break;
- }
+ kfree(ec);
}
- cd->start_offset = c_start(&excd);
- memcpy(cd->d.string, excd.d.string, 256);
- return 1;
-}
-
-unsigned int ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
-{
- switch (ec->slot_no) {
- case 0 ... 3:
- switch (type) {
- case ECARD_MEMC:
- return IO_EC_MEMC_BASE + (ec->slot_no << 12);
- case ECARD_IOC:
- return IO_EC_IOC_BASE + (speed << 17) + (ec->slot_no << 12);
-
-#ifdef IO_EC_EASI_BASE
- case ECARD_EASI:
- return IO_EC_EASI_BASE + (ec->slot_no << 22);
-#endif
- }
- break;
-
- case 4 ... 7:
- switch (type) {
-#ifdef IO_EC_IOC4_BASE
- case ECARD_IOC:
- return IO_EC_IOC4_BASE + (speed << 17) + ((ec->slot_no - 4) << 12);
-#endif
-#ifdef IO_EC_EASI_BASE
- case ECARD_EASI:
- return IO_EC_EASI_BASE + (ec->slot_no << 22);
-#endif
- default:
- break;
- }
- break;
+ cards = NULL;
-#ifdef IO_EC_MEMC8_BASE
- case 8:
- return IO_EC_MEMC8_BASE;
-#endif
- }
- return 0;
+ memset(slot_to_expcard, 0, sizeof(slot_to_expcard));
}
-static struct irqaction irqexpansioncard = {
- ecard_irq_noexpmask,
- SA_INTERRUPT,
- 0,
- "expansion cards",
- NULL,
- NULL
-};
-
/*
* Initialise the expansion card system.
* Locate all hardware - interrupt management and
@@ -635,51 +983,31 @@
*/
__initfunc(void ecard_init(void))
{
- int i, nc = 0;
-
- memset(expcard, 0, sizeof(expcard));
-
-#ifdef HAS_EXPMASK
- if (ecard_checkirqhw()) {
- printk(KERN_DEBUG "Expansion card interrupt management hardware found\n");
- irqexpansioncard.handler = ecard_irq_expmask;
- irqexpansioncard.flags |= SA_IRQNOMASK;
- have_expmask = -1;
- }
-#endif
+ int slot;
- printk("Installed expansion cards:");
+ oldlatch_init();
- /*
- * First of all, probe all cards on the expansion card interrupt line
- */
- for (i = 0; i < 8; i++)
- if (ecard_probe(i, nc, ECARD_IOC) || ecard_probe(i, nc, ECARD_EASI))
- nc += 1;
- else
- have_expmask &= ~(1<
+
.equ ioc_base_high, IOC_BASE & 0xff000000
.equ ioc_base_low, IOC_BASE & 0x00ff0000
.macro disable_fiq
@@ -187,20 +191,79 @@
.endm
#elif defined(CONFIG_ARCH_EBSA285)
+#include
.macro disable_fiq
.endm
+ .equ irq_mask_pci_err_high, IRQ_MASK_PCI_ERR & 0xff000000
+ .equ irq_mask_pci_err_low, IRQ_MASK_PCI_ERR & 0x00ff0000
+
.macro get_irqnr_and_base, irqnr, irqstat, base
mov r4, #0xfe000000
ldr \irqstat, [r4, #0x180] @ get interrupts
- mov \irqnr, #0
-1001: tst \irqstat, #1
- addeq \irqnr, \irqnr, #1
- moveq \irqstat, \irqstat, lsr #1
- tsteq \irqnr, #32
- beq 1001b
- teq \irqnr, #32
+
+ tst \irqstat, #IRQ_MASK_SDRAMPARITY
+ movne \irqnr, #IRQ_SDRAMPARITY
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_UART_RX
+ movne \irqnr, #IRQ_CONRX
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_DMA1
+ movne \irqnr, #IRQ_DMA1
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_DMA2
+ movne \irqnr, #IRQ_DMA2
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_IN0
+ movne \irqnr, #IRQ_IN0
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_IN1
+ movne \irqnr, #IRQ_IN1
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_IN2
+ movne \irqnr, #IRQ_IN2
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_IN3
+ movne \irqnr, #IRQ_IN3
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_PCI
+ movne \irqnr, #IRQ_PCI
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_I2OINPOST
+ movne \irqnr, #IRQ_I2OINPOST
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_TIMER1
+ movne \irqnr, #IRQ_TIMER1
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_TIMER2
+ movne \irqnr, #IRQ_TIMER2
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_TIMER3
+ movne \irqnr, #IRQ_TIMER3
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_UART_TX
+ movne \irqnr, #IRQ_CONTX
+ bne 1001f
+
+ tst \irqstat, #irq_mask_pci_err_high
+ tsteq \irqstat, #irq_mask_pci_err_low
+ movne \irqnr, #IRQ_PCI_ERR
+ bne 1001f
+1001:
.endm
.macro irq_prio_table
@@ -227,15 +290,18 @@
.endm
#elif defined(CONFIG_ARCH_VNC)
+#include
.macro disable_fiq
.endm
.equ pci_iack_high, PCI_IACK & 0xff000000
.equ pci_iack_low, PCI_IACK & 0x00ff0000
+ .equ irq_mask_pci_err_high, IRQ_MASK_PCI_ERR & 0xff000000
+ .equ irq_mask_pci_err_low, IRQ_MASK_PCI_ERR & 0x00ff0000
.macro get_irqnr_and_base, irqnr, irqstat, base
- mov r4, #IO_BASE_ARM_CSR
+ mov r4, #ARMCSR_BASE
ldr \irqstat, [r4, #CSR_IRQ_STATUS] @ just show us the unmasked ones
@ run through hard priorities
@@ -269,7 +335,8 @@
b 1001f
1002: @ PCI errors
- tst \irqstat, #IRQ_MASK_PCI_ERR
+ tst \irqstat, #irq_mask_pci_err_high
+ tsteq \irqstat, #irq_mask_pci_err_low
movne \irqnr, #IRQ_PCI_ERR
bne 1001f
@@ -348,25 +415,6 @@
msr cpsr, \temp
.endm
- .macro initialise_traps_extra
- mrs r0, cpsr
- bic r0, r0, #31
- orr r0, r0, #0xd3
- msr cpsr, r0
- .endm
-
-
-#ifndef __ARM_ARCH_4__
-.Larm700bug: str lr, [r8]
- ldr r0, [sp, #S_PSR] @ Get calling cpsr
- msr spsr, r0
- ldmia sp, {r0 - lr}^ @ Get calling r0 - lr
- mov r0, r0
- add sp, sp, #S_PC
- ldr lr, [sp], #S_FRAME_SIZE - S_PC @ Get PC and jump over PC, PSR, OLD_R0
- movs pc, lr
-#endif
-
.macro get_current_task, rd
mov \rd, sp, lsr #13
mov \rd, \rd, lsl #13
@@ -379,231 +427,89 @@
adr\cond \reg, \label
.endm
-/*=============================================================================
- * Address exception handler
- *-----------------------------------------------------------------------------
- * These aren't too critical.
- * (they're not supposed to happen, and won't happen in 32-bit mode).
- */
-
-vector_addrexcptn:
- b vector_addrexcptn
-
-/*=============================================================================
- * Undefined FIQs
- *-----------------------------------------------------------------------------
- * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC
- * MUST PRESERVE SVC SPSR, but need to switch to SVC mode to show our msg.
- * Basically to switch modes, we *HAVE* to clobber one register... brain
- * damage alert! I don't think that we can execute any code in here in any
- * other mode than FIQ... Ok you can switch to another mode, but you can't
- * get out of that mode without clobbering one register.
- */
-_unexp_fiq: disable_fiq
- subs pc, lr, #4
-
-/*=============================================================================
- * Interrupt entry dispatcher
- *-----------------------------------------------------------------------------
- * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
- */
-vector_IRQ: @
- @ save mode specific registers
- @
- ldr r13, .LCirq
- sub lr, lr, #4
- str lr, [r13] @ save lr_IRQ
- mrs lr, spsr
- str lr, [r13, #4] @ save spsr_IRQ
- @
- @ now branch to the relevent MODE handling routine
- @
- mrs sp, cpsr @ switch to SVC mode
- bic sp, sp, #31
- orr sp, sp, #0x13
- msr spsr, sp
- and lr, lr, #15
- cmp lr, #4
- addlts pc, pc, lr, lsl #2 @ Changes mode and branches
- b __irq_invalid @ 4 - 15
- b __irq_usr @ 0 (USR_26 / USR_32)
- b __irq_invalid @ 1 (FIQ_26 / FIQ_32)
- b __irq_invalid @ 2 (IRQ_26 / IRQ_32)
- b __irq_svc @ 3 (SVC_26 / SVC_32)
-/*
- *------------------------------------------------------------------------------------------------
- * Undef instr entry dispatcher - dispatches it to the correct handler for the processor mode
- *------------------------------------------------------------------------------------------------
- * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
- */
-.LCirq: .word __temp_irq
-.LCund: .word __temp_und
-.LCabt: .word __temp_abt
-
-vector_undefinstr:
- @
- @ save mode specific registers
- @
- ldr r13, [pc, #.LCund - . - 8]
- str lr, [r13]
- mrs lr, spsr
- str lr, [r13, #4]
- @
- @ now branch to the relevent MODE handling routine
- @
- mrs sp, cpsr
- bic sp, sp, #31
- orr sp, sp, #0x13
- msr spsr, sp
- and lr, lr, #15
- cmp lr, #4
- addlts pc, pc, lr, lsl #2 @ Changes mode and branches
- b __und_invalid @ 4 - 15
- b __und_usr @ 0 (USR_26 / USR_32)
- b __und_invalid @ 1 (FIQ_26 / FIQ_32)
- b __und_invalid @ 2 (IRQ_26 / IRQ_32)
- b __und_svc @ 3 (SVC_26 / SVC_32)
-/*
- *------------------------------------------------------------------------------------------------
- * Prefetch abort dispatcher - dispatches it to the correct handler for the processor mode
- *------------------------------------------------------------------------------------------------
- * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
- */
-vector_prefetch:
- @
- @ save mode specific registers
- @
- sub lr, lr, #4
- ldr r13, .LCabt
- str lr, [r13]
- mrs lr, spsr
- str lr, [r13, #4]
- @
- @ now branch to the relevent MODE handling routine
- @
- mrs sp, cpsr
- bic sp, sp, #31
- orr sp, sp, #0x13
- msr spsr, sp
- and lr, lr, #15
- adds pc, pc, lr, lsl #2 @ Changes mode and branches
- b __pabt_invalid @ 4 - 15
- b __pabt_usr @ 0 (USR_26 / USR_32)
- b __pabt_invalid @ 1 (FIQ_26 / FIQ_32)
- b __pabt_invalid @ 2 (IRQ_26 / IRQ_32)
- b __pabt_invalid @ 3 (SVC_26 / SVC_32)
/*
- *------------------------------------------------------------------------------------------------
- * Data abort dispatcher - dispatches it to the correct handler for the processor mode
- *------------------------------------------------------------------------------------------------
- * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
+ * Invalid mode handlers
*/
-vector_data: @
- @ save mode specific registers
- @
- sub lr, lr, #8
- ldr r13, .LCabt
- str lr, [r13]
- mrs lr, spsr
- str lr, [r13, #4]
- @
- @ now branch to the relevent MODE handling routine
- @
- mrs sp, cpsr
- bic sp, sp, #31
- orr sp, sp, #0x13
- msr spsr, sp
- and lr, lr, #15
- cmp lr, #4
- addlts pc, pc, lr, lsl #2 @ Changes mode & branches
- b __dabt_invalid @ 4 - 15
- b __dabt_usr @ 0 (USR_26 / USR_32)
- b __dabt_invalid @ 1 (FIQ_26 / FIQ_32)
- b __dabt_invalid @ 2 (IRQ_26 / IRQ_32)
- b __dabt_svc @ 3 (SVC_26 / SVC_32)
+__pabt_invalid: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
+ stmia sp, {r0 - lr} @ Save XXX r0 - lr
+ ldr r4, .LCabt
+ mov r1, #BAD_PREFETCH
+ b 1f
-/*=============================================================================
- * Prefetch abort handler
- *-----------------------------------------------------------------------------
- */
-pabtmsg: .ascii "Pabt: %08lX\n\0"
- .align
-__pabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
- stmia sp, {r0 - r12} @ Save r0 - r12
- add r8, sp, #S_PC
- stmdb r8, {sp, lr}^ @ Save sp_usr lr_usr
+__dabt_invalid: sub sp, sp, #S_FRAME_SIZE
+ stmia sp, {r0 - lr} @ Save SVC r0 - lr [lr *should* be intact]
ldr r4, .LCabt
- ldmia r4, {r5 - r7} @ Get USR pc, cpsr
- stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0
+ mov r1, #BAD_DATA
+ b 1f
- mrs r7, cpsr @ Enable interrupts if they were
- bic r7, r7, #I_BIT @ previously
- msr cpsr, r7
- mov r0, r5 @ address (pc)
- mov r1, sp @ regs
- bl SYMBOL_NAME(do_PrefetchAbort) @ call abort handler
- teq r0, #0 @ Does this still apply???
- bne ret_from_exception @ Return from exception
-#ifdef DEBUG_UNDEF
- adr r0, t
- bl SYMBOL_NAME(printk)
-#endif
- mov r0, r5
- mov r1, sp
- and r2, r6, #31
- bl SYMBOL_NAME(do_undefinstr)
- ldr lr, [sp, #S_PSR] @ Get USR cpsr
- msr spsr, lr
- ldmia sp, {r0 - pc}^ @ Restore USR registers
+__irq_invalid: sub sp, sp, #S_FRAME_SIZE @ Allocate space on stack for frame
+ stmfd sp, {r0 - lr} @ Save r0 - lr
+ ldr r4, .LCirq
+ mov r1, #BAD_IRQ
+ b 1f
-__pabt_invalid: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
- stmia sp, {r0 - lr} @ Save XXX r0 - lr
- mov r7, r0 @ OLD R0
- ldr r4, .LCabt
- ldmia r4, {r5 - r7} @ Get XXX pc, cpsr
+__und_invalid: sub sp, sp, #S_FRAME_SIZE
+ stmia sp, {r0 - lr}
+ ldr r4, .LCund
+ mov r1, #BAD_UNDEFINSTR @ int reason
+
+1: mov fp, #0
+ ldmia r4, {r5 - r7} @ Get XXX pc, cpsr, old_r0
add r4, sp, #S_PC
stmia r4, {r5 - r7} @ Save XXX pc, cpsr, old_r0
- mov r0, sp @ Prefetch aborts are definitely *not*
- mov r1, #BAD_PREFETCH @ allowed in non-user modes. We cant
- and r2, r6, #31 @ recover from this problem.
+ mov r0, sp
+ and r2, r6, #31 @ int mode
b SYMBOL_NAME(bad_mode)
-#ifdef DEBUG_UNDEF
-t: .ascii "*** undef ***\r\n\0"
- .align
-#endif
-/*=============================================================================
- * Data abort handler code
- *-----------------------------------------------------------------------------
- */
-.LCprocfns: .word SYMBOL_NAME(processor)
+wfs_mask_data: .word 0x0e200110 @ WFS/RFS
+ .word 0x0fef0fff
+ .word 0x0d0d0100 @ LDF [sp]/STF [sp]
+ .word 0x0d0b0100 @ LDF [fp]/STF [fp]
+ .word 0x0f0f0f00
-__dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
- stmia sp, {r0 - r12} @ save r0 - r12
- add r3, sp, #S_PC
- stmdb r3, {sp, lr}^
- ldr r0, .LCabt
- ldmia r0, {r0 - r2} @ Get USR pc, cpsr
- stmia r3, {r0 - r2} @ Save USR pc, cpsr, old_r0
- mov fp, #0
- mrs r2, cpsr @ Enable interrupts if they were
- bic r2, r2, #I_BIT @ previously
- msr cpsr, r2
- ldr r2, .LCprocfns
- mov lr, pc
- ldr pc, [r2, #8] @ call processor specific code
- mov r3, sp
- bl SYMBOL_NAME(do_DataAbort)
- b ret_from_sys_call
+/* We get here if an undefined instruction happens and the floating
+ * point emulator is not present. If the offending instruction was
+ * a WFS, we just perform a normal return as if we had emulated the
+ * operation. This is a hack to allow some basic userland binaries
+ * to run so that the emulator module proper can be loaded. --philb
+ */
+fpe_not_present:
+ adr r10, wfs_mask_data
+ ldmia r10, {r4, r5, r6, r7, r8}
+ ldr r10, [sp, #S_PC] @ Load PC
+ sub r10, r10, #-4
+ mask_pc r10, r10
+ ldrt r10, [r10] @ get instruction
+ and r5, r10, r5
+ teq r5, r4 @ Is it WFS?
+ moveq pc, r9
+ and r5, r10, r8
+ teq r5, r6 @ Is it LDF/STF on sp or fp?
+ teqne r5, r7
+ movne pc, lr
+ tst r10, #0x00200000 @ Does it have WB
+ moveq pc, r9
+ and r4, r10, #255 @ get offset
+ and r6, r10, #0x000f0000
+ tst r10, #0x00800000 @ +/-
+ rsbeq r4, r4, #0
+ ldr r5, [sp, r6, lsr #14] @ Load reg
+ add r5, r5, r4, lsl #2
+ str r5, [sp, r6, lsr #14] @ Save reg
+ mov pc, r9
+/*
+ * SVC mode handlers
+ */
+ .align 5
__dabt_svc: sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ save r0 - r12
ldr r2, .LCabt
add r0, sp, #S_FRAME_SIZE
+ ldmia r2, {r2 - r4} @ get pc, cpsr
add r5, sp, #S_SP
mov r1, lr
- ldmia r2, {r2 - r4} @ get pc, cpsr
stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
tst r3, #I_BIT
mrseq r0, cpsr @ Enable interrupts if they were
@@ -619,29 +525,15 @@
msr spsr, r0
ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
-__dabt_invalid: sub sp, sp, #S_FRAME_SIZE
- stmia sp, {r0 - lr} @ Save SVC r0 - lr [lr *should* be intact]
- mov r7, r0
- ldr r4, .LCabt
- ldmia r4, {r5, r6} @ Get SVC pc, cpsr
- add r4, sp, #S_PC
- stmia r4, {r5, r6, r7} @ Save SVC pc, cpsr, old_r0
- mov r0, sp
- mov r1, #BAD_DATA
- and r2, r6, #31
- b SYMBOL_NAME(bad_mode)
-
-/*=============================================================================
- * Interrupt (IRQ) handler
- *-----------------------------------------------------------------------------
- */
-__irq_usr: sub sp, sp, #S_FRAME_SIZE
+ .align 5
+__irq_svc: sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ save r0 - r12
- add r8, sp, #S_PC
- stmdb r8, {sp, lr}^
- ldr r4, .LCirq
- ldmia r4, {r5 - r7} @ get saved PC, SPSR
- stmia r8, {r5 - r7} @ save pc, psr, old_r0
+ ldr r7, .LCirq
+ add r5, sp, #S_FRAME_SIZE
+ ldmia r7, {r7 - r9}
+ add r4, sp, #S_SP
+ mov r6, lr
+ stmia r4, {r5, r6, r7, r8, r9} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
1: get_irqnr_and_base r0, r6, r5
movne r1, sp
@
@@ -649,48 +541,97 @@
@
adrsvc ne, lr, 1b
bne do_IRQ
- b ret_with_reschedule
-
- irq_prio_table
+ ldr r0, [sp, #S_PSR]
+ msr spsr, r0
+ ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
-__irq_svc: sub sp, sp, #S_FRAME_SIZE
+ .align 5
+__und_svc: sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ save r0 - r12
mov r6, lr
- ldr r7, .LCirq
+ ldr r7, .LCund
ldmia r7, {r7 - r9}
add r5, sp, #S_FRAME_SIZE
add r4, sp, #S_SP
- stmia r4, {r5, r6, r7, r8, r9} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
+ stmia r4, {r5 - r9} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
+
+ adrsvc al, r9, 1f @ r9 = normal FP return
+ bl call_fpe @ lr = undefined instr return
+
+ mov r0, r5 @ unsigned long pc
+ mov r1, sp @ struct pt_regs *regs
+ bl SYMBOL_NAME(do_undefinstr)
+
+1: ldr lr, [sp, #S_PSR] @ Get SVC cpsr
+ msr spsr, lr
+ ldmia sp, {r0 - pc}^ @ Restore SVC registers
+
+ .align 5
+.LCirq: .word __temp_irq
+.LCund: .word __temp_und
+.LCabt: .word __temp_abt
+.LCprocfns: .word SYMBOL_NAME(processor)
+.LCfp: .word SYMBOL_NAME(fp_enter)
+
+ irq_prio_table
+
+/*
+ * User mode handlers
+ */
+#ifdef DEBUG_UNDEF
+t: .ascii "Prefetch -> undefined instruction\n\0"
+ .align
+#endif
+ .align 5
+__dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
+ stmia sp, {r0 - r12} @ save r0 - r12
+ add r3, sp, #S_PC
+ stmdb r3, {sp, lr}^
+ ldr r4, .LCabt
+ ldmia r4, {r0 - r2} @ Get USR pc, cpsr
+ stmia r3, {r0 - r2} @ Save USR pc, cpsr, old_r0
+
+#ifdef CONFIG_ALIGNMENT_TRAP
+ ldr r7, [r4, #OFF_CR_ALIGNMENT(__temp_abt)]
+ mcr p15, 0, r7, c1, c0
+#endif
+
+ mov fp, #0
+ mrs r2, cpsr @ Enable interrupts if they were
+ bic r2, r2, #I_BIT @ previously
+ msr cpsr, r2
+ ldr r2, .LCprocfns
+ mov lr, pc
+ ldr pc, [r2, #8] @ call processor specific code
+ mov r3, sp
+ adrsvc al, lr, ret_from_sys_call
+ b SYMBOL_NAME(do_DataAbort)
+
+ .align 5
+__irq_usr: sub sp, sp, #S_FRAME_SIZE
+ stmia sp, {r0 - r12} @ save r0 - r12
+ add r8, sp, #S_PC
+ stmdb r8, {sp, lr}^
+ ldr r4, .LCirq
+ ldmia r4, {r5 - r7} @ get saved PC, SPSR
+ stmia r8, {r5 - r7} @ save pc, psr, old_r0
+
+#ifdef CONFIG_ALIGNMENT_TRAP
+ ldr r7, [r4, #OFF_CR_ALIGNMENT(__temp_irq)]
+ mcr p15, 0, r7, c1, c0
+#endif
+
1: get_irqnr_and_base r0, r6, r5
movne r1, sp
+ adrsvc ne, lr, 1b
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@
- adrsvc ne, lr, 1b
bne do_IRQ
- ldr r0, [sp, #S_PSR]
- msr spsr, r0
- ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
-
-__irq_invalid: sub sp, sp, #S_FRAME_SIZE @ Allocate space on stack for frame
- stmfd sp, {r0 - lr} @ Save r0 - lr
- mov r7, #-1
- ldr r4, .LCirq
- ldmia r4, {r5, r6} @ get saved pc, psr
- add r4, sp, #S_PC
- stmia r4, {r5, r6, r7}
- mov fp, #0
- mov r0, sp
- mov r1, #BAD_IRQ
- b SYMBOL_NAME(bad_mode)
-
-/*=============================================================================
- * Undefined instruction handler
- *-----------------------------------------------------------------------------
- * Handles floating point instructions
- */
-.LC2: .word SYMBOL_NAME(fp_enter)
+ mov r4, #0
+ b ret_with_reschedule
+ .align 5
__und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
stmia sp, {r0 - r12} @ Save r0 - r12
add r8, sp, #S_PC
@@ -698,99 +639,311 @@
ldr r4, .LCund
ldmia r4, {r5 - r7}
stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0
+
+#ifdef CONFIG_ALIGNMENT_TRAP
+ ldr r7, [r4, #OFF_CR_ALIGNMENT(__temp_und)]
+ mcr p15, 0, r7, c1, c0
+#endif
+
mov fp, #0
- adrsvc al, r9, ret_from_exception @ r9 = normal FP return
+ adrsvc al, r9, ret_from_sys_call @ r9 = normal FP return
adrsvc al, lr, fpundefinstr @ lr = undefined instr return
-1: get_current_task r10
+call_fpe: get_current_task r10
mov r8, #1
strb r8, [r10, #TSK_USED_MATH] @ set current->used_math
add r10, r10, #TSS_FPESAVE @ r10 = workspace
- ldr r4, .LC2
+ ldr r4, .LCfp
ldr pc, [r4] @ Call FP module USR entry point
-__und_svc: sub sp, sp, #S_FRAME_SIZE
- stmia sp, {r0 - r12} @ save r0 - r12
- mov r6, lr
- ldr r7, .LCund
- ldmia r7, {r7 - r9}
- add r5, sp, #S_FRAME_SIZE
- add r4, sp, #S_SP
- stmia r4, {r5 - r9} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
-
- adrsvc al, r9, 3f @ r9 = normal FP return
- bl 1b @ lr = undefined instr return
-
- mov r0, r5 @ unsigned long pc
- mov r1, sp @ struct pt_regs *regs
- bl SYMBOL_NAME(do_undefinstr)
-
-3: ldr lr, [sp, #S_PSR] @ Get SVC cpsr
- msr spsr, lr
- ldmia sp, {r0 - pc}^ @ Restore SVC registers
-
fpundefinstr: mov r0, lr
mov r1, sp
mrs r4, cpsr @ Enable interrupts
bic r4, r4, #I_BIT
msr cpsr, r4
- adrsvc al, lr, ret_from_exception
+ adrsvc al, lr, ret_from_sys_call
b SYMBOL_NAME(do_undefinstr)
-__und_invalid: sub sp, sp, #S_FRAME_SIZE
- stmia sp, {r0 - lr}
- mov r7, r0
- ldr r4, .LCund
- ldmia r4, {r5, r6} @ Get UND/IRQ/FIQ/ABT pc, cpsr
- add r4, sp, #S_PC
- stmia r4, {r5, r6, r7} @ Save UND/IRQ/FIQ/ABT pc, cpsr, old_r0
- mov r0, sp @ struct pt_regs *regs
- mov r1, #BAD_UNDEFINSTR @ int reason
- and r2, r6, #31 @ int mode
- b SYMBOL_NAME(bad_mode) @ Does not ever return...
+ .align 5
+__pabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
+ stmia sp, {r0 - r12} @ Save r0 - r12
+ add r8, sp, #S_PC
+ stmdb r8, {sp, lr}^ @ Save sp_usr lr_usr
+ ldr r4, .LCabt
+ ldmia r4, {r5 - r7} @ Get USR pc, cpsr
+ stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0
-/* We get here if an undefined instruction happens and the floating
- * point emulator is not present. If the offending instruction was
- * a WFS, we just perform a normal return as if we had emulated the
- * operation. This is a hack to allow some basic userland binaries
- * to run so that the emulator module proper can be loaded. --philb
- */
-fpe_not_present:
- adr r10, wfs_mask_data
- ldmia r10, {r4, r5, r6, r7, r8}
- ldr r10, [sp, #S_PC] @ Load PC
- sub r10, r10, #4
- mask_pc r10, r10
- ldrt r10, [r10] @ get instruction
- and r5, r10, r5
- teq r5, r4 @ Is it WFS?
- moveq pc, r9
- and r5, r10, r8
- teq r5, r6 @ Is it LDF/STF on sp or fp?
- teqne r5, r7
- movne pc, lr
- tst r10, #0x00200000 @ Does it have WB
- moveq pc, r9
- and r4, r10, #255 @ get offset
- and r6, r10, #0x000f0000
- tst r10, #0x00800000 @ +/-
- rsbeq r4, r4, #0
- ldr r5, [sp, r6, lsr #14] @ Load reg
- add r5, r5, r4, lsl #2
- str r5, [sp, r6, lsr #14] @ Save reg
- mov pc, r9
+#ifdef CONFIG_ALIGNMENT_TRAP
+ ldr r7, [r4, #OFF_CR_ALIGNMENT(__temp_abt)]
+ mcr p15, 0, r7, c1, c0
+#endif
-wfs_mask_data: .word 0x0e200110 @ WFS
- .word 0x0fff0fff
- .word 0x0d0d0100 @ LDF [sp]/STF [sp]
- .word 0x0d0b0100 @ LDF [fp]/STF [fp]
- .word 0x0f0f0f00
+ mrs r7, cpsr @ Enable interrupts if they were
+ bic r7, r7, #I_BIT @ previously
+ msr cpsr, r7
+ mov r0, r5 @ address (pc)
+ mov r1, sp @ regs
+ bl SYMBOL_NAME(do_PrefetchAbort) @ call abort handler
+ teq r0, #0 @ Does this still apply???
+ bne ret_from_sys_call @ Return from exception
+#ifdef DEBUG_UNDEF
+ adr r0, t
+ bl SYMBOL_NAME(printk)
+#endif
+ mov r0, r5
+ mov r1, sp
+ and r2, r6, #31
+ bl SYMBOL_NAME(do_undefinstr)
+ ldr lr, [sp, #S_PSR] @ Get USR cpsr
+ msr spsr, lr
+ ldmia sp, {r0 - pc}^ @ Restore USR registers
#include "entry-common.S"
+ .text
+
+#ifndef __ARM_ARCH_4__
+.Larm700bug: str lr, [r8]
+ ldr r0, [sp, #S_PSR] @ Get calling cpsr
+ msr spsr, r0
+ ldmia sp, {r0 - lr}^ @ Get calling r0 - lr
+ mov r0, r0
+ add sp, sp, #S_PC
+ ldr lr, [sp], #S_FRAME_SIZE - S_PC @ Get PC and jump over PC, PSR, OLD_R0
+ movs pc, lr
+#endif
+
+ .section ".text.init",#alloc,#execinstr
+/*
+ * Vector stubs. NOTE that we only align 'vector_IRQ' to a cache line boundary,
+ * and we rely on each stub being exactly 48 (1.5 cache lines) in size. This
+ * means that we only ever load two cache lines for this code, or one if we're
+ * lucky. We also copy this code to 0x200 so that we can use branches in the
+ * vectors, rather than ldr's.
+ */
+ .align 5
+__stubs_start:
+/*
+ * Interrupt dispatcher
+ * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
+ */
+vector_IRQ: @
+ @ save mode specific registers
+ @
+ ldr r13, .LCsirq
+ sub lr, lr, #4
+ str lr, [r13] @ save lr_IRQ
+ mrs lr, spsr
+ str lr, [r13, #4] @ save spsr_IRQ
+ @
+ @ now branch to the relevent MODE handling routine
+ @
+ bic r13, lr, #63
+ orr r13, r13, #0x93
+ msr spsr, r13 @ switch to SVC_32 mode
+
+ and lr, lr, #15
+ adr r13, .LCtab_irq
+ ldr lr, [r13, lr, lsl #2]
+ movs pc, lr @ Changes mode and branches
+/*
+ * Data abort dispatcher - dispatches it to the correct handler for the processor mode
+ * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
+ */
+vector_data: @
+ @ save mode specific registers
+ @
+ sub lr, lr, #8
+ ldr r13, .LCsabt
+ str lr, [r13]
+ mrs lr, spsr
+ str lr, [r13, #4]
+ @
+ @ now branch to the relevent MODE handling routine
+ @
+ bic r13, lr, #63
+ orr r13, r13, #0x93
+ msr spsr, r13 @ switch to SVC_32 mode
+
+ and lr, lr, #15
+ adr r13, .LCtab_dabt
+ ldr lr, [r13, lr, lsl #2]
+ movs pc, lr @ Changes mode and branches
+
+/*
+ * Prefetch abort dispatcher - dispatches it to the correct handler for the processor mode
+ * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
+ */
+vector_prefetch:
+ @
+ @ save mode specific registers
+ @
+ sub lr, lr, #4
+ ldr r13, .LCsabt
+ str lr, [r13] @ save lr_ABT
+ mrs lr, spsr
+ str lr, [r13, #4] @ save spsr_ABT
+ @
+ @ now branch to the relevent MODE handling routine
+ @
+ bic r13, lr, #63
+ orr r13, r13, #0x93
+ msr spsr, r13 @ switch to SVC_32 mode
+
+ ands lr, lr, #15
+ ldreq lr, .LCtab_pabt
+ ldrne lr, .LCtab_pabt + 4
+ movs pc, lr
+
+/*
+ * Undef instr entry dispatcher - dispatches it to the correct handler for the processor mode
+ * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
+ */
+vector_undefinstr:
+ @
+ @ save mode specific registers
+ @
+ ldr r13, .LCsund
+ str lr, [r13] @ save lr_UND
+ mrs lr, spsr
+ str lr, [r13, #4] @ save spsr_UND
+ @
+ @ now branch to the relevent MODE handling routine
+ @
+ bic r13, lr, #63
+ orr r13, r13, #0x93
+ msr spsr, r13 @ switch to SVC_32 mode
+
+ and lr, lr, #15
+ adr r13, .LCtab_und
+ ldr lr, [r13, lr, lsl #2]
+ movs pc, lr @ Changes mode and branches
+
+/*=============================================================================
+ * Undefined FIQs
+ *-----------------------------------------------------------------------------
+ * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC
+ * MUST PRESERVE SVC SPSR, but need to switch to SVC mode to show our msg.
+ * Basically to switch modes, we *HAVE* to clobber one register... brain
+ * damage alert! I don't think that we can execute any code in here in any
+ * other mode than FIQ... Ok you can switch to another mode, but you can't
+ * get out of that mode without clobbering one register.
+ */
+vector_FIQ: disable_fiq
+ subs pc, lr, #4
+
+/*=============================================================================
+ * Address exception handler
+ *-----------------------------------------------------------------------------
+ * These aren't too critical.
+ * (they're not supposed to happen, and won't happen in 32-bit data mode).
+ */
+
+vector_addrexcptn:
+ b vector_addrexcptn
+
+/*
+ * We group all the following data together to optimise
+ * for CPUs with separate I & D caches.
+ */
+ .align 5
+
+.LCtab_irq: .word __irq_usr @ 0 (USR_26 / USR_32)
+ .word __irq_invalid @ 1 (FIQ_26 / FIQ_32)
+ .word __irq_invalid @ 2 (IRQ_26 / IRQ_32)
+ .word __irq_svc @ 3 (SVC_26 / SVC_32)
+ .word __irq_invalid @ 4
+ .word __irq_invalid @ 5
+ .word __irq_invalid @ 6
+ .word __irq_invalid @ 7
+ .word __irq_invalid @ 8
+ .word __irq_invalid @ 9
+ .word __irq_invalid @ a
+ .word __irq_invalid @ b
+ .word __irq_invalid @ c
+ .word __irq_invalid @ d
+ .word __irq_invalid @ e
+ .word __irq_invalid @ f
+
+.LCtab_und: .word __und_usr @ 0 (USR_26 / USR_32)
+ .word __und_invalid @ 1 (FIQ_26 / FIQ_32)
+ .word __und_invalid @ 2 (IRQ_26 / IRQ_32)
+ .word __und_svc @ 3 (SVC_26 / SVC_32)
+ .word __und_invalid @ 4
+ .word __und_invalid @ 5
+ .word __und_invalid @ 6
+ .word __und_invalid @ 7
+ .word __und_invalid @ 8
+ .word __und_invalid @ 9
+ .word __und_invalid @ a
+ .word __und_invalid @ b
+ .word __und_invalid @ c
+ .word __und_invalid @ d
+ .word __und_invalid @ e
+ .word __und_invalid @ f
+
+.LCtab_dabt: .word __dabt_usr @ 0 (USR_26 / USR_32)
+ .word __dabt_invalid @ 1 (FIQ_26 / FIQ_32)
+ .word __dabt_invalid @ 2 (IRQ_26 / IRQ_32)
+ .word __dabt_svc @ 3 (SVC_26 / SVC_32)
+ .word __dabt_invalid @ 4
+ .word __dabt_invalid @ 5
+ .word __dabt_invalid @ 6
+ .word __dabt_invalid @ 7
+ .word __dabt_invalid @ 8
+ .word __dabt_invalid @ 9
+ .word __dabt_invalid @ a
+ .word __dabt_invalid @ b
+ .word __dabt_invalid @ c
+ .word __dabt_invalid @ d
+ .word __dabt_invalid @ e
+ .word __dabt_invalid @ f
+
+.LCtab_pabt: .word __pabt_usr
+ .word __pabt_invalid
+
+.LCvswi: .word vector_swi
+
+.LCsirq: .word __temp_irq
+.LCsund: .word __temp_und
+.LCsabt: .word __temp_abt
+
+__stubs_end:
+
+ .equ __real_stubs_start, .LCvectors + 0x200
+
+.LCvectors: swi SYS_ERROR0
+ b __real_stubs_start + (vector_undefinstr - __stubs_start)
+ ldr pc, __real_stubs_start + (.LCvswi - __stubs_start)
+ b __real_stubs_start + (vector_prefetch - __stubs_start)
+ b __real_stubs_start + (vector_data - __stubs_start)
+ b __real_stubs_start + (vector_addrexcptn - __stubs_start)
+ b __real_stubs_start + (vector_IRQ - __stubs_start)
+ b __real_stubs_start + (vector_FIQ - __stubs_start)
+
+ENTRY(trap_init)
+ stmfd sp!, {r4 - r6, lr}
+ adr r0, __stubs_start @ copy stubs to 0x200
+ adr r1, __stubs_end
+ mov r2, #0x200
+1: ldr r3, [r0], #4
+ str r3, [r2], #4
+ cmp r0, r1
+ blt 1b
+
+ adr r1, .LCvectors @ set up the vectors
+ mov r0, #0
+ ldmia r1, {r1, r2, r3, r4, r5, r6, ip, lr}
+ stmia r0, {r1, r2, r3, r4, r5, r6, ip, lr}
+ LOADREGS(fd, sp!, {r4 - r6, pc})
+
.data
+/*
+ * Do not reorder these, and do not insert extra data between...
+ */
+
__temp_irq: .word 0 @ saved lr_irq
.word 0 @ saved spsr_irq
.word -1 @ old_r0
@@ -800,3 +953,10 @@
__temp_abt: .word 0 @ Saved lr_abt
.word 0 @ Saved spsr_abt
.word -1 @ old_r0
+
+ .globl SYMBOL_NAME(cr_alignment)
+ .globl SYMBOL_NAME(cr_no_alignment)
+SYMBOL_NAME(cr_alignment):
+ .space 4
+SYMBOL_NAME(cr_no_alignment):
+ .space 4
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/entry-common.S linux.ac/arch/arm/kernel/entry-common.S
--- linux.vanilla/arch/arm/kernel/entry-common.S Tue Dec 22 23:19:26 1998
+++ linux.ac/arch/arm/kernel/entry-common.S Sun Jan 24 21:11:31 1999
@@ -1,51 +1,55 @@
+#include
+
/*============================================================================
* All exits to user mode from the kernel go through this code.
*/
-
-#include
-
.globl ret_from_sys_call
-ret_from_exception:
- adr r0, 1f
- ldmia r0, {r0, r1}
+ .align 5
+fast_syscall_return:
+ str r0, [sp, #S_R0 + 4] @ returned r0
+slow_syscall_return:
+ add sp, sp, #4
+ret_from_sys_call:
+ adr r0, bh_data
+ ldmia r0, {r0, r4}
ldr r0, [r0]
- ldr r1, [r1]
+ ldr r1, [r4]
tst r0, r1
blne SYMBOL_NAME(do_bottom_half)
-ret_from_intr: ldr r0, [sp, #S_PSR]
- tst r0, #3
- beq ret_with_reschedule
- b ret_from_all
+ret_with_reschedule:
+ get_current_task r1 @ check for scheduling
+ ldr r0, [r1, #TSK_NEED_RESCHED]
+ teq r0, #0
+ bne ret_reschedule
+ ldr r1, [r1, #TSK_SIGPENDING]
+ teq r1, #0 @ check for signals
+ bne ret_signal
+
+ret_from_all: restore_user_regs
ret_signal: mov r1, sp
adrsvc al, lr, ret_from_all
+ mov r2, r4
b SYMBOL_NAME(do_signal)
-2: bl SYMBOL_NAME(schedule)
+ret_reschedule: adrsvc al, lr, ret_with_reschedule
+ b SYMBOL_NAME(schedule)
-ret_from_sys_call:
- adr r0, 1f
+ret_from_exception:
+ adr r0, bh_data
ldmia r0, {r0, r1}
ldr r0, [r0]
ldr r1, [r1]
tst r0, r1
- adrsvc ne, lr, ret_from_intr
- bne SYMBOL_NAME(do_bottom_half)
-
-ret_with_reschedule:
- get_current_task r1
- ldr r0, [r1, #TSK_NEED_RESCHED]
- teq r0, #0
- bne 2b
- ldr r1, [r1, #TSK_SIGPENDING]
- teq r1, #0
- bne ret_signal
-
-ret_from_all: restore_user_regs
+ mov r4, #0
+ blne SYMBOL_NAME(do_bottom_half)
+ ldr r0, [sp, #S_PSR]
+ tst r0, #3 @ returning to user mode?
+ beq ret_with_reschedule
+ b ret_from_all
-1: .word SYMBOL_NAME(bh_mask)
- .word SYMBOL_NAME(bh_active)
+#include "calls.S"
/*=============================================================================
* SWI handler
@@ -57,140 +61,67 @@
* too worried.
*/
-#include "calls.S"
-
+ .align 5
vector_swi: save_user_regs
- mov fp, #0
mask_pc lr, lr
- ldr r6, [lr, #-4]! @ get SWI instruction
+ mov fp, #0
+ ldr r6, [lr, #-4] @ get SWI instruction
arm700_bug_check r6, r7
enable_irqs r7
-
+
+ str r4, [sp, #-4]! @ new style: (r0 = arg1, r4 = arg5)
+ adrsvc al, lr, fast_syscall_return
+
bic r6, r6, #0xff000000 @ mask off SWI op-code
eor r6, r6, #OS_NUMBER<<20 @ check OS number
cmp r6, #NR_syscalls @ check upper syscall limit
bcs 2f
- get_current_task r5
- ldr ip, [r5, #TSK_FLAGS] @ check for syscall tracing
- tst ip, #PF_TRACESYS
- bne 1f
+ adr r5, SYMBOL_NAME(sys_call_table)
- adr ip, SYMBOL_NAME(sys_call_table)
- str r4, [sp, #-4]! @ new style: (r0 = arg1, r5 = arg5)
- mov lr, pc
- ldr pc, [ip, r6, lsl #2] @ call sys routine
- add sp, sp, #4
- str r0, [sp, #S_R0] @ returned r0
- b ret_from_sys_call
+ get_current_task r7
+ ldr ip, [r7, #TSK_FLAGS] @ check for syscall tracing
+ tst ip, #PF_TRACESYS
+ ldreq pc, [r5, r6, lsl #2] @ call sys routine
-1: ldr r7, [sp, #S_IP] @ save old IP
+ ldr r7, [sp, #S_IP + 4] @ save old IP
mov r0, #0
- str r0, [sp, #S_IP] @ trace entry [IP = 0]
+ str r0, [sp, #S_IP + 4] @ trace entry [IP = 0]
bl SYMBOL_NAME(syscall_trace)
- str r7, [sp, #S_IP]
- ldmia sp, {r0 - r3} @ have to reload r0 - r3
- adr ip, SYMBOL_NAME(sys_call_table)
- str r4, [sp, #-4]! @ new style: (r0 = arg1, r5 = arg5)
+ str r7, [sp, #S_IP + 4]
+
+ ldmib sp, {r0 - r3} @ have to reload r0 - r3
mov lr, pc
- ldr pc, [ip, r6, lsl #2] @ call sys routine
- add sp, sp, #4
- str r0, [sp, #S_R0] @ returned r0
+ ldr pc, [r5, r6, lsl #2] @ call sys routine
+ str r0, [sp, #S_R0 + 4] @ returned r0
+
mov r0, #1
- str r0, [sp, #S_IP] @ trace exit [IP = 1]
+ str r0, [sp, #S_IP + 4] @ trace exit [IP = 1]
bl SYMBOL_NAME(syscall_trace)
- str r7, [sp, #S_IP]
- b ret_from_sys_call
+ str r7, [sp, #S_IP + 4]
+ b slow_syscall_return
-2: tst r6, #0x00f00000 @ is it a Unix SWI?
+2: add r1, sp, #4
+ tst r6, #0x00f00000 @ is it a Unix SWI?
bne 3f
- cmp r6, #(KSWI_SYS_BASE - KSWI_BASE)
- bcc 4f @ not private func
- bic r0, r6, #0x000f0000
- mov r1, sp
- bl SYMBOL_NAME(arm_syscall)
- b ret_from_sys_call
-
-3: eor r0, r6, #OS_NUMBER<<20 @ Put OS number back
- mov r1, sp
- bl SYMBOL_NAME(deferred)
- ldmfd sp, {r0 - r3}
- b ret_from_sys_call
-
-4: bl SYMBOL_NAME(sys_ni_syscall)
- str r0, [sp, #0] @ returned r0
- b ret_from_sys_call
+ subs r0, r6, #(KSWI_SYS_BASE - KSWI_BASE)
+ bcs SYMBOL_NAME(arm_syscall)
+ b SYMBOL_NAME(sys_ni_syscall) @ not private func
+
+3: add sp, sp, #4
+ eor r0, r6, #OS_NUMBER <<20 @ Put OS number back
+ adrsvc al, lr, slow_syscall_return
+ b SYMBOL_NAME(deferred)
-@ r0 = syscall number
-@ r1 = syscall r0
-@ r5 = syscall r4
-@ ip = syscall table
-SYMBOL_NAME(sys_syscall):
- mov r6, r0
- eor r6, r6, #OS_NUMBER << 20
- cmp r6, #NR_syscalls @ check range
- movgt r0, #-ENOSYS
- movgt pc, lr
- add sp, sp, #4 @ take of the save of our r4
- ldmib sp, {r0 - r4} @ get our args
- str r4, [sp, #-4]! @ Put our arg on the stack
- ldr pc, [ip, r6, lsl #2]
+ .align 5
+
+bh_data: .word SYMBOL_NAME(bh_mask)
+ .word SYMBOL_NAME(bh_active)
ENTRY(sys_call_table)
#include "calls.S"
-/*============================================================================
- * Special system call wrappers
- */
-sys_fork_wrapper:
- add r0, sp, #4
- b SYMBOL_NAME(sys_fork)
-
-sys_execve_wrapper:
- add r3, sp, #4
- b SYMBOL_NAME(sys_execve)
-
-sys_mount_wrapper:
- mov r6, lr
- add r5, sp, #4
- str r5, [sp]
- str r4, [sp, #-4]!
- bl SYMBOL_NAME(sys_compat_mount)
- add sp, sp, #4
- RETINSTR(mov,pc,r6)
-
-sys_clone_wapper:
- add r2, sp, #4
- b SYMBOL_NAME(sys_clone)
-
-sys_llseek_wrapper:
- mov r6, lr
- add r5, sp, #4
- str r5, [sp]
- str r4, [sp, #-4]!
- bl SYMBOL_NAME(sys_compat_llseek)
- add sp, sp, #4
- RETINSTR(mov,pc,r6)
-
-sys_sigsuspend_wrapper:
- add r3, sp, #4
- b SYMBOL_NAME(sys_sigsuspend)
-
-sys_rt_sigsuspend_wrapper:
- add r2, sp, #4
- b SYMBOL_NAME(sys_rt_sigsuspend)
-
-sys_sigreturn_wrapper:
- add r0, sp, #4
- b SYMBOL_NAME(sys_sigreturn)
-
-sys_rt_sigreturn_wrapper:
- add r0, sp, #4
- b SYMBOL_NAME(sys_rt_sigreturn)
-
-sys_sigaltstack_wrapper:
- ldr r2, [sp, #4 + S_SP]
- b do_sigaltstack
+#if defined(CONFIG_CPU_26)
/*
*=============================================================================
@@ -211,45 +142,6 @@
.section ".text.init",#alloc,#execinstr
-#if defined(CONFIG_CPU_32)
-/*
- * these go into 0x00
- */
-.Lbranches: swi SYS_ERROR0
- ldr pc, .Lbranches + 0xe4
- ldr pc, .Lbranches + 0xe8
- ldr pc, .Lbranches + 0xec
- ldr pc, .Lbranches + 0xf0
- ldr pc, .Lbranches + 0xf4
- ldr pc, .Lbranches + 0xf8
- ldr pc, .Lbranches + 0xfc
-/*
- * this is put into 0xe4 and above
- */
-.Ljump_addresses:
- .word vector_undefinstr @ 0xe4
- .word vector_swi @ 0xe8
- .word vector_prefetch @ 0xec
- .word vector_data @ 0xf0
- .word vector_addrexcptn @ 0xf4
- .word vector_IRQ @ 0xf8
- .word _unexp_fiq @ 0xfc
-/*
- * initialise the trap system
- */
-ENTRY(trap_init)
- stmfd sp!, {r4 - r7, lr}
- initialise_traps_extra
- mov r0, #0xe4
- adr r1, .Ljump_addresses
- ldmia r1, {r1 - r7}
- stmia r0, {r1 - r7}
- mov r0, #0
- adr r1, .Lbranches
- ldmia r1, {r1 - r7}
- stmia r0, {r1 - r7}
- LOADREGS(fd, sp!, {r4 - r7, pc})
-#elif defined(CONFIG_CPU_26)
.Ljump_addresses:
swi SYS_ERROR0
.word vector_undefinstr - 12
@@ -279,11 +171,75 @@
ldmfd sp!, {r4 - r7, pc}^
#endif
- .previous
+ .text
/*============================================================================
- * FP support
+ * Special system call wrappers
*/
+@ r0 = syscall number
+@ r5 = syscall table
+SYMBOL_NAME(sys_syscall):
+ eor r6, r0, #OS_NUMBER << 20
+ cmp r6, #NR_syscalls @ check range
+ ldmleib sp, {r0 - r4} @ get our args
+ strle r4, [sp] @ Put our arg on the stack
+ ldrle pc, [r5, r6, lsl #2]
+ mov r0, #-ENOSYS
+ mov pc, lr
+
+sys_fork_wrapper:
+ add r0, sp, #4
+ b SYMBOL_NAME(sys_fork)
+
+sys_vfork_wrapper:
+ add r0, sp, #4
+ b SYMBOL_NAME(sys_vfork)
+
+sys_execve_wrapper:
+ add r3, sp, #4
+ b SYMBOL_NAME(sys_execve)
+
+sys_mount_wrapper:
+ mov r6, lr
+ add r5, sp, #4
+ str r5, [sp]
+ str r4, [sp, #-4]!
+ bl SYMBOL_NAME(sys_compat_mount)
+ add sp, sp, #4
+ RETINSTR(mov,pc,r6)
+
+sys_clone_wapper:
+ add r2, sp, #4
+ b SYMBOL_NAME(sys_clone)
+
+sys_llseek_wrapper:
+ mov r6, lr
+ add r5, sp, #4
+ str r5, [sp]
+ str r4, [sp, #-4]!
+ bl SYMBOL_NAME(sys_compat_llseek)
+ add sp, sp, #4
+ RETINSTR(mov,pc,r6)
+
+sys_sigsuspend_wrapper:
+ add r3, sp, #4
+ b SYMBOL_NAME(sys_sigsuspend)
+
+sys_rt_sigsuspend_wrapper:
+ add r2, sp, #4
+ b SYMBOL_NAME(sys_rt_sigsuspend)
+
+sys_sigreturn_wrapper:
+ add r0, sp, #4
+ b SYMBOL_NAME(sys_sigreturn)
+
+sys_rt_sigreturn_wrapper:
+ add r0, sp, #4
+ b SYMBOL_NAME(sys_rt_sigreturn)
+
+sys_sigaltstack_wrapper:
+ ldr r2, [sp, #4 + S_SP]
+ b do_sigaltstack
.data
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/fiq.c linux.ac/arch/arm/kernel/fiq.c
--- linux.vanilla/arch/arm/kernel/fiq.c Tue Dec 22 23:19:26 1998
+++ linux.ac/arch/arm/kernel/fiq.c Sun Jan 24 21:11:31 1999
@@ -113,21 +113,68 @@
void set_fiq_regs(struct pt_regs *regs)
{
- /* not yet -
- * this is temporary to get the floppy working
- * again on RiscPC. It *will* become more
- * generic.
- */
-#ifdef CONFIG_ARCH_ACORN
- extern void floppy_fiqsetup(unsigned long len, unsigned long addr,
- unsigned long port);
- floppy_fiqsetup(regs->ARM_r9, regs->ARM_r10, regs->ARM_fp);
+ register unsigned long tmp, tmp2;
+ __asm__ volatile (
+#ifdef CONFIG_CPU_26
+ "mov %0, pc
+ bic %1, %0, #0x0c000003
+ orr %1, %1, #1
+ teqp %1, #0 @ select FIQ mode
+ mov r0, r0
+ ldmia %2, {r8 - r14}
+ teqp %0, #0 @ return to SVC mode
+ mov r0, r0"
#endif
+#ifdef CONFIG_CPU_32
+ "mrs %0, cpsr
+ bic %1, %0, #0xf
+ orr %1, %1, #1
+ msr cpsr, %1 @ select FIQ mode
+ mov r0, r0
+ ldmia %2, {r8 - r14}
+ msr cpsr, %0 @ return to SVC mode
+ mov r0, r0"
+#endif
+ : "=r" (tmp), "=r" (tmp2)
+ : "r" (®s->ARM_r8)
+ /* These registers aren't modified by the above code in a way
+ visible to the compiler, but we mark them as clobbers anyway
+ so that GCC won't put any of the input or output operands in
+ them. */
+ : "r8", "r9", "r10", "r11", "r12", "r13", "r14");
}
void get_fiq_regs(struct pt_regs *regs)
{
- /* not yet */
+ register unsigned long tmp, tmp2;
+ __asm__ volatile (
+#ifdef CONFIG_CPU_26
+ "mov %0, pc
+ bic %1, %0, #0x0c000003
+ orr %1, %1, #1
+ teqp %1, #0 @ select FIQ mode
+ mov r0, r0
+ stmia %2, {r8 - r14}
+ teqp %0, #0 @ return to SVC mode
+ mov r0, r0"
+#endif
+#ifdef CONFIG_CPU_32
+ "mrs %0, cpsr
+ bic %1, %0, #0xf
+ orr %1, %1, #1
+ msr cpsr, %1 @ select FIQ mode
+ mov r0, r0
+ stmia %2, {r8 - r14}
+ msr cpsr, %0 @ return to SVC mode
+ mov r0, r0"
+#endif
+ : "=r" (tmp), "=r" (tmp2)
+ : "r" (®s->ARM_r8)
+ /* These registers aren't modified by the above code in a way
+ visible to the compiler, but we mark them as clobbers anyway
+ so that GCC won't put any of the input or output operands in
+ them. */
+ : "r8", "r9", "r10", "r11", "r12", "r13", "r14");
}
int claim_fiq(struct fiq_handler *f)
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/head-armv.S linux.ac/arch/arm/kernel/head-armv.S
--- linux.vanilla/arch/arm/kernel/head-armv.S Tue Dec 22 23:19:26 1998
+++ linux.ac/arch/arm/kernel/head-armv.S Sun Jan 24 21:11:31 1999
@@ -8,12 +8,20 @@
#include
#include
-#ifndef CONFIG_ARCH_VNC
+#define DEBUG
+
+ .globl SYMBOL_NAME(swapper_pg_dir)
+ .equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x4000
+
+ .section ".text.init",#alloc,#execinstr
+ENTRY(stext)
+ENTRY(_stext)
+
#if (TEXTADDR & 0xffff) != 0x8000
#error TEXTADDR must start at 0xXXXX8000
#endif
-#else
- .text
+
+#if defined(CONFIG_ARCH_VNC) || defined(CONFIG_ARCH_NETWINDER)
mov r0, r0
mov r0, r0
mov r0, r0
@@ -22,16 +30,34 @@
mov r0, r0
mov r0, r0
mov r0, r0
+
+ adr r2, 1f
+ ldmdb r2, {r7, r8}
+ and r3, r2, #0x0000c000
+ teq r3, #0x00008000
+ beq __entry
+ bic r3, r2, #0xc000
+ orr r3, r3, #0x8000
+ mov r0, r3
+ mov r4, #32
+ sub r5, r8, r7
+ b 1f
+
+ .word _stext
+ .word _end
+
+1: ldmia r2!, {r6, r7, r8, r9}
+ stmia r3!, {r6, r7, r8, r9}
+ subs r4, r4, #16
+ bcs 1b
+ movs r4, r5
+ mov r5, #0
+ movne pc, r0
+
mov r0, #0
mov r1, #5
#endif
-#define DEBUG
-
- .globl SYMBOL_NAME(swapper_pg_dir)
- .equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x4000
-
- .text
/*
* Entry point and restart point. Entry *must* be called with r0 == 0,
* MMU off. Note! These should be unique!!! Please read Documentation/ARM-README
@@ -45,16 +71,15 @@
* r1 = 5 -> Corel Netwinder
* r1 = 6 -> CATS
* r1 = 7 -> tbox
+ * r1 = 8 -> SA110/21285 as co-processor
*/
-ENTRY(stext)
-ENTRY(_stext)
__entry: teq r0, #0 @ check for illegal entry...
bne .Lerror @ loop indefinitely
cmp r1, #8 @ Unknown machine architecture
bge .Lerror
-/* First thing to do is to get the page tables set up so that we can call the kernel
- * in the correct place. This is relocatable code...
+/* First thing to do is to get the page tables set up so that we can call
+ * the kernel in the correct place. This is relocatable code...
* - Read processor ID register (CP#15, CR0).
*/
mrc p15, 0, r9, c0, c0 @ get Processor ID
@@ -111,7 +136,11 @@
add r3, r3, #1 << 20
teq r0, r2
bne 1b
-#ifdef CONFIG_ARCH_VNC
+#ifdef CONFIG_ARCH_NETWINDER
+ teq r1, #5
+ bne 1f
+#endif
+#if defined(CONFIG_ARCH_VNC) || defined(CONFIG_ARCH_NETWINDER)
add r0, r4, #0x3f00
add r0, r0, #0x00f8
mov r3, #0x7c000000
@@ -120,6 +149,7 @@
add r3, r3, #1 << 20
str r3, [r0], #4
#endif
+1:
#endif
#ifdef CONFIG_ARCH_RPC
/* Map in screen at 0x02000000 & SCREEN2_BASE
@@ -250,7 +280,11 @@
mcr p15, 0, r4, c2, c0 @ load page table pointer
mov r0, #0x1f @ Domains 0, 1 = client
mcr p15, 0, r0, c3, c0 @ load domain access register
+#ifdef CONFIG_ALIGNMENT_TRAP
+ mov r0, #0x3f @ ....S..DPWCAM
+#else
mov r0, #0x3d @ ....S..DPWC.M
+#endif
orr r0, r0, #0x100
mov pc, lr
@@ -261,7 +295,11 @@
mcr p15, 0, r4, c2, c0 @ load page table pointer
mov r0, #0x1f @ Domains 0, 1 = client
mcr p15, 0, r0, c3, c0 @ load domain access register
+#ifdef CONFIG_ALIGNMENT_TRAP
+ mov r0, #0x7f @ ....S.LDPWCAM
+#else
mov r0, #0x7d @ ....S.LDPWC.M
+#endif
orr r0, r0, #0x100
mov pc, lr
@@ -276,12 +314,14 @@
mrc p15, 0, r0, c1, c0 @ get control register v4
bic r0, r0, #0x0e00
bic r0, r0, #0x0002
+#ifdef CONFIG_ALIGNMENT_TRAP
+ orr r0, r0, #0x003f @ I...S..DPWCAM
+#else
orr r0, r0, #0x003d @ I...S..DPWC.M
+#endif
orr r0, r0, #0x1100 @ v4 supports separate I cache
mov pc, lr
- .section ".text.init",#alloc,#execinstr
-
.Lsa_fastclock: mcr p15, 0, r4, c15, c1, 2 @ Enable clock switching
mov pc, lr
@@ -290,18 +330,22 @@
.long SYMBOL_NAME(__bss_start)
.long SYMBOL_NAME(processor_id)
.long SYMBOL_NAME(_end)
+ .long SYMBOL_NAME(cr_alignment)
.long SYMBOL_NAME(init_task_union)+8192
.align
.Lalready_done_mmap:
adr r4, .LC0
- ldmia r4, {r3, r4, r5, r6, r8, sp} @ Setup stack
+ ldmia r4, {r3, r4, r5, r6, r7, r8, sp} @ Setup stack
add r10, r10, r3 @ Add base back in
mov fp, #0
-1: cmp r5, r8 @ Clear BSS
+1: cmp r5, r7 @ Clear BSS
strcc fp, [r5],#4
bcc 1b
+ bic r2, r0, #2 @ Clear 'A' bit
+ stmia r8, {r0, r2} @ Save control register values
+
str r1, [r4] @ Save machine type
str r9, [r6] @ Save processor ID
mov lr, pc
@@ -363,6 +407,7 @@
.endm
#elif defined(CONFIG_ARCH_EBSA285)
+#if 1
.macro addruart,rx
mov \rx, #0xfe000000
.endm
@@ -379,7 +424,30 @@
.macro waituart,rd,rx
.endm
+#else
+ .macro addruart,rx
+ mov \rx, #0xff000000
+ orr \rx, \rx, #0x00e00000
+ orr \rx, \rx, #0x000003f8
+ .endm
+ .macro senduart,rd,rx
+ strb \rd, [\rx]
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldrb \rd, [\rx, #0x5]
+ and \rd, \rd, #0x60
+ teq \rd, #0x60
+ bne 1002b
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldrb \rd, [\rx, #0x6]
+ tst \rd, #0x10
+ beq 1001b
+ .endm
+#endif
#elif defined(CONFIG_ARCH_NEXUSPCI)
.macro addruart,rx
ldr \rx, =0xfff00000
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/hw-ebsa285.c linux.ac/arch/arm/kernel/hw-ebsa285.c
--- linux.vanilla/arch/arm/kernel/hw-ebsa285.c Mon Dec 28 23:09:40 1998
+++ linux.ac/arch/arm/kernel/hw-ebsa285.c Sun Jan 24 21:11:31 1999
@@ -3,27 +3,37 @@
*
* EBSA285 hardware specific functions
*
- * Copyright (C) 1998 Russell King, Phil Blundel
+ * Copyright (C) 1998 Russell King, Phil Blundell
*/
+#include
+#include
#include
#include
#include
#include
#include
#include
+#include
+#include
#include
+#include
+#include
#include
+#include
#include
-extern int setup_arm_irq(int, struct irqaction *);
+#define ETHER10_IO_BASE 0x301
+#define DEC21143_IO_BASE 0x401
+#define DEC21143_MEM_BASE 0x00800000
+#define CYBER2000_MEM_BASE 0x01000000
+extern int setup_arm_irq(int, struct irqaction *);
extern void pci_set_cmd(struct pci_dev *dev, unsigned short clear, unsigned short set);
extern void pci_set_base_addr(struct pci_dev *dev, int idx, unsigned int addr);
extern void pci_set_irq_line(struct pci_dev *dev, unsigned int irq);
-static int irqmap_ebsa[] __initdata = { 9, 8, 18, 11 };
-static int irqmap_cats[] __initdata = { 18, 8, 9, 11 };
+static int irqmap_ebsa[] __initdata = { IRQ_IN1, IRQ_IN0, IRQ_PCI, IRQ_IN3 };
__initfunc(static int ebsa_irqval(struct pci_dev *dev))
{
@@ -37,6 +47,9 @@
return irqmap_ebsa[(PCI_SLOT(dev->devfn) + pin) & 3];
}
+#ifdef CONFIG_CATS
+static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
+
__initfunc(static int cats_irqval(struct pci_dev *dev))
{
if (dev->irq >= 128)
@@ -56,77 +69,179 @@
dev->bus->number, dev->devfn, dev->irq);
return 0;
}
+#endif
__initfunc(void pcibios_fixup_ebsa285(struct pci_dev *dev))
{
- char cmd;
+ /* Latency timer of 32 */
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32);
+ /* 32-byte cache line size */
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
+ /* Set SysErr enable, Parity enable */
+ pci_set_cmd(dev, PCI_COMMAND_FAST_BACK, PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
/* sort out the irq mapping for this device */
switch (machine_type) {
case MACH_TYPE_EBSA285:
dev->irq = ebsa_irqval(dev);
+ /* Turn on bus mastering - boot loader doesn't
+ * - perhaps it should! - dag
+ */
+ pci_set_cmd(dev, 0, PCI_COMMAND_MASTER);
break;
+
+#ifdef CONFIG_CATS
case MACH_TYPE_CATS:
dev->irq = cats_irqval(dev);
+ /* Turn on bus mastering - boot loader doesn't
+ * - perhaps it should! - dag
+ */
+ pci_set_cmd(dev, 0, PCI_COMMAND_MASTER);
break;
+#endif
+#ifdef CONFIG_ARCH_NETWINDER
+ case MACH_TYPE_NETWINDER:
+ /* disable ROM */
+ pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
+
+#define DEV(v,d) ((v)<<16|(d))
+ switch (DEV(dev->vendor, dev->device)) {
+ /* Ether 100 */
+ case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142):
+ pci_set_base_addr(dev, 0, DEC21143_IO_BASE);
+ pci_set_base_addr(dev, 1, DEC21143_MEM_BASE);
+ pci_set_cmd(dev, 0, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
+ dev->irq = IRQ_NETWINDER_ETHER100;
+ break;
+
+ /* Ether 10 */
+ case DEV(PCI_VENDOR_ID_WINBOND2,0x5a5a):
+ pci_set_base_addr(dev, 0, ETHER10_IO_BASE);
+ pci_set_cmd(dev, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY, PCI_COMMAND_IO);
+ dev->irq = IRQ_NETWINDER_ETHER10;
+ break;
+
+ /* ISA bridge */
+ case DEV(PCI_VENDOR_ID_WINBOND,PCI_DEVICE_ID_WINBOND_83C553):
+ pci_set_base_addr(dev, 0, 0);
+ pci_set_cmd(dev, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY, PCI_COMMAND_IO);
+ /*
+ * Enable all memory requests from ISA to be channeled to PCI
+ */
+ pci_write_config_byte(dev, 0x48, 255);
+ /*
+ * Disable ping-pong (as per errata)
+ */
+ pci_write_config_byte(dev, 0x42, 0);
+ /*
+ * Enable PCI packet retry
+ */
+ pci_write_config_byte(dev, 0x40, 0x22);
+ /*
+ * Do not use PCI CPU park enable, park on
+ * last master, disable GAT bit
+ */
+ pci_write_config_byte(dev, 0x83, 0x02);
+ /*
+ * Default rotating priorities
+ */
+ pci_write_config_byte(dev, 0x80, 0xe0);
+ /*
+ * Rotate bank 4
+ */
+ pci_write_config_byte(dev, 0x81, 0x01);
+ break;
+
+ /* IDE */
+ case DEV(PCI_VENDOR_ID_WINBOND,PCI_DEVICE_ID_WINBOND_82C105):
+ pci_set_base_addr(dev, 0, 0x1f1);
+ pci_set_base_addr(dev, 1, 0x3f5);
+ pci_set_base_addr(dev, 2, 0x171);
+ pci_set_base_addr(dev, 3, 0x375);
+ pci_set_base_addr(dev, 4, 0xe801);
+ pci_set_cmd(dev, PCI_COMMAND_MEMORY, PCI_COMMAND_MASTER | PCI_COMMAND_IO);
+ dev->irq = IRQ_NETWINDER_IDE;
+ break;
+
+ /* VGA */
+ case DEV(PCI_VENDOR_ID_INTERG,0x2000):
+ pci_set_base_addr(dev, 0, CYBER2000_MEM_BASE);
+ pci_set_cmd(dev, PCI_COMMAND_MASTER, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+ dev->irq = IRQ_NETWINDER_VGA;
+ break;
+ }
+#endif
}
-
- /* Turn on bus mastering - boot loader doesn't
- * - perhaps it should! - dag
- */
- pci_read_config_byte(dev, PCI_COMMAND, &cmd);
- pci_write_config_byte(dev, PCI_COMMAND, cmd | PCI_COMMAND_MASTER);
}
-static void irq_pci_err(int irq, void *dev_id, struct pt_regs *regs)
+static void
+irq_pci_err(int irq, void *dev_id, struct pt_regs *regs)
{
- const char *err = "unknown";
- unsigned long cmd = *(unsigned long *)0xfe000004 & 0xffff;
- unsigned long ctrl = *(unsigned long *)0xfe00013c & 0xffffde07;
- static unsigned long next_warn[7];
- int idx = 6;
-
- switch(irq) {
- case IRQ_PCIPARITY:
- *(unsigned long *)0xfe000004 = cmd | 1 << 31;
- idx = 0;
- err = "parity";
- break;
+ static unsigned long next_warn;
+ unsigned long cmd = *CSR_PCICMD & 0x0000ffff;
+ unsigned long ctrl = (*CSR_SA110_CNTL) & 0xffffde07;
+ unsigned long irqstatus = *CSR_IRQ_RAWSTATUS;
+ struct pci_dev *dev;
+ int warn = time_after_eq(jiffies, next_warn);
+
+ if (warn) {
+ next_warn = jiffies + 3 * HZ / 100;
+ printk(KERN_DEBUG "PCI: ");
+ }
- case IRQ_PCITARGETABORT:
- *(unsigned long *)0xfe000004 = cmd | 1 << 28;
- idx = 1;
- err = "target abort";
- break;
+ if (irqstatus & (1 << 31)) {
+ if (warn)
+ printk("parity error ");
+ cmd |= 1 << 31;
+ }
- case IRQ_PCIMASTERABORT:
- *(unsigned long *)0xfe000004 = cmd | 1 << 29;
- idx = 2;
- err = "master abort";
- break;
+ if (irqstatus & (1 << 30)) {
+ if (warn)
+ printk("target abort ");
+ cmd |= 1 << 28;
+ }
- case IRQ_PCIDATAPARITY:
- *(unsigned long *)0xfe000004 = cmd | 1 << 24;
- idx = 3;
- err = "data parity";
- break;
+ if (irqstatus & (1 << 29)) {
+ if (warn)
+ printk("master abort ");
+ cmd |= 1 << 29;
+ }
- case IRQ_DISCARDTIMER:
- *(unsigned long *)0xfe00013c = ctrl | 1 << 8;
- idx = 4;
- err = "discard timer";
- break;
+ if (irqstatus & (1 << 28)) {
+ if (warn)
+ printk("data parity error ");
+ cmd |= 1 << 24;
+ }
- case IRQ_SERR:
- *(unsigned long *)0xfe00013c = ctrl | 1 << 3;
- idx = 5;
- err = "system";
- break;
+ if (irqstatus & (1 << 27)) {
+ if (warn)
+ printk("discard timer expired ");
+ ctrl |= 1 << 8;
}
- if (time_after_eq(jiffies, next_warn[idx])) {
- next_warn[idx] = jiffies + 3 * HZ / 100;
- printk(KERN_ERR "PCI %s error detected\n", err);
+
+ if (irqstatus & (1 << 23)) {
+ if (warn)
+ printk("system error ");
+ ctrl |= 1 << 3;
+ }
+
+ if (warn)
+ printk("pc=%08lX\n", instruction_pointer(regs));
+
+ for (dev = pci_devices; dev; dev = dev->next) {
+ unsigned short status;
+
+ pci_read_config_word(dev, PCI_STATUS, &status);
+ if (status & 0xf900) {
+ printk("PCI: [%04X:%04X] status = %X\n",
+ dev->vendor, dev->device, status);
+
+ pci_write_config_word(dev, PCI_STATUS, status & 0xf900);
+ }
}
+
+ *CSR_PCICMD = cmd;
+ *CSR_SA110_CNTL = ctrl;
}
static struct irqaction irq_pci_error = {
@@ -135,12 +250,9 @@
__initfunc(void pcibios_init_ebsa285(void))
{
- setup_arm_irq(IRQ_PCIPARITY, &irq_pci_error);
- setup_arm_irq(IRQ_PCITARGETABORT, &irq_pci_error);
- setup_arm_irq(IRQ_PCIMASTERABORT, &irq_pci_error);
- setup_arm_irq(IRQ_PCIDATAPARITY, &irq_pci_error);
- setup_arm_irq(IRQ_DISCARDTIMER, &irq_pci_error);
- setup_arm_irq(IRQ_SERR, &irq_pci_error);
+ unsigned int mem_size = (int)high_memory - PAGE_OFFSET;
+
+ setup_arm_irq(IRQ_PCI_ERR, &irq_pci_error);
/*
* Map our SDRAM at a known address in PCI space, just in case
@@ -150,12 +262,374 @@
*
* We should really only do this if the central function is enabled.
*/
- *(unsigned long *)0xfe000010 = 0;
- *(unsigned long *)0xfe000018 = 0xe0000000;
- *(unsigned long *)0xfe0000f8 = 0;
- *(unsigned long *)0xfe0000fc = 0;
- *(unsigned long *)0xfe000100 = 0x01fc0000;
- *(unsigned long *)0xfe000104 = 0;
- *(unsigned long *)0xfe000108 = 0x80000000;
- *(unsigned long *)0xfe000004 = 0x17;
+ *CSR_CSRBASEMASK = 0;
+ *CSR_CSRBASEOFFSET = 0;
+ *CSR_SDRAMBASEMASK = (mem_size - 1) & 0x0ffc0000;
+ *CSR_SDRAMBASEOFFSET = 0;
+ *CSR_ROMBASEMASK = 0x80000000;
+ *CSR_PCICACHELINESIZE = 0x00002008;
+ *CSR_PCICSRBASE = 0;
+ *CSR_PCICSRIOBASE = 0;
+ *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET);
+ *CSR_PCIROMBASE = 0;
+ *CSR_PCICMD = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+ PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY;
+ *CSR_PCIADDR_EXTN = 0;
+}
+
+/*
+ * Netwinder stuff
+ */
+#ifdef CONFIG_ARCH_NETWINDER
+/*
+ * This is a lock for accessing ports 0x338 and 0x33a
+ */
+spinlock_t __netwinder_data gpio_lock = SPIN_LOCK_UNLOCKED;
+
+static unsigned int __netwinder_data current_gpio_op = 0;
+static unsigned int __netwinder_data current_gpio_io = 0;
+static unsigned int __netwinder_data current_cpld = 0;
+
+void __netwinder_text gpio_modify_op(int mask, int set)
+{
+ unsigned int new_gpio, changed;
+unsigned long flags; save_flags_cli(flags);
+if ((flags & 128) == 0) {printk("gpio_modify_op called with IRQs enabled from %p\n", __builtin_return_address(0)); __backtrace(); }
+
+ new_gpio = (current_gpio_op & ~mask) | set;
+ changed = new_gpio ^ current_gpio_op;
+ current_gpio_op = new_gpio;
+
+ if (changed & 0xff)
+ outb(new_gpio, 0x338);
+ if (changed & 0xff00)
+ outb(new_gpio >> 8, 0x33a);
+restore_flags(flags);
+}
+
+static inline void __gpio_modify_io(int mask, int in)
+{
+ unsigned int new_gpio, changed;
+ int port;
+
+ new_gpio = (current_gpio_io & ~mask) | in;
+ changed = new_gpio ^ current_gpio_io;
+ current_gpio_io = new_gpio;
+
+ changed >>= 1;
+ new_gpio >>= 1;
+
+ outb(7, 0x370);
+ outb(7, 0x371);
+
+ for (port = 0xe1; changed && port < 0xe8; changed >>= 1) {
+ outb(port, 0x370);
+ outb(new_gpio & 1, 0x371);
+
+ port += 1;
+ new_gpio >>= 1;
+ }
+
+ outb(7, 0x370);
+ outb(8, 0x371);
+
+ for (port = 0xe8; changed && port < 0xec; changed >>= 1) {
+ outb(port, 0x370);
+ outb(new_gpio & 1, 0x371);
+
+ port += 1;
+ new_gpio >>= 1;
+ }
+}
+
+void __netwinder_text gpio_modify_io(int mask, int in)
+{
+ /* Open up the SuperIO chip */
+ outb(0x87, 0x370);
+ outb(0x87, 0x370);
+
+ __gpio_modify_io(mask, in);
+
+ /* Close up the EFER gate */
+ outb(0xaa, 0x370);
+}
+
+int __netwinder_text gpio_read(void)
+{
+ return inb(0x338) | inb(0x33a) << 8;
+}
+
+void __netwinder_text cpld_modify(int mask, int set)
+{
+ int msk;
+
+ current_cpld = (current_cpld & ~mask) | set;
+
+ gpio_modify_io(GPIO_DATA, 0);
+ gpio_modify_op(GPIO_IOLOAD, 0);
+
+ for (msk = 8; msk; msk >>= 1) {
+ int bit = current_cpld & msk;
+
+ gpio_modify_op(GPIO_DATA | GPIO_IOCLK, bit ? GPIO_DATA : 0);
+ gpio_modify_op(GPIO_IOCLK, GPIO_IOCLK);
+ }
+
+ gpio_modify_op(GPIO_IOCLK|GPIO_DATA, 0);
+ gpio_modify_op(GPIO_IOLOAD|GPIO_DSCLK, GPIO_IOLOAD|GPIO_DSCLK);
+ gpio_modify_op(GPIO_IOLOAD, 0);
+}
+
+__initfunc(static void hw_init_cpld(void))
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&gpio_lock, flags);
+ cpld_modify(-1, CPLD_UNMUTE | 4);
+ spin_unlock_irqrestore(&gpio_lock, flags);
}
+
+__initfunc(static void hw_init_wb553(void))
+{
+ unsigned long flags;
+#define WRITE_REG(r,v) do { outb((r), 0x370); outb((v), 0x371); } while (0)
+
+ /* Open up the SuperIO chip */
+ outb(0x87, 0x370);
+ outb(0x87, 0x370);
+
+ /* Set the serial interrupt numbers */
+ WRITE_REG(7, 5); /* keyboard subsection */
+ WRITE_REG(0x72, 5); /* interrupt number for mouse - IRQ5 */
+
+ WRITE_REG(7, 6); /* Infrared */
+ WRITE_REG(0x70, 6); /* IRQ 6 */
+
+ WRITE_REG(0x2a, 0xc1); /* Enable GP12, GP11, GP10 as I/O, CIRRX, IRRXH */
+
+ WRITE_REG(0x2b, 0x6b); /* Enable GP23, GP22, GP21, GP20, GP13 as I/O */
+
+ WRITE_REG(0x2c, 0x55); /* Enable GP17, GP16, GP15, GP14 as I/O */
+
+ current_gpio_io = -1;
+ __gpio_modify_io(-1, GPIO_DONE | GPIO_WDTIMER);
+
+ WRITE_REG(7, 7); /* Aux function group 1 (dev 7) */
+ WRITE_REG(0x60, 0x03); /* Group controlled by IO port 0x338 */
+ WRITE_REG(0x61, 0x38); /* GP 11, 12, 13, 14, 15, 16 */
+
+ WRITE_REG(0x70, 0x0a); /* IRQ10 for GP10 (Orange button) */
+
+ WRITE_REG(0xe0, 0x19); /* GP10 control reg set for debounce & input */
+ WRITE_REG(0x30, 0x01); /* Turn on section 7 (aux function group 1) */
+
+ WRITE_REG(7, 8); /* Aux function group 2 (dev 8) */
+ WRITE_REG(0x60, 0x03); /* Group controlled by IO port 0x33a */
+ WRITE_REG(0x61, 0x3a);
+
+ /* Clear watchdog timer regs */
+ WRITE_REG(0xf2, 0x00); /* Watchdog timeout value (disabled) */
+ WRITE_REG(0xf3, 0x00); /* Watchdog reg (reset to default) */
+ WRITE_REG(0xf4, 0x00); /* Reset if in timed out state (bit 0) */
+
+ /* T.B.D. set IRDA inputs (touch reg 2A, EC, ED) */
+ WRITE_REG(0x30, 0x01); /* Turn on section 8 (aux function group 2) */
+
+ spin_lock_irqsave(&gpio_lock, flags);
+ gpio_modify_op(-1, GPIO_RED_LED | GPIO_FAN);
+ spin_unlock_irqrestore(&gpio_loc, flags);
+
+ /* Close up the EFER gate */
+ outb(0xaa, 0x370);
+}
+
+static unsigned char rwa_unlock[] __initdata =
+{ 0x00, 0x00, 0x6a, 0xb5, 0xda, 0xed, 0xf6, 0xfb, 0x7d, 0xbe, 0xdf, 0x6f, 0x37, 0x1b,
+ 0x0d, 0x86, 0xc3, 0x61, 0xb0, 0x58, 0x2c, 0x16, 0x8b, 0x45, 0xa2, 0xd1, 0xe8, 0x74,
+ 0x3a, 0x9d, 0xce, 0xe7, 0x73, 0x39 };
+
+#ifndef DEBUG
+#define dprintk if (0) printk
+#else
+#define dprintk printk
+#endif
+
+__initfunc(static void hw_init_rwa010(void))
+{
+ unsigned char si[9];
+ int i, j;
+
+#define WRITE_RWA(r,v) do { outb((r), 0x279); outb((v), 0xa79); } while (0)
+
+ WRITE_RWA(2, 2);
+ mdelay(10);
+
+ for (i = 0; i < sizeof(rwa_unlock); i++)
+ outb(rwa_unlock[i], 0x279);
+
+ WRITE_RWA(3, 0);
+ WRITE_RWA(0, 128);
+
+ outb(1, 0x279);
+
+ mdelay(10);
+
+ dprintk("Identifier: ");
+ for (i = 0; i < 9; i++) {
+ si[i] = 0;
+ for (j = 0; j < 8; j++) {
+ int bit;
+ mdelay(1);
+ inb(0x203);
+ mdelay(1);
+ bit = inb(0x203);
+ dprintk("%02X ", bit);
+ si[i] |= bit << j;
+ }
+ mdelay(10);
+ dprintk("%02X ", si[i]);
+ }
+ dprintk("\n");
+
+ WRITE_RWA(6, 2); // Assign a card no = 2
+
+ dprintk("Card no = %d\n", inb(0x203));
+
+ WRITE_RWA(7, 3);
+ WRITE_RWA(0x30, 0);
+
+ WRITE_RWA(7, 4);
+ WRITE_RWA(0x30, 0);
+
+ WRITE_RWA(7, 2);
+ WRITE_RWA(0x30, 0);
+
+ WRITE_RWA(7, 5);
+
+ dprintk("Slider base: ");
+ WRITE_RWA(0x61, 1);
+ i = inb(0x203);
+
+ WRITE_RWA(0x60, 2);
+ dprintk("%02X%02X (201)\n", inb(0x203), i);
+
+ WRITE_RWA(0x30, 1);
+
+
+ WRITE_RWA(7, 0);
+
+ dprintk("WaveArtist base: ");
+ WRITE_RWA(0x61, 0x50);
+ i = inb(0x203);
+
+ WRITE_RWA(0x60, 0x02);
+ dprintk("%02X%02X (250),", inb(0x203), i);
+
+ WRITE_RWA(0x70, 3);
+ dprintk(" irq: %d (3),", inb(0x203));
+
+ WRITE_RWA(0x74, 7);
+ dprintk(" dma: %d (7)\n", inb(0x203));
+
+ WRITE_RWA(0x30, 1);
+
+ WRITE_RWA(7, 1);
+
+ dprintk("SoundBlaster base: ");
+ WRITE_RWA(0x61, 0x20);
+ i = inb(0x203);
+
+ WRITE_RWA(0x60, 0x02);
+ dprintk("%02X%02X (220),", inb(0x203), i);
+
+ dprintk(" irq: ");
+ WRITE_RWA(0x70, 3);
+ dprintk("%d (3),", inb(0x203));
+
+ dprintk(" 8-bit DMA: ");
+ WRITE_RWA(0x74, 1);
+ dprintk("%d (1)\n", inb(0x203));
+
+ dprintk("AdLib base: ");
+ WRITE_RWA(0x63, 0x88);
+ i = inb(0x203);
+
+ WRITE_RWA(0x62, 0x03);
+ dprintk("%02X%02X (388)\n", inb(0x203), i);
+
+ WRITE_RWA(0x30, 1);
+
+ outb(1, 0x226);
+ udelay(3);
+ outb(0, 0x226);
+
+ for (i = 0; i < 5; i++) {
+ if (inb(0x22e) & 0x80)
+ break;
+ mdelay(1);
+ }
+ if (i == 5)
+ printk("SoundBlaster: DSP reset failed\n");
+
+ dprintk("SoundBlaster DSP reset: %02X (AA)\n", inb(0x22a));
+
+ for (i = 0; i < 5; i++) {
+ if ((inb(0x22c) & 0x80) == 0)
+ break;
+ mdelay(1);
+ }
+
+ if (i == 5)
+ printk("SoundBlaster: DSP not ready\n");
+ else {
+ outb(0xe1, 0x22c);
+
+ dprintk("SoundBlaster DSP id: ");
+ i = inb(0x22a);
+ udelay(1);
+ i |= inb(0x22a) << 8;
+ dprintk("%04X\n", i);
+
+ for (i = 0; i < 5; i++) {
+ if ((inb(0x22c) & 0x80) == 0)
+ break;
+ mdelay(1);
+ }
+
+ if (i == 5)
+ printk("SoundBlaster: could not turn speaker off\n");
+
+ outb(0xd3, 0x22c);
+ }
+}
+
+__initfunc(void hw_init(void))
+{
+ unsigned long flags;
+
+ hw_init_wb553();
+ hw_init_cpld();
+ hw_init_rwa010();
+#if 0
+ /* does anyone want to have this in? */
+ drum();
+#endif
+
+#ifdef CONFIG_LEDS /* Clear both LEDs and start the LED driver up */
+ spin_lock_irqsave(&gpio_lock, flags);
+ gpio_modify_op(GPIO_RED_LED|GPIO_GREEN_LED, 0);
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ leds_event(led_start);
+#else /* Set the green LED on and the red LED off */
+ spin_lock_irqsave(&gpio_lock, flags);
+ gpio_modify_op(GPIO_RED_LED|GPIO_GREEN_LED, GPIO_GREEN_LED);
+ spin_unlock_irqrestore(&gpio_lock, flags);
+#endif /* CONFIG_LEDS */
+}
+
+EXPORT_SYMBOL(gpio_lock);
+EXPORT_SYMBOL(gpio_modify_op);
+EXPORT_SYMBOL(gpio_modify_io);
+EXPORT_SYMBOL(cpld_modify);
+
+#endif
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/iic.c linux.ac/arch/arm/kernel/iic.c
--- linux.vanilla/arch/arm/kernel/iic.c Sun Nov 8 15:08:43 1998
+++ linux.ac/arch/arm/kernel/iic.c Sun Jan 24 21:11:31 1999
@@ -9,8 +9,11 @@
#include
#include
-#include
#include
+#include
+#include
+
+#define FORCE_ONES 0xdc
/*
* if delay loop has been calibrated then us that,
@@ -42,7 +45,7 @@
{
unsigned char out;
- out = inb(IOC_CONTROL) | 0xc2;
+ out = inb(IOC_CONTROL) | FORCE_ONES | 0x02;
outb(out, IOC_CONTROL);
iic_delay();
@@ -55,7 +58,7 @@
{
unsigned char out;
- out = inb(IOC_CONTROL) | 0xc3;
+ out = inb(IOC_CONTROL) | FORCE_ONES | 0x03;
iic_delay();
outb(out ^ 1, IOC_CONTROL);
@@ -69,7 +72,7 @@
unsigned char out, in;
int i;
- out = (inb(IOC_CONTROL) & 0xfc) | 0xc0;
+ out = (inb(IOC_CONTROL) & 0xfc) | FORCE_ONES;
outb(out, IOC_CONTROL);
for (i = 7; i >= 0; i--) {
@@ -110,7 +113,7 @@
unsigned char out, in;
int i;
- out = (inb(IOC_CONTROL) & 0xfc) | 0xc0;
+ out = (inb(IOC_CONTROL) & 0xfc) | FORCE_ONES;
outb(out, IOC_CONTROL);
in = 0;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/init_task.c linux.ac/arch/arm/kernel/init_task.c
--- linux.vanilla/arch/arm/kernel/init_task.c Tue Dec 22 23:19:26 1998
+++ linux.ac/arch/arm/kernel/init_task.c Sun Jan 24 21:11:31 1999
@@ -6,6 +6,7 @@
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
+static struct file * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/ioport.c linux.ac/arch/arm/kernel/ioport.c
--- linux.vanilla/arch/arm/kernel/ioport.c Sun Nov 8 15:08:43 1998
+++ linux.ac/arch/arm/kernel/ioport.c Thu Jan 1 01:00:00 1970
@@ -1,29 +0,0 @@
-/*
- * linux/arch/arm/kernel/ioport.c
- *
- * Io-port support is not used for ARM
- */
-
-#include
-#include
-#include
-#include
-#include
-
-/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
-/*asmlinkage void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)
-{
-}*/
-
-asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
-{
- return -ENOSYS;
-}
-
-asmlinkage int sys_iopl(long ebx,long ecx,long edx,
- long esi, long edi, long ebp, long eax, long ds,
- long es, long fs, long gs, long orig_eax,
- long eip,long cs,long eflags,long esp,long ss)
-{
- return -ENOSYS;
-}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/irq.c linux.ac/arch/arm/kernel/irq.c
--- linux.vanilla/arch/arm/kernel/irq.c Mon Dec 28 23:09:40 1998
+++ linux.ac/arch/arm/kernel/irq.c Sun Jan 24 21:11:31 1999
@@ -49,6 +49,7 @@
unsigned int local_bh_count[NR_CPUS];
unsigned int local_irq_count[NR_CPUS];
spinlock_t irq_controller_lock;
+int setup_arm_irq(int, struct irqaction *);
extern int get_fiq_list(char *);
extern void init_FIQ(void);
@@ -71,6 +72,12 @@
static struct irqdesc irq_desc[NR_IRQS];
/*
+ * Get architecture specific interrupt handlers
+ * and interrupt initialisation.
+ */
+#include
+
+/*
* Dummy mask/unmask handler
*/
static void dummy_mask_unmask_irq(unsigned int irq)
@@ -130,10 +137,14 @@
*/
asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
{
- struct irqdesc * desc = irq_desc + irq;
+ struct irqdesc * desc;
struct irqaction * action;
int status, cpu;
+ irq = fixup_irq(irq);
+
+ desc = irq_desc + irq;
+
spin_lock(&irq_controller_lock);
desc->mask_ack(irq);
spin_unlock(&irq_controller_lock);
@@ -261,10 +272,6 @@
return 0;
}
-/*
- * Using "struct sigaction" is slightly silly, but there
- * are historical reasons and it works well, so..
- */
int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
unsigned long irq_flags, const char * devname, void *dev_id)
{
@@ -405,14 +412,9 @@
irq_found = NO_IRQ;
out:
spin_unlock_irq(&irq_controller_lock);
+printk("probe_irq_off: irq %d\n", irq_found);
return irq_found;
}
-
-/*
- * Get architecture specific interrupt handlers
- * and interrupt initialisation.
- */
-#include
__initfunc(void init_IRQ(void))
{
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/leds-ebsa285.c linux.ac/arch/arm/kernel/leds-ebsa285.c
--- linux.vanilla/arch/arm/kernel/leds-ebsa285.c Sun Nov 8 15:08:44 1998
+++ linux.ac/arch/arm/kernel/leds-ebsa285.c Sun Jan 24 21:11:31 1999
@@ -9,36 +9,72 @@
* - Amber - On if system is not idle
* - Red - currently unused
*/
+#include
+#include
+#include
+
#include
#include
+#include
#include
-static char led_state = XBUS_LED_RED | XBUS_LED_GREEN;
+static int led_state;
+static char ebsa_led_state = XBUS_LED_RED | XBUS_LED_GREEN;
void leds_event(led_event_t ledevt)
{
unsigned long flags;
+ switch (ledevt) {
+ case led_start:
+ led_state = !machine_is_cats();
+ return;
+
+ case led_stop:
+ led_state = 0;
+ return;
+
+ default:
+ break;
+ }
+
+ if (!led_state)
+ return;
+
save_flags_cli(flags);
switch(ledevt) {
+#ifdef CONFIG_LEDS_CPU
case led_idle_start:
- led_state |= XBUS_LED_AMBER;
+ ebsa_led_state |= XBUS_LED_AMBER;
break;
case led_idle_end:
- led_state &= ~XBUS_LED_AMBER;
+ ebsa_led_state &= ~XBUS_LED_AMBER;
break;
-
+#endif
+#ifdef CONFIG_LEDS_TIMER
case led_timer:
- led_state ^= XBUS_LED_GREEN;
+ ebsa_led_state ^= XBUS_LED_GREEN;
break;
-
+#endif
default:
break;
}
restore_flags(flags);
- *XBUS_LEDS = led_state;
+ switch (machine_type) {
+ case MACH_TYPE_EBSA285:
+ *XBUS_LEDS = led_state;
+ break;
+
+ case MACH_TYPE_NETWINDER:
+ spin_lock_irqsave(&gpio_lock, flags);
+ gpio_modify_op(GPIO_RED_LED | GPIO_GREEN_LED,
+ (ebsa_led_state & XBUS_LED_AMBER ? GPIO_RED_LED : 0) |
+ (ebsa_led_state & XBUS_LED_GREEN ? GPIO_GREEN_LED : 0));
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ break;
+ }
}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/process.c linux.ac/arch/arm/kernel/process.c
--- linux.vanilla/arch/arm/kernel/process.c Sun Nov 8 15:08:44 1998
+++ linux.ac/arch/arm/kernel/process.c Sun Jan 24 21:11:31 1999
@@ -55,46 +55,37 @@
}
/*
- * The idle loop on an arm..
+ * The idle loop on an ARM...
*/
asmlinkage int sys_idle(void)
{
- int ret = -EPERM;
-
- lock_kernel();
if (current->pid != 0)
- goto out;
+ return -EPERM;
+
/* endless idle loop with no priority at all */
- current->priority = -100;
- for (;;)
- {
+ while (1) {
+ if (!current->need_resched && !hlt_counter)
+ proc_idle();
+ current->policy = SCHED_YIELD;
+ schedule();
+#ifndef CONFIG_NO_PGT_CACHE
check_pgt_cache();
-#if 0 //def ARCH_IDLE_OK
- if (!hlt_counter && !current->need_resched)
- proc_idle ();
#endif
- run_task_queue(&tq_scheduler);
- schedule();
}
- ret = 0;
-out:
- unlock_kernel();
- return ret;
}
+static char reboot_mode = 'h';
+
__initfunc(void reboot_setup(char *str, int *ints))
{
+ reboot_mode = str[0];
}
-/*
- * This routine reboots the machine by resetting the expansion cards via
- * their loaders, turning off the processor cache (if ARM3), copying the
- * first instruction of the ROM to 0, and executing it there.
- */
void machine_restart(char * __unused)
{
- proc_hard_reset ();
- arch_hard_reset ();
+ arch_reset(reboot_mode);
+ panic("Reboot failed\n");
+ while (1);
}
void machine_halt(void)
@@ -150,6 +141,67 @@
}
/*
+ * Task structure and kernel stack allocation.
+ *
+ * Taken from the i386 version.
+ */
+#ifdef CONFIG_CPU_32
+#define EXTRA_TASK_STRUCT 8
+static struct task_struct *task_struct_stack[EXTRA_TASK_STRUCT];
+static int task_struct_stack_ptr = -1;
+#endif
+
+struct task_struct *alloc_task_struct(void)
+{
+ struct task_struct *tsk;
+
+#ifndef EXTRA_TASK_STRUCT
+ tsk = ll_alloc_task_struct();
+#else
+ int index;
+
+ index = task_struct_stack_ptr;
+ if (index >= EXTRA_TASK_STRUCT/2)
+ goto use_cache;
+
+ tsk = ll_alloc_task_struct();
+
+ if (!tsk) {
+ index = task_struct_stack_ptr;
+
+ if (index >= 0) {
+use_cache: tsk = task_struct_stack[index];
+ task_struct_stack_ptr = index - 1;
+ }
+ }
+#endif
+#ifdef CONFIG_SYSRQ
+ /* You need this if you want SYSRQ-T to give sensible stack
+ * usage information
+ */
+ if (tsk) {
+ char *p = (char *)tsk;
+ memzero(p+KERNEL_STACK_SIZE, KERNEL_STACK_SIZE);
+ }
+#endif
+
+ return tsk;
+}
+
+void free_task_struct(struct task_struct *p)
+{
+#ifdef EXTRA_TASK_STRUCT
+ int index = task_struct_stack_ptr + 1;
+
+ if (index < EXTRA_TASK_STRUCT) {
+ task_struct_stack[index] = p;
+ task_struct_stack_ptr = index;
+ } else
+#endif
+ ll_free_task_struct(p);
+}
+
+/*
* Free current thread data structures etc..
*/
void exit_thread(void)
@@ -179,9 +231,10 @@
childregs = ((struct pt_regs *)((unsigned long)p + 8192)) - 1;
*childregs = *regs;
childregs->ARM_r0 = 0;
+ childregs->ARM_sp = esp;
save = ((struct context_save_struct *)(childregs)) - 1;
- copy_thread_css(save);
+ init_thread_css(save);
p->tss.save = save;
return 0;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/setup.c linux.ac/arch/arm/kernel/setup.c
--- linux.vanilla/arch/arm/kernel/setup.c Tue Dec 22 23:19:27 1998
+++ linux.ac/arch/arm/kernel/setup.c Sun Jan 24 21:11:31 1999
@@ -56,12 +56,16 @@
#define SUPPORT_CPU_SA110
#endif
-#ifndef CONFIG_CMDLINE
-#define CONFIG_CMDLINE "root=/dev/nfs rw"
-#endif
#define MEM_SIZE (16*1024*1024)
#define COMMAND_LINE_SIZE 256
+#ifndef CONFIG_CMDLINE
+#define CONFIG_CMDLINE ""
+#endif
+
+extern void reboot_setup(char *str, int *ints);
+extern void disable_hlt(void);
+
struct drive_info_struct { char dummy[32]; } drive_info;
struct screen_info screen_info = {
orig_video_lines: 30,
@@ -87,20 +91,26 @@
/*-- Match -- --- Mask -- -- Manu -- Processor uname -m --- ELF STUFF ---
--- processor asm funcs --- */
#if defined(CONFIG_CPU_26)
+ /* ARM2 fake ident */
{ 0x41560200, 0xfffffff0, "ARM/VLSI", "arm2" , "armv1" , "v1", 0,
&arm2_processor_functions },
+ /* ARM250 fake ident */
{ 0x41560250, 0xfffffff0, "ARM/VLSI", "arm250" , "armv2" , "v2", HWCAP_SWP,
&arm250_processor_functions },
+ /* ARM3 processors */
{ 0x41560300, 0xfffffff0, "ARM/VLSI", "arm3" , "armv2" , "v2", HWCAP_SWP,
&arm3_processor_functions },
#elif defined(CONFIG_CPU_32)
#ifdef SUPPORT_CPU_ARM6
+ /* ARM6 */
{ 0x41560600, 0xfffffff0, "ARM/VLSI", "arm6" , "armv3" , "v3", HWCAP_SWP,
&arm6_processor_functions },
+ /* ARM610 */
{ 0x41560610, 0xfffffff0, "ARM/VLSI", "arm610" , "armv3" , "v3", HWCAP_SWP,
&arm6_processor_functions },
#endif
#ifdef SUPPORT_CPU_ARM7
+ /* ARM7's have a strange numbering */
{ 0x41007000, 0xffffff00, "ARM/VLSI", "arm7" , "armv3" , "v3", HWCAP_SWP,
&arm7_processor_functions },
/* ARM710 IDs are non-standard */
@@ -108,8 +118,14 @@
&arm7_processor_functions },
#endif
#ifdef SUPPORT_CPU_SA110
- { 0x4401a100, 0xfffffff0, "DEC", "sa110" , "armv4" , "v3", HWCAP_SWP|HWCAP_HALF,
+#ifdef CONFIG_ARCH_RPC
+ /* Acorn RiscPC's can't handle ARMv4 half-word instructions */
+ { 0x4401a100, 0xfffffff0, "DEC", "sa110" , "armv4" , "v4", HWCAP_SWP,
&sa110_processor_functions },
+#else
+ { 0x4401a100, 0xfffffff0, "DEC", "sa110" , "armv4" , "v4", HWCAP_SWP|HWCAP_HALF,
+ &sa110_processor_functions },
+#endif
#endif
#endif
{ 0x00000000, 0x00000000, "***", "unknown", "unknown", "**", 0, NULL }
@@ -132,139 +148,10 @@
*/
/*
- * Risc-PC specific initialisation
- */
-#ifdef CONFIG_ARCH_RPC
-
-#include
-
-unsigned int vram_half_sam;
-
-static void
-setup_rpc(struct param_struct *params)
-{
- extern void init_dram_banks(const struct param_struct *params);
-
- init_dram_banks(params);
-
- switch (params->u1.s.pages_in_vram) {
- case 256:
- vram_half_sam = 1024;
- break;
- case 512:
- default:
- vram_half_sam = 2048;
- }
-}
-#else
-#define setup_rpc(x)
-#endif
-
-#ifdef PARAMS_BASE
-
-#ifdef CONFIG_ARCH_ACORN
-int memc_ctrl_reg;
-int number_ide_drives;
-int number_mfm_drives;
-#endif
-
-static struct param_struct *params = (struct param_struct *)PARAMS_BASE;
-
-__initfunc(static char *
-setup_params(unsigned long *mem_end_p))
-{
- ROOT_DEV = to_kdev_t(params->u1.s.rootdev);
- ORIG_X = params->u1.s.video_x;
- ORIG_Y = params->u1.s.video_y;
- ORIG_VIDEO_COLS = params->u1.s.video_num_cols;
- ORIG_VIDEO_LINES = params->u1.s.video_num_rows;
-
-#ifdef CONFIG_ARCH_ACORN
-#ifndef CONFIG_FB
- {
- extern int bytes_per_char_h;
- extern int bytes_per_char_v;
-
- bytes_per_char_h = params->u1.s.bytes_per_char_h;
- bytes_per_char_v = params->u1.s.bytes_per_char_v;
- }
-#endif
- memc_ctrl_reg = params->u1.s.memc_control_reg;
- number_ide_drives = (params->u1.s.adfsdrives >> 6) & 3;
- number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3;
-
- setup_rpc(params);
-
- if (!(params->u1.s.flags & FLAG_READONLY))
- root_mountflags &= ~MS_RDONLY;
-#endif
-#ifdef CONFIG_BLK_DEV_RAM
- {
- extern int rd_doload;
- extern int rd_prompt;
- extern int rd_image_start;
-
- rd_image_start = params->u1.s.rd_start;
- rd_prompt = (params->u1.s.flags & FLAG_RDPROMPT) == 0;
- rd_doload = (params->u1.s.flags & FLAG_RDLOAD) == 0;
- }
-#endif
-
-#ifdef CONFIG_ARCH_ACORN
- *mem_end_p = GET_MEMORY_END(params);
-#elif defined(CONFIG_ARCH_EBSA285)
- *mem_end_p = PAGE_OFFSET + params->u1.s.page_size * params->u1.s.nr_pages;
-#else
- *mem_end_p = PAGE_OFFSET + MEM_SIZE;
-#endif
-
- return params->commandline;
-}
-
-#else
-
-static char default_command_line[] __initdata = CONFIG_CMDLINE;
-
-__initfunc(static char *
-setup_params(unsigned long *mem_end_p))
-{
- ROOT_DEV = 0x00ff;
-
-#ifdef CONFIG_BLK_DEV_RAM
- {
- extern int rd_doload;
- extern int rd_prompt;
- extern int rd_image_start;
-
- rd_image_start = 0;
- rd_prompt = 1;
- rd_doload = 1;
- }
-#endif
-
- *mem_end_p = PAGE_OFFSET + MEM_SIZE;
-
- return default_command_line;
-}
-#endif
-
-/*
* initial ram disk
*/
#ifdef CONFIG_BLK_DEV_INITRD
__initfunc(static void
-setup_initrd(const struct param_struct *params))
-{
- if (params->u1.s.initrd_start) {
- initrd_start = params->u1.s.initrd_start;
- initrd_end = initrd_start + params->u1.s.initrd_size;
- } else {
- initrd_start = 0;
- initrd_end = 0;
- }
-}
-
-__initfunc(static void
check_initrd(unsigned long mem_start, unsigned long mem_end))
{
if (initrd_end > mem_end) {
@@ -276,7 +163,6 @@
}
#else
-#define setup_initrd(p)
#define check_initrd(ms,me)
#endif
@@ -289,48 +175,48 @@
armidlist[armidindex].mask)
armidindex += 1;
- if (armidlist[armidindex].id == 0) {
-#ifdef CONFIG_ARCH_ACORN
- int i;
-
- for (i = 0; i < 3200; i++)
- ((unsigned long *)SCREEN2_BASE)[i] = 0x77113322;
-#endif
+ if (armidlist[armidindex].id == 0)
while (1);
- }
processor = *armidlist[armidindex].proc;
processor._proc_init();
}
+static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
static char command_line[COMMAND_LINE_SIZE] = { 0, };
char saved_command_line[COMMAND_LINE_SIZE];
__initfunc(static void
setup_mem(char *cmd_line, unsigned long *mem_start, unsigned long *mem_end))
{
- char c, *to = command_line;
+ char c = ' ', *to = command_line;
int len = 0;
*mem_start = (unsigned long)&_end;
for (;;) {
- if (cmd_line[0] == ' ' &&
- cmd_line[1] == 'm' &&
- cmd_line[2] == 'e' &&
- cmd_line[3] == 'm' &&
- cmd_line[4] == '=') {
- *mem_end = simple_strtoul(cmd_line+5, &cmd_line, 0);
- switch(*cmd_line) {
- case 'M':
- case 'm':
- *mem_end <<= 10;
- case 'K':
- case 'k':
- *mem_end <<= 10;
+ if (c == ' ') {
+ if (cmd_line[0] == 'm' &&
+ cmd_line[1] == 'e' &&
+ cmd_line[2] == 'm' &&
+ cmd_line[3] == '=') {
+ *mem_end = simple_strtoul(cmd_line+4, &cmd_line, 0);
+ switch(*cmd_line) {
+ case 'M':
+ case 'm':
+ *mem_end <<= 10;
+ case 'K':
+ case 'k':
+ *mem_end <<= 10;
+ cmd_line++;
+ }
+ *mem_end = *mem_end + PAGE_OFFSET;
+ }
+ /* if there are two spaces, remove one */
+ if (*cmd_line == ' ') {
cmd_line++;
+ continue;
}
- *mem_end = *mem_end + PAGE_OFFSET;
}
c = *cmd_line++;
if (!c)
@@ -341,8 +227,49 @@
}
*to = '\0';
+
+ /* remove trailing spaces */
+ while (*--to == ' ' && to != command_line)
+ *to = '\0';
+}
+
+__initfunc(static void
+setup_ram(int doload, int prompt, int image_start))
+{
+#ifdef CONFIG_BLK_DEV_RAM
+ extern int rd_doload;
+ extern int rd_prompt;
+ extern int rd_image_start;
+
+ rd_image_start = image_start;
+ rd_prompt = prompt;
+ rd_doload = doload;
+#endif
+}
+
+/*
+ * initial ram disk
+ */
+__initfunc(static void
+setup_initrd(unsigned int start, unsigned int size))
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (start) {
+ initrd_start = start;
+ initrd_end = start + size;
+ } else {
+ initrd_start = 0;
+ initrd_end = 0;
+ }
+#endif
}
+#ifdef CONFIG_ARCH_ACORN
+int memc_ctrl_reg;
+int number_ide_drives;
+int number_mfm_drives;
+#endif
+
__initfunc(void
setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p))
{
@@ -350,6 +277,11 @@
unsigned long memory_end;
char endian = 'l';
char *from;
+#ifdef PARAMS_BASE
+ struct param_struct *params = (struct param_struct *)PARAMS_BASE;
+#else
+ struct param_struct *params = NULL;
+#endif
if (smptrap == 1)
return;
@@ -357,8 +289,83 @@
setup_processor();
- from = setup_params(&memory_end);
- setup_initrd(params);
+ init_task.mm->start_code = TASK_SIZE;
+ init_task.mm->end_code = TASK_SIZE + (unsigned long) &_etext;
+ init_task.mm->end_data = TASK_SIZE + (unsigned long) &_edata;
+ init_task.mm->brk = TASK_SIZE + (unsigned long) &_end;
+
+ /*
+ * Add your machine dependencies here
+ */
+ switch (machine_type) {
+ case MACH_TYPE_EBSA110:
+ /* EBSA110 locks if we execute 'wait for interrupt' */
+ disable_hlt();
+ params = NULL;
+ break;
+
+ case MACH_TYPE_CATS:
+ /* CATS must use soft-reboot */
+ reboot_setup("s", NULL);
+ break;
+
+ case MACH_TYPE_NETWINDER:
+ /* to be fixed in NeTTrom 2.0.6 */
+ params = NULL;
+ break;
+
+ default:
+ break;
+ }
+
+ if (params) {
+ memory_end = params->u1.s.page_size *
+ params->u1.s.nr_pages;
+
+ ROOT_DEV = to_kdev_t(params->u1.s.rootdev);
+ ORIG_X = params->u1.s.video_x;
+ ORIG_Y = params->u1.s.video_y;
+ ORIG_VIDEO_COLS = params->u1.s.video_num_cols;
+ ORIG_VIDEO_LINES = params->u1.s.video_num_rows;
+
+ setup_ram((params->u1.s.flags & FLAG_RDLOAD) == 0,
+ (params->u1.s.flags & FLAG_RDPROMPT) == 0,
+ params->u1.s.rd_start);
+
+ setup_initrd(params->u1.s.initrd_start,
+ params->u1.s.initrd_size);
+
+ if (!(params->u1.s.flags & FLAG_READONLY))
+ root_mountflags &= ~MS_RDONLY;
+
+#ifdef CONFIG_ARCH_ACORN
+ memc_ctrl_reg = params->u1.s.memc_control_reg;
+ number_ide_drives = (params->u1.s.adfsdrives >> 6) & 3;
+ number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3;
+#ifndef CONFIG_FB
+ {
+ extern int bytes_per_char_h;
+ extern int bytes_per_char_v;
+
+ bytes_per_char_h = params->u1.s.bytes_per_char_h;
+ bytes_per_char_v = params->u1.s.bytes_per_char_v;
+ }
+#endif
+ setup_rpc(params);
+#endif
+
+ from = params->commandline;
+ } else {
+ memory_end = MEM_SIZE;
+ ROOT_DEV = 0x00ff;
+
+ setup_ram(1, 1, 0);
+ setup_initrd(0, 0);
+
+ from = default_command_line;
+ }
+
+ memory_end += PAGE_OFFSET;
/* Save unparsed command line copy for /proc/cmdline */
memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
@@ -367,14 +374,6 @@
setup_mem(from, memory_start_p, &memory_end);
check_initrd(*memory_start_p, memory_end);
- init_task.mm->start_code = TASK_SIZE;
- init_task.mm->end_code = TASK_SIZE + (unsigned long) &_etext;
- init_task.mm->end_data = TASK_SIZE + (unsigned long) &_edata;
- init_task.mm->brk = TASK_SIZE + (unsigned long) &_end;
-
- *cmdline_p = command_line;
- *memory_end_p = memory_end;
-
sprintf(system_utsname.machine, "%s%c", armidlist[armidindex].arch_vsn, endian);
sprintf(elf_platform, "%s%c", armidlist[armidindex].elf_vsn, endian);
@@ -385,6 +384,9 @@
conswitchp = &dummy_con;
#endif
#endif
+
+ *cmdline_p = command_line;
+ *memory_end_p = memory_end;
}
static const struct {
@@ -393,11 +395,12 @@
} machine_desc[] = {
{ "DEC-EBSA110", "DEC" },
{ "Acorn-RiscPC", "Acorn" },
- { "Nexus-NexusPCI", "PCI" },
+ { "unknown", "PCI" },
+ { "Nexus-FTV/PCI", "PCI" },
{ "DEC-EBSA285", "PCI" },
- { "Corel-Netwinder", "PCI/ISA" },
- { "Chalice-CATS", "PCI" },
- { "unknown-TBOX", "PCI" }
+ { "Corel-NetWinder", "PCI/ISA" },
+ { "Chalice-CATS", "PCI/ISA" },
+ { "unknown-TBOX", "none" }
};
#if defined(CONFIG_ARCH_ARC)
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/signal.c linux.ac/arch/arm/kernel/signal.c
--- linux.vanilla/arch/arm/kernel/signal.c Sun Nov 8 15:08:43 1998
+++ linux.ac/arch/arm/kernel/signal.c Sun Jan 24 21:11:32 1999
@@ -28,7 +28,7 @@
asmlinkage int sys_wait4(pid_t pid, unsigned long * stat_addr,
int options, unsigned long *ru);
-asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs);
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
extern int ptrace_cancel_bpt (struct task_struct *);
extern int ptrace_set_bpt (struct task_struct *);
@@ -50,7 +50,7 @@
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if (do_signal(&saveset, regs))
+ if (do_signal(&saveset, regs, 0))
return regs->ARM_r0;
}
}
@@ -78,7 +78,7 @@
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if (do_signal(&saveset, regs))
+ if (do_signal(&saveset, regs, 0))
return regs->ARM_r0;
}
}
@@ -260,6 +260,18 @@
return err;
}
+static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+ unsigned long framesize)
+{
+ unsigned long sp = regs->ARM_sp;
+
+ /* This is the X/Open sanctioned signal stack switching. */
+ if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
+ sp = current->sas_ss_sp + current->sas_ss_size;
+
+ return (void *)(sp - framesize);
+}
+
static void setup_frame(int sig, struct k_sigaction *ka,
sigset_t *set, struct pt_regs *regs)
{
@@ -267,9 +279,9 @@
unsigned long retcode;
int err = 0;
- frame = (struct sigframe *)regs->ARM_sp - 1;
+ frame = get_sigframe(ka, regs, sizeof(*frame));
- if (!access_ok(VERIFT_WRITE, frame, sizeof (*frame)))
+ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto segv_and_exit;
err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
@@ -299,6 +311,11 @@
regs->ARM_sp = (unsigned long)frame;
regs->ARM_lr = retcode;
regs->ARM_pc = (unsigned long)ka->sa.sa_handler;
+#if defined(CONFIG_CPU_32)
+ /* Maybe we need to deliver a 32-bit signal to a 26-bit task. */
+ if (ka->sa.sa_flags & SA_THIRTYTWO)
+ regs->ARM_cpsr = USR_MODE;
+#endif
if (valid_user_regs(regs))
return;
@@ -315,7 +332,8 @@
unsigned long retcode;
int err = 0;
- frame = (struct rt_sigframe *)regs->ARM_sp - 1;
+ frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe));
+
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto segv_and_exit;
@@ -350,6 +368,11 @@
regs->ARM_sp = (unsigned long)frame;
regs->ARM_lr = retcode;
regs->ARM_pc = (unsigned long)ka->sa.sa_handler;
+#if defined(CONFIG_CPU_32)
+ /* Maybe we need to deliver a 32-bit signal to a 26-bit task. */
+ if (ka->sa.sa_flags & SA_THIRTYTWO)
+ regs->ARM_cpsr = USR_MODE;
+#endif
if (valid_user_regs(regs))
return;
@@ -393,18 +416,19 @@
* the kernel can handle, and then we build all the user-level signal handling
* stack-frames in one go after that.
*/
-asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
{
- unsigned long instr, *pc = (unsigned long *)(instruction_pointer(regs)-4);
struct k_sigaction *ka;
siginfo_t info;
- int single_stepping, swi_instr;
+ int single_stepping;
+
+ if (!user_mode(regs))
+ return 0;
if (!oldset)
oldset = ¤t->blocked;
single_stepping = ptrace_cancel_bpt (current);
- swi_instr = (!get_user (instr, pc) && (instr & 0x0f000000) == 0x0f000000);
for (;;) {
unsigned long signr;
@@ -503,7 +527,7 @@
}
/* Are we from a system call? */
- if (swi_instr) {
+ if (syscall) {
switch (regs->ARM_r0) {
case -ERESTARTNOHAND:
regs->ARM_r0 = -EINTR;
@@ -527,7 +551,7 @@
return 1;
}
- if (swi_instr &&
+ if (syscall &&
(regs->ARM_r0 == -ERESTARTNOHAND ||
regs->ARM_r0 == -ERESTARTSYS ||
regs->ARM_r0 == -ERESTARTNOINTR)) {
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/sys_arm.c linux.ac/arch/arm/kernel/sys_arm.c
--- linux.vanilla/arch/arm/kernel/sys_arm.c Tue Dec 22 23:19:27 1998
+++ linux.ac/arch/arm/kernel/sys_arm.c Sun Jan 24 21:11:32 1999
@@ -221,13 +221,7 @@
*/
asmlinkage int sys_fork(struct pt_regs *regs)
{
- int ret;
-
- lock_kernel();
- ret = do_fork(SIGCHLD, regs->ARM_sp, regs);
- unlock_kernel();
-
- return ret;
+ return do_fork(SIGCHLD, regs->ARM_sp, regs);
}
/* Clone a task - this clones the calling program thread.
@@ -235,14 +229,23 @@
*/
asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, struct pt_regs *regs)
{
- int ret;
-
- lock_kernel();
if (!newsp)
newsp = regs->ARM_sp;
- ret = do_fork(clone_flags, newsp, regs);
- unlock_kernel();
- return ret;
+ return do_fork(clone_flags, newsp, regs);
+}
+
+asmlinkage int sys_vfork(struct pt_regs *regs)
+{
+ int child;
+ struct semaphore sem = MUTEX_LOCKED;
+
+ current->vfork_sem = &sem;
+ child = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs);
+
+ if (child > 0)
+ down(&sem);
+
+ return child;
}
/* sys_execve() executes a new program.
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/time.c linux.ac/arch/arm/kernel/time.c
--- linux.vanilla/arch/arm/kernel/time.c Sun Jan 24 19:55:30 1999
+++ linux.ac/arch/arm/kernel/time.c Sun Jan 24 21:11:32 1999
@@ -130,27 +130,12 @@
time_state = TIME_ERROR; /* p. 24, (a) */
time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT;
- sti ();
+ sti();
}
-/*
- * timer_interrupt() needs to keep up the real-time clock,
- * as well as call the "do_timer()" routine every clocktick.
- */
-static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- if (reset_timer ())
- do_timer(regs);
-
- update_rtc ();
-}
-
-static struct irqaction irqtimer = { timer_interrupt, 0, 0, "timer", NULL, NULL};
-
__initfunc(void time_init(void))
{
- xtime.tv_sec = setup_timer();
xtime.tv_usec = 0;
- setup_arm_irq(IRQ_TIMER, &irqtimer);
+ setup_timer();
}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/kernel/traps.c linux.ac/arch/arm/kernel/traps.c
--- linux.vanilla/arch/arm/kernel/traps.c Tue Dec 22 23:19:27 1998
+++ linux.ac/arch/arm/kernel/traps.c Sun Jan 24 21:11:32 1999
@@ -54,7 +54,7 @@
if (stackptr < PAGE_OFFSET || stackptr + size > (unsigned long)high_memory)
return -EFAULT;
#endif
- return 0;
+ return 0;
}
/*
@@ -199,9 +199,8 @@
void bad_user_access_alignment (const void *ptr)
{
- void *pc;
- __asm__("mov %0, lr\n": "=r" (pc));
- printk (KERN_ERR "bad_user_access_alignment called: ptr = %p, pc = %p\n", ptr, pc);
+ printk (KERN_ERR "bad_user_access_alignment called: ptr = %p, pc = %p\n", ptr,
+ __builtin_return_address(0));
current->tss.error_code = 0;
current->tss.trap_no = 11;
force_sig (SIGBUS, current);
@@ -210,6 +209,10 @@
asmlinkage void do_undefinstr (int address, struct pt_regs *regs, int mode)
{
+#ifdef CONFIG_DEBUG_USER
+ printk(KERN_INFO "%s (%d): undefined instruction: pc=%08lx\n",
+ current->comm, current->pid, instruction_pointer(regs));
+#endif
current->tss.error_code = 0;
current->tss.trap_no = 6;
force_sig (SIGILL, current);
@@ -218,6 +221,10 @@
asmlinkage void do_excpt (int address, struct pt_regs *regs, int mode)
{
+#ifdef CONFIG_DEBUG_USER
+ printk(KERN_INFO "%s (%d): address exception: pc=%08lx\n",
+ current->comm, current->pid, instruction_pointer(regs));
+#endif
current->tss.error_code = 0;
current->tss.trap_no = 11;
force_sig (SIGBUS, current);
@@ -249,19 +256,14 @@
*/
asmlinkage void math_state_restore (void)
{
- current->used_math = 1;
+ current->used_math = 1;
}
-asmlinkage void arm_syscall (int no, struct pt_regs *regs)
+asmlinkage int arm_syscall (int no, struct pt_regs *regs)
{
switch (no) {
case 0: /* branch through 0 */
force_sig(SIGSEGV, current);
-// if (user_mode(regs)) {
-// dump_state("branch through zero", regs, 0);
-// if (regs->ARM_fp)
-// c_backtrace (regs->ARM_fp, processor_mode(regs));
-// }
die_if_kernel ("branch through zero", regs, 0, SIGSEGV);
break;
@@ -271,21 +273,54 @@
force_sig (SIGTRAP, current);
break;
+ case 2: /* sys_cacheflush */
+#ifdef CONFIG_CPU_32
+ /* r0 = start, r1 = length, r2 = flags */
+ processor.u.armv3v4._flush_cache_area(regs->ARM_r0,
+ regs->ARM_r1,
+ 1);
+#endif
+ break;
+
default:
+ /* Calls 9f00xx..9f07ff are defined to return -ENOSYS
+ if not implemented, rather than raising SIGILL. This
+ way the calling program can gracefully determine whether
+ a feature is supported. */
+ if (no <= 0x7ff)
+ return -ENOSYS;
+#ifdef CONFIG_DEBUG_USER
+ /* experiance shows that these seem to indicate that
+ * something catastrophic has happened
+ */
printk ("[%d] %s: arm syscall %d\n", current->pid, current->comm, no);
- force_sig (SIGILL, current);
if (user_mode(regs)) {
show_regs (regs);
c_backtrace (regs->ARM_fp, processor_mode(regs));
}
+#endif
+ force_sig (SIGILL, current);
die_if_kernel ("Oops", regs, no, SIGILL);
break;
}
+ return 0;
}
asmlinkage void deferred(int n, struct pt_regs *regs)
{
- dump_state("old system call", regs, n);
+ /* You might think just testing `handler' would be enough, but PER_LINUX
+ points it to no_lcall7 to catch undercover SVr4 binaries. Gutted. */
+ if (current->personality != PER_LINUX && current->exec_domain->handler) {
+ /* Hand it off to iBCS. The extra parameter and consequent type
+ forcing is necessary because of the weird ARM calling convention. */
+ void (*handler)(int nr, struct pt_regs *regs) = (void *)current->exec_domain->handler;
+ (*handler)(n, regs);
+ return;
+ }
+#ifdef CONFIG_DEBUG_USER
+ printk(KERN_ERR "[%d] %s: old system call.\n", current->pid,
+ current->comm);
+#endif
force_sig (SIGILL, current);
}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/lib/Makefile linux.ac/arch/arm/lib/Makefile
--- linux.vanilla/arch/arm/lib/Makefile Tue Dec 22 23:19:27 1998
+++ linux.ac/arch/arm/lib/Makefile Sun Jan 24 21:11:32 1999
@@ -6,7 +6,7 @@
L_TARGET := lib.a
L_OBJS := backtrace.o bitops.o checksum.o delay.o io.o memcpy.o \
- system.o string.o uaccess.o
+ semaphore.o string.o system.o uaccess.o
ifeq ($(PROCESSOR),armo)
L_OBJS += uaccess-armo.o
@@ -24,10 +24,6 @@
ifeq ($(MACHINE),ebsa110)
L_OBJS += io-ebsa110.o
-endif
-
-ifeq ($(MACHINE),vnc)
- L_OBJS += io-ebsa285.o
endif
ifeq ($(MACHINE),ebsa285)
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/lib/checksum.S linux.ac/arch/arm/lib/checksum.S
--- linux.vanilla/arch/arm/lib/checksum.S Sun Nov 8 15:08:44 1998
+++ linux.ac/arch/arm/lib/checksum.S Sun Jan 24 21:11:32 1999
@@ -520,13 +520,13 @@
LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
ldr r4, [r0], #4
tst r2, #2
- beq Lexit
+ beq Lexit_r4
adcs r3, r3, r4, lsl #16
strb r4, [r1], #1
mov r4, r4, lsr #8
strb r4, [r1], #1
mov r4, r4, lsr #8
- b Lexit
+ b Lexit_r4
Ltoo_small: teq r2, #0
LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
@@ -538,10 +538,12 @@
adds r3, r3, ip
strb ip, [r1], #1
strb r8, [r1], #1
-Lexit: tst r2, #1
-Ltoo_small1: ldrneb ip, [r0], #1
- strneb ip, [r1], #1
- adcnes r3, r3, ip
+ tst r2, #1
+Ltoo_small1: ldrneb r4, [r0], #1
+Lexit_r4: tst r2, #1
+ strneb r4, [r1], #1
+ andne r4, r4, #255
+ adcnes r3, r3, r4
adcs r0, r3, #0
LOADREGS(ea,fp,{r4 - r8, fp, sp, pc})
@@ -598,13 +600,13 @@
adceq r0, r3, #0
LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
tst r2, #2
- beq Lexit
+ beq Lexit_r4
adcs r3, r3, r4, lsl #16
strb r4, [r1], #1
mov r4, r4, lsr #8
strb r4, [r1], #1
mov r4, r4, lsr #8
- b Lexit
+ b Lexit_r4
Lsrc2_aligned: mov r4, r4, lsr #16
adds r3, r3, #0
@@ -650,13 +652,13 @@
adceq r0, r3, #0
LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
tst r2, #2
- beq Lexit
+ beq Lexit_r4
adcs r3, r3, r4, lsl #16
strb r4, [r1], #1
mov r4, r4, lsr #8
strb r4, [r1], #1
ldrb r4, [r0], #1
- b Lexit
+ b Lexit_r4
Lsrc3_aligned: mov r4, r4, lsr #24
adds r3, r3, #0
@@ -702,14 +704,14 @@
adceq r0, r3, #0
LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
tst r2, #2
- beq Lexit
+ beq Lexit_r4
adcs r3, r3, r4, lsl #16
strb r4, [r1], #1
ldr r4, [r0], #4
strb r4, [r1], #1
adcs r3, r3, r4, lsl #24
mov r4, r4, lsr #8
- b Lexit
+ b Lexit_r4
ENTRY(__csum_ipv6_magic)
stmfd sp!, {lr}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/lib/io-ebsa285.S linux.ac/arch/arm/lib/io-ebsa285.S
--- linux.vanilla/arch/arm/lib/io-ebsa285.S Tue Dec 22 23:19:27 1998
+++ linux.ac/arch/arm/lib/io-ebsa285.S Sun Jan 24 21:11:32 1999
@@ -1,8 +1,12 @@
#include
+ .macro ioaddr, rd,rn
+ add \rd, \rn, #0xff000000
+ add \rd, \rd, #0x00e00000
+ .endm
+
ENTRY(insl)
- add r0, r0, #0xff000000
- add r0, r0, #0x00e00000
+ ioaddr r0, r0
ands ip, r1, #3
bne 2f
@@ -14,49 +18,48 @@
2: cmp ip, #2
ldr ip, [r0]
- blt 3f
- bgt 4f
+ blt 4f
+ bgt 6f
strh ip, [r1], #2
mov ip, ip, lsr #16
-1: subs r2, r2, #1
+3: subs r2, r2, #1
ldrne r3, [r0]
orrne ip, ip, r3, lsl #16
strne ip, [r1], #4
movne ip, r3, lsr #16
- bne 1b
+ bne 3b
strh ip, [r1], #2
mov pc, lr
-3: strb ip, [r1], #1
+4: strb ip, [r1], #1
mov ip, ip, lsr #8
strh ip, [r1], #2
mov ip, ip, lsr #16
-1: subs r2, r2, #1
+5: subs r2, r2, #1
ldrne r3, [r0]
orrne ip, ip, r3, lsl #8
strne ip, [r1], #4
movne ip, r3, lsr #24
- bne 1b
+ bne 5b
strb ip, [r1], #1
mov pc, lr
-4: strb ip, [r1], #1
+6: strb ip, [r1], #1
mov ip, ip, lsr #8
-1: subs r2, r2, #1
+7: subs r2, r2, #1
ldrne r3, [r0]
orrne ip, ip, r3, lsl #24
strne ip, [r1], #4
movne ip, r3, lsr #8
- bne 1b
+ bne 7b
strb ip, [r1], #1
mov ip, ip, lsr #8
strh ip, [r1], #2
mov pc, lr
ENTRY(outsl)
- add r0, r0, #0xff000000
- add r0, r0, #0x00e00000
+ ioaddr r0, r0
ands ip, r1, #3
bne 2f
@@ -70,31 +73,31 @@
cmp ip, #2
ldr ip, [r1], #4
mov ip, ip, lsr #16
- blt 3f
- bgt 4f
+ blt 4f
+ bgt 5f
-1: ldr r3, [r1], #4
+3: ldr r3, [r1], #4
orr ip, ip, r3, lsl #16
str ip, [r0]
mov ip, r3, lsr #16
subs r2, r2, #1
- bne 1b
+ bne 3b
mov pc, lr
-3: ldr r3, [r1], #4
+4: ldr r3, [r1], #4
orr ip, ip, r3, lsl #8
str ip, [r0]
mov ip, r3, lsr #24
subs r2, r2, #1
- bne 3b
+ bne 4b
mov pc, lr
-4: ldr r3, [r1], #4
+5: ldr r3, [r1], #4
orr ip, ip, r3, lsl #24
str ip, [r0]
mov ip, r3, lsr #8
subs r2, r2, #1
- bne 4b
+ bne 5b
mov pc, lr
/* Nobody could say these are optimal, but not to worry. */
@@ -102,8 +105,7 @@
ENTRY(outswb)
mov r2, r2, lsr #1
ENTRY(outsw)
- add r0, r0, #0xff000000
- add r0, r0, #0x00e00000
+ ioaddr r0, r0
1: subs r2, r2, #1
ldrgeh r3, [r1], #2
strgeh r3, [r0]
@@ -114,8 +116,7 @@
mov r2, r2, lsr #1
ENTRY(insw)
stmfd sp!, {r4, r5, lr}
- add r0, r0, #0xff000000
- add r0, r0, #0x00e00000
+ ioaddr r0, r0
@ + 8 + 9 +10 +11 +12 +13 +14 +15 +16 +17
subs ip, r2, #8
blo too_little
@@ -176,8 +177,7 @@
ENTRY(insb)
- add r0, r0, #0xff000000
- add r0, r0, #0x00e00000
+ ioaddr r0, r0
1: teq r2, #0
ldrneb r3, [r0]
strneb r3, [r1], #1
@@ -187,8 +187,7 @@
ENTRY(outsb)
- add r0, r0, #0xff000000
- add r0, r0, #0x00e00000
+ ioaddr r0, r0
1: teq r2, #0
ldrneb r3, [r1], #1
strneb r3, [r0]
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/lib/semaphore.S linux.ac/arch/arm/lib/semaphore.S
--- linux.vanilla/arch/arm/lib/semaphore.S Thu Jan 1 01:00:00 1970
+++ linux.ac/arch/arm/lib/semaphore.S Sun Jan 24 21:11:32 1999
@@ -0,0 +1,29 @@
+/*
+ * linux/arch/arm/lib/semaphore.S
+ *
+ * Idea from i386 code, Copyright Linus Torvalds.
+ * Converted for ARM by Russell King
+ */
+#include
+#include
+
+/*
+ * The semaphore operations have a special calling sequence
+ * that allows us to keep the distruption of the main code
+ * path to a minimum. These routines save and restore the
+ * registers that will be touched by __down etc.
+ */
+ENTRY(__down_failed)
+ stmfd sp!, {r0 - r3, ip, lr}
+ bl SYMBOL_NAME(__down)
+ LOADREGS(fd, sp!, {r0 - r3, ip, pc})
+
+ENTRY(__down_interruptible_failed)
+ stmfd sp!, {r1 - r3, ip, lr}
+ bl SYMBOL_NAME(__down_interruptible)
+ LOADREGS(fd, sp!, {r1 - r3, ip, pc})
+
+ENTRY(__up_wakeup)
+ stmfd sp!, {r0 - r3, ip, lr}
+ bl SYMBOL_NAME(__up)
+ LOADREGS(fd, sp!, {r0 - r3, ip, pc})
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/mm/Makefile linux.ac/arch/arm/mm/Makefile
--- linux.vanilla/arch/arm/mm/Makefile Sun Nov 8 15:08:44 1998
+++ linux.ac/arch/arm/mm/Makefile Sun Jan 24 21:11:32 1999
@@ -22,7 +22,7 @@
endif
ifeq ($(PROCESSOR),armv)
- O_OBJS += small_page.o proc-arm6,7.o proc-sa110.o
+ O_OBJS += small_page.o proc-arm6,7.o proc-sa110.o ioremap.o
endif
include $(TOPDIR)/Rules.make
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/mm/fault-armo.c linux.ac/arch/arm/mm/fault-armo.c
--- linux.vanilla/arch/arm/mm/fault-armo.c Tue Dec 22 23:19:28 1998
+++ linux.ac/arch/arm/mm/fault-armo.c Sun Jan 24 21:11:32 1999
@@ -157,19 +157,17 @@
bad_area:
up(&mm->mmap_sem);
if (mode & FAULT_CODE_USER) {
-//extern int console_loglevel;
-//cli();
tsk->tss.error_code = mode;
tsk->tss.trap_no = 14;
-//console_loglevel = 9;
+#ifdef CONFIG_DEBUG_USER
printk ("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n",
tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode);
-//#ifdef DEBUG
+#ifdef DEBUG
show_regs (regs);
c_backtrace (regs->ARM_fp, 0);
-//#endif
+#endif
+#endif
force_sig(SIGSEGV, tsk);
-//while (1);
goto out;
}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/mm/fault-armv.c linux.ac/arch/arm/mm/fault-armv.c
--- linux.vanilla/arch/arm/mm/fault-armv.c Tue Dec 22 23:19:28 1998
+++ linux.ac/arch/arm/mm/fault-armv.c Sun Jan 24 21:11:32 1999
@@ -5,6 +5,7 @@
* Modifications for ARM processor (c) 1995, 1996 Russell King
*/
+#include
#include
#include
#include
@@ -16,10 +17,13 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
+#include
#define FAULT_CODE_READ 0x02
#define FAULT_CODE_USER 0x01
@@ -48,8 +52,8 @@
if (pgd) {
init = pgd_offset(&init_mm, 0);
- memzero ((void *)pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
- memcpy (pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+ memzero((void *)pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
+ memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
(PTRS_PER_PGD - USER_PTRS_PER_PGD) * BYTES_PER_PTR);
}
return pgd;
@@ -62,14 +66,14 @@
pte = (pte_t *) get_small_page(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (pte) {
- memzero (pte, PTRS_PER_PTE * BYTES_PER_PTR);
+ memzero(pte, PTRS_PER_PTE * BYTES_PER_PTR);
set_pmd(pmd, mk_user_pmd(pte));
return pte + offset;
}
set_pmd(pmd, mk_user_pmd(BAD_PAGETABLE));
return NULL;
}
- free_small_page ((unsigned long) pte);
+ free_small_page((unsigned long) pte);
if (pmd_bad(*pmd)) {
__bad_pmd(pmd);
return NULL;
@@ -84,14 +88,14 @@
pte = (pte_t *) get_small_page(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (pte) {
- memzero (pte, PTRS_PER_PTE * BYTES_PER_PTR);
+ memzero(pte, PTRS_PER_PTE * BYTES_PER_PTR);
set_pmd(pmd, mk_kernel_pmd(pte));
return pte + offset;
}
set_pmd(pmd, mk_kernel_pmd(BAD_PAGETABLE));
return NULL;
}
- free_small_page ((unsigned long) pte);
+ free_small_page((unsigned long) pte);
if (pmd_bad(*pmd)) {
__bad_pmd_kernel(pmd);
return NULL;
@@ -102,7 +106,7 @@
extern void die_if_kernel(char *msg, struct pt_regs *regs, unsigned int err, unsigned int ret);
#ifdef DEBUG
-static int sp_valid (unsigned long *sp)
+static int sp_valid(unsigned long *sp)
{
unsigned long addr = (unsigned long) sp;
@@ -114,7 +118,7 @@
}
#endif
-static void kernel_page_fault (unsigned long addr, int mode, struct pt_regs *regs,
+static void kernel_page_fault(unsigned long addr, int mode, struct pt_regs *regs,
struct task_struct *tsk, struct mm_struct *mm)
{
/*
@@ -123,26 +127,26 @@
*/
pgd_t *pgd;
if (addr < PAGE_SIZE)
- printk (KERN_ALERT "Unable to handle kernel NULL pointer dereference");
+ printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
else
- printk (KERN_ALERT "Unable to handle kernel paging request");
- printk (" at virtual address %08lx\n", addr);
- printk (KERN_ALERT "current->tss.memmap = %08lX\n", tsk->tss.memmap);
- pgd = pgd_offset (mm, addr);
- printk (KERN_ALERT "*pgd = %08lx", pgd_val (*pgd));
- if (!pgd_none (*pgd)) {
+ printk(KERN_ALERT "Unable to handle kernel paging request");
+ printk(" at virtual address %08lx\n", addr);
+ printk(KERN_ALERT "current->tss.memmap = %08lX\n", tsk->tss.memmap);
+ pgd = pgd_offset(mm, addr);
+ printk(KERN_ALERT "*pgd = %08lx", pgd_val(*pgd));
+ if (!pgd_none(*pgd)) {
pmd_t *pmd;
- pmd = pmd_offset (pgd, addr);
- printk (", *pmd = %08lx", pmd_val (*pmd));
- if (!pmd_none (*pmd))
- printk (", *pte = %08lx", pte_val (*pte_offset (pmd, addr)));
- }
- printk ("\n");
- die_if_kernel ("Oops", regs, mode, SIGKILL);
- do_exit (SIGKILL);
+ pmd = pmd_offset(pgd, addr);
+ printk(", *pmd = %08lx", pmd_val(*pmd));
+ if (!pmd_none(*pmd))
+ printk(", *pte = %08lx", pte_val(*pte_offset(pmd, addr)));
+ }
+ printk("\n");
+ die_if_kernel("Oops", regs, mode, SIGKILL);
+ do_exit(SIGKILL);
}
-static void page_fault (unsigned long addr, int mode, struct pt_regs *regs)
+static void do_page_fault(unsigned long addr, int mode, struct pt_regs *regs)
{
struct task_struct *tsk;
struct mm_struct *mm;
@@ -154,12 +158,12 @@
mm = tsk->mm;
down(&mm->mmap_sem);
- vma = find_vma (mm, addr);
+ vma = find_vma(mm, addr);
if (!vma)
goto bad_area;
if (vma->vm_start <= addr)
goto good_area;
- if (!(vma->vm_flags & VM_GROWSDOWN) || expand_stack (vma, addr))
+ if (!(vma->vm_flags & VM_GROWSDOWN) || expand_stack(vma, addr))
goto bad_area;
/*
@@ -174,7 +178,7 @@
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
}
- handle_mm_fault (tsk, vma, addr & PAGE_MASK, !(mode & FAULT_CODE_READ));
+ handle_mm_fault(tsk, vma, addr & PAGE_MASK, !(mode & FAULT_CODE_READ));
up(&mm->mmap_sem);
goto out;
@@ -187,21 +191,23 @@
if (mode & FAULT_CODE_USER) {
tsk->tss.error_code = mode;
tsk->tss.trap_no = 14;
- printk ("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n",
+#ifdef CONFIG_DEBUG_USER
+ printk("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n",
tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode);
#ifdef DEBUG
{
unsigned int i, j;
unsigned long *sp = (unsigned long *) (regs->ARM_sp - 128);
- for (j = 0; j < 20 && sp_valid (sp); j++) {
- printk ("%p: ", sp);
- for (i = 0; i < 8 && sp_valid (sp); i += 1, sp++)
- printk ("%08lx ", *sp);
- printk ("\n");
+ for (j = 0; j < 20 && sp_valid(sp); j++) {
+ printk("%p: ", sp);
+ for (i = 0; i < 8 && sp_valid(sp); i += 1, sp++)
+ printk("%08lx ", *sp);
+ printk("\n");
}
}
- show_regs (regs);
- c_backtrace (regs->ARM_fp, regs->ARM_cpsr);
+ show_regs(regs);
+ c_backtrace(regs->ARM_fp, regs->ARM_cpsr);
+#endif
#endif
force_sig(SIGSEGV, tsk);
goto out;
@@ -209,92 +215,363 @@
/* Are we prepared to handle this kernel fault? */
if ((fixup = search_exception_table(instruction_pointer(regs))) != 0) {
+#ifdef DEBUG
printk(KERN_DEBUG "%s: Exception at [<%lx>] addr=%lx (fixup: %lx)\n",
tsk->comm, regs->ARM_pc, addr, fixup);
+#endif
regs->ARM_pc = fixup;
goto out;
}
- kernel_page_fault (addr, mode, regs, tsk, mm);
+ kernel_page_fault(addr, mode, regs, tsk, mm);
out:
unlock_kernel();
}
+#ifdef CONFIG_ALIGNMENT_TRAP
+/*
+ * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998
+ * /proc/sys/debug/alignment, modified and integrated into
+ * Linux 2.1 by Russell King
+ *
+ * NOTE!!! This is not portable onto the ARM6/ARM7 processors yet. Also,
+ * it seems to give a severe performance impact (1 abort/ms - NW runs at
+ * ARM6 speeds) with GCC 2.7.2.2 - needs checking with a later GCC/EGCS.
+ *
+ * IMHO, I don't think that the trap handler is advantageous on ARM6,7
+ * processors (they'll run like an ARM3). We'll see.
+ */
+#define CODING_BITS(i) (i & 0x0e000000)
+
+#define LDST_I_BIT(i) (i & (1 << 26)) /* Immediate constant */
+#define LDST_P_BIT(i) (i & (1 << 24)) /* Preindex */
+#define LDST_U_BIT(i) (i & (1 << 23)) /* Add offset */
+#define LDST_W_BIT(i) (i & (1 << 21)) /* Writeback */
+#define LDST_L_BIT(i) (i & (1 << 20)) /* Load */
+
+#define LDSTH_I_BIT(i) (i & (1 << 22)) /* half-word immed */
+#define LDM_S_BIT(i) (i & (1 << 22)) /* write CPSR from SPSR */
+
+#define RN_BITS(i) ((i >> 16) & 15) /* Rn */
+#define RD_BITS(i) ((i >> 12) & 15) /* Rd */
+#define RM_BITS(i) (i & 15) /* Rm */
+
+#define REGMASK_BITS(i) (i & 0xffff)
+#define OFFSET_BITS(i) (i & 0x0fff)
+
+#define IS_SHIFT(i) (i & 0x0ff0)
+#define SHIFT_BITS(i) ((i >> 7) & 0x1f)
+#define SHIFT_TYPE(i) (i & 0x60)
+#define SHIFT_LSL 0x00
+#define SHIFT_LSR 0x20
+#define SHIFT_ASR 0x40
+#define SHIFT_RORRRX 0x60
+
+static unsigned long ai_user;
+static unsigned long ai_sys;
+static unsigned long ai_skipped;
+static unsigned long ai_half;
+static unsigned long ai_word;
+static unsigned long ai_multi;
+
+static int proc_alignment_read(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ char *p = page;
+ int len;
+
+ p += sprintf(p, "User:\t\t%li\n", ai_user);
+ p += sprintf(p, "System:\t\t%li\n", ai_sys);
+ p += sprintf(p, "Skipped:\t%li\n", ai_skipped);
+ p += sprintf(p, "Half:\t\t%li\n", ai_half);
+ p += sprintf(p, "Word:\t\t%li\n", ai_word);
+ p += sprintf(p, "Multi:\t\t%li\n", ai_multi);
+
+ len = (p - page) - off;
+ if (len < 0)
+ len = 0;
+
+ *eof = (len <= count) ? 1 : 0;
+ *start = page + off;
+
+ return len;
+}
+
/*
- * Handle a data abort. Note that we have to handle a range of addresses
- * on ARM2/3 for ldm. If both pages are zero-mapped, then we have to force
- * a copy-on-write
+ * This needs to be done after sysctl_init, otherwise sys/
+ * will be overwritten.
*/
+void __init alignment_init(void)
+{
+ struct proc_dir_entry *e;
+
+ e = create_proc_entry("sys/debug/alignment", S_IFREG | S_IRUGO, NULL);
+
+ if (e)
+ e->read_proc = proc_alignment_read;
+}
+
+static void
+do_alignment_exception(struct pt_regs *regs)
+{
+ unsigned int instr, rd, rn, correction, nr_regs, regbits;
+ unsigned long eaddr;
+ union { unsigned long un; signed long sn; } offset;
+
+ if (user_mode(regs)) {
+ set_cr(cr_no_alignment);
+ ai_user += 1;
+ return;
+ }
+
+ ai_sys += 1;
+
+ instr = *(unsigned long *)instruction_pointer(regs);
+ correction = 4; /* sometimes 8 on ARMv3 */
+ regs->ARM_pc += correction + 4;
+
+ rd = RD_BITS(instr);
+ rn = RN_BITS(instr);
+ eaddr = regs->uregs[rn];
+
+ switch(CODING_BITS(instr)) {
+ case 0x00000000:
+ if ((instr & 0x0ff00ff0) == 0x01000090) {
+ ai_skipped += 1;
+ printk(KERN_ERR "Unaligned trap: not handling swp instruction\n");
+ break;
+ }
+
+ if (((instr & 0x0e000090) == 0x00000090) && (instr & 0x60) != 0) {
+ ai_half += 1;
+ if (LDSTH_I_BIT(instr))
+ offset.un = (instr & 0xf00) >> 4 | (instr & 15);
+ else
+ offset.un = regs->uregs[RM_BITS(instr)];
+
+ if (LDST_P_BIT(instr)) {
+ if (LDST_U_BIT(instr))
+ eaddr += offset.un;
+ else
+ eaddr -= offset.un;
+ }
+
+ if (LDST_L_BIT(instr))
+ regs->uregs[rd] = get_unaligned((unsigned short *)eaddr);
+ else
+ put_unaligned(regs->uregs[rd], (unsigned short *)eaddr);
+
+ /* signed half-word? */
+ if (instr & 0x40)
+ regs->uregs[rd] = (long)((short) regs->uregs[rd]);
+
+ if (!LDST_P_BIT(instr)) {
+ if (LDST_U_BIT(instr))
+ eaddr += offset.un;
+ else
+ eaddr -= offset.un;
+ regs->uregs[rn] = eaddr;
+ } else if (LDST_W_BIT(instr))
+ regs->uregs[rn] = eaddr;
+ break;
+ }
+
+ default:
+ ai_skipped += 1;
+ panic("Alignment trap: not handling instruction %08X at %08lX",
+ instr, regs->ARM_pc - correction - 4);
+ break;
+
+ case 0x04000000:
+ offset.un = OFFSET_BITS(instr);
+ goto ldr_str;
+
+ case 0x06000000:
+ offset.un = regs->uregs[RM_BITS(instr)];
+
+ if (IS_SHIFT(instr)) {
+ unsigned int shiftval = SHIFT_BITS(instr);
+
+ switch(SHIFT_TYPE(instr)) {
+ case SHIFT_LSL:
+ offset.un <<= shiftval;
+ break;
+
+ case SHIFT_LSR:
+ offset.un >>= shiftval;
+ break;
+
+ case SHIFT_ASR:
+ offset.sn >>= shiftval;
+ break;
+
+ case SHIFT_RORRRX:
+ if (shiftval == 0) {
+ offset.un >>= 1;
+ if (regs->ARM_cpsr & CC_C_BIT)
+ offset.un |= 1 << 31;
+ } else
+ offset.un = offset.un >> shiftval |
+ offset.un << (32 - shiftval);
+ break;
+ }
+ }
+
+ ldr_str:
+ ai_word += 1;
+ if (LDST_P_BIT(instr)) {
+ if (LDST_U_BIT(instr))
+ eaddr += offset.un;
+ else
+ eaddr -= offset.un;
+ } else {
+ if (LDST_W_BIT(instr))
+ printk(KERN_ERR "Not handling ldrt/strt correctly\n");
+ }
+
+ if (LDST_L_BIT(instr)) {
+ regs->uregs[rd] = get_unaligned((unsigned long *)eaddr);
+ if (rd == 15)
+ correction = 0;
+ } else
+ put_unaligned(regs->uregs[rd], (unsigned long *)eaddr);
+
+ if (!LDST_P_BIT(instr)) {
+ if (LDST_U_BIT(instr))
+ eaddr += offset.un;
+ else
+ eaddr -= offset.un;
+
+ regs->uregs[rn] = eaddr;
+ } else if (LDST_W_BIT(instr))
+ regs->uregs[rn] = eaddr;
+ break;
+
+ case 0x08000000:
+ if (LDM_S_BIT(instr))
+ panic("Alignment trap: not handling LDM with s-bit\n");
+ ai_multi += 1;
+
+ for (regbits = REGMASK_BITS(instr), nr_regs = 0; regbits; regbits >>= 1)
+ nr_regs += 4;
+
+ if (!LDST_U_BIT(instr))
+ eaddr -= nr_regs;
+
+ if ((LDST_U_BIT(instr) == 0 && LDST_P_BIT(instr) == 0) ||
+ (LDST_U_BIT(instr) && LDST_P_BIT(instr)))
+ eaddr += 4;
+
+ for (regbits = REGMASK_BITS(instr), rd = 0; regbits; regbits >>= 1, rd += 1)
+ if (regbits & 1) {
+ if (LDST_L_BIT(instr)) {
+ regs->uregs[rd] = get_unaligned((unsigned long *)eaddr);
+ if (rd == 15)
+ correction = 0;
+ } else
+ put_unaligned(regs->uregs[rd], (unsigned long *)eaddr);
+ eaddr += 4;
+ }
+
+ if (LDST_W_BIT(instr)) {
+ if (LDST_P_BIT(instr) && !LDST_U_BIT(instr))
+ eaddr -= nr_regs;
+ else if (LDST_P_BIT(instr))
+ eaddr -= 4;
+ else if (!LDST_U_BIT(instr))
+ eaddr -= 4 + nr_regs;
+ regs->uregs[rn] = eaddr;
+ }
+ break;
+ }
+
+ regs->ARM_pc -= correction;
+}
+
+#endif
+
asmlinkage void
-do_DataAbort (unsigned long addr, int fsr, int error_code, struct pt_regs *regs)
+do_DataAbort(unsigned long addr, int fsr, int error_code, struct pt_regs *regs)
{
if (user_mode(regs))
error_code |= FAULT_CODE_USER;
+
#define DIE(signr,nam)\
force_sig(signr, current);\
die_if_kernel(nam, regs, fsr, signr);\
- break;
+ break
switch (fsr & 15) {
case 2:
- DIE(SIGKILL, "Terminal exception")
+ DIE(SIGKILL, "Terminal exception");
case 0:
- DIE(SIGSEGV, "Vector exception")
+ DIE(SIGSEGV, "Vector exception");
case 1:
case 3:
- DIE(SIGBUS, "Alignment exception")
+#ifdef CONFIG_ALIGNMENT_TRAP
+ do_alignment_exception(regs);
+#else
+ /* this should never happen */
+ DIE(SIGBUS, "Alignment exception");
+#endif
+ break;
+
case 12:
case 14:
- DIE(SIGBUS, "External abort on translation")
+ DIE(SIGBUS, "External abort on translation");
case 9:
case 11:
- DIE(SIGSEGV, "Domain fault")
+ DIE(SIGSEGV, "Domain fault");
case 13:/* permission fault on section */
+#ifdef CONFIG_DEBUG_USER
+ printk("%s: permission fault on section, address=0x%08lx, code %d\n",
+ current->comm, addr, error_code);
#ifdef DEBUG
{
unsigned int i, j;
unsigned long *sp;
- printk ("%s: section permission fault (bad address=0x%08lx, code %d)\n",
- current->comm, addr, error_code);
sp = (unsigned long *) (regs->ARM_sp - 128);
- for (j = 0; j < 20 && sp_valid (sp); j++) {
- printk ("%p: ", sp);
- for (i = 0; i < 8 && sp_valid (sp); i += 1, sp++)
- printk ("%08lx ", *sp);
- printk ("\n");
+ for (j = 0; j < 20 && sp_valid(sp); j++) {
+ printk("%p: ", sp);
+ for (i = 0; i < 8 && sp_valid(sp); i += 1, sp++)
+ printk("%08lx ", *sp);
+ printk("\n");
}
- show_regs (regs);
+ show_regs(regs);
c_backtrace(regs->ARM_fp, regs->ARM_cpsr);
}
#endif
- DIE(SIGSEGV, "Permission fault")
+#endif
+ DIE(SIGSEGV, "Permission fault");
case 15:/* permission fault on page */
case 5: /* page-table entry descriptor fault */
case 7: /* first-level descriptor fault */
- page_fault (addr, error_code, regs);
+ do_page_fault(addr, error_code, regs);
break;
case 4:
case 6:
- DIE(SIGBUS, "External abort on linefetch")
+ DIE(SIGBUS, "External abort on linefetch");
case 8:
case 10:
- DIE(SIGBUS, "External abort on non-linefetch")
+ DIE(SIGBUS, "External abort on non-linefetch");
}
}
asmlinkage int
-do_PrefetchAbort (unsigned long addr, struct pt_regs *regs)
+do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
{
#if 0
- /* does this still apply ? */
+ /* does this still apply? It doesn't seem to happen, so
+ * I guess not.
+ */
if (the memc mapping for this page exists - can check now...) {
- printk ("Page in, but got abort (undefined instruction?)\n");
+ printk("Page in, but got abort (undefined instruction?)\n");
return 0;
}
#endif
- page_fault (addr, FAULT_CODE_USER|FAULT_CODE_READ, regs);
+ do_page_fault(addr, FAULT_CODE_USER|FAULT_CODE_READ, regs);
return 1;
}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/mm/init.c linux.ac/arch/arm/mm/init.c
--- linux.vanilla/arch/arm/mm/init.c Tue Dec 22 23:19:28 1998
+++ linux.ac/arch/arm/mm/init.c Sun Jan 24 21:11:32 1999
@@ -137,6 +137,9 @@
flush_tlb_all();
update_memc_all();
+ end_mem &= PAGE_MASK;
+ high_memory = (void *)end_mem;
+
return free_area_init(start_mem, end_mem);
}
@@ -161,19 +164,18 @@
/* mark usable pages in the mem_map[] */
mark_usable_memory_areas(&start_mem, end_mem);
+#define BETWEEN(w,min,max) ((w) >= (unsigned long)(min) && \
+ (w) < (unsigned long)(max))
+
for (tmp = PAGE_OFFSET; tmp < end_mem ; tmp += PAGE_SIZE) {
if (PageReserved(mem_map+MAP_NR(tmp))) {
- if (tmp >= KERNTOPHYS(_stext) &&
- tmp < KERNTOPHYS(_edata)) {
- if (tmp < KERNTOPHYS(_etext))
- codepages++;
- else
- datapages++;
- } else if (tmp >= KERNTOPHYS(__init_begin)
- && tmp < KERNTOPHYS(__init_end))
+ if (BETWEEN(tmp, &__init_begin, &__init_end))
initpages++;
- else if (tmp >= KERNTOPHYS(__bss_start)
- && tmp < (unsigned long) start_mem)
+ else if (BETWEEN(tmp, &_stext, &_etext))
+ codepages++;
+ else if (BETWEEN(tmp, &_etext, &_edata))
+ datapages++;
+ else if (BETWEEN(tmp, &__bss_start, start_mem))
datapages++;
else
reservedpages++;
@@ -181,13 +183,16 @@
}
atomic_set(&mem_map[MAP_NR(tmp)].count, 1);
#ifdef CONFIG_BLK_DEV_INITRD
- if (!initrd_start || (tmp < initrd_start || tmp >= initrd_end))
+ if (!initrd_start || !BETWEEN(tmp, initrd_start, initrd_end))
#endif
free_page(tmp);
}
- printk ("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
+
+#undef BETWEEN
+
+ printk ("Memory: %luk/%luM available (%dk code, %dk reserved, %dk data, %dk init)\n",
(unsigned long) nr_free_pages << (PAGE_SHIFT-10),
- max_mapnr << (PAGE_SHIFT-10),
+ max_mapnr >> (20 - PAGE_SHIFT),
codepages << (PAGE_SHIFT-10),
reservedpages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10),
@@ -203,17 +208,45 @@
#endif
}
-void free_initmem (void)
+static void free_area(unsigned long addr, unsigned long end, char *s)
{
- unsigned long addr;
+ unsigned int size = (end - addr) >> 10;
- addr = (unsigned long)(&__init_begin);
- for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
+ for (; addr < end; addr += PAGE_SIZE) {
mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
atomic_set(&mem_map[MAP_NR(addr)].count, 1);
free_page(addr);
}
- printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
+
+ if (size)
+ printk(" %dk %s", size, s);
+}
+
+void free_initmem (void)
+{
+ printk("Freeing unused kernel memory:");
+
+ free_area((unsigned long)(&__init_begin),
+ (unsigned long)(&__init_end),
+ "init");
+
+#ifdef CONFIG_FOOTBRIDGE
+ {
+ extern int __netwinder_begin, __netwinder_end, __ebsa285_begin, __ebsa285_end;
+
+ if (!machine_is_netwinder())
+ free_area((unsigned long)(&__netwinder_begin),
+ (unsigned long)(&__netwinder_end),
+ "netwinder");
+
+ if (!machine_is_ebsa285() && !machine_is_cats())
+ free_area((unsigned long)(&__ebsa285_begin),
+ (unsigned long)(&__ebsa285_end),
+ "ebsa285/cats");
+ }
+#endif
+
+ printk("\n");
}
void si_meminfo(struct sysinfo *val)
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/mm/ioremap.c linux.ac/arch/arm/mm/ioremap.c
--- linux.vanilla/arch/arm/mm/ioremap.c Thu Jan 1 01:00:00 1970
+++ linux.ac/arch/arm/mm/ioremap.c Sun Jan 24 21:11:32 1999
@@ -0,0 +1,153 @@
+/*
+ * arch/arm/mm/ioremap.c
+ *
+ * Re-map IO memory to kernel address space so that we can access it.
+ *
+ * (C) Copyright 1995 1996 Linus Torvalds
+ *
+ * Hacked for ARM by Phil Blundell
+ * Hacked to allow all architectures to build, and various cleanups
+ * by Russell King
+ */
+
+/*
+ * This allows a driver to remap an arbitrary region of bus memory into
+ * virtual space. One should *only* use readl, writel, memcpy_toio and
+ * so on with such remapped areas.
+ *
+ * Because the ARM only has a 32-bit address space we can't address the
+ * whole of the (physical) PCI space at once. PCI huge-mode addressing
+ * allows us to circumvent this restriction by splitting PCI space into
+ * two 2GB chunks and mapping only one at a time into processor memory.
+ * We use MMU protection domains to trap any attempt to access the bank
+ * that is not currently mapped. (This isn't fully implemented yet.)
+ *
+ * DC21285 currently has a bug in that the PCI address extension
+ * register affects the address of any writes waiting in the outbound
+ * FIFO. Unfortunately, it is not possible to tell the DC21285 to
+ * flush this - flushing the area causes the bus to lock.
+ */
+
+#include
+#include
+
+/*
+ * Only include this if we have valid_ioaddr() is defined
+ */
+#ifdef valid_ioaddr
+
+static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
+ unsigned long phys_addr, pgprot_t pgprot)
+{
+ unsigned long end;
+
+ address &= ~PMD_MASK;
+ end = address + size;
+ if (end > PMD_SIZE)
+ end = PMD_SIZE;
+ do {
+ if (!pte_none(*pte))
+ printk("remap_area_pte: page already exists\n");
+ set_pte(pte, mk_pte_phys(phys_addr, pgprot));
+ address += PAGE_SIZE;
+ phys_addr += PAGE_SIZE;
+ pte++;
+ } while (address < end);
+}
+
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
+ unsigned long phys_addr, unsigned long flags)
+{
+ unsigned long end;
+ pgprot_t pgprot;
+
+ address &= ~PGDIR_MASK;
+ end = address + size;
+
+ if (end > PGDIR_SIZE)
+ end = PGDIR_SIZE;
+
+ phys_addr -= address;
+ pgprot = __pgprot(PTE_TYPE_SMALL | _PTE_WRITE | flags);
+ do {
+ pte_t * pte = pte_alloc_kernel(pmd, address);
+ if (!pte)
+ return -ENOMEM;
+ remap_area_pte(pte, address, end - address, address + phys_addr, pgprot);
+ address = (address + PMD_SIZE) & PMD_MASK;
+ pmd++;
+ } while (address < end);
+ return 0;
+}
+
+static int remap_area_pages(unsigned long address, unsigned long phys_addr,
+ unsigned long size, unsigned long flags)
+{
+ pgd_t * dir;
+ unsigned long end = address + size;
+
+ phys_addr -= address;
+ dir = pgd_offset(&init_mm, address);
+ flush_cache_all();
+ while (address < end) {
+ pmd_t *pmd = pmd_alloc_kernel(dir, address);
+ if (!pmd)
+ return -ENOMEM;
+ if (remap_area_pmd(pmd, address, end - address,
+ phys_addr + address, flags))
+ return -ENOMEM;
+ set_pgdir(address, *dir);
+ address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ dir++;
+ }
+ flush_tlb_all();
+ return 0;
+}
+
+/*
+ * Remap an arbitrary physical address space into the kernel virtual
+ * address space. Needed when the kernel wants to access high addresses
+ * directly.
+ *
+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+ * have to convert them into an offset in a page-aligned mapping, but the
+ * caller shouldn't need to know that small detail.
+ */
+void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
+{
+ void * addr;
+ struct vm_struct * area;
+ unsigned long offset;
+
+ /*
+ * Mappings have to be page-aligned
+ */
+ offset = phys_addr & ~PAGE_MASK;
+ size = PAGE_ALIGN(size + offset);
+
+ /*
+ * Don't allow mappings that wrap..
+ */
+ if (!size || size > phys_addr + size)
+ return NULL;
+
+ /*
+ * Ok, go for it..
+ */
+ area = get_vm_area(size);
+ if (!area)
+ return NULL;
+ addr = area->addr;
+ if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
+ vfree(addr);
+ return NULL;
+ }
+ return (void *) (offset + (char *)addr);
+}
+
+void iounmap(void *addr)
+{
+ return vfree((void *) (PAGE_MASK & (unsigned long) addr));
+}
+
+#endif
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/mm/mm-ebsa285.c linux.ac/arch/arm/mm/mm-ebsa285.c
--- linux.vanilla/arch/arm/mm/mm-ebsa285.c Tue Dec 22 23:19:28 1998
+++ linux.ac/arch/arm/mm/mm-ebsa285.c Sun Jan 24 21:11:32 1999
@@ -16,24 +16,23 @@
#include
/*
- * This is to allow us to fiddle with the EEPROM
- * This entry will go away in time, once the fmu
- * can mmap() the flash.
+ * The first entry allows us to fiddle with the EEPROM from user-space.
+ * This entry will go away in time, once the fmu32 can mmap() the
+ * flash. It can't at the moment.
*
- * These ones are so that we can fiddle
- * with the various cards (eg VGA)
- * until we're happy with them...
+ * If you want to fiddle with PCI VGA cards from user space, then
+ * change the '0, 1 }' for the PCI MEM and PCI IO to '1, 1 }'
+ * You can then access the PCI bus at 0xe0000000 and 0xffe00000.
*/
#define MAPPING \
{ 0xd8000000, DC21285_FLASH, 0x00400000, DOMAIN_USER, 1, 1 }, /* EEPROM */ \
- { 0xdc000000, 0x7c000000, 0x00100000, DOMAIN_USER, 1, 1 }, /* VGA */ \
- { 0xe0000000, DC21285_PCI_MEM, 0x18000000, DOMAIN_USER, 1, 1 }, /* VGA */ \
+ { 0xe0000000, DC21285_PCI_MEM, 0x18000000, DOMAIN_IO , 0, 1 }, /* PCI memory */ \
{ 0xf8000000, DC21285_PCI_TYPE_0_CONFIG, 0x01000000, DOMAIN_IO , 0, 1 }, /* Type 0 Config */ \
{ 0xf9000000, DC21285_PCI_TYPE_1_CONFIG, 0x01000000, DOMAIN_IO , 0, 1 }, /* Type 1 Config */ \
{ PCI_IACK, DC21285_PCI_IACK, 0x01000000, DOMAIN_IO , 0, 1 }, /* PCI IACK */ \
{ 0xfd000000, DC21285_OUTBOUND_WRITE_FLUSH, 0x01000000, DOMAIN_IO , 0, 1 }, /* Out wrflsh */ \
- { 0xfe000000, DC21285_ARMCSR_BASE, 0x01000000, DOMAIN_IO , 0, 1 }, /* CSR */ \
- { 0xffe00000, DC21285_PCI_IO, 0x00100000, DOMAIN_IO , 0, 1 }, /* PCI I/O */ \
+ { ARMCSR_BASE,DC21285_ARMCSR_BASE, 0x01000000, DOMAIN_IO , 0, 1 }, /* CSR */ \
+ { PCIO_BASE, DC21285_PCI_IO, 0x00100000, DOMAIN_IO , 0, 1 }, /* PCI I/O */ \
{ 0xfff00000, 0x40000000, 0x00100000, DOMAIN_IO , 0, 1 }, /* X-Bus */
#include "mm-armv.c"
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/mm/mm-vnc.c linux.ac/arch/arm/mm/mm-vnc.c
--- linux.vanilla/arch/arm/mm/mm-vnc.c Tue Dec 22 23:19:28 1998
+++ linux.ac/arch/arm/mm/mm-vnc.c Thu Jan 1 01:00:00 1970
@@ -1,31 +0,0 @@
-/*
- * arch/arm/mm/mm-vnc.c
- *
- * Extra MM routines for the Corel VNC architecture
- *
- * Copyright (C) 1998 Russell King
- */
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-/* Table describing the MMU translation mapping
- * mainly used to set up the I/O mappings.
- */
-#define MAPPING \
- { 0xd0000000, DC21285_FLASH, 0x00800000, DOMAIN_IO , 0, 1 }, /* Flash */ \
- { 0xe0000000, DC21285_PCI_MEM, 0x18000000, DOMAIN_IO , 0, 1 }, /* PCI Mem */ \
- { 0xf8000000, DC21285_PCI_TYPE_0_CONFIG, 0x01000000, DOMAIN_IO , 0, 1 }, /* Type 0 Config */ \
- { 0xf9000000, DC21285_PCI_TYPE_1_CONFIG, 0x01000000, DOMAIN_IO , 0, 1 }, /* Type 1 Config */ \
- { PCI_IACK, DC21285_PCI_IACK, 0x01000000, DOMAIN_IO , 0, 1 }, /* PCI IACK */ \
- { 0xfd000000, DC21285_OUTBOUND_WRITE_FLUSH, 0x01000000, DOMAIN_IO , 0, 1 }, /* Out wrflsh */ \
- { 0xfe000000, DC21285_ARMCSR_BASE, 0x01000000, DOMAIN_IO , 0, 1 }, /* CSR */ \
- { 0xffe00000, DC21285_PCI_IO, 0x00100000, DOMAIN_IO , 0, 1 }, /* PCI I/O */ \
-
-#include "mm-armv.c"
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/mm/proc-sa110.S linux.ac/arch/arm/mm/proc-sa110.S
--- linux.vanilla/arch/arm/mm/proc-sa110.S Tue Dec 22 23:19:28 1998
+++ linux.ac/arch/arm/mm/proc-sa110.S Sun Jan 24 21:11:32 1999
@@ -8,6 +8,7 @@
*/
#include
#include
+#include
#include "../lib/constants.h"
/* This is the maximum size of an area which will be flushed. If the area
@@ -21,7 +22,6 @@
/*
* Function: sa110_flush_cache_all (void)
- *
* Purpose : Flush all cache lines
*/
.align 5
@@ -33,7 +33,7 @@
ands r1, r1, #1
eor r1, r1, #1
str r1, [r3]
- ldr ip, =0xdf000000
+ ldr ip, =FLUSH_BASE
addne ip, ip, #32768
add r1, ip, #16384 @ only necessary for 16k
1: ldr r3, [ip], #32
@@ -47,11 +47,9 @@
/*
* Function: sa110_flush_cache_area (unsigned long address, int end, int flags)
- *
* Params : address Area start address
* : end Area end address
* : flags b0 = I cache as well
- *
* Purpose : clean & flush all cache lines associated with this area of memory
*/
.align 5
@@ -74,10 +72,8 @@
/*
* Function: sa110_cache_wback_area(unsigned long address, unsigned long end)
- *
* Params : address Area start address
* : end Area end address
- *
* Purpose : ensure all dirty cachelines in the specified area have been
* written out to memory (for DMA)
*/
@@ -99,13 +95,10 @@
/*
* Function: sa110_cache_purge_area(unsigned long address, unsigned long end)
- *
* Params : address Area start address
* : end Area end address
- *
* Purpose : throw away all D-cached data in specified region without
* an obligation to write it ack.
- *
* Note : Must clean the D-cached entries around the boundaries if the
* start and/or end address are not cache aligned.
*/
@@ -124,9 +117,7 @@
/*
* Function: sa110_flush_cache_entry (unsigned long address)
- *
* Params : address Address of cache line to flush
- *
* Purpose : clean & flush an entry
*/
.align 5
@@ -139,9 +130,7 @@
/*
* Function: sa110_flush_cache_pte (unsigned long address)
- *
* Params : address Address of cache line to clean
- *
* Purpose : Ensure that physical memory reflects cache at this location
* for page table purposes.
*/
@@ -151,11 +140,9 @@
/*
* Function: sa110_flush_ram_page (unsigned long page)
- *
* Params : address Area start address
* : size size of area
* : flags b0 = I cache as well
- *
* Purpose : clean & flush all cache lines associated with this area of memory
*/
.align 5
@@ -176,7 +163,6 @@
/*
* Function: sa110_flush_tlb_all (void)
- *
* Purpose : flush all TLB entries in all caches
*/
.align 5
@@ -188,11 +174,9 @@
/*
* Function: sa110_flush_tlb_area (unsigned long address, unsigned long end, int flags)
- *
* Params : address Area start address
* : end Area end address
* : flags b0 = I cache as well
- *
* Purpose : flush a TLB entry
*/
.align 5
@@ -221,13 +205,10 @@
mov pc, lr
/*
* Function: sa110_switch_to (struct task_struct *prev, struct task_struct *next)
- *
* Params : prev Old task structure
* : next New task structure for process to run
- *
* Purpose : Perform a task switch, saving the old processes state, and restoring
* the new.
- *
* Notes : We don't fiddle with the FP registers here - we postpone this until
* the new task actually uses FP. This way, we don't swap FP for tasks
* that do not require it.
@@ -237,6 +218,7 @@
stmfd sp!, {r4 - r9, fp, lr} @ Store most regs on stack
mrs ip, cpsr
stmfd sp!, {ip} @ Save cpsr_SVC
+@ ldr r2, [r0, #TSS_MEMMAP] @ Get old page tables
str sp, [r0, #TSS_SAVE] @ Save sp_SVC
ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC
ldr r0, [r1, #TSK_ADDR_LIMIT]
@@ -245,12 +227,21 @@
movne r0, #DOM_USERDOMAIN
mcr p15, 0, r0, c3, c0 @ Set segment
ldr r0, [r1, #TSS_MEMMAP] @ Page table pointer
+/*
+ * Flushing the cache is nightmarishly slow, so we take any excuse
+ * to get out of it. If the old page table is the same as the new,
+ * this is a CLONE_VM relative of the old task and there is no need
+ * to flush. The overhead of the tests isn't even on the radar
+ * compared to the cost of the flush itself.
+ */
+ teq r0, r2
+ beq 2f
ldr r3, =Lclean_switch
ldr r2, [r3]
ands r2, r2, #1
eor r2, r2, #1
str r2, [r3]
- ldr r2, =0xdf000000
+ ldr r2, =FLUSH_BASE
addne r2, r2, #32768
add r1, r2, #16384 @ only necessary for 16k
1: ldr r3, [r2], #32
@@ -261,17 +252,14 @@
mcr p15, 0, r1, c7, c10, 4 @ drain WB
mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
mcr p15, 0, r1, c8, c7, 0 @ flush TLBs
- ldmfd sp!, {ip}
+2: ldmfd sp!, {ip}
msr spsr, ip @ Save tasks CPSR into SPSR for this return
ldmfd sp!, {r4 - r9, fp, pc}^ @ Load all regs saved previously
/*
* Function: sa110_data_abort ()
- *
* Params : r0 = address of aborted instruction
- *
* Purpose : obtain information about current aborted instruction
- *
* Returns : r0 = address of abort
* : r1 = FSR
* : r2 != 0 if writing
@@ -289,10 +277,8 @@
/*
* Function: sa110_set_pmd ()
- *
* Params : r0 = Address to set
* : r1 = value to set
- *
* Purpose : Set a PMD and flush it out of any WB cache
*/
.align 5
@@ -304,20 +290,19 @@
* Function: sa110_check_bugs (void)
* : sa110_proc_init (void)
* : sa110_proc_fin (void)
- *
* Notes : This processor does not require these
*/
_sa110_check_bugs:
mrs ip, cpsr
bic ip, ip, #F_BIT
msr cpsr, ip
+
_sa110_proc_init:
_sa110_proc_fin:
mov pc, lr
/*
* Function: sa110_reset
- *
* Notes : This sets up everything for a reset
*/
_sa110_reset: mrs r1, cpsr
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/arm/vmlinux-armv.lds linux.ac/arch/arm/vmlinux-armv.lds
--- linux.vanilla/arch/arm/vmlinux-armv.lds Sun Nov 8 15:08:45 1998
+++ linux.ac/arch/arm/vmlinux-armv.lds Sun Jan 24 21:11:32 1999
@@ -7,50 +7,64 @@
ENTRY(_start)
SECTIONS
{
- _text = .; /* Text and read-only data */
- .text : {
+ _text = .; /* Text and read-only data */
+ .text : { } /* Set text start address */
+
+ __init_begin = .; /* Init code and data */
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __ebsa285_begin = .;
+ .text.ebsa285 : { *(.text.ebsa285) }
+ .data.ebsa285 : { *(.data.ebsa285) }
+ . = ALIGN(4096);
+ __ebsa285_end = .;
+
+ __netwinder_begin = .;
+ .text.netwinder : { *(.text.netwinder) }
+ .data.netwinder : { *(.data.netwinder) }
+ . = ALIGN(4096);
+ __netwinder_end = .;
+
+ .text.real : { /* Real text segment */
*(.text)
*(.fixup)
*(.gnu.warning)
- } = 0x9090
+ }
+
.text.lock : { *(.text.lock) } /* out-of-line lock text */
.rodata : { *(.rodata) }
.kstrtab : { *(.kstrtab) }
- . = ALIGN(16); /* Exception table */
+ . = ALIGN(16); /* Exception table */
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
- __start___ksymtab = .; /* Kernel symbol table */
+ __start___ksymtab = .; /* Kernel symbol table */
__ksymtab : { *(__ksymtab) }
__stop___ksymtab = .;
- _etext = .; /* End of text section */
+ _etext = .; /* End of text section */
. = ALIGN(8192);
- .data : { /* Data */
+ .data : { /* Data */
*(.init.task)
*(.data)
CONSTRUCTORS
}
- _edata = .; /* End of data section */
-
- . = ALIGN(4096); /* Init code and data */
- __init_begin = .;
- .text.init : { *(.text.init) }
- .data.init : { *(.data.init) }
- . = ALIGN(4096);
- __init_end = .;
+ _edata = .; /* End of data section */
- __bss_start = .; /* BSS */
+ __bss_start = .; /* BSS */
.bss : {
*(.bss)
}
_end = . ;
- /* Stabs debugging sections. */
+ /* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/i386/kernel/init_task.c linux.ac/arch/i386/kernel/init_task.c
--- linux.vanilla/arch/i386/kernel/init_task.c Sun Nov 8 15:08:22 1998
+++ linux.ac/arch/i386/kernel/init_task.c Fri Dec 4 17:14:23 1998
@@ -7,7 +7,6 @@
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
-static struct file * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/i386/kernel/smp.c linux.ac/arch/i386/kernel/smp.c
--- linux.vanilla/arch/i386/kernel/smp.c Tue Jan 26 09:44:20 1999
+++ linux.ac/arch/i386/kernel/smp.c Wed Jan 27 19:10:10 1999
@@ -1803,7 +1803,11 @@
asmlinkage void smp_spurious_interrupt(void)
{
/* ack_APIC_irq(); see sw-dev-man vol 3, chapter 7.4.13.5 */
- printk("spurious APIC interrupt, ayiee, should never happen.\n");
+ /*
+ * Maybe we should log it - but we ought to log it 2.0 style
+ * saying its the P6 fault 8)
+ */
+ /* printk("spurious APIC interrupt, ayiee, should never happen.\n"); */
}
/*
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/m68k/kernel/process.c linux.ac/arch/m68k/kernel/process.c
--- linux.vanilla/arch/m68k/kernel/process.c Sun Jan 24 19:55:31 1999
+++ linux.ac/arch/m68k/kernel/process.c Sun Jan 24 20:22:53 1999
@@ -40,7 +40,6 @@
*/
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
-static struct file * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/mips/kernel/init_task.c linux.ac/arch/mips/kernel/init_task.c
--- linux.vanilla/arch/mips/kernel/init_task.c Sun Nov 8 15:08:29 1998
+++ linux.ac/arch/mips/kernel/init_task.c Fri Dec 4 17:14:23 1998
@@ -6,7 +6,6 @@
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
-static struct files * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/mips/kernel/irixioctl.c linux.ac/arch/mips/kernel/irixioctl.c
--- linux.vanilla/arch/mips/kernel/irixioctl.c Sun Nov 8 15:08:29 1998
+++ linux.ac/arch/mips/kernel/irixioctl.c Fri Dec 4 17:14:23 1998
@@ -33,7 +33,7 @@
{
struct file *filp;
- if(fd >= NR_OPEN || !(filp = current->files->fd[fd]))
+ if(fd >= current->files->max_fds || !(filp = current->files->fd[fd]))
return ((struct tty_struct *) 0);
if(filp->private_data) {
struct tty_struct *ttyp = (struct tty_struct *) filp->private_data;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/mips/kernel/sysirix.c linux.ac/arch/mips/kernel/sysirix.c
--- linux.vanilla/arch/mips/kernel/sysirix.c Sun Nov 8 15:10:06 1998
+++ linux.ac/arch/mips/kernel/sysirix.c Fri Dec 4 17:14:23 1998
@@ -788,7 +788,8 @@
error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statfs));
if (error)
goto out;
- if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+ if (fd >= current->files->max_fds ||
+ !(file = current->files->fd[fd])) {
error = -EBADF;
goto out;
}
@@ -1111,7 +1112,8 @@
lock_kernel();
if(!(flags & MAP_ANONYMOUS)) {
- if(fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+ if(fd >= current->files->max_fds ||
+ !(file = current->files->fd[fd])) {
retval = -EBADF;
goto out;
}
@@ -1583,7 +1585,8 @@
error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
if (error)
goto out;
- if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+ if (fd >= current->files->max_fds ||
+ !(file = current->files->fd[fd])) {
error = -EBADF;
goto out;
}
@@ -1727,7 +1730,8 @@
}
if(!(flags & MAP_ANONYMOUS)) {
- if(fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+ if(fd >= current->files->max_fds ||
+ !(file = current->files->fd[fd])) {
error = -EBADF;
goto out;
}
@@ -1879,7 +1883,8 @@
error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
if (error)
goto out;
- if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+ if (fd >= current->files->max_fds ||
+ !(file = current->files->fd[fd])) {
error = -EBADF;
goto out;
}
@@ -2040,7 +2045,8 @@
current->pid, fd, dirent, count, eob);
#endif
error = -EBADF;
- if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+ if (fd >= current->files->max_fds ||
+ !(file = current->files->fd[fd]))
goto out;
dentry = file->f_dentry;
@@ -2151,7 +2157,8 @@
current->pid, fd, dirent, cnt);
#endif
error = -EBADF;
- if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+ if (fd >= current->files->max_fds ||
+ !(file = current->files->fd[fd]))
goto out;
dentry = file->f_dentry;
@@ -2212,7 +2219,8 @@
current->pid, fd, dirent, cnt);
#endif
error = -EBADF;
- if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+ if (fd >= current->files->max_fds ||
+ !(file = current->files->fd[fd]))
goto out;
dentry = file->f_dentry;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/ppc/kernel/process.c linux.ac/arch/ppc/kernel/process.c
--- linux.vanilla/arch/ppc/kernel/process.c Sat Jan 9 21:50:36 1999
+++ linux.ac/arch/ppc/kernel/process.c Sat Jan 9 21:57:09 1999
@@ -67,7 +67,6 @@
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
-static struct file * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/ppc/kernel/syscalls.c linux.ac/arch/ppc/kernel/syscalls.c
--- linux.vanilla/arch/ppc/kernel/syscalls.c Sun Nov 8 15:08:33 1998
+++ linux.ac/arch/ppc/kernel/syscalls.c Fri Dec 4 17:14:34 1998
@@ -205,7 +205,8 @@
lock_kernel();
if (!(flags & MAP_ANONYMOUS)) {
- if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+ if (fd >= current->files->max_fds ||
+ !(file = current->files->fd[fd]))
goto out;
}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/ppc/mbx_defconfig linux.ac/arch/ppc/mbx_defconfig
--- linux.vanilla/arch/ppc/mbx_defconfig Mon Dec 28 23:09:41 1998
+++ linux.ac/arch/ppc/mbx_defconfig Tue Dec 22 23:35:52 1998
@@ -14,7 +14,6 @@
# CONFIG_ALL_PPC is not set
# CONFIG_APUS is not set
CONFIG_MBX=y
-CONFIG_SMP=n
CONFIG_MACH_SPECIFIC=y
CONFIG_SERIAL_CONSOLE=y
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/sparc/kernel/init_task.c linux.ac/arch/sparc/kernel/init_task.c
--- linux.vanilla/arch/sparc/kernel/init_task.c Sun Nov 8 15:10:06 1998
+++ linux.ac/arch/sparc/kernel/init_task.c Fri Dec 4 17:14:35 1998
@@ -6,7 +6,6 @@
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
-static struct file * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/arch/sparc64/kernel/init_task.c linux.ac/arch/sparc64/kernel/init_task.c
--- linux.vanilla/arch/sparc64/kernel/init_task.c Sun Nov 8 15:08:40 1998
+++ linux.ac/arch/sparc64/kernel/init_task.c Fri Dec 4 17:14:35 1998
@@ -6,7 +6,6 @@
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
-static struct file * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/block/Config.in linux.ac/drivers/acorn/block/Config.in
--- linux.vanilla/drivers/acorn/block/Config.in Sun Nov 8 15:08:19 1998
+++ linux.ac/drivers/acorn/block/Config.in Sun Jan 24 23:54:36 1999
@@ -11,6 +11,7 @@
fi
tristate 'MFM harddisk support' CONFIG_BLK_DEV_MFM
+tristate 'Old Archimedes floppy (1772) support' CONFIG_BLK_DEV_FD1772
if [ "$CONFIG_BLK_DEV_MFM" != "n" ]; then
bool ' Autodetect hard drive geometry' CONFIG_BLK_DEV_MFM_AUTODETECT
fi
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/block/Makefile linux.ac/drivers/acorn/block/Makefile
--- linux.vanilla/drivers/acorn/block/Makefile Sun Nov 8 15:08:19 1998
+++ linux.ac/drivers/acorn/block/Makefile Sun Jan 24 23:54:36 1999
@@ -14,13 +14,11 @@
M_OBJS :=
MOD_LIST_NAME := ACORN_BLOCK_MODULES
-ifeq ($(CONFIG_ARCH_ARC),y)
- ifeq ($(CONFIG_BLK_DEV_FD),y)
- L_OBJS += fd1772.o fd1772dma.o
- else
- ifeq ($(CONFIG_BLK_DEV_FD),m)
- M_OBJS += fd1772_mod.o
- endif
+ifeq ($(CONFIG_BLK_DEV_FD1772),y)
+ L_OBJS += fd1772.o fd1772dma.o
+else
+ ifeq ($(CONFIG_BLK_DEV_FD1772),m)
+ M_OBJS += fd1772_mod.o
endif
endif
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/block/fd1772.c linux.ac/drivers/acorn/block/fd1772.c
--- linux.vanilla/drivers/acorn/block/fd1772.c Sat Jan 9 21:50:36 1999
+++ linux.ac/drivers/acorn/block/fd1772.c Sun Jan 24 23:54:36 1999
@@ -136,6 +136,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/block/ide-ics.c linux.ac/drivers/acorn/block/ide-ics.c
--- linux.vanilla/drivers/acorn/block/ide-ics.c Tue Dec 22 23:19:34 1998
+++ linux.ac/drivers/acorn/block/ide-ics.c Sun Jan 24 23:54:36 1999
@@ -81,6 +81,8 @@
icside_irqenable_arcin_v5,
icside_irqdisable_arcin_v5,
NULL,
+ NULL,
+ NULL,
NULL
};
@@ -106,9 +108,22 @@
inb (ide_base_port + ICS_ARCIN_V6_INTROFFSET_2);
}
+/* Prototype: icside_irqprobe(struct expansion_card *ec)
+ * Purpose : detect an active interrupt from card
+ */
+static int icside_irqpending_arcin_v6(struct expansion_card *ec)
+{
+ unsigned int ide_base_port = (unsigned int)ec->irq_data;
+
+ return inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 ||
+ inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_2) & 1;
+}
+
static const expansioncard_ops_t icside_ops_arcin_v6 = {
icside_irqenable_arcin_v6,
icside_irqdisable_arcin_v6,
+ icside_irqpending_arcin_v6,
+ NULL,
NULL,
NULL
};
@@ -220,8 +235,6 @@
case ics_if_arcin_v6:
port = ecard_address (ec, ECARD_IOC, ECARD_FAST);
- ec->irqaddr = ioaddr(port + ICS_ARCIN_V6_INTRSTAT_1);
- ec->irqmask = 1;
ec->irq_data = (void *)port;
ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v6;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/block/ide-rapide.c linux.ac/drivers/acorn/block/ide-rapide.c
--- linux.vanilla/drivers/acorn/block/ide-rapide.c Sun Nov 8 15:08:19 1998
+++ linux.ac/drivers/acorn/block/ide-rapide.c Sun Jan 24 23:54:36 1999
@@ -13,7 +13,6 @@
#include
#include
#include
-#include
#include "../../block/ide.h"
@@ -28,14 +27,20 @@
static inline int rapide_register(struct expansion_card *ec)
{
unsigned long port = ecard_address (ec, ECARD_MEMC, 0);
- ide_ioregspec_t spec;
+ hw_regs_t hw;
- spec.base = port;
- spec.ctrl = port + 0x206;
- spec.offset = 1 << 4;
- spec.irq = ec->irq;
+ int i;
- return ide_register_port(&spec);
+ memset(&hw, 0, sizeof(hw));
+
+ for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+ hw.io_ports[i] = (ide_ioreg_t)port;
+ port += 1 << 4;
+ }
+ hw.io_ports[IDE_CONTROL_OFFSET] = port + 0x206;
+ hw.irq = ec->irq;
+
+ return ide_register_hw(&hw, NULL);
}
int rapide_init(void)
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/block/mfmhd.c linux.ac/drivers/acorn/block/mfmhd.c
--- linux.vanilla/drivers/acorn/block/mfmhd.c Sun Nov 8 15:08:19 1998
+++ linux.ac/drivers/acorn/block/mfmhd.c Sun Jan 24 23:54:36 1999
@@ -123,6 +123,7 @@
#include
#include
#include
+#include
/*
* This sort of stuff should be in a header file shared with ide.c, hd.c, xd.c etc
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/char/Config.in linux.ac/drivers/acorn/char/Config.in
--- linux.vanilla/drivers/acorn/char/Config.in Tue Dec 22 23:19:34 1998
+++ linux.ac/drivers/acorn/char/Config.in Thu Jan 1 01:00:00 1970
@@ -1,15 +0,0 @@
-if [ "$CONFIG_SERIAL" != "n" ]; then
- tristate ' Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL
- tristate ' Dual serial port support' CONFIG_DUALSP_SERIAL
-fi
-
-if [ "$CONFIG_MOUSE" = "y" ]; then
- if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
- if [ "$CONFIG_ARCH_RPC" != "y" ]; then
- define_bool CONFIG_KBDMOUSE y
- else
- define_bool CONFIG_RPCMOUSE y
- fi
- fi
-fi
-
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/char/keyb_ps2.c linux.ac/drivers/acorn/char/keyb_ps2.c
--- linux.vanilla/drivers/acorn/char/keyb_ps2.c Tue Dec 22 23:19:34 1998
+++ linux.ac/drivers/acorn/char/keyb_ps2.c Sun Jan 24 23:54:37 1999
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
#include
extern void kbd_reset_kdown(void);
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/char/mouse_rpc.c linux.ac/drivers/acorn/char/mouse_rpc.c
--- linux.vanilla/drivers/acorn/char/mouse_rpc.c Tue Dec 22 23:19:34 1998
+++ linux.ac/drivers/acorn/char/mouse_rpc.c Sun Jan 24 23:54:37 1999
@@ -1,5 +1,5 @@
/*
- * linux/drivers/char/rpcmouse.c
+ * linux/drivers/char/mouse_rpc.c
*
* Copyright (C) 1996-1998 Russell King
*
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
#include "../../char/mouse.h"
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/net/ether1.c linux.ac/drivers/acorn/net/ether1.c
--- linux.vanilla/drivers/acorn/net/ether1.c Mon Dec 28 23:09:41 1998
+++ linux.ac/drivers/acorn/net/ether1.c Sun Jan 24 23:54:37 1999
@@ -128,7 +128,7 @@
{
int used;
- addr = IO_BASE + (addr << 2);
+ addr = ioaddr(addr);
__asm__ __volatile__(
"subs %3, %3, #2
@@ -171,7 +171,7 @@
{
int used;
- addr = IO_BASE + (addr << 2);
+ addr = ioaddr(addr);
__asm__ __volatile__(
"subs %3, %3, #2
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/net/ether3.c linux.ac/drivers/acorn/net/ether3.c
--- linux.vanilla/drivers/acorn/net/ether3.c Sun Nov 8 15:08:20 1998
+++ linux.ac/drivers/acorn/net/ether3.c Sun Jan 24 23:54:37 1999
@@ -33,11 +33,13 @@
* packet starts two bytes from the end of the
* buffer, it corrupts the receiver chain, and
* never updates the transmit status correctly.
+ * 1.14 RMK 07/01/1998 Added initial code for ETHERB addressing.
+ *
* TODO:
* When we detect a fatal error on the interface, we should restart it.
*/
-static char *version = "ether3 ethernet driver (c) 1995-1998 R.M.King v1.13\n";
+static char *version = "ether3 ethernet driver (c) 1995-1999 R.M.King v1.14\n";
#include
#include
@@ -471,6 +473,25 @@
return error;
}
+static void
+ether3_get_dev(struct device *dev, struct expansion_card *ec)
+{
+ ecard_claim(ec);
+
+ dev->base_addr = ecard_address(ec, ECARD_MEMC, 0);
+ dev->irq = ec->irq;
+
+ if (ec->cid.manufacturer == MANU_ANT &&
+ ec->cid.product == PROD_ANT_ETHERB) {
+ dev->base_addr += 0x200;
+ }
+
+ ec->irqaddr = ioaddr(dev->base_addr);
+ ec->irqmask = 0xf0;
+
+ ether3_addr(dev->dev_addr, ec);
+}
+
#ifndef MODULE
__initfunc(int
ether3_probe(struct device *dev))
@@ -485,12 +506,8 @@
if ((ec = ecard_find(0, ether3_cids)) == NULL)
return ENODEV;
- dev->base_addr = ecard_address(ec, ECARD_MEMC, 0);
- dev->irq = ec->irq;
-
- ecard_claim(ec);
+ ether3_get_dev(dev, ec);
- ether3_addr(dev->dev_addr, ec);
return ether3_probe1(dev);
}
#endif
@@ -942,17 +959,13 @@
my_ethers[i] = (struct device *)kmalloc(sizeof(struct device), GFP_KERNEL);
memset(my_ethers[i], 0, sizeof(struct device));
- my_ethers[i]->irq = ec[i]->irq;
- my_ethers[i]->base_addr= ecard_address(ec[i], ECARD_MEMC, 0);
my_ethers[i]->init = ether3_probe1;
my_ethers[i]->name = ethernames[i];
- ether3_addr(my_ethers[i]->dev_addr, ec[i]);
-
- ecard_claim(ec[i]);
+ ether3_get_dev(my_ethers[i], ec[i]);
if(register_netdev(my_ethers[i]) != 0) {
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < MAX_ECARDS; i++) {
if(my_ethers[i]) {
kfree(my_ethers[i]);
my_ethers[i] = NULL;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/net/etherh.c linux.ac/drivers/acorn/net/etherh.c
--- linux.vanilla/drivers/acorn/net/etherh.c Tue Dec 22 23:19:35 1998
+++ linux.ac/drivers/acorn/net/etherh.c Sun Jan 24 23:54:37 1999
@@ -461,6 +461,8 @@
etherh_irq_enable,
etherh_irq_disable,
NULL,
+ NULL,
+ NULL,
NULL
};
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/scsi/acornscsi.c linux.ac/drivers/acorn/scsi/acornscsi.c
--- linux.vanilla/drivers/acorn/scsi/acornscsi.c Mon Dec 28 23:09:41 1998
+++ linux.ac/drivers/acorn/scsi/acornscsi.c Sun Jan 24 23:54:37 1999
@@ -21,6 +21,8 @@
* 12-Oct-1997 RMK Added catch for re-entering interrupt routine.
* 15-Oct-1997 RMK Improved handling of commands.
* 27-Jun-1998 RMK Changed asm/delay.h to linux/delay.h.
+ * 13-Dec-1998 RMK Better abort code and command handling. Extra state
+ * transitions added to allow dodgy devices to work.
*/
#define DEBUG_NO_WRITE 1
#define DEBUG_QUEUES 2
@@ -35,7 +37,7 @@
#define DEBUG_RESET 1024
#define DEBUG_ALL (DEBUG_RESET|DEBUG_MESSAGES|DEBUG_LINK|DEBUG_WRITE|\
DEBUG_PHASES|DEBUG_CONNECT|DEBUG_DISCON|DEBUG_ABORT|\
- DEBUG_DMA|DEBUG_QUEUES|DEBUG_NO_WRITE)
+ DEBUG_DMA|DEBUG_QUEUES)
/* DRIVER CONFIGURATION
*
@@ -186,26 +188,7 @@
#define DMAC_BUFFER_SIZE 65536
#endif
-/*
- * This is used to dump the previous states of the SBIC
- */
-static struct status_entry {
- unsigned long when;
- unsigned char ssr;
- unsigned char ph;
- unsigned char irq;
- unsigned char unused;
-} status[9][16];
-static unsigned char status_ptr[9];
-
-#define ADD_STATUS(_q,_ssr,_ph,_irq) \
-({ \
- status[(_q)][status_ptr[(_q)]].when = jiffies; \
- status[(_q)][status_ptr[(_q)]].ssr = (_ssr); \
- status[(_q)][status_ptr[(_q)]].ph = (_ph); \
- status[(_q)][status_ptr[(_q)]].irq = (_irq); \
- status_ptr[(_q)] = (status_ptr[(_q)] + 1) & 15; \
-})
+#define STATUS_BUFFER_TO_PRINT 24
unsigned int sdtr_period = SDTR_PERIOD;
unsigned int sdtr_size = SDTR_SIZE;
@@ -214,31 +197,31 @@
PROC_SCSI_EATA, 9, "acornscsi", S_IFDIR | S_IRUGO | S_IXUGO, 2
};
-static void acornscsi_done (AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result);
-static int acornscsi_reconnect_finish (AS_Host *host);
-static void acornscsi_dma_cleanup (AS_Host *host);
-static void acornscsi_abortcmd (AS_Host *host, unsigned char tag);
+static void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result);
+static int acornscsi_reconnect_finish(AS_Host *host);
+static void acornscsi_dma_cleanup(AS_Host *host);
+static void acornscsi_abortcmd(AS_Host *host, unsigned char tag);
/* ====================================================================================
* Miscellaneous
*/
static inline void
-sbic_arm_write (unsigned int io_port, int reg, int value)
+sbic_arm_write(unsigned int io_port, int reg, int value)
{
- outb_t (reg, io_port);
- outb_t (value, io_port + 4);
+ outb_t(reg, io_port);
+ outb_t(value, io_port + 4);
}
#define sbic_arm_writenext(io,val) \
- outb_t ((val), (io) + 4)
+ outb_t((val), (io) + 4)
static inline
-int sbic_arm_read (unsigned int io_port, int reg)
+int sbic_arm_read(unsigned int io_port, int reg)
{
if(reg == ASR)
return inl_t(io_port) & 255;
- outb_t (reg, io_port);
+ outb_t(reg, io_port);
return inl_t(io_port + 4) & 255;
}
@@ -247,129 +230,165 @@
#ifdef USE_DMAC
#define dmac_read(io_port,reg) \
- inb ((io_port) + (reg))
+ inb((io_port) + (reg))
#define dmac_write(io_port,reg,value) \
- ({ outb ((value), (io_port) + (reg)); })
+ ({ outb((value), (io_port) + (reg)); })
#define dmac_clearintr(io_port) \
- ({ outb (0, (io_port)); })
+ ({ outb(0, (io_port)); })
static inline
-unsigned int dmac_address (unsigned int io_port)
+unsigned int dmac_address(unsigned int io_port)
{
- return dmac_read (io_port, TXADRHI) << 16 |
- dmac_read (io_port, TXADRMD) << 8 |
- dmac_read (io_port, TXADRLO);
+ return dmac_read(io_port, TXADRHI) << 16 |
+ dmac_read(io_port, TXADRMD) << 8 |
+ dmac_read(io_port, TXADRLO);
}
static
-void acornscsi_dumpdma (AS_Host *host, char *where)
+void acornscsi_dumpdma(AS_Host *host, char *where)
{
unsigned int mode, addr, len;
- mode = dmac_read (host->dma.io_port, MODECON);
- addr = dmac_address (host->dma.io_port);
- len = dmac_read (host->dma.io_port, TXCNTHI) << 8 |
- dmac_read (host->dma.io_port, TXCNTLO);
+ mode = dmac_read(host->dma.io_port, MODECON);
+ addr = dmac_address(host->dma.io_port);
+ len = dmac_read(host->dma.io_port, TXCNTHI) << 8 |
+ dmac_read(host->dma.io_port, TXCNTLO);
- printk ("scsi%d: %s: DMAC %02x @%06x+%04x msk %02x, ",
+ printk("scsi%d: %s: DMAC %02x @%06x+%04x msk %02x, ",
host->host->host_no, where,
mode, addr, (len + 1) & 0xffff,
- dmac_read (host->dma.io_port, MASKREG));
+ dmac_read(host->dma.io_port, MASKREG));
- printk ("DMA @%06x, ", host->dma.start_addr);
- printk ("BH @%p +%04x, ", host->scsi.SCp.ptr,
+ printk("DMA @%06x, ", host->dma.start_addr);
+ printk("BH @%p +%04x, ", host->scsi.SCp.ptr,
host->scsi.SCp.this_residual);
- printk ("DT @+%04x ST @+%04x", host->dma.transferred,
+ printk("DT @+%04x ST @+%04x", host->dma.transferred,
host->scsi.SCp.scsi_xferred);
- printk ("\n");
+ printk("\n");
}
#endif
static
-unsigned long acornscsi_sbic_xfcount (AS_Host *host)
+unsigned long acornscsi_sbic_xfcount(AS_Host *host)
{
unsigned long length;
- length = sbic_arm_read (host->scsi.io_port, TRANSCNTH) << 16;
- length |= sbic_arm_readnext (host->scsi.io_port) << 8;
- length |= sbic_arm_readnext (host->scsi.io_port);
+ length = sbic_arm_read(host->scsi.io_port, TRANSCNTH) << 16;
+ length |= sbic_arm_readnext(host->scsi.io_port) << 8;
+ length |= sbic_arm_readnext(host->scsi.io_port);
return length;
}
-static
-int acornscsi_sbic_issuecmd (AS_Host *host, int command)
+static int
+acornscsi_sbic_wait(AS_Host *host, int stat_mask, int stat, int timeout, char *msg)
{
- int asr;
+ int asr;
- do {
- asr = sbic_arm_read (host->scsi.io_port, ASR);
- } while (asr & ASR_CIP);
+ do {
+ asr = sbic_arm_read(host->scsi.io_port, ASR);
+
+ if ((asr & stat_mask) == stat)
+ return 0;
+
+ udelay(1);
+ } while (--timeout);
+
+ printk("scsi%d: timeout while %s\n", host->host->host_no, msg);
+
+ return -1;
+}
+
+static
+int acornscsi_sbic_issuecmd(AS_Host *host, int command)
+{
+ if (acornscsi_sbic_wait(host, ASR_CIP, 0, 1000, "issuing command"))
+ return -1;
- sbic_arm_write (host->scsi.io_port, CMND, command);
+ sbic_arm_write(host->scsi.io_port, CMND, command);
return 0;
}
static void
-acornscsi_csdelay (unsigned int cs)
+acornscsi_csdelay(unsigned int cs)
{
unsigned long target_jiffies, flags;
target_jiffies = jiffies + 1 + cs * HZ / 100;
- save_flags (flags);
- sti ();
+ save_flags(flags);
+ sti();
while (time_before(jiffies, target_jiffies)) barrier();
- restore_flags (flags);
+ restore_flags(flags);
}
static
-void acornscsi_resetcard (AS_Host *host)
+void acornscsi_resetcard(AS_Host *host)
{
- unsigned int i;
+ unsigned int i, timeout;
/* assert reset line */
host->card.page_reg = 0x80;
- outb (host->card.page_reg, host->card.io_page);
+ outb(host->card.page_reg, host->card.io_page);
/* wait 3 cs. SCSI standard says 25ms. */
- acornscsi_csdelay (3);
+ acornscsi_csdelay(3);
host->card.page_reg = 0;
- outb (host->card.page_reg, host->card.io_page);
+ outb(host->card.page_reg, host->card.io_page);
/*
* Should get a reset from the card
*/
- while (!(inb (host->card.io_intr) & 8));
- sbic_arm_read (host->scsi.io_port, ASR);
- sbic_arm_read (host->scsi.io_port, SSR);
+ timeout = 1000;
+ do {
+ if (inb(host->card.io_intr) & 8)
+ break;
+ udelay(1);
+ } while (--timeout);
+
+ if (timeout == 0)
+ printk("scsi%d: timeout while resetting card\n",
+ host->host->host_no);
+
+ sbic_arm_read(host->scsi.io_port, ASR);
+ sbic_arm_read(host->scsi.io_port, SSR);
/* setup sbic - WD33C93A */
- sbic_arm_write (host->scsi.io_port, OWNID, OWNID_EAF | host->host->this_id);
- sbic_arm_write (host->scsi.io_port, CMND, CMND_RESET);
+ sbic_arm_write(host->scsi.io_port, OWNID, OWNID_EAF | host->host->this_id);
+ sbic_arm_write(host->scsi.io_port, CMND, CMND_RESET);
/*
* Command should cause a reset interrupt
*/
- while (!(inb (host->card.io_intr) & 8));
- sbic_arm_read (host->scsi.io_port, ASR);
- if (sbic_arm_read (host->scsi.io_port, SSR) != 0x01)
- printk (KERN_CRIT "scsi%d: WD33C93A didn't give enhanced reset interrupt\n",
+ timeout = 1000;
+ do {
+ if (inb(host->card.io_intr) & 8)
+ break;
+ udelay(1);
+ } while (--timeout);
+
+ if (timeout == 0)
+ printk("scsi%d: timeout while resetting card\n",
host->host->host_no);
- sbic_arm_write (host->scsi.io_port, CTRL, INIT_SBICDMA | CTRL_IDI);
- sbic_arm_write (host->scsi.io_port, TIMEOUT, TIMEOUT_TIME);
- sbic_arm_write (host->scsi.io_port, SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
- sbic_arm_write (host->scsi.io_port, SOURCEID, SOURCEID_ER | SOURCEID_DSP);
+ sbic_arm_read(host->scsi.io_port, ASR);
+ if (sbic_arm_read(host->scsi.io_port, SSR) != 0x01)
+ printk(KERN_CRIT "scsi%d: WD33C93A didn't give enhanced reset interrupt\n",
+ host->host->host_no);
+
+ sbic_arm_write(host->scsi.io_port, CTRL, INIT_SBICDMA | CTRL_IDI);
+ sbic_arm_write(host->scsi.io_port, TIMEOUT, TIMEOUT_TIME);
+ sbic_arm_write(host->scsi.io_port, SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
+ sbic_arm_write(host->scsi.io_port, SOURCEID, SOURCEID_ER | SOURCEID_DSP);
host->card.page_reg = 0x40;
- outb (host->card.page_reg, host->card.io_page);
+ outb(host->card.page_reg, host->card.io_page);
/* setup dmac - uPC71071 */
dmac_write(host->dma.io_port, INIT, 0);
@@ -391,7 +410,7 @@
}
/* wait 25 cs. SCSI standard says 250ms. */
- acornscsi_csdelay (25);
+ acornscsi_csdelay(25);
}
/*=============================================================================================
@@ -461,80 +480,101 @@
};
static
-void print_scsi_status (unsigned int ssr)
+void print_scsi_status(unsigned int ssr)
{
if (acornscsi_map[ssr] != -1)
- printk ("%s:%s",
+ printk("%s:%s",
acornscsi_interrupttype[(ssr >> 4)],
acornscsi_interruptcode[acornscsi_map[ssr]]);
else
- printk ("%X:%X", ssr >> 4, ssr & 0x0f);
+ printk("%X:%X", ssr >> 4, ssr & 0x0f);
}
#endif
static
-void print_sbic_status (int asr, int ssr, int cmdphase)
+void print_sbic_status(int asr, int ssr, int cmdphase)
{
#ifdef CONFIG_ACORNSCSI_CONSTANTS
- printk ("sbic: %c%c%c%c%c%c ",
+ printk("sbic: %c%c%c%c%c%c ",
asr & ASR_INT ? 'I' : 'i',
asr & ASR_LCI ? 'L' : 'l',
asr & ASR_BSY ? 'B' : 'b',
asr & ASR_CIP ? 'C' : 'c',
asr & ASR_PE ? 'P' : 'p',
asr & ASR_DBR ? 'D' : 'd');
- printk ("scsi: ");
- print_scsi_status (ssr);
- printk (" ph %02X\n", cmdphase);
+ printk("scsi: ");
+ print_scsi_status(ssr);
+ printk(" ph %02X\n", cmdphase);
#else
- printk ("sbic: %02X scsi: %X:%X ph: %02X\n",
+ printk("sbic: %02X scsi: %X:%X ph: %02X\n",
asr, (ssr & 0xf0)>>4, ssr & 0x0f, cmdphase);
#endif
}
-static
-void acornscsi_dumplog (AS_Host *host, int target)
+static void
+acornscsi_dumplogline(AS_Host *host, int target, int line)
{
- unsigned int prev;
- do {
- signed int statptr;
+ unsigned long prev;
+ signed int ptr;
- printk ("%c:", target == 8 ? 'H' : ('0' + target));
- statptr = status_ptr[target] - 10;
+ ptr = host->status_ptr[target] - STATUS_BUFFER_TO_PRINT;
+ if (ptr < 0)
+ ptr += STATUS_BUFFER_SIZE;
- if (statptr < 0)
- statptr += 16;
+ printk("%c: %3s:", target == 8 ? 'H' : '0' + target,
+ line == 0 ? "ph" : line == 1 ? "ssr" : "int");
- prev = status[target][statptr].when;
+ prev = host->status[target][ptr].when;
- for (; statptr != status_ptr[target]; statptr = (statptr + 1) & 15) {
- if (status[target][statptr].when) {
-#ifdef CONFIG_ACORNSCSI_CONSTANTS
- printk ("%c%02X:S=",
- status[target][statptr].irq ? '-' : ' ',
- status[target][statptr].ph);
- print_scsi_status (status[target][statptr].ssr);
-#else
- printk ("%c%02X:%02X",
- status[target][statptr].irq ? '-' : ' ',
- status[target][statptr].ph,
- status[target][statptr].ssr);
-#endif
- printk ("+%02ld",
- (status[target][statptr].when - prev) < 100 ?
- (status[target][statptr].when - prev) : 99);
- prev = status[target][statptr].when;
- }
+ for (; ptr != host->status_ptr[target]; ptr = (ptr + 1) & (STATUS_BUFFER_SIZE - 1)) {
+ unsigned long time_diff;
+
+ if (!host->status[target][ptr].when)
+ continue;
+
+ switch (line) {
+ case 0:
+ printk("%c%02X", host->status[target][ptr].irq ? '-' : ' ',
+ host->status[target][ptr].ph);
+ break;
+
+ case 1:
+ printk(" %02X", host->status[target][ptr].ssr);
+ break;
+
+ case 2:
+ time_diff = host->status[target][ptr].when - prev;
+ prev = host->status[target][ptr].when;
+ if (time_diff == 0)
+ printk("==^");
+ else if (time_diff >= 100)
+ printk(" ");
+ else
+ printk(" %02ld", time_diff);
+ break;
+ }
}
- printk ("\n");
+
+ printk("\n");
+}
+
+static
+void acornscsi_dumplog(AS_Host *host, int target)
+{
+ do {
+ acornscsi_dumplogline(host, target, 0);
+ acornscsi_dumplogline(host, target, 1);
+ acornscsi_dumplogline(host, target, 2);
+
if (target == 8)
break;
+
target = 8;
} while (1);
}
static
-char acornscsi_target (AS_Host *host)
+char acornscsi_target(AS_Host *host)
{
if (host->SCpnt)
return '0' + host->SCpnt->target;
@@ -542,7 +582,7 @@
}
/*
- * Prototype: cmdtype_t acornscsi_cmdtype (int command)
+ * Prototype: cmdtype_t acornscsi_cmdtype(int command)
* Purpose : differentiate READ from WRITE from other commands
* Params : command - command to interpret
* Returns : CMD_READ - command reads data,
@@ -550,7 +590,7 @@
* CMD_MISC - everything else
*/
static inline
-cmdtype_t acornscsi_cmdtype (int command)
+cmdtype_t acornscsi_cmdtype(int command)
{
switch (command) {
case WRITE_6: case WRITE_10: case WRITE_12:
@@ -563,7 +603,7 @@
}
/*
- * Prototype: int acornscsi_datadirection (int command)
+ * Prototype: int acornscsi_datadirection(int command)
* Purpose : differentiate between commands that have a DATA IN phase
* and a DATA OUT phase
* Params : command - command to interpret
@@ -571,7 +611,7 @@
* DATADIR_IN - data in phase expected
*/
static
-datadir_t acornscsi_datadirection (int command)
+datadir_t acornscsi_datadirection(int command)
{
switch (command) {
case CHANGE_DEFINITION: case COMPARE: case COPY:
@@ -605,13 +645,13 @@
};
/*
- * Prototype: int acornscsi_getperiod (unsigned char syncxfer)
+ * Prototype: int acornscsi_getperiod(unsigned char syncxfer)
* Purpose : period for the synchronous transfer setting
* Params : syncxfer SYNCXFER register value
* Returns : period in ns.
*/
static
-int acornscsi_getperiod (unsigned char syncxfer)
+int acornscsi_getperiod(unsigned char syncxfer)
{
int i;
@@ -626,14 +666,14 @@
}
/*
- * Prototype: int round_period (unsigned int period)
+ * Prototype: int round_period(unsigned int period)
* Purpose : return index into above table for a required REQ period
* Params : period - time (ns) for REQ
* Returns : table index
* Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
*/
static inline
-int round_period (unsigned int period)
+int round_period(unsigned int period)
{
int i;
@@ -646,7 +686,7 @@
}
/*
- * Prototype: unsigned char calc_sync_xfer (unsigned int period, unsigned int offset)
+ * Prototype: unsigned char calc_sync_xfer(unsigned int period, unsigned int offset)
* Purpose : calculate value for 33c93s SYNC register
* Params : period - time (ns) for REQ
* offset - offset in bytes between REQ/ACK
@@ -654,7 +694,7 @@
* Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
*/
static
-unsigned char calc_sync_xfer (unsigned int period, unsigned int offset)
+unsigned char calc_sync_xfer(unsigned int period, unsigned int offset)
{
return sync_xfer_table[round_period(period)].reg_value |
((offset < SDTR_SIZE) ? offset : SDTR_SIZE);
@@ -664,14 +704,14 @@
* Command functions
*/
/*
- * Function: acornscsi_kick (AS_Host *host)
+ * Function: acornscsi_kick(AS_Host *host)
* Purpose : kick next command to interface
* Params : host - host to send command to
* Returns : INTR_IDLE if idle, otherwise INTR_PROCESSING
* Notes : interrupts are always disabled!
*/
static
-intr_ret_t acornscsi_kick (AS_Host *host)
+intr_ret_t acornscsi_kick(AS_Host *host)
{
int from_queue = 0;
Scsi_Cmnd *SCpnt;
@@ -682,7 +722,7 @@
/* retrieve next command */
if (!SCpnt) {
- SCpnt = queue_remove_exclude (&host->queues.issue, host->busyluns);
+ SCpnt = queue_remove_exclude(&host->queues.issue, host->busyluns);
if (!SCpnt)
return INTR_IDLE;
@@ -690,11 +730,11 @@
}
if (host->scsi.disconnectable && host->SCpnt) {
- queue_add_cmd_tail (&host->queues.disconnected, host->SCpnt);
+ queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt);
host->scsi.disconnectable = 0;
#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
- DBG(host->SCpnt, printk ("scsi%d.%c: moved command to disconnected queue\n",
- host->host->host_no, acornscsi_target (host)));
+ DBG(host->SCpnt, printk("scsi%d.%c: moved command to disconnected queue\n",
+ host->host->host_no, acornscsi_target(host)));
#endif
host->SCpnt = NULL;
}
@@ -703,9 +743,9 @@
* If we have an interrupt pending, then we may have been reselected.
* In this case, we don't want to write to the registers
*/
- if (!(sbic_arm_read (host->scsi.io_port, ASR) & (ASR_INT|ASR_BSY|ASR_CIP))) {
- sbic_arm_write (host->scsi.io_port, DESTID, SCpnt->target);
- sbic_arm_write (host->scsi.io_port, CMND, CMND_SELWITHATN);
+ if (!(sbic_arm_read(host->scsi.io_port, ASR) & (ASR_INT|ASR_BSY|ASR_CIP))) {
+ sbic_arm_write(host->scsi.io_port, DESTID, SCpnt->target);
+ sbic_arm_write(host->scsi.io_port, CMND, CMND_SELWITHATN);
}
/*
@@ -717,9 +757,10 @@
host->scsi.SCp = SCpnt->SCp;
host->dma.xfer_setup = 0;
host->dma.xfer_required = 0;
+ host->dma.xfer_done = 0;
#if (DEBUG & (DEBUG_ABORT|DEBUG_CONNECT))
- DBG(SCpnt,printk ("scsi%d.%c: starting cmd %02X\n",
+ DBG(SCpnt,printk("scsi%d.%c: starting cmd %02X\n",
host->host->host_no, '0' + SCpnt->target,
SCpnt->cmnd[0]));
#endif
@@ -736,11 +777,11 @@
SCpnt->tag = SCpnt->device->current_tag;
} else
#endif
- set_bit (SCpnt->target * 8 + SCpnt->lun, host->busyluns);
+ set_bit(SCpnt->target * 8 + SCpnt->lun, host->busyluns);
host->stats.removes += 1;
- switch (acornscsi_cmdtype (SCpnt->cmnd[0])) {
+ switch (acornscsi_cmdtype(SCpnt->cmnd[0])) {
case CMD_WRITE:
host->stats.writes += 1;
break;
@@ -757,25 +798,25 @@
}
/*
- * Function: void acornscsi_done (AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result)
+ * Function: void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result)
* Purpose : complete processing for command
* Params : host - interface that completed
* result - driver byte of result
*/
static
-void acornscsi_done (AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result)
+void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result)
{
Scsi_Cmnd *SCpnt = *SCpntp;
/* clean up */
- sbic_arm_write (host->scsi.io_port, SOURCEID, SOURCEID_ER | SOURCEID_DSP);
+ sbic_arm_write(host->scsi.io_port, SOURCEID, SOURCEID_ER | SOURCEID_DSP);
host->stats.fins += 1;
if (SCpnt) {
*SCpntp = NULL;
- acornscsi_dma_cleanup (host);
+ acornscsi_dma_cleanup(host);
SCpnt->result = result << 16 | host->scsi.SCp.Message << 8 | host->scsi.SCp.Status;
@@ -787,35 +828,63 @@
* It doesn't appear to be set to something meaningful by the higher
* levels all the time.
*/
- if (host->scsi.SCp.ptr && result == DID_OK &&
- acornscsi_cmdtype (SCpnt->cmnd[0]) != CMD_MISC) {
- switch (status_byte (SCpnt->result)) {
- case CHECK_CONDITION:
- case COMMAND_TERMINATED:
- case BUSY:
- case QUEUE_FULL:
- case RESERVATION_CONFLICT:
- break;
+ if (result == DID_OK) {
+ int xfer_warn = 0;
- default:
- printk (KERN_ERR "scsi%d.H: incomplete data transfer detected: result=%08X command=",
- host->host->host_no, SCpnt->result);
- print_command (SCpnt->cmnd);
- acornscsi_dumpdma (host, "done");
- acornscsi_dumplog (host, SCpnt->target);
- SCpnt->result &= 0xffff;
- SCpnt->result |= DID_ERROR << 16;
- }
+ if (SCpnt->underflow == 0) {
+ if (host->scsi.SCp.ptr &&
+ acornscsi_cmdtype(SCpnt->cmnd[0]) != CMD_MISC)
+ xfer_warn = 1;
+ } else {
+ if (host->scsi.SCp.scsi_xferred < SCpnt->underflow ||
+ host->scsi.SCp.scsi_xferred != host->dma.transferred)
+ xfer_warn = 1;
+ }
+
+ /* ANSI standard says: (SCSI-2 Rev 10c Sect 5.6.6)
+ * Targets which break data transfers into multiple
+ * connections shall end each successful connection
+ * (except possibly the last) with a SAVE DATA
+ * POINTER - DISCONNECT message sequence.
+ *
+ * This makes it difficult to ensure that a transfer has
+ * completed. If we reach the end of a transfer during
+ * the command, then we can only have finished the transfer.
+ * therefore, if we seem to have some data remaining, this
+ * is not a problem.
+ */
+ if (host->dma.xfer_done)
+ xfer_warn = 0;
+
+ if (xfer_warn) {
+ switch (status_byte(SCpnt->result)) {
+ case CHECK_CONDITION:
+ case COMMAND_TERMINATED:
+ case BUSY:
+ case QUEUE_FULL:
+ case RESERVATION_CONFLICT:
+ break;
+
+ default:
+ printk(KERN_ERR "scsi%d.H: incomplete data transfer detected: result=%08X command=",
+ host->host->host_no, SCpnt->result);
+ print_command(SCpnt->cmnd);
+ acornscsi_dumpdma(host, "done");
+ acornscsi_dumplog(host, SCpnt->target);
+ SCpnt->result &= 0xffff;
+ SCpnt->result |= DID_ERROR << 16;
+ }
+ }
}
if (!SCpnt->scsi_done)
- panic ("scsi%d.H: null scsi_done function in acornscsi_done", host->host->host_no);
+ panic("scsi%d.H: null scsi_done function in acornscsi_done", host->host->host_no);
- clear_bit (SCpnt->target * 8 + SCpnt->lun, host->busyluns);
+ clear_bit(SCpnt->target * 8 + SCpnt->lun, host->busyluns);
- SCpnt->scsi_done (SCpnt);
+ SCpnt->scsi_done(SCpnt);
} else
- printk ("scsi%d: null command in acornscsi_done", host->host->host_no);
+ printk("scsi%d: null command in acornscsi_done", host->host->host_no);
host->scsi.phase = PHASE_IDLE;
}
@@ -828,7 +897,7 @@
* Notes : this will only be one SG entry or less
*/
static
-void acornscsi_data_updateptr (AS_Host *host, Scsi_Pointer *SCp, unsigned int length)
+void acornscsi_data_updateptr(AS_Host *host, Scsi_Pointer *SCp, unsigned int length)
{
SCp->ptr += length;
SCp->this_residual -= length;
@@ -839,13 +908,15 @@
SCp->buffers_residual--;
SCp->ptr = (char *)SCp->buffer->address;
SCp->this_residual = SCp->buffer->length;
- } else
+ } else {
SCp->ptr = NULL;
+ host->dma.xfer_done = 1;
+ }
}
}
/*
- * Prototype: void acornscsi_data_read (AS_Host *host, char *ptr,
+ * Prototype: void acornscsi_data_read(AS_Host *host, char *ptr,
* unsigned int start_addr, unsigned int length)
* Purpose : read data from DMA RAM
* Params : host - host to transfer from
@@ -855,16 +926,16 @@
* Notes : this will only be one SG entry or less
*/
static
-void acornscsi_data_read (AS_Host *host, char *ptr,
+void acornscsi_data_read(AS_Host *host, char *ptr,
unsigned int start_addr, unsigned int length)
{
- extern void __acornscsi_in (int port, char *buf, int len);
+ extern void __acornscsi_in(int port, char *buf, int len);
unsigned int page, offset, len = length;
page = (start_addr >> 12);
offset = start_addr & ((1 << 12) - 1);
- outb ((page & 0x3f) | host->card.page_reg, host->card.io_page);
+ outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
while (len > 0) {
unsigned int this_len;
@@ -874,7 +945,7 @@
else
this_len = len;
- __acornscsi_in (host->card.io_ram + (offset << 1), ptr, this_len);
+ __acornscsi_in(host->card.io_ram + (offset << 1), ptr, this_len);
offset += this_len;
ptr += this_len;
@@ -883,14 +954,14 @@
if (offset == (1 << 12)) {
offset = 0;
page ++;
- outb ((page & 0x3f) | host->card.page_reg, host->card.io_page);
+ outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
}
}
- outb (host->card.page_reg, host->card.io_page);
+ outb(host->card.page_reg, host->card.io_page);
}
/*
- * Prototype: void acornscsi_data_write (AS_Host *host, char *ptr,
+ * Prototype: void acornscsi_data_write(AS_Host *host, char *ptr,
* unsigned int start_addr, unsigned int length)
* Purpose : write data to DMA RAM
* Params : host - host to transfer from
@@ -900,16 +971,16 @@
* Notes : this will only be one SG entry or less
*/
static
-void acornscsi_data_write (AS_Host *host, char *ptr,
+void acornscsi_data_write(AS_Host *host, char *ptr,
unsigned int start_addr, unsigned int length)
{
- extern void __acornscsi_out (int port, char *buf, int len);
+ extern void __acornscsi_out(int port, char *buf, int len);
unsigned int page, offset, len = length;
page = (start_addr >> 12);
offset = start_addr & ((1 << 12) - 1);
- outb ((page & 0x3f) | host->card.page_reg, host->card.io_page);
+ outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
while (len > 0) {
unsigned int this_len;
@@ -919,7 +990,7 @@
else
this_len = len;
- __acornscsi_out (host->card.io_ram + (offset << 1), ptr, this_len);
+ __acornscsi_out(host->card.io_ram + (offset << 1), ptr, this_len);
offset += this_len;
ptr += this_len;
@@ -928,10 +999,10 @@
if (offset == (1 << 12)) {
offset = 0;
page ++;
- outb ((page & 0x3f) | host->card.page_reg, host->card.io_page);
+ outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
}
}
- outb (host->card.page_reg, host->card.io_page);
+ outb(host->card.page_reg, host->card.io_page);
}
/* =========================================================================================
@@ -939,25 +1010,25 @@
*/
#ifdef USE_DMAC
/*
- * Prototype: void acornscsi_dmastop (AS_Host *host)
+ * Prototype: void acornscsi_dmastop(AS_Host *host)
* Purpose : stop all DMA
* Params : host - host on which to stop DMA
* Notes : This is called when leaving DATA IN/OUT phase,
* or when interface is RESET
*/
static inline
-void acornscsi_dma_stop (AS_Host *host)
+void acornscsi_dma_stop(AS_Host *host)
{
- dmac_write (host->dma.io_port, MASKREG, MASK_ON);
- dmac_clearintr (host->dma.io_intr_clear);
+ dmac_write(host->dma.io_port, MASKREG, MASK_ON);
+ dmac_clearintr(host->dma.io_intr_clear);
#if (DEBUG & DEBUG_DMA)
- DBG(host->SCpnt, acornscsi_dumpdma (host, "stop"));
+ DBG(host->SCpnt, acornscsi_dumpdma(host, "stop"));
#endif
}
/*
- * Function: void acornscsi_dma_setup (AS_Host *host, dmadir_t direction)
+ * Function: void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
* Purpose : setup DMA controller for data transfer
* Params : host - host to setup
* direction - data transfer direction
@@ -965,19 +1036,19 @@
* while we're in a DATA I/O phase
*/
static
-void acornscsi_dma_setup (AS_Host *host, dmadir_t direction)
+void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
{
unsigned int address, length, mode;
host->dma.direction = direction;
- dmac_write (host->dma.io_port, MASKREG, MASK_ON);
+ dmac_write(host->dma.io_port, MASKREG, MASK_ON);
if (direction == DMA_OUT) {
#if (DEBUG & DEBUG_NO_WRITE)
if (NO_WRITE & (1 << host->SCpnt->target)) {
- printk (KERN_CRIT "scsi%d.%c: I can't handle DMA_OUT!\n",
- host->host->host_no, acornscsi_target (host));
+ printk(KERN_CRIT "scsi%d.%c: I can't handle DMA_OUT!\n",
+ host->host->host_no, acornscsi_target(host));
return;
}
#endif
@@ -988,7 +1059,7 @@
/*
* Allocate some buffer space, limited to half the buffer size
*/
- length = min (host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2);
+ length = min(host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2);
if (length) {
host->dma.start_addr = address = host->dma.free_addr;
host->dma.free_addr = (host->dma.free_addr + length) &
@@ -998,27 +1069,27 @@
* Transfer data to DMA memory
*/
if (direction == DMA_OUT)
- acornscsi_data_write (host, host->scsi.SCp.ptr, host->dma.start_addr,
+ acornscsi_data_write(host, host->scsi.SCp.ptr, host->dma.start_addr,
length);
length -= 1;
- dmac_write (host->dma.io_port, TXCNTLO, length);
- dmac_write (host->dma.io_port, TXCNTHI, length >> 8);
- dmac_write (host->dma.io_port, TXADRLO, address);
- dmac_write (host->dma.io_port, TXADRMD, address >> 8);
- dmac_write (host->dma.io_port, TXADRHI, 0);
- dmac_write (host->dma.io_port, MODECON, mode);
- dmac_write (host->dma.io_port, MASKREG, MASK_OFF);
+ dmac_write(host->dma.io_port, TXCNTLO, length);
+ dmac_write(host->dma.io_port, TXCNTHI, length >> 8);
+ dmac_write(host->dma.io_port, TXADRLO, address);
+ dmac_write(host->dma.io_port, TXADRMD, address >> 8);
+ dmac_write(host->dma.io_port, TXADRHI, 0);
+ dmac_write(host->dma.io_port, MODECON, mode);
+ dmac_write(host->dma.io_port, MASKREG, MASK_OFF);
#if (DEBUG & DEBUG_DMA)
- DBG(host->SCpnt, acornscsi_dumpdma (host, "strt"));
+ DBG(host->SCpnt, acornscsi_dumpdma(host, "strt"));
#endif
host->dma.xfer_setup = 1;
}
}
/*
- * Function: void acornscsi_dma_cleanup (AS_Host *host)
+ * Function: void acornscsi_dma_cleanup(AS_Host *host)
* Purpose : ensure that all DMA transfers are up-to-date & host->scsi.SCp is correct
* Params : host - host to finish
* Notes : This is called when a command is:
@@ -1026,10 +1097,10 @@
* : This must not return until all transfers are completed.
*/
static
-void acornscsi_dma_cleanup (AS_Host *host)
+void acornscsi_dma_cleanup(AS_Host *host)
{
- dmac_write (host->dma.io_port, MASKREG, MASK_ON);
- dmac_clearintr (host->dma.io_intr_clear);
+ dmac_write(host->dma.io_port, MASKREG, MASK_ON);
+ dmac_clearintr(host->dma.io_intr_clear);
/*
* Check for a pending transfer
@@ -1037,7 +1108,7 @@
if (host->dma.xfer_required) {
host->dma.xfer_required = 0;
if (host->dma.direction == DMA_IN)
- acornscsi_data_read (host, host->dma.xfer_ptr,
+ acornscsi_data_read(host, host->dma.xfer_ptr,
host->dma.xfer_start, host->dma.xfer_length);
}
@@ -1056,17 +1127,17 @@
/*
* Calculate number of bytes transferred from DMA.
*/
- transferred = dmac_address (host->dma.io_port) - host->dma.start_addr;
+ transferred = dmac_address(host->dma.io_port) - host->dma.start_addr;
host->dma.transferred += transferred;
if (host->dma.direction == DMA_IN)
- acornscsi_data_read (host, host->scsi.SCp.ptr,
+ acornscsi_data_read(host, host->scsi.SCp.ptr,
host->dma.start_addr, transferred);
/*
* Update SCSI pointers
*/
- acornscsi_data_updateptr (host, &host->scsi.SCp, transferred);
+ acornscsi_data_updateptr(host, &host->scsi.SCp, transferred);
#if (DEBUG & DEBUG_DMA)
DBG(host->SCpnt, acornscsi_dumpdma(host, "cupo"));
#endif
@@ -1074,7 +1145,7 @@
}
/*
- * Function: void acornscsi_dmacintr (AS_Host *host)
+ * Function: void acornscsi_dmacintr(AS_Host *host)
* Purpose : handle interrupts from DMAC device
* Params : host - host to process
* Notes : If reading, we schedule the read to main memory &
@@ -1084,21 +1155,21 @@
* : Called whenever DMAC finished it's current transfer.
*/
static
-void acornscsi_dma_intr (AS_Host *host)
+void acornscsi_dma_intr(AS_Host *host)
{
unsigned int address, length, transferred;
#if (DEBUG & DEBUG_DMA)
- DBG(host->SCpnt, acornscsi_dumpdma (host, "inti"));
+ DBG(host->SCpnt, acornscsi_dumpdma(host, "inti"));
#endif
- dmac_write (host->dma.io_port, MASKREG, MASK_ON);
- dmac_clearintr (host->dma.io_intr_clear);
+ dmac_write(host->dma.io_port, MASKREG, MASK_ON);
+ dmac_clearintr(host->dma.io_intr_clear);
/*
* Calculate amount transferred via DMA
*/
- transferred = dmac_address (host->dma.io_port) - host->dma.start_addr;
+ transferred = dmac_address(host->dma.io_port) - host->dma.start_addr;
host->dma.transferred += transferred;
/*
@@ -1111,12 +1182,12 @@
host->dma.xfer_required = 1;
}
- acornscsi_data_updateptr (host, &host->scsi.SCp, transferred);
+ acornscsi_data_updateptr(host, &host->scsi.SCp, transferred);
/*
* Allocate some buffer space, limited to half the on-board RAM size
*/
- length = min (host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2);
+ length = min(host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2);
if (length) {
host->dma.start_addr = address = host->dma.free_addr;
host->dma.free_addr = (host->dma.free_addr + length) &
@@ -1126,19 +1197,19 @@
* Transfer data to DMA memory
*/
if (host->dma.direction == DMA_OUT)
- acornscsi_data_write (host, host->scsi.SCp.ptr, host->dma.start_addr,
+ acornscsi_data_write(host, host->scsi.SCp.ptr, host->dma.start_addr,
length);
length -= 1;
- dmac_write (host->dma.io_port, TXCNTLO, length);
- dmac_write (host->dma.io_port, TXCNTHI, length >> 8);
- dmac_write (host->dma.io_port, TXADRLO, address);
- dmac_write (host->dma.io_port, TXADRMD, address >> 8);
- dmac_write (host->dma.io_port, TXADRHI, 0);
- dmac_write (host->dma.io_port, MASKREG, MASK_OFF);
+ dmac_write(host->dma.io_port, TXCNTLO, length);
+ dmac_write(host->dma.io_port, TXCNTHI, length >> 8);
+ dmac_write(host->dma.io_port, TXADRLO, address);
+ dmac_write(host->dma.io_port, TXADRMD, address >> 8);
+ dmac_write(host->dma.io_port, TXADRHI, 0);
+ dmac_write(host->dma.io_port, MASKREG, MASK_OFF);
#if (DEBUG & DEBUG_DMA)
- DBG(host->SCpnt, acornscsi_dumpdma (host, "into"));
+ DBG(host->SCpnt, acornscsi_dumpdma(host, "into"));
#endif
} else {
host->dma.xfer_setup = 0;
@@ -1149,48 +1220,48 @@
* attention condition. We continue giving one byte until
* the device recognises the attention.
*/
- if (dmac_read (host->dma.io_port, STATUS) & STATUS_RQ0) {
- acornscsi_abortcmd (host, host->SCpnt->tag);
+ if (dmac_read(host->dma.io_port, STATUS) & STATUS_RQ0) {
+ acornscsi_abortcmd(host, host->SCpnt->tag);
- dmac_write (host->dma.io_port, TXCNTLO, 0);
- dmac_write (host->dma.io_port, TXCNTHI, 0);
- dmac_write (host->dma.io_port, TXADRLO, 0);
- dmac_write (host->dma.io_port, TXADRMD, 0);
- dmac_write (host->dma.io_port, TXADRHI, 0);
- dmac_write (host->dma.io_port, MASKREG, MASK_OFF);
+ dmac_write(host->dma.io_port, TXCNTLO, 0);
+ dmac_write(host->dma.io_port, TXCNTHI, 0);
+ dmac_write(host->dma.io_port, TXADRLO, 0);
+ dmac_write(host->dma.io_port, TXADRMD, 0);
+ dmac_write(host->dma.io_port, TXADRHI, 0);
+ dmac_write(host->dma.io_port, MASKREG, MASK_OFF);
}
#endif
}
}
/*
- * Function: void acornscsi_dma_xfer (AS_Host *host)
+ * Function: void acornscsi_dma_xfer(AS_Host *host)
* Purpose : transfer data between AcornSCSI and memory
* Params : host - host to process
*/
static
-void acornscsi_dma_xfer (AS_Host *host)
+void acornscsi_dma_xfer(AS_Host *host)
{
host->dma.xfer_required = 0;
if (host->dma.direction == DMA_IN)
- acornscsi_data_read (host, host->dma.xfer_ptr,
+ acornscsi_data_read(host, host->dma.xfer_ptr,
host->dma.xfer_start, host->dma.xfer_length);
}
/*
- * Function: void acornscsi_dma_adjust (AS_Host *host)
+ * Function: void acornscsi_dma_adjust(AS_Host *host)
* Purpose : adjust DMA pointers & count for bytes transfered to
* SBIC but not SCSI bus.
* Params : host - host to adjust DMA count for
*/
static
-void acornscsi_dma_adjust (AS_Host *host)
+void acornscsi_dma_adjust(AS_Host *host)
{
if (host->dma.xfer_setup) {
signed long transferred;
#if (DEBUG & (DEBUG_DMA|DEBUG_WRITE))
- DBG(host->SCpnt, acornscsi_dumpdma (host, "adji"));
+ DBG(host->SCpnt, acornscsi_dumpdma(host, "adji"));
#endif
/*
* Calculate correct DMA address - DMA is ahead of SCSI bus while
@@ -1205,17 +1276,17 @@
*/
transferred = host->scsi.SCp.scsi_xferred - host->dma.transferred;
if (transferred < 0)
- printk ("scsi%d.%c: Ack! DMA write correction %ld < 0!\n",
- host->host->host_no, acornscsi_target (host), transferred);
+ printk("scsi%d.%c: Ack! DMA write correction %ld < 0!\n",
+ host->host->host_no, acornscsi_target(host), transferred);
else if (transferred == 0)
host->dma.xfer_setup = 0;
else {
transferred += host->dma.start_addr;
- dmac_write (host->dma.io_port, TXADRLO, transferred);
- dmac_write (host->dma.io_port, TXADRMD, transferred >> 8);
- dmac_write (host->dma.io_port, TXADRHI, transferred >> 16);
+ dmac_write(host->dma.io_port, TXADRLO, transferred);
+ dmac_write(host->dma.io_port, TXADRMD, transferred >> 8);
+ dmac_write(host->dma.io_port, TXADRHI, transferred >> 16);
#if (DEBUG & (DEBUG_DMA|DEBUG_WRITE))
- DBG(host->SCpnt, acornscsi_dumpdma (host, "adjo"));
+ DBG(host->SCpnt, acornscsi_dumpdma(host, "adjo"));
#endif
}
}
@@ -1225,66 +1296,88 @@
/* =========================================================================================
* Data I/O
*/
+static int
+acornscsi_write_pio(AS_Host *host, char *bytes, int *ptr, int len, unsigned int max_timeout)
+{
+ unsigned int asr, timeout = max_timeout;
+ int my_ptr = *ptr;
+
+ while (my_ptr < len) {
+ asr = sbic_arm_read(host->scsi.io_port, ASR);
+
+ if (asr & ASR_DBR) {
+ timeout = max_timeout;
+
+ sbic_arm_write(host->scsi.io_port, DATA, bytes[my_ptr++]);
+ } else if (asr & ASR_INT)
+ break;
+ else if (--timeout == 0)
+ break;
+ udelay(1);
+ }
+
+ *ptr = my_ptr;
+
+ return (timeout == 0) ? -1 : 0;
+}
+
/*
- * Function: void acornscsi_sendcommand (AS_Host *host)
+ * Function: void acornscsi_sendcommand(AS_Host *host)
* Purpose : send a command to a target
* Params : host - host which is connected to target
*/
-static
-void acornscsi_sendcommand (AS_Host *host)
+static void
+acornscsi_sendcommand(AS_Host *host)
{
Scsi_Cmnd *SCpnt = host->SCpnt;
- unsigned int asr;
- unsigned char *cmdptr, *cmdend;
- sbic_arm_write (host->scsi.io_port, TRANSCNTH, 0);
- sbic_arm_writenext (host->scsi.io_port, 0);
- sbic_arm_writenext (host->scsi.io_port, SCpnt->cmd_len - host->scsi.SCp.sent_command);
- acornscsi_sbic_issuecmd (host, CMND_XFERINFO);
-
- cmdptr = SCpnt->cmnd + host->scsi.SCp.sent_command;
- cmdend = SCpnt->cmnd + SCpnt->cmd_len;
-
- while (cmdptr < cmdend) {
- asr = sbic_arm_read (host->scsi.io_port, ASR);
- if (asr & ASR_DBR)
- sbic_arm_write (host->scsi.io_port, DATA, *cmdptr++);
- else if (asr & ASR_INT)
- break;
- }
- if (cmdptr >= cmdend)
- host->scsi.SCp.sent_command = cmdptr - SCpnt->cmnd;
+ sbic_arm_write(host->scsi.io_port, TRANSCNTH, 0);
+ sbic_arm_writenext(host->scsi.io_port, 0);
+ sbic_arm_writenext(host->scsi.io_port, SCpnt->cmd_len - host->scsi.SCp.sent_command);
+
+ acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
+
+ if (acornscsi_write_pio(host, SCpnt->cmnd,
+ (int *)&host->scsi.SCp.sent_command, SCpnt->cmd_len, 1000000))
+ printk("scsi%d: timeout while sending command\n", host->host->host_no);
+
host->scsi.phase = PHASE_COMMAND;
}
static
-void acornscsi_sendmessage (AS_Host *host)
+void acornscsi_sendmessage(AS_Host *host)
{
- unsigned int message_length = msgqueue_msglength (&host->scsi.msgs);
- int msgnr;
+ unsigned int message_length = msgqueue_msglength(&host->scsi.msgs);
+ unsigned int msgnr;
struct message *msg;
#if (DEBUG & DEBUG_MESSAGES)
- printk ("scsi%d.%c: sending message ",
- host->host->host_no, acornscsi_target (host));
+ printk("scsi%d.%c: sending message ",
+ host->host->host_no, acornscsi_target(host));
#endif
switch (message_length) {
case 0:
- acornscsi_sbic_issuecmd (host, CMND_XFERINFO | CMND_SBT);
- while ((sbic_arm_read (host->scsi.io_port, ASR) & ASR_DBR) == 0);
- sbic_arm_write (host->scsi.io_port, DATA, NOP);
+ acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT);
+
+ acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 1");
+
+ sbic_arm_write(host->scsi.io_port, DATA, NOP);
+
host->scsi.last_message = NOP;
#if (DEBUG & DEBUG_MESSAGES)
- printk ("NOP");
+ printk("NOP");
#endif
break;
case 1:
- acornscsi_sbic_issuecmd (host, CMND_XFERINFO | CMND_SBT);
+ acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT);
msg = msgqueue_getmsg(&host->scsi.msgs, 0);
- while ((sbic_arm_read (host->scsi.io_port, ASR) & ASR_DBR) == 0);
- sbic_arm_write (host->scsi.io_port, DATA, msg->msg[0]);
+
+ acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 2");
+
+ sbic_arm_write(host->scsi.io_port, DATA, msg->msg[0]);
+
host->scsi.last_message = msg->msg[0];
#if (DEBUG & DEBUG_MESSAGES)
print_msg(msg->msg);
@@ -1300,86 +1393,85 @@
* initiator. This provides an interlock so that the
* initiator can determine which message byte is rejected.
*/
- sbic_arm_write (host->scsi.io_port, TRANSCNTH, 0);
- sbic_arm_writenext (host->scsi.io_port, 0);
- sbic_arm_writenext (host->scsi.io_port, message_length);
- acornscsi_sbic_issuecmd (host, CMND_XFERINFO);
+ sbic_arm_write(host->scsi.io_port, TRANSCNTH, 0);
+ sbic_arm_writenext(host->scsi.io_port, 0);
+ sbic_arm_writenext(host->scsi.io_port, message_length);
+ acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
msgnr = 0;
while ((msg = msgqueue_getmsg(&host->scsi.msgs, msgnr++)) != NULL) {
- unsigned int asr, i;
+ unsigned int i;
#if (DEBUG & DEBUG_MESSAGES)
- print_msg (msg);
+ print_msg(msg);
#endif
- for (i = 0; i < msg->length;) {
- asr = sbic_arm_read (host->scsi.io_port, ASR);
- if (asr & ASR_DBR)
- sbic_arm_write (host->scsi.io_port, DATA, msg->msg[i++]);
- if (asr & ASR_INT)
- break;
- }
+ i = 0;
+ if (acornscsi_write_pio(host, msg->msg, &i, msg->length, 1000000))
+ printk("scsi%d: timeout while sending message\n", host->host->host_no);
+
host->scsi.last_message = msg->msg[0];
if (msg->msg[0] == EXTENDED_MESSAGE)
host->scsi.last_message |= msg->msg[2] << 8;
- if (asr & ASR_INT)
+
+ if (i != msg->length)
break;
}
break;
}
#if (DEBUG & DEBUG_MESSAGES)
- printk ("\n");
+ printk("\n");
#endif
}
/*
- * Function: void acornscsi_readstatusbyte (AS_Host *host)
+ * Function: void acornscsi_readstatusbyte(AS_Host *host)
* Purpose : Read status byte from connected target
* Params : host - host connected to target
*/
static
-void acornscsi_readstatusbyte (AS_Host *host)
+void acornscsi_readstatusbyte(AS_Host *host)
{
- acornscsi_sbic_issuecmd (host, CMND_XFERINFO|CMND_SBT);
- while ((sbic_arm_read (host->scsi.io_port, ASR) & ASR_DBR) == 0);
-
- host->scsi.SCp.Status = sbic_arm_read (host->scsi.io_port, DATA);
+ acornscsi_sbic_issuecmd(host, CMND_XFERINFO|CMND_SBT);
+ acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "reading status byte");
+ host->scsi.SCp.Status = sbic_arm_read(host->scsi.io_port, DATA);
}
/*
- * Function: unsigned char acornscsi_readmessagebyte (AS_Host *host)
+ * Function: unsigned char acornscsi_readmessagebyte(AS_Host *host)
* Purpose : Read one message byte from connected target
* Params : host - host connected to target
*/
static
-unsigned char acornscsi_readmessagebyte (AS_Host *host)
+unsigned char acornscsi_readmessagebyte(AS_Host *host)
{
unsigned char message;
- acornscsi_sbic_issuecmd (host, CMND_XFERINFO | CMND_SBT);
- while ((sbic_arm_read (host->scsi.io_port, ASR) & ASR_DBR) == 0);
+ acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT);
- message = sbic_arm_read (host->scsi.io_port, DATA);
+ acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "for message byte");
+
+ message = sbic_arm_read(host->scsi.io_port, DATA);
/* wait for MSGIN-XFER-PAUSED */
- while ((sbic_arm_read (host->scsi.io_port, ASR) & ASR_INT) == 0);
- sbic_arm_read (host->scsi.io_port, SSR);
+ acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after message byte");
+
+ sbic_arm_read(host->scsi.io_port, SSR);
return message;
}
/*
- * Function: void acornscsi_message (AS_Host *host)
+ * Function: void acornscsi_message(AS_Host *host)
* Purpose : Read complete message from connected target & action message
* Params : host - host connected to target
*/
static
-void acornscsi_message (AS_Host *host)
+void acornscsi_message(AS_Host *host)
{
unsigned char message[16];
unsigned int msgidx = 0, msglen = 1;
do {
- message[msgidx] = acornscsi_readmessagebyte (host);
+ message[msgidx] = acornscsi_readmessagebyte(host);
switch (msgidx) {
case 0:
@@ -1395,17 +1487,17 @@
}
msgidx += 1;
if (msgidx < msglen) {
- acornscsi_sbic_issuecmd (host, CMND_NEGATEACK);
+ acornscsi_sbic_issuecmd(host, CMND_NEGATEACK);
/* wait for next msg-in */
- while ((sbic_arm_read (host->scsi.io_port, ASR) & ASR_INT) == 0);
- sbic_arm_read (host->scsi.io_port, SSR);
+ acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after negate ack");
+ sbic_arm_read(host->scsi.io_port, SSR);
}
} while (msgidx < msglen);
#if (DEBUG & DEBUG_MESSAGES)
printk("scsi%d.%c: message in: ",
- host->host->host_no, acornscsi_target (host));
+ host->host->host_no, acornscsi_target(host));
print_msg(message);
printk("\n");
#endif
@@ -1419,7 +1511,7 @@
*/
if (message[0] == SIMPLE_QUEUE_TAG)
host->scsi.reconnected.tag = message[1];
- if (acornscsi_reconnect_finish (host))
+ if (acornscsi_reconnect_finish(host))
host->scsi.phase = PHASE_MSGIN;
}
@@ -1429,7 +1521,7 @@
case COMMAND_COMPLETE:
if (host->scsi.phase != PHASE_STATUSIN) {
printk(KERN_ERR "scsi%d.%c: command complete following non-status in phase?\n",
- host->host->host_no, acornscsi_target (host));
+ host->host->host_no, acornscsi_target(host));
acornscsi_dumplog(host, host->SCpnt->target);
}
host->scsi.phase = PHASE_DONE;
@@ -1443,7 +1535,7 @@
* direct the initiator to copy the active data pointer to
* the saved data pointer for the current I/O process.
*/
- acornscsi_dma_cleanup (host);
+ acornscsi_dma_cleanup(host);
host->SCpnt->SCp = host->scsi.SCp;
host->SCpnt->SCp.sent_command = 0;
host->scsi.phase = PHASE_MSGIN;
@@ -1459,7 +1551,7 @@
* status pointers shall be restored to the beginning of
* the present command and status areas.'
*/
- acornscsi_dma_cleanup (host);
+ acornscsi_dma_cleanup(host);
host->scsi.SCp = host->SCpnt->SCp;
host->scsi.phase = PHASE_MSGIN;
break;
@@ -1474,7 +1566,7 @@
* message. When reconnection is completed, the most recent
* saved pointer values are restored.'
*/
- acornscsi_dma_cleanup (host);
+ acornscsi_dma_cleanup(host);
host->scsi.phase = PHASE_DISCONNECT;
break;
@@ -1493,8 +1585,8 @@
/*
* If we have any messages waiting to go out, then assert ATN now
*/
- if (msgqueue_msglength (&host->scsi.msgs))
- acornscsi_sbic_issuecmd (host, CMND_ASSERTATN);
+ if (msgqueue_msglength(&host->scsi.msgs))
+ acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
switch (host->scsi.last_message) {
#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
@@ -1507,21 +1599,21 @@
* message is received, it shall respond with a MESSAGE REJECT
* message and accept the I/O process as if it were untagged.
*/
- printk (KERN_NOTICE "scsi%d.%c: disabling tagged queueing\n",
- host->host->host_no, acornscsi_target (host));
+ printk(KERN_NOTICE "scsi%d.%c: disabling tagged queueing\n",
+ host->host->host_no, acornscsi_target(host));
host->SCpnt->device->tagged_queue = 0;
- set_bit (host->SCpnt->target * 8 + host->SCpnt->lun, &host->busyluns);
+ set_bit(host->SCpnt->target * 8 + host->SCpnt->lun, &host->busyluns);
break;
#endif
case EXTENDED_MESSAGE | (EXTENDED_SDTR << 8):
/*
* Target can't handle synchronous transfers
*/
- printk (KERN_NOTICE "scsi%d.%c: Using asynchronous transfer\n",
- host->host->host_no, acornscsi_target (host));
+ printk(KERN_NOTICE "scsi%d.%c: Using asynchronous transfer\n",
+ host->host->host_no, acornscsi_target(host));
host->device[host->SCpnt->target].sync_xfer = SYNCHTRANSFER_2DBA;
host->device[host->SCpnt->target].sync_state = SYNC_ASYNCHRONOUS;
- sbic_arm_write (host->scsi.io_port, SYNCHTRANSFER, host->device[host->SCpnt->target].sync_xfer);
+ sbic_arm_write(host->scsi.io_port, SYNCHTRANSFER, host->device[host->SCpnt->target].sync_xfer);
break;
default:
@@ -1535,8 +1627,8 @@
case SIMPLE_QUEUE_TAG:
/* tag queue reconnect... message[1] = queue tag. Print something to indicate something happened! */
- printk ("scsi%d.%c: reconnect queue tag %02X\n",
- host->host->host_no, acornscsi_target (host),
+ printk("scsi%d.%c: reconnect queue tag %02X\n",
+ host->host->host_no, acornscsi_target(host),
message[1]);
break;
@@ -1552,26 +1644,26 @@
* and the target retries fail, then we fallback to asynchronous mode
*/
host->device[host->SCpnt->target].sync_state = SYNC_COMPLETED;
- printk (KERN_NOTICE "scsi%d.%c: Using synchronous transfer, offset %d, %d ns\n",
+ printk(KERN_NOTICE "scsi%d.%c: Using synchronous transfer, offset %d, %d ns\n",
host->host->host_no, acornscsi_target(host),
message[4], message[3] * 4);
host->device[host->SCpnt->target].sync_xfer =
- calc_sync_xfer (message[3] * 4, message[4]);
+ calc_sync_xfer(message[3] * 4, message[4]);
} else {
unsigned char period, length;
/*
* Target requested synchronous transfers. The agreement is only
* to be in operation AFTER the target leaves message out phase.
*/
- acornscsi_sbic_issuecmd (host, CMND_ASSERTATN);
- period = max (message[3], sdtr_period / 4);
- length = min (message[4], sdtr_size);
- msgqueue_addmsg (&host->scsi.msgs, 5, EXTENDED_MESSAGE, 3,
+ acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
+ period = max(message[3], sdtr_period / 4);
+ length = min(message[4], sdtr_size);
+ msgqueue_addmsg(&host->scsi.msgs, 5, EXTENDED_MESSAGE, 3,
EXTENDED_SDTR, period, length);
host->device[host->SCpnt->target].sync_xfer =
- calc_sync_xfer (period * 4, length);
+ calc_sync_xfer(period * 4, length);
}
- sbic_arm_write (host->scsi.io_port, SYNCHTRANSFER, host->device[host->SCpnt->target].sync_xfer);
+ sbic_arm_write(host->scsi.io_port, SYNCHTRANSFER, host->device[host->SCpnt->target].sync_xfer);
break;
#else
/* We do not accept synchronous transfers. Respond with a
@@ -1584,9 +1676,9 @@
* to a wide data transfer request.
*/
default:
- acornscsi_sbic_issuecmd (host, CMND_ASSERTATN);
- msgqueue_flush (&host->scsi.msgs);
- msgqueue_addmsg (&host->scsi.msgs, 1, MESSAGE_REJECT);
+ acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
+ msgqueue_flush(&host->scsi.msgs);
+ msgqueue_addmsg(&host->scsi.msgs, 1, MESSAGE_REJECT);
break;
}
break;
@@ -1607,19 +1699,19 @@
* if there are more linked commands available.
*/
if (!host->SCpnt->next_link) {
- printk (KERN_WARNING "scsi%d.%c: lun %d tag %d linked command complete, but no next_link\n",
- instance->host_no, acornscsi_target (host), host->SCpnt->tag);
- acornscsi_sbic_issuecmd (host, CMND_ASSERTATN);
- msgqueue_addmsg (&host->scsi.msgs, 1, ABORT);
+ printk(KERN_WARNING "scsi%d.%c: lun %d tag %d linked command complete, but no next_link\n",
+ instance->host_no, acornscsi_target(host), host->SCpnt->tag);
+ acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
+ msgqueue_addmsg(&host->scsi.msgs, 1, ABORT);
} else {
Scsi_Cmnd *SCpnt = host->SCpnt;
- acornscsi_dma_cleanup (host);
+ acornscsi_dma_cleanup(host);
host->SCpnt = host->SCpnt->next_link;
host->SCpnt->tag = SCpnt->tag;
SCpnt->result = DID_OK | host->scsi.SCp.Message << 8 | host->Scsi.SCp.Status;
- SCpnt->done (SCpnt);
+ SCpnt->done(SCpnt);
/* initialise host->SCpnt->SCp */
}
@@ -1628,42 +1720,42 @@
#endif
default: /* reject message */
- printk (KERN_ERR "scsi%d.%c: unrecognised message %02X, rejecting\n",
- host->host->host_no, acornscsi_target (host),
+ printk(KERN_ERR "scsi%d.%c: unrecognised message %02X, rejecting\n",
+ host->host->host_no, acornscsi_target(host),
message[0]);
- acornscsi_sbic_issuecmd (host, CMND_ASSERTATN);
- msgqueue_flush (&host->scsi.msgs);
- msgqueue_addmsg (&host->scsi.msgs, 1, MESSAGE_REJECT);
+ acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
+ msgqueue_flush(&host->scsi.msgs);
+ msgqueue_addmsg(&host->scsi.msgs, 1, MESSAGE_REJECT);
host->scsi.phase = PHASE_MSGIN;
break;
}
- acornscsi_sbic_issuecmd (host, CMND_NEGATEACK);
+ acornscsi_sbic_issuecmd(host, CMND_NEGATEACK);
}
/*
- * Function: int acornscsi_buildmessages (AS_Host *host)
+ * Function: int acornscsi_buildmessages(AS_Host *host)
* Purpose : build the connection messages for a host
* Params : host - host to add messages to
*/
static
-void acornscsi_buildmessages (AS_Host *host)
+void acornscsi_buildmessages(AS_Host *host)
{
#if 0
/* does the device need resetting? */
if (cmd_reset) {
- msgqueue_addmsg (&host->scsi.msgs, 1, BUS_DEVICE_RESET);
+ msgqueue_addmsg(&host->scsi.msgs, 1, BUS_DEVICE_RESET);
return;
}
#endif
- msgqueue_addmsg (&host->scsi.msgs, 1,
+ msgqueue_addmsg(&host->scsi.msgs, 1,
IDENTIFY(host->device[host->SCpnt->target].disconnect_ok,
host->SCpnt->lun));
#if 0
/* does the device need the current command aborted */
if (cmd_aborted) {
- acornscsi_abortcmd (host->SCpnt->tag);
+ acornscsi_abortcmd(host->SCpnt->tag);
return;
}
#endif
@@ -1678,14 +1770,14 @@
tag_type = HEAD_OF_QUEUE_TAG;
else
tag_type = SIMPLE_QUEUE_TAG;
- msgqueue_addmsg (&host->scsi.msgs, 2, tag_type, host->SCpnt->tag);
+ msgqueue_addmsg(&host->scsi.msgs, 2, tag_type, host->SCpnt->tag);
}
#endif
#ifdef CONFIG_SCSI_ACORNSCSI_SYNC
if (host->device[host->SCpnt->target].sync_state == SYNC_NEGOCIATE) {
host->device[host->SCpnt->target].sync_state = SYNC_SENT_REQUEST;
- msgqueue_addmsg (&host->scsi.msgs, 5,
+ msgqueue_addmsg(&host->scsi.msgs, 5,
EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
sdtr_period / 4, sdtr_size);
}
@@ -1693,29 +1785,29 @@
}
/*
- * Function: int acornscsi_starttransfer (AS_Host *host)
+ * Function: int acornscsi_starttransfer(AS_Host *host)
* Purpose : transfer data to/from connected target
* Params : host - host to which target is connected
* Returns : 0 if failure
*/
static
-int acornscsi_starttransfer (AS_Host *host)
+int acornscsi_starttransfer(AS_Host *host)
{
int residual;
if (!host->scsi.SCp.ptr /*&& host->scsi.SCp.this_residual*/) {
- printk (KERN_ERR "scsi%d.%c: null buffer passed to acornscsi_starttransfer\n",
- host->host->host_no, acornscsi_target (host));
+ printk(KERN_ERR "scsi%d.%c: null buffer passed to acornscsi_starttransfer\n",
+ host->host->host_no, acornscsi_target(host));
return 0;
}
residual = host->SCpnt->request_bufflen - host->scsi.SCp.scsi_xferred;
- sbic_arm_write (host->scsi.io_port, SYNCHTRANSFER, host->device[host->SCpnt->target].sync_xfer);
- sbic_arm_writenext (host->scsi.io_port, residual >> 16);
- sbic_arm_writenext (host->scsi.io_port, residual >> 8);
- sbic_arm_writenext (host->scsi.io_port, residual);
- acornscsi_sbic_issuecmd (host, CMND_XFERINFO);
+ sbic_arm_write(host->scsi.io_port, SYNCHTRANSFER, host->device[host->SCpnt->target].sync_xfer);
+ sbic_arm_writenext(host->scsi.io_port, residual >> 16);
+ sbic_arm_writenext(host->scsi.io_port, residual >> 8);
+ sbic_arm_writenext(host->scsi.io_port, residual);
+ acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
return 1;
}
@@ -1723,7 +1815,7 @@
* Connection & Disconnection
*/
/*
- * Function : acornscsi_reconnect (AS_Host *host)
+ * Function : acornscsi_reconnect(AS_Host *host)
* Purpose : reconnect a previously disconnected command
* Params : host - host specific data
* Remarks : SCSI spec says:
@@ -1731,27 +1823,27 @@
* of saved pointers upon reconnection of the I/O process'
*/
static
-int acornscsi_reconnect (AS_Host *host)
+int acornscsi_reconnect(AS_Host *host)
{
unsigned int target, lun, ok = 0;
- target = sbic_arm_read (host->scsi.io_port, SOURCEID);
+ target = sbic_arm_read(host->scsi.io_port, SOURCEID);
if (!(target & 8))
- printk (KERN_ERR "scsi%d: invalid source id after reselection "
+ printk(KERN_ERR "scsi%d: invalid source id after reselection "
"- device fault?\n",
host->host->host_no);
target &= 7;
if (host->SCpnt && !host->scsi.disconnectable) {
- printk (KERN_ERR "scsi%d.%d: reconnected while command in "
+ printk(KERN_ERR "scsi%d.%d: reconnected while command in "
"progress to target %d?\n",
host->host->host_no, target, host->SCpnt->target);
host->SCpnt = NULL;
}
- lun = sbic_arm_read (host->scsi.io_port, DATA) & 7;
+ lun = sbic_arm_read(host->scsi.io_port, DATA) & 7;
host->scsi.reconnected.target = target;
host->scsi.reconnected.lun = lun;
@@ -1761,7 +1853,7 @@
host->SCpnt->target == target && host->SCpnt->lun == lun)
ok = 1;
- if (!ok && queue_probetgtlun (&host->queues.disconnected, target, lun))
+ if (!ok && queue_probetgtlun(&host->queues.disconnected, target, lun))
ok = 1;
ADD_STATUS(target, 0x81, host->scsi.phase, 0);
@@ -1770,26 +1862,28 @@
host->scsi.phase = PHASE_RECONNECTED;
} else {
/* this doesn't seem to work */
- printk (KERN_ERR "scsi%d.%c: reselected with no command "
+ printk(KERN_ERR "scsi%d.%c: reselected with no command "
"to reconnect with\n",
host->host->host_no, '0' + target);
- acornscsi_dumplog (host, target);
- acornscsi_sbic_issuecmd (host, CMND_ASSERTATN);
- msgqueue_addmsg (&host->scsi.msgs, 1, ABORT);
- host->scsi.phase = PHASE_ABORTED;
+ acornscsi_dumplog(host, target);
+ acornscsi_abortcmd(host, 0);
+ if (host->SCpnt) {
+ queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt);
+ host->SCpnt = NULL;
+ }
}
- acornscsi_sbic_issuecmd (host, CMND_NEGATEACK);
+ acornscsi_sbic_issuecmd(host, CMND_NEGATEACK);
return !ok;
}
/*
- * Function: int acornscsi_reconect_finish (AS_Host *host)
+ * Function: int acornscsi_reconect_finish(AS_Host *host)
* Purpose : finish reconnecting a command
* Params : host - host to complete
* Returns : 0 if failed
*/
static
-int acornscsi_reconnect_finish (AS_Host *host)
+int acornscsi_reconnect_finish(AS_Host *host)
{
if (host->scsi.disconnectable && host->SCpnt) {
host->scsi.disconnectable = 0;
@@ -1797,45 +1891,44 @@
host->SCpnt->lun == host->scsi.reconnected.lun &&
host->SCpnt->tag == host->scsi.reconnected.tag) {
#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
- DBG(host->SCpnt, printk ("scsi%d.%c: reconnected",
- host->host->host_no, acornscsi_target (host)));
+ DBG(host->SCpnt, printk("scsi%d.%c: reconnected",
+ host->host->host_no, acornscsi_target(host)));
#endif
} else {
- queue_add_cmd_tail (&host->queues.disconnected, host->SCpnt);
+ queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt);
#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
- DBG(host->SCpnt, printk ("scsi%d.%c: had to move command "
+ DBG(host->SCpnt, printk("scsi%d.%c: had to move command "
"to disconnected queue\n",
- host->host->host_no, acornscsi_target (host)));
+ host->host->host_no, acornscsi_target(host)));
#endif
host->SCpnt = NULL;
}
}
if (!host->SCpnt) {
- host->SCpnt = queue_remove_tgtluntag (&host->queues.disconnected,
+ host->SCpnt = queue_remove_tgtluntag(&host->queues.disconnected,
host->scsi.reconnected.target,
host->scsi.reconnected.lun,
host->scsi.reconnected.tag);
#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
- DBG(host->SCpnt, printk ("scsi%d.%c: had to get command",
- host->host->host_no, acornscsi_target (host)));
+ DBG(host->SCpnt, printk("scsi%d.%c: had to get command",
+ host->host->host_no, acornscsi_target(host)));
#endif
}
- if (!host->SCpnt) {
- acornscsi_abortcmd (host, host->scsi.reconnected.tag);
- host->scsi.phase = PHASE_ABORTED;
- } else {
+ if (!host->SCpnt)
+ acornscsi_abortcmd(host, host->scsi.reconnected.tag);
+ else {
/*
* Restore data pointer from SAVED pointers.
*/
host->scsi.SCp = host->SCpnt->SCp;
#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
- printk (", data pointers: [%p, %X]",
+ printk(", data pointers: [%p, %X]",
host->scsi.SCp.ptr, host->scsi.SCp.this_residual);
#endif
}
#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
- printk ("\n");
+ printk("\n");
#endif
host->dma.transferred = host->scsi.SCp.scsi_xferred;
@@ -1844,47 +1937,48 @@
}
/*
- * Function: void acornscsi_disconnect_unexpected (AS_Host *host)
+ * Function: void acornscsi_disconnect_unexpected(AS_Host *host)
* Purpose : handle an unexpected disconnect
* Params : host - host on which disconnect occurred
*/
static
-void acornscsi_disconnect_unexpected (AS_Host *host)
+void acornscsi_disconnect_unexpected(AS_Host *host)
{
- printk (KERN_ERR "scsi%d.%c: unexpected disconnect\n",
- host->host->host_no, acornscsi_target (host));
+ printk(KERN_ERR "scsi%d.%c: unexpected disconnect\n",
+ host->host->host_no, acornscsi_target(host));
#if (DEBUG & DEBUG_ABORT)
- acornscsi_dumplog (host, 8);
+ acornscsi_dumplog(host, 8);
#endif
- acornscsi_done (host, &host->SCpnt, DID_ABORT);
+ acornscsi_done(host, &host->SCpnt, DID_ERROR);
}
/*
- * Function: void acornscsi_abortcmd (AS_host *host, unsigned char tag)
+ * Function: void acornscsi_abortcmd(AS_host *host, unsigned char tag)
* Purpose : abort a currently executing command
* Params : host - host with connected command to abort
* tag - tag to abort
*/
static
-void acornscsi_abortcmd (AS_Host *host, unsigned char tag)
+void acornscsi_abortcmd(AS_Host *host, unsigned char tag)
{
- sbic_arm_write (host->scsi.io_port, CMND, CMND_ASSERTATN);
+ host->scsi.phase = PHASE_ABORTED;
+ sbic_arm_write(host->scsi.io_port, CMND, CMND_ASSERTATN);
- msgqueue_flush (&host->scsi.msgs);
+ msgqueue_flush(&host->scsi.msgs);
#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
if (tag)
- msgqueue_addmsg (&host->scsi.msgs, 2, ABORT_TAG, tag);
+ msgqueue_addmsg(&host->scsi.msgs, 2, ABORT_TAG, tag);
else
#endif
- msgqueue_addmsg (&host->scsi.msgs, 1, ABORT);
+ msgqueue_addmsg(&host->scsi.msgs, 1, ABORT);
}
/* ==========================================================================================
* Interrupt routines.
*/
/*
- * Function: int acornscsi_sbicintr (AS_Host *host)
+ * Function: int acornscsi_sbicintr(AS_Host *host)
* Purpose : handle interrupts from SCSI device
* Params : host - host to process
* Returns : INTR_PROCESS if expecting another SBIC interrupt
@@ -1892,15 +1986,15 @@
* INTR_NEXT_COMMAND if we have finished processing the command
*/
static
-intr_ret_t acornscsi_sbicintr (AS_Host *host, int in_irq)
+intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq)
{
unsigned int asr, ssr;
- asr = sbic_arm_read (host->scsi.io_port, ASR);
+ asr = sbic_arm_read(host->scsi.io_port, ASR);
if (!(asr & ASR_INT))
return INTR_IDLE;
- ssr = sbic_arm_read (host->scsi.io_port, SSR);
+ ssr = sbic_arm_read(host->scsi.io_port, SSR);
#if (DEBUG & DEBUG_PHASES)
print_sbic_status(asr, ssr, host->scsi.phase);
@@ -1913,23 +2007,23 @@
switch (ssr) {
case 0x00: /* reset state - not advanced */
- printk (KERN_ERR "scsi%d: reset in standard mode but wanted advanced mode.\n",
+ printk(KERN_ERR "scsi%d: reset in standard mode but wanted advanced mode.\n",
host->host->host_no);
/* setup sbic - WD33C93A */
- sbic_arm_write (host->scsi.io_port, OWNID, OWNID_EAF | host->host->this_id);
- sbic_arm_write (host->scsi.io_port, CMND, CMND_RESET);
+ sbic_arm_write(host->scsi.io_port, OWNID, OWNID_EAF | host->host->this_id);
+ sbic_arm_write(host->scsi.io_port, CMND, CMND_RESET);
return INTR_IDLE;
case 0x01: /* reset state - advanced */
- sbic_arm_write (host->scsi.io_port, CTRL, INIT_SBICDMA | CTRL_IDI);
- sbic_arm_write (host->scsi.io_port, TIMEOUT, TIMEOUT_TIME);
- sbic_arm_write (host->scsi.io_port, SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
- sbic_arm_write (host->scsi.io_port, SOURCEID, SOURCEID_ER | SOURCEID_DSP);
- msgqueue_flush (&host->scsi.msgs);
+ sbic_arm_write(host->scsi.io_port, CTRL, INIT_SBICDMA | CTRL_IDI);
+ sbic_arm_write(host->scsi.io_port, TIMEOUT, TIMEOUT_TIME);
+ sbic_arm_write(host->scsi.io_port, SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
+ sbic_arm_write(host->scsi.io_port, SOURCEID, SOURCEID_ER | SOURCEID_DSP);
+ msgqueue_flush(&host->scsi.msgs);
return INTR_IDLE;
case 0x41: /* unexpected disconnect aborted command */
- acornscsi_disconnect_unexpected (host);
+ acornscsi_disconnect_unexpected(host);
return INTR_NEXT_COMMAND;
}
@@ -1939,35 +2033,35 @@
case 0x11: /* -> PHASE_CONNECTED */
/* BUS FREE -> SELECTION */
host->scsi.phase = PHASE_CONNECTED;
- msgqueue_flush (&host->scsi.msgs);
+ msgqueue_flush(&host->scsi.msgs);
host->dma.transferred = host->scsi.SCp.scsi_xferred;
/* 33C93 gives next interrupt indicating bus phase */
- asr = sbic_arm_read (host->scsi.io_port, ASR);
+ asr = sbic_arm_read(host->scsi.io_port, ASR);
if (!(asr & ASR_INT))
break;
- ssr = sbic_arm_read (host->scsi.io_port, SSR);
+ ssr = sbic_arm_read(host->scsi.io_port, SSR);
ADD_STATUS(8, ssr, host->scsi.phase, 1);
ADD_STATUS(host->SCpnt->target, ssr, host->scsi.phase, 1);
goto connected;
case 0x42: /* select timed out */
/* -> PHASE_IDLE */
- acornscsi_done (host, &host->SCpnt, DID_NO_CONNECT);
+ acornscsi_done(host, &host->SCpnt, DID_NO_CONNECT);
return INTR_NEXT_COMMAND;
case 0x81: /* -> PHASE_RECONNECTED or PHASE_ABORTED */
/* BUS FREE -> RESELECTION */
host->origSCpnt = host->SCpnt;
host->SCpnt = NULL;
- msgqueue_flush (&host->scsi.msgs);
- acornscsi_reconnect (host);
+ msgqueue_flush(&host->scsi.msgs);
+ acornscsi_reconnect(host);
break;
default:
- printk (KERN_ERR "scsi%d.%c: PHASE_CONNECTING, SSR %02X?\n",
- host->host->host_no, acornscsi_target (host), ssr);
- acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);
- acornscsi_abortcmd (host, host->SCpnt->tag);
+ printk(KERN_ERR "scsi%d.%c: PHASE_CONNECTING, SSR %02X?\n",
+ host->host->host_no, acornscsi_target(host), ssr);
+ acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->target : 8);
+ acornscsi_abortcmd(host, host->SCpnt->tag);
}
return INTR_PROCESSING;
@@ -1977,12 +2071,12 @@
#ifdef NONSTANDARD
case 0x8a: /* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */
/* SELECTION -> COMMAND */
- acornscsi_sendcommand (host);
+ acornscsi_sendcommand(host);
break;
case 0x8b: /* -> PHASE_STATUS */
/* SELECTION -> STATUS */
- acornscsi_readstatusbyte (host);
+ acornscsi_readstatusbyte(host);
host->scsi.phase = PHASE_STATUSIN;
break;
#endif
@@ -1990,55 +2084,57 @@
case 0x8e: /* -> PHASE_MSGOUT */
/* SELECTION ->MESSAGE OUT */
host->scsi.phase = PHASE_MSGOUT;
- acornscsi_buildmessages (host);
- acornscsi_sendmessage (host);
+ acornscsi_buildmessages(host);
+ acornscsi_sendmessage(host);
break;
/* these should not happen */
case 0x85: /* target disconnected */
- acornscsi_done (host, &host->SCpnt, DID_ERROR);
+ acornscsi_done(host, &host->SCpnt, DID_ERROR);
break;
default:
- printk (KERN_ERR "scsi%d.%c: PHASE_CONNECTED, SSR %02X?\n",
- host->host->host_no, acornscsi_target (host), ssr);
- acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);
- acornscsi_abortcmd (host, host->SCpnt->tag);
+ printk(KERN_ERR "scsi%d.%c: PHASE_CONNECTED, SSR %02X?\n",
+ host->host->host_no, acornscsi_target(host), ssr);
+ acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->target : 8);
+ acornscsi_abortcmd(host, host->SCpnt->tag);
}
return INTR_PROCESSING;
case PHASE_MSGOUT: /* STATE: connected & sent IDENTIFY message */
/*
- * SCSI standard says th at a MESSAGE OUT phases can be followed by a DATA phase
+ * SCSI standard says that MESSAGE OUT phases can be followed by a
+ * DATA phase, STATUS phase, MESSAGE IN phase or COMMAND phase
*/
switch (ssr) {
- case 0x8a:
+ case 0x8a: /* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */
case 0x1a: /* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */
/* MESSAGE OUT -> COMMAND */
- acornscsi_sendcommand (host);
+ acornscsi_sendcommand(host);
break;
+ case 0x8b: /* -> PHASE_STATUS */
case 0x1b: /* -> PHASE_STATUS */
/* MESSAGE OUT -> STATUS */
- acornscsi_readstatusbyte (host);
+ acornscsi_readstatusbyte(host);
host->scsi.phase = PHASE_STATUSIN;
break;
case 0x8e: /* -> PHASE_MSGOUT */
/* MESSAGE_OUT(MESSAGE_IN) ->MESSAGE OUT */
- acornscsi_sendmessage (host);
+ acornscsi_sendmessage(host);
break;
- case 0x4f:
+ case 0x4f: /* -> PHASE_MSGIN, PHASE_DISCONNECT */
case 0x1f: /* -> PHASE_MSGIN, PHASE_DISCONNECT */
/* MESSAGE OUT -> MESSAGE IN */
- acornscsi_message (host);
+ acornscsi_message(host);
break;
default:
- printk (KERN_ERR "scsi%d.%c: PHASE_MSGOUT, SSR %02X?\n",
- host->host->host_no, acornscsi_target (host), ssr);
- acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);
+ printk(KERN_ERR "scsi%d.%c: PHASE_MSGOUT, SSR %02X?\n",
+ host->host->host_no, acornscsi_target(host), ssr);
+ acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->target : 8);
}
return INTR_PROCESSING;
@@ -2047,43 +2143,43 @@
case 0x18: /* -> PHASE_DATAOUT */
/* COMMAND -> DATA OUT */
if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len)
- acornscsi_abortcmd (host, host->SCpnt->tag);
- acornscsi_dma_setup (host, DMA_OUT);
- if (!acornscsi_starttransfer (host))
- acornscsi_abortcmd (host, host->SCpnt->tag);
+ acornscsi_abortcmd(host, host->SCpnt->tag);
+ acornscsi_dma_setup(host, DMA_OUT);
+ if (!acornscsi_starttransfer(host))
+ acornscsi_abortcmd(host, host->SCpnt->tag);
host->scsi.phase = PHASE_DATAOUT;
return INTR_IDLE;
case 0x19: /* -> PHASE_DATAIN */
/* COMMAND -> DATA IN */
if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len)
- acornscsi_abortcmd (host, host->SCpnt->tag);
- acornscsi_dma_setup (host, DMA_IN);
- if (!acornscsi_starttransfer (host))
- acornscsi_abortcmd (host, host->SCpnt->tag);
+ acornscsi_abortcmd(host, host->SCpnt->tag);
+ acornscsi_dma_setup(host, DMA_IN);
+ if (!acornscsi_starttransfer(host))
+ acornscsi_abortcmd(host, host->SCpnt->tag);
host->scsi.phase = PHASE_DATAIN;
return INTR_IDLE;
case 0x1b: /* -> PHASE_STATUS */
/* COMMAND -> STATUS */
- acornscsi_readstatusbyte (host);
+ acornscsi_readstatusbyte(host);
host->scsi.phase = PHASE_STATUSIN;
break;
case 0x1e: /* -> PHASE_MSGOUT */
/* COMMAND -> MESSAGE OUT */
- acornscsi_sendmessage (host);
+ acornscsi_sendmessage(host);
break;
case 0x1f: /* -> PHASE_MSGIN, PHASE_DISCONNECT */
/* COMMAND -> MESSAGE IN */
- acornscsi_message (host);
+ acornscsi_message(host);
break;
default:
- printk (KERN_ERR "scsi%d.%c: PHASE_COMMAND, SSR %02X?\n",
- host->host->host_no, acornscsi_target (host), ssr);
- acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);
+ printk(KERN_ERR "scsi%d.%c: PHASE_COMMAND, SSR %02X?\n",
+ host->host->host_no, acornscsi_target(host), ssr);
+ acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->target : 8);
}
return INTR_PROCESSING;
@@ -2094,19 +2190,19 @@
host->scsi.phase = PHASE_IDLE;
host->stats.disconnects += 1;
} else {
- printk (KERN_ERR "scsi%d.%c: PHASE_DISCONNECT, SSR %02X instead of disconnect?\n",
- host->host->host_no, acornscsi_target (host), ssr);
- acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);
+ printk(KERN_ERR "scsi%d.%c: PHASE_DISCONNECT, SSR %02X instead of disconnect?\n",
+ host->host->host_no, acornscsi_target(host), ssr);
+ acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->target : 8);
}
return INTR_NEXT_COMMAND;
case PHASE_IDLE: /* STATE: disconnected */
if (ssr == 0x81) /* -> PHASE_RECONNECTED or PHASE_ABORTED */
- acornscsi_reconnect (host);
+ acornscsi_reconnect(host);
else {
- printk (KERN_ERR "scsi%d.%c: PHASE_IDLE, SSR %02X while idle?\n",
- host->host->host_no, acornscsi_target (host), ssr);
- acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);
+ printk(KERN_ERR "scsi%d.%c: PHASE_IDLE, SSR %02X while idle?\n",
+ host->host->host_no, acornscsi_target(host), ssr);
+ acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->target : 8);
}
return INTR_PROCESSING;
@@ -2119,54 +2215,54 @@
* If we reconnected and we're not in MESSAGE IN phase after IDENTIFY,
* reconnect I_T_L command
*/
- if (ssr != 0x8f && !acornscsi_reconnect_finish (host))
+ if (ssr != 0x8f && !acornscsi_reconnect_finish(host))
return INTR_IDLE;
ADD_STATUS(host->SCpnt->target, ssr, host->scsi.phase, in_irq);
switch (ssr) {
case 0x88: /* data out phase */
/* -> PHASE_DATAOUT */
/* MESSAGE IN -> DATA OUT */
- acornscsi_dma_setup (host, DMA_OUT);
- if (!acornscsi_starttransfer (host))
- acornscsi_abortcmd (host, host->SCpnt->tag);
+ acornscsi_dma_setup(host, DMA_OUT);
+ if (!acornscsi_starttransfer(host))
+ acornscsi_abortcmd(host, host->SCpnt->tag);
host->scsi.phase = PHASE_DATAOUT;
return INTR_IDLE;
case 0x89: /* data in phase */
/* -> PHASE_DATAIN */
/* MESSAGE IN -> DATA IN */
- acornscsi_dma_setup (host, DMA_IN);
- if (!acornscsi_starttransfer (host))
- acornscsi_abortcmd (host, host->SCpnt->tag);
+ acornscsi_dma_setup(host, DMA_IN);
+ if (!acornscsi_starttransfer(host))
+ acornscsi_abortcmd(host, host->SCpnt->tag);
host->scsi.phase = PHASE_DATAIN;
return INTR_IDLE;
case 0x8a: /* command out */
/* MESSAGE IN -> COMMAND */
- acornscsi_sendcommand (host);/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */
+ acornscsi_sendcommand(host);/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */
break;
case 0x8b: /* status in */
/* -> PHASE_STATUSIN */
/* MESSAGE IN -> STATUS */
- acornscsi_readstatusbyte (host);
+ acornscsi_readstatusbyte(host);
host->scsi.phase = PHASE_STATUSIN;
break;
case 0x8e: /* message out */
/* -> PHASE_MSGOUT */
/* MESSAGE IN -> MESSAGE OUT */
- acornscsi_sendmessage (host);
+ acornscsi_sendmessage(host);
break;
case 0x8f: /* message in */
- acornscsi_message (host); /* -> PHASE_MSGIN, PHASE_DISCONNECT */
+ acornscsi_message(host); /* -> PHASE_MSGIN, PHASE_DISCONNECT */
break;
default:
- printk (KERN_ERR "scsi%d.%c: PHASE_RECONNECTED, SSR %02X after reconnect?\n",
- host->host->host_no, acornscsi_target (host), ssr);
- acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);
+ printk(KERN_ERR "scsi%d.%c: PHASE_RECONNECTED, SSR %02X after reconnect?\n",
+ host->host->host_no, acornscsi_target(host), ssr);
+ acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->target : 8);
}
return INTR_PROCESSING;
@@ -2177,41 +2273,45 @@
*/
switch (ssr) {
case 0x19: /* -> PHASE_DATAIN */
- acornscsi_abortcmd (host, host->SCpnt->tag);
+ case 0x89: /* -> PHASE_DATAIN */
+ acornscsi_abortcmd(host, host->SCpnt->tag);
return INTR_IDLE;
- case 0x4b: /* -> PHASE_STATUSIN */
case 0x1b: /* -> PHASE_STATUSIN */
+ case 0x4b: /* -> PHASE_STATUSIN */
+ case 0x8b: /* -> PHASE_STATUSIN */
/* DATA IN -> STATUS */
host->scsi.SCp.scsi_xferred = host->SCpnt->request_bufflen -
- acornscsi_sbic_xfcount (host);
- acornscsi_dma_stop (host);
- acornscsi_readstatusbyte (host);
+ acornscsi_sbic_xfcount(host);
+ acornscsi_dma_stop(host);
+ acornscsi_readstatusbyte(host);
host->scsi.phase = PHASE_STATUSIN;
break;
case 0x1e: /* -> PHASE_MSGOUT */
case 0x4e: /* -> PHASE_MSGOUT */
+ case 0x8e: /* -> PHASE_MSGOUT */
/* DATA IN -> MESSAGE OUT */
host->scsi.SCp.scsi_xferred = host->SCpnt->request_bufflen -
- acornscsi_sbic_xfcount (host);
- acornscsi_dma_stop (host);
- acornscsi_sendmessage (host);
+ acornscsi_sbic_xfcount(host);
+ acornscsi_dma_stop(host);
+ acornscsi_sendmessage(host);
break;
case 0x1f: /* message in */
case 0x4f: /* message in */
+ case 0x8f: /* message in */
/* DATA IN -> MESSAGE IN */
host->scsi.SCp.scsi_xferred = host->SCpnt->request_bufflen -
- acornscsi_sbic_xfcount (host);
- acornscsi_dma_stop (host);
- acornscsi_message (host); /* -> PHASE_MSGIN, PHASE_DISCONNECT */
+ acornscsi_sbic_xfcount(host);
+ acornscsi_dma_stop(host);
+ acornscsi_message(host); /* -> PHASE_MSGIN, PHASE_DISCONNECT */
break;
default:
- printk (KERN_ERR "scsi%d.%c: PHASE_DATAIN, SSR %02X?\n",
- host->host->host_no, acornscsi_target (host), ssr);
- acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);
+ printk(KERN_ERR "scsi%d.%c: PHASE_DATAIN, SSR %02X?\n",
+ host->host->host_no, acornscsi_target(host), ssr);
+ acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->target : 8);
}
return INTR_PROCESSING;
@@ -2222,58 +2322,69 @@
*/
switch (ssr) {
case 0x18: /* -> PHASE_DATAOUT */
- acornscsi_abortcmd (host, host->SCpnt->tag);
+ case 0x88: /* -> PHASE_DATAOUT */
+ acornscsi_abortcmd(host, host->SCpnt->tag);
return INTR_IDLE;
- case 0x4b: /* -> PHASE_STATUSIN */
case 0x1b: /* -> PHASE_STATUSIN */
+ case 0x4b: /* -> PHASE_STATUSIN */
+ case 0x8b: /* -> PHASE_STATUSIN */
/* DATA OUT -> STATUS */
host->scsi.SCp.scsi_xferred = host->SCpnt->request_bufflen -
- acornscsi_sbic_xfcount (host);
- acornscsi_dma_stop (host);
- acornscsi_dma_adjust (host);
- acornscsi_readstatusbyte (host);
+ acornscsi_sbic_xfcount(host);
+ acornscsi_dma_stop(host);
+ acornscsi_dma_adjust(host);
+ acornscsi_readstatusbyte(host);
host->scsi.phase = PHASE_STATUSIN;
break;
case 0x1e: /* -> PHASE_MSGOUT */
case 0x4e: /* -> PHASE_MSGOUT */
+ case 0x8e: /* -> PHASE_MSGOUT */
/* DATA OUT -> MESSAGE OUT */
host->scsi.SCp.scsi_xferred = host->SCpnt->request_bufflen -
- acornscsi_sbic_xfcount (host);
- acornscsi_dma_stop (host);
- acornscsi_dma_adjust (host);
- acornscsi_sendmessage (host);
+ acornscsi_sbic_xfcount(host);
+ acornscsi_dma_stop(host);
+ acornscsi_dma_adjust(host);
+ acornscsi_sendmessage(host);
break;
case 0x1f: /* message in */
case 0x4f: /* message in */
+ case 0x8f: /* message in */
/* DATA OUT -> MESSAGE IN */
host->scsi.SCp.scsi_xferred = host->SCpnt->request_bufflen -
- acornscsi_sbic_xfcount (host);
- acornscsi_dma_stop (host);
- acornscsi_dma_adjust (host);
- acornscsi_message (host); /* -> PHASE_MSGIN, PHASE_DISCONNECT */
+ acornscsi_sbic_xfcount(host);
+ acornscsi_dma_stop(host);
+ acornscsi_dma_adjust(host);
+ acornscsi_message(host); /* -> PHASE_MSGIN, PHASE_DISCONNECT */
break;
default:
- printk (KERN_ERR "scsi%d.%c: PHASE_DATAOUT, SSR %02X?\n",
- host->host->host_no, acornscsi_target (host), ssr);
- acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);
+ printk(KERN_ERR "scsi%d.%c: PHASE_DATAOUT, SSR %02X?\n",
+ host->host->host_no, acornscsi_target(host), ssr);
+ acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->target : 8);
}
return INTR_PROCESSING;
case PHASE_STATUSIN: /* STATE: status in complete */
- if (ssr == 0x1f) /* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
+ switch (ssr) {
+ case 0x1f: /* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
+ case 0x8f: /* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
/* STATUS -> MESSAGE IN */
- acornscsi_message (host);
- else if (ssr == 0x1e) /* -> PHASE_MSGOUT */
+ acornscsi_message(host);
+ break;
+
+ case 0x1e: /* -> PHASE_MSGOUT */
+ case 0x8e: /* -> PHASE_MSGOUT */
/* STATUS -> MESSAGE OUT */
- acornscsi_sendmessage (host);
- else {
- printk (KERN_ERR "scsi%d.%c: PHASE_STATUSIN, SSR %02X instead of MESSAGE_IN?\n",
- host->host->host_no, acornscsi_target (host), ssr);
- acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);
+ acornscsi_sendmessage(host);
+ break;
+
+ default:
+ printk(KERN_ERR "scsi%d.%c: PHASE_STATUSIN, SSR %02X instead of MESSAGE_IN?\n",
+ host->host->host_no, acornscsi_target(host), ssr);
+ acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->target : 8);
}
return INTR_PROCESSING;
@@ -2281,78 +2392,93 @@
switch (ssr) {
case 0x1e: /* -> PHASE_MSGOUT */
case 0x4e: /* -> PHASE_MSGOUT */
+ case 0x8e: /* -> PHASE_MSGOUT */
/* MESSAGE IN -> MESSAGE OUT */
- acornscsi_sendmessage (host);
+ acornscsi_sendmessage(host);
break;
case 0x1f: /* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
case 0x2f:
case 0x4f:
case 0x8f:
- acornscsi_message (host);
+ acornscsi_message(host);
+ break;
+
+ case 0x85:
+ printk("scsi%d.%c: strange message in disconnection\n",
+ host->host->host_no, acornscsi_target(host));
+ acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->target : 8);
+ acornscsi_done(host, &host->SCpnt, DID_ERROR);
break;
default:
- printk (KERN_ERR "scsi%d.%c: PHASE_MSGIN, SSR %02X after message in?\n",
- host->host->host_no, acornscsi_target (host), ssr);
- acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);
+ printk(KERN_ERR "scsi%d.%c: PHASE_MSGIN, SSR %02X after message in?\n",
+ host->host->host_no, acornscsi_target(host), ssr);
+ acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->target : 8);
}
return INTR_PROCESSING;
case PHASE_DONE: /* STATE: received status & message */
switch (ssr) {
case 0x85: /* -> PHASE_IDLE */
- acornscsi_done (host, &host->SCpnt, DID_OK);
+ acornscsi_done(host, &host->SCpnt, DID_OK);
return INTR_NEXT_COMMAND;
+ case 0x1e:
case 0x8e:
- acornscsi_sendmessage (host);
+ acornscsi_sendmessage(host);
break;
default:
- printk (KERN_ERR "scsi%d.%c: PHASE_DONE, SSR %02X instead of disconnect?\n",
- host->host->host_no, acornscsi_target (host), ssr);
- acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);
+ printk(KERN_ERR "scsi%d.%c: PHASE_DONE, SSR %02X instead of disconnect?\n",
+ host->host->host_no, acornscsi_target(host), ssr);
+ acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->target : 8);
}
return INTR_PROCESSING;
case PHASE_ABORTED:
switch (ssr) {
case 0x85:
- acornscsi_done (host, &host->SCpnt, DID_ABORT);
+ if (host->SCpnt)
+ acornscsi_done(host, &host->SCpnt, DID_ABORT);
+ else {
+ clear_bit(host->scsi.reconnected.target * 8 + host->scsi.reconnected.lun,
+ host->busyluns);
+ host->scsi.phase = PHASE_IDLE;
+ }
return INTR_NEXT_COMMAND;
case 0x1e:
case 0x2e:
case 0x4e:
case 0x8e:
- acornscsi_sendmessage (host);
+ acornscsi_sendmessage(host);
break;
default:
- printk (KERN_ERR "scsi%d.%c: PHASE_ABORTED, SSR %02X?\n",
- host->host->host_no, acornscsi_target (host), ssr);
- acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);
+ printk(KERN_ERR "scsi%d.%c: PHASE_ABORTED, SSR %02X?\n",
+ host->host->host_no, acornscsi_target(host), ssr);
+ acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->target : 8);
}
return INTR_PROCESSING;
default:
- printk (KERN_ERR "scsi%d.%c: unknown driver phase %d\n",
- host->host->host_no, acornscsi_target (host), ssr);
- acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);
+ printk(KERN_ERR "scsi%d.%c: unknown driver phase %d\n",
+ host->host->host_no, acornscsi_target(host), ssr);
+ acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->target : 8);
}
return INTR_PROCESSING;
}
/*
- * Prototype: void acornscsi_intr (int irq, void *dev_id, struct pt_regs *regs)
+ * Prototype: void acornscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
* Purpose : handle interrupts from Acorn SCSI card
* Params : irq - interrupt number
* dev_id - device specific data (AS_Host structure)
* regs - processor registers when interrupt occurred
*/
static
-void acornscsi_intr (int irq, void *dev_id, struct pt_regs *regs)
+void acornscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
{
AS_Host *host = (AS_Host *)dev_id;
intr_ret_t ret;
@@ -2360,21 +2486,21 @@
int in_irq = 0;
if (host->scsi.interrupt)
- printk ("scsi%d: interrupt re-entered\n", host->host->host_no);
+ printk("scsi%d: interrupt re-entered\n", host->host->host_no);
host->scsi.interrupt = 1;
do {
ret = INTR_IDLE;
- iostatus = inb (host->card.io_intr);
+ iostatus = inb(host->card.io_intr);
if (iostatus & 2) {
- acornscsi_dma_intr (host);
- iostatus = inb (host->card.io_intr);
+ acornscsi_dma_intr(host);
+ iostatus = inb(host->card.io_intr);
}
if (iostatus & 8)
- ret = acornscsi_sbicintr (host, in_irq);
+ ret = acornscsi_sbicintr(host, in_irq);
/*
* If we have a transfer pending, start it.
@@ -2382,10 +2508,10 @@
* it's data
*/
if (host->dma.xfer_required)
- acornscsi_dma_xfer (host);
+ acornscsi_dma_xfer(host);
if (ret == INTR_NEXT_COMMAND)
- ret = acornscsi_kick (host);
+ ret = acornscsi_kick(host);
in_irq = 1;
} while (ret != INTR_IDLE);
@@ -2398,29 +2524,29 @@
*/
/*
- * Function : acornscsi_queuecmd (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
+ * Function : acornscsi_queuecmd(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
* Purpose : queues a SCSI command
* Params : cmd - SCSI command
* done - function called on completion, with pointer to command descriptor
* Returns : 0, or < 0 on error.
*/
-int acornscsi_queuecmd (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+int acornscsi_queuecmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
{
AS_Host *host = (AS_Host *)SCpnt->host->hostdata;
if (!done) {
/* there should be some way of rejecting errors like this without panicing... */
- panic ("scsi%d: queuecommand called with NULL done function [cmd=%p]",
+ panic("scsi%d: queuecommand called with NULL done function [cmd=%p]",
SCpnt->host->host_no, SCpnt);
return -EINVAL;
}
#if (DEBUG & DEBUG_NO_WRITE)
- if (acornscsi_cmdtype (SCpnt->cmnd[0]) == CMD_WRITE && (NO_WRITE & (1 << SCpnt->target))) {
- printk (KERN_CRIT "scsi%d.%c: WRITE attempted with NO_WRITE flag set\n",
+ if (acornscsi_cmdtype(SCpnt->cmnd[0]) == CMD_WRITE && (NO_WRITE & (1 << SCpnt->target))) {
+ printk(KERN_CRIT "scsi%d.%c: WRITE attempted with NO_WRITE flag set\n",
SCpnt->host->host_no, '0' + SCpnt->target);
SCpnt->result = DID_NO_CONNECT << 16;
- done (SCpnt);
+ done(SCpnt);
return 0;
}
#endif
@@ -2429,7 +2555,7 @@
SCpnt->host_scribble = NULL;
SCpnt->result = 0;
SCpnt->tag = 0;
- SCpnt->SCp.phase = (int)acornscsi_datadirection (SCpnt->cmnd[0]);
+ SCpnt->SCp.phase = (int)acornscsi_datadirection(SCpnt->cmnd[0]);
SCpnt->SCp.sent_command = 0;
SCpnt->SCp.scsi_xferred = 0;
SCpnt->SCp.Status = 0;
@@ -2452,21 +2578,21 @@
{
unsigned long flags;
- if (!queue_add_cmd_ordered (&host->queues.issue, SCpnt)) {
+ if (!queue_add_cmd_ordered(&host->queues.issue, SCpnt)) {
SCpnt->result = DID_ERROR << 16;
- done (SCpnt);
+ done(SCpnt);
return 0;
}
- save_flags_cli (flags);
+ save_flags_cli(flags);
if (host->scsi.phase == PHASE_IDLE)
- acornscsi_kick (host);
- restore_flags (flags);
+ acornscsi_kick(host);
+ restore_flags(flags);
}
return 0;
}
/*
- * Prototype: void acornscsi_reportstatus (Scsi_Cmnd **SCpntp1, Scsi_Cmnd **SCpntp2, int result)
+ * Prototype: void acornscsi_reportstatus(Scsi_Cmnd **SCpntp1, Scsi_Cmnd **SCpntp2, int result)
* Purpose : pass a result to *SCpntp1, and check if *SCpntp1 = *SCpntp2
* Params : SCpntp1 - pointer to command to return
* SCpntp2 - pointer to command to check
@@ -2474,7 +2600,7 @@
* Returns : *SCpntp2 = NULL if *SCpntp1 is the same command structure as *SCpntp2.
*/
static inline
-void acornscsi_reportstatus (Scsi_Cmnd **SCpntp1, Scsi_Cmnd **SCpntp2, int result)
+void acornscsi_reportstatus(Scsi_Cmnd **SCpntp1, Scsi_Cmnd **SCpntp2, int result)
{
Scsi_Cmnd *SCpnt = *SCpntp1;
@@ -2482,80 +2608,203 @@
*SCpntp1 = NULL;
SCpnt->result = result;
- SCpnt->scsi_done (SCpnt);
+ SCpnt->scsi_done(SCpnt);
}
if (SCpnt == *SCpntp2)
*SCpntp2 = NULL;
}
+enum res_abort { res_not_running, res_success, res_success_clear, res_snooze };
+
/*
- * Prototype: int acornscsi_abort (Scsi_Cmnd *SCpnt)
+ * Prototype: enum res acornscsi_do_abort(Scsi_Cmnd *SCpnt)
+ * Purpose : abort a command on this host
+ * Params : SCpnt - command to abort
+ * Returns : our abort status
+ */
+static enum res_abort
+acornscsi_do_abort(AS_Host *host, Scsi_Cmnd *SCpnt)
+{
+ enum res_abort res = res_not_running;
+
+ if (queue_removecmd(&host->queues.issue, SCpnt)) {
+ /*
+ * The command was on the issue queue, and has not been
+ * issued yet. We can remove the command from the queue,
+ * and acknowledge the abort. Neither the devices nor the
+ * interface know about the command.
+ */
+//#if (DEBUG & DEBUG_ABORT)
+ printk("on issue queue ");
+//#endif
+ res = res_success;
+ } else if (queue_removecmd(&host->queues.disconnected, SCpnt)) {
+ /*
+ * The command was on the disconnected queue. Simply
+ * acknowledge the abort condition, and when the target
+ * reconnects, we will give it an ABORT message. The
+ * target should then disconnect, and we will clear
+ * the busylun bit.
+ */
+//#if (DEBUG & DEBUG_ABORT)
+ printk("on disconnected queue ");
+//#endif
+ res = res_success;
+ } else if (host->SCpnt == SCpnt) {
+ unsigned long flags;
+
+//#if (DEBUG & DEBUG_ABORT)
+ printk("executing ");
+//#endif
+
+ save_flags(flags);
+ cli();
+ switch (host->scsi.phase) {
+ /*
+ * If the interface is idle, and the command is 'disconnectable',
+ * then it is the same as on the disconnected queue. We simply
+ * remove all traces of the command. When the target reconnects,
+ * we will give it an ABORT message since the command could not
+ * be found. When the target finally disconnects, we will clear
+ * the busylun bit.
+ */
+ case PHASE_IDLE:
+ if (host->scsi.disconnectable) {
+ host->scsi.disconnectable = 0;
+ host->SCpnt = NULL;
+ res = res_success;
+ }
+ break;
+
+ /*
+ * If the command has connected and done nothing further,
+ * simply force a disconnect. We also need to clear the
+ * busylun bit.
+ */
+ case PHASE_CONNECTED:
+ sbic_arm_write(host->scsi.io_port, CMND, CMND_DISCONNECT);
+ host->SCpnt = NULL;
+ res = res_success_clear;
+ break;
+
+ default:
+ acornscsi_abortcmd(host, host->SCpnt->tag);
+ res = res_snooze;
+ }
+ restore_flags(flags);
+ } else if (host->origSCpnt == SCpnt) {
+ /*
+ * The command will be executed next, but a command
+ * is currently using the interface. This is similar to
+ * being on the issue queue, except the busylun bit has
+ * been set.
+ */
+ host->origSCpnt = NULL;
+//#if (DEBUG & DEBUG_ABORT)
+ printk("waiting for execution ");
+//#endif
+ res = res_success_clear;
+ } else
+ printk("unknown ");
+
+ return res;
+}
+
+/*
+ * Prototype: int acornscsi_abort(Scsi_Cmnd *SCpnt)
* Purpose : abort a command on this host
* Params : SCpnt - command to abort
* Returns : one of SCSI_ABORT_ macros
*/
-int acornscsi_abort (Scsi_Cmnd *SCpnt)
+int acornscsi_abort(Scsi_Cmnd *SCpnt)
{
- AS_Host *host = (AS_Host *) SCpnt->host->hostdata;
- int result = SCSI_ABORT_NOT_RUNNING;
+ AS_Host *host = (AS_Host *) SCpnt->host->hostdata;
+ int result;
- host->stats.aborts += 1;
+ host->stats.aborts += 1;
#if (DEBUG & DEBUG_ABORT)
- {
- int asr, ssr;
- asr = sbic_arm_read (host->scsi.io_port, ASR);
- ssr = sbic_arm_read (host->scsi.io_port, SSR);
+ {
+ int asr, ssr;
+ asr = sbic_arm_read(host->scsi.io_port, ASR);
+ ssr = sbic_arm_read(host->scsi.io_port, SSR);
- printk (KERN_WARNING "acornscsi_abort: ");
- print_sbic_status(asr, ssr, host->scsi.phase);
- acornscsi_dumplog (host, SCpnt->target);
- }
+ printk(KERN_WARNING "acornscsi_abort: ");
+ print_sbic_status(asr, ssr, host->scsi.phase);
+ acornscsi_dumplog(host, SCpnt->target);
+ }
#endif
- if (queue_removecmd (&host->queues.issue, SCpnt)) {
- SCpnt->result = DID_ABORT << 16;
- SCpnt->scsi_done (SCpnt);
-#if (DEBUG & DEBUG_ABORT)
- printk ("scsi%d: command on issue queue\n", host->host->host_no);
-#endif
- result = SCSI_ABORT_SUCCESS;
- } else if (queue_cmdonqueue (&host->queues.disconnected, SCpnt)) {
- printk ("scsi%d: command on disconnected queue\n", host->host->host_no);
- result = SCSI_ABORT_SNOOZE;
- } else if (host->SCpnt == SCpnt) {
- acornscsi_abortcmd (host, host->SCpnt->tag);
- printk ("scsi%d: command executing\n", host->host->host_no);
- result = SCSI_ABORT_SNOOZE;
- } else if (host->origSCpnt == SCpnt) {
- host->origSCpnt = NULL;
- SCpnt->result = DID_ABORT << 16;
- SCpnt->scsi_done (SCpnt);
-#if (DEBUG & DEBUG_ABORT)
- printk ("scsi%d: command waiting for execution\n", host->host->host_no);
-#endif
- result = SCSI_ABORT_SUCCESS;
- }
+ printk("scsi%d: ", host->host->host_no);
+
+ switch (acornscsi_do_abort(host, SCpnt)) {
+ /*
+ * We managed to find the command and cleared it out.
+ * We do not expect the command to be executing on the
+ * target, but we have set the busylun bit.
+ */
+ case res_success_clear:
+//#if (DEBUG & DEBUG_ABORT)
+ printk("clear ");
+//#endif
+ clear_bit(SCpnt->target * 8 + SCpnt->lun, host->busyluns);
+
+ /*
+ * We found the command, and cleared it out. Either
+ * the command is still known to be executing on the
+ * target, or the busylun bit is not set.
+ */
+ case res_success:
+//#if (DEBUG & DEBUG_ABORT)
+ printk("success\n");
+//#endif
+ SCpnt->result = DID_ABORT << 16;
+ SCpnt->scsi_done(SCpnt);
+ result = SCSI_ABORT_SUCCESS;
+ break;
- if (result == SCSI_ABORT_NOT_RUNNING) {
- printk ("scsi%d: abort(): command not running\n", host->host->host_no);
- acornscsi_dumplog (host, SCpnt->target);
+ /*
+ * We did find the command, but unfortunately we couldn't
+ * unhook it from ourselves. Wait some more, and if it
+ * still doesn't complete, reset the interface.
+ */
+ case res_snooze:
+//#if (DEBUG & DEBUG_ABORT)
+ printk("snooze\n");
+//#endif
+ result = SCSI_ABORT_SNOOZE;
+ break;
+
+ /*
+ * The command could not be found (either because it completed,
+ * or it got dropped.
+ */
+ default:
+ case res_not_running:
+ acornscsi_dumplog(host, SCpnt->target);
#if (DEBUG & DEBUG_ABORT)
- result = SCSI_ABORT_SNOOZE;
+ result = SCSI_ABORT_SNOOZE;
+#else
+ result = SCSI_ABORT_NOT_RUNNING;
#endif
- }
- return result;
+//#if (DEBUG & DEBUG_ABORT)
+ printk("not running\n");
+//#endif
+ break;
+ }
+
+ return result;
}
/*
- * Prototype: int acornscsi_reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags)
+ * Prototype: int acornscsi_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
* Purpose : reset a command on this host/reset this host
* Params : SCpnt - command causing reset
* result - what type of reset to perform
* Returns : one of SCSI_RESET_ macros
*/
-int acornscsi_reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags)
+int acornscsi_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
{
AS_Host *host = (AS_Host *)SCpnt->host->hostdata;
Scsi_Cmnd *SCptr;
@@ -2566,16 +2815,16 @@
{
int asr, ssr;
- asr = sbic_arm_read (host->scsi.io_port, ASR);
- ssr = sbic_arm_read (host->scsi.io_port, SSR);
+ asr = sbic_arm_read(host->scsi.io_port, ASR);
+ ssr = sbic_arm_read(host->scsi.io_port, SSR);
- printk (KERN_WARNING "acornscsi_reset: ");
+ printk(KERN_WARNING "acornscsi_reset: ");
print_sbic_status(asr, ssr, host->scsi.phase);
- acornscsi_dumplog (host, SCpnt->target);
+ acornscsi_dumplog(host, SCpnt->target);
}
#endif
- acornscsi_dma_stop (host);
+ acornscsi_dma_stop(host);
SCptr = host->SCpnt;
@@ -2583,19 +2832,19 @@
* do hard reset. This resets all devices on this host, and so we
* must set the reset status on all commands.
*/
- acornscsi_resetcard (host);
+ acornscsi_resetcard(host);
/*
* report reset on commands current connected/disconnected
*/
- acornscsi_reportstatus (&host->SCpnt, &SCptr, DID_RESET);
+ acornscsi_reportstatus(&host->SCpnt, &SCptr, DID_RESET);
- while ((SCptr = queue_remove (&host->queues.disconnected)) != NULL)
- acornscsi_reportstatus (&SCptr, &SCpnt, DID_RESET);
+ while ((SCptr = queue_remove(&host->queues.disconnected)) != NULL)
+ acornscsi_reportstatus(&SCptr, &SCpnt, DID_RESET);
if (SCpnt) {
SCpnt->result = DID_RESET << 16;
- SCpnt->scsi_done (SCpnt);
+ SCpnt->scsi_done(SCpnt);
}
return SCSI_RESET_BUS_RESET | SCSI_RESET_HOST_RESET | SCSI_RESET_SUCCESS;
@@ -2607,19 +2856,19 @@
static struct expansion_card *ecs[MAX_ECARDS];
/*
- * Prototype: void acornscsi_init (AS_Host *host)
+ * Prototype: void acornscsi_init(AS_Host *host)
* Purpose : initialise the AS_Host structure for one interface & setup hardware
* Params : host - host to setup
*/
static
-void acornscsi_init (AS_Host *host)
+void acornscsi_init(AS_Host *host)
{
- memset (&host->stats, 0, sizeof (host->stats));
- queue_initialise (&host->queues.issue);
- queue_initialise (&host->queues.disconnected);
- msgqueue_initialise (&host->scsi.msgs);
+ memset(&host->stats, 0, sizeof (host->stats));
+ queue_initialise(&host->queues.issue);
+ queue_initialise(&host->queues.disconnected);
+ msgqueue_initialise(&host->scsi.msgs);
- acornscsi_resetcard (host);
+ acornscsi_resetcard(host);
}
int acornscsi_detect(Scsi_Host_Template * tpnt)
@@ -2634,7 +2883,7 @@
for (i = 0; i < MAX_ECARDS; i++)
ecs[i] = NULL;
- ecard_startfind ();
+ ecard_startfind();
while(1) {
ecs[count] = ecard_find(0, acornscsi_cids);
@@ -2642,37 +2891,37 @@
break;
if (ecs[count]->irq == 0xff) {
- printk ("scsi: WD33C93 does not have IRQ enabled - ignoring\n");
+ printk("scsi: WD33C93 does not have IRQ enabled - ignoring\n");
continue;
}
ecard_claim(ecs[count]); /* Must claim here - card produces irq on reset */
- instance = scsi_register (tpnt, sizeof(AS_Host));
+ instance = scsi_register(tpnt, sizeof(AS_Host));
host = (AS_Host *)instance->hostdata;
- instance->io_port = ecard_address (ecs[count], ECARD_MEMC, 0);
+ instance->io_port = ecard_address(ecs[count], ECARD_MEMC, 0);
instance->irq = ecs[count]->irq;
host->host = instance;
- host->scsi.io_port = ioaddr (instance->io_port + 0x800);
+ host->scsi.io_port = ioaddr(instance->io_port + 0x800);
host->scsi.irq = instance->irq;
host->card.io_intr = POD_SPACE(instance->io_port) + 0x800;
host->card.io_page = POD_SPACE(instance->io_port) + 0xc00;
- host->card.io_ram = ioaddr (instance->io_port);
+ host->card.io_ram = ioaddr(instance->io_port);
host->dma.io_port = instance->io_port + 0xc00;
host->dma.io_intr_clear = POD_SPACE(instance->io_port) + 0x800;
ecs[count]->irqaddr = (char *)ioaddr(host->card.io_intr);
ecs[count]->irqmask = 0x0a;
- request_region (instance->io_port + 0x800, 2, "acornscsi(sbic)");
- request_region (host->card.io_intr, 1, "acornscsi(intr)");
- request_region (host->card.io_page, 1, "acornscsi(page)");
+ request_region(instance->io_port + 0x800, 2, "acornscsi(sbic)");
+ request_region(host->card.io_intr, 1, "acornscsi(intr)");
+ request_region(host->card.io_page, 1, "acornscsi(page)");
#ifdef USE_DMAC
- request_region (host->dma.io_port, 256, "acornscsi(dmac)");
+ request_region(host->dma.io_port, 256, "acornscsi(dmac)");
#endif
- request_region (instance->io_port, 2048, "acornscsi(ram)");
+ request_region(instance->io_port, 2048, "acornscsi(ram)");
if (request_irq(host->scsi.irq, acornscsi_intr, SA_INTERRUPT, "acornscsi", host)) {
printk(KERN_CRIT "scsi%d: IRQ%d not free, interrupts disabled\n",
@@ -2680,7 +2929,7 @@
host->scsi.irq = NO_IRQ;
}
- acornscsi_init (host);
+ acornscsi_init(host);
++count;
}
@@ -2688,12 +2937,12 @@
}
/*
- * Function: int acornscsi_release (struct Scsi_Host *host)
+ * Function: int acornscsi_release(struct Scsi_Host *host)
* Purpose : release all resources used by this adapter
* Params : host - driver structure to release
* Returns : nothing of any consequence
*/
-int acornscsi_release (struct Scsi_Host *instance)
+int acornscsi_release(struct Scsi_Host *instance)
{
AS_Host *host = (AS_Host *)instance->hostdata;
int i;
@@ -2701,30 +2950,30 @@
/*
* Put card into RESET state
*/
- outb (0x80, host->card.io_page);
+ outb(0x80, host->card.io_page);
if (host->scsi.irq != NO_IRQ)
- free_irq (host->scsi.irq, host);
+ free_irq(host->scsi.irq, host);
- release_region (instance->io_port + 0x800, 2);
- release_region (host->card.io_intr, 1);
- release_region (host->card.io_page, 1);
- release_region (host->dma.io_port, 256);
- release_region (instance->io_port, 2048);
+ release_region(instance->io_port + 0x800, 2);
+ release_region(host->card.io_intr, 1);
+ release_region(host->card.io_page, 1);
+ release_region(host->dma.io_port, 256);
+ release_region(instance->io_port, 2048);
for (i = 0; i < MAX_ECARDS; i++)
- if (ecs[i] && instance->io_port == ecard_address (ecs[i], ECARD_MEMC, 0))
- ecard_release (ecs[i]);
+ if (ecs[i] && instance->io_port == ecard_address(ecs[i], ECARD_MEMC, 0))
+ ecard_release(ecs[i]);
- msgqueue_free (&host->scsi.msgs);
- queue_free (&host->queues.disconnected);
- queue_free (&host->queues.issue);
+ msgqueue_free(&host->scsi.msgs);
+ queue_free(&host->queues.disconnected);
+ queue_free(&host->queues.issue);
return 0;
}
/*
- * Function: char *acornscsi_info (struct Scsi_Host *host)
+ * Function: char *acornscsi_info(struct Scsi_Host *host)
* Purpose : return a string describing this interface
* Params : host - host to give information on
* Returns : a constant string
@@ -2736,7 +2985,7 @@
p = string;
- p += sprintf (string, "%s at port %lX irq %d v%d.%d.%d"
+ p += sprintf(string, "%s at port %X irq %d v%d.%d.%d"
#ifdef CONFIG_SCSI_ACORNSCSI_SYNC
" SYNC"
#endif
@@ -2772,7 +3021,7 @@
host = (AS_Host *)instance->hostdata;
- p += sprintf (p, "AcornSCSI driver v%d.%d.%d"
+ p += sprintf(p, "AcornSCSI driver v%d.%d.%d"
#ifdef CONFIG_SCSI_ACORNSCSI_SYNC
" SYNC"
#endif
@@ -2787,14 +3036,14 @@
#endif
"\n\n", VER_MAJOR, VER_MINOR, VER_PATCH);
- p += sprintf (p, "SBIC: WD33C93A Address: %08X IRQ : %d\n",
+ p += sprintf(p, "SBIC: WD33C93A Address: %08X IRQ : %d\n",
host->scsi.io_port, host->scsi.irq);
#ifdef USE_DMAC
- p += sprintf (p, "DMAC: uPC71071 Address: %08X IRQ : %d\n\n",
+ p += sprintf(p, "DMAC: uPC71071 Address: %08X IRQ : %d\n\n",
host->dma.io_port, host->scsi.irq);
#endif
- p += sprintf (p, "Statistics:\n"
+ p += sprintf(p, "Statistics:\n"
"Queued commands: %-10u Issued commands: %-10u\n"
"Done commands : %-10u Reads : %-10u\n"
"Writes : %-10u Others : %-10u\n"
@@ -2809,47 +3058,47 @@
for (devidx = 0; devidx < 9; devidx ++) {
unsigned int statptr, prev;
- p += sprintf (p, "\n%c:", devidx == 8 ? 'H' : ('0' + devidx));
- statptr = status_ptr[devidx] - 10;
+ p += sprintf(p, "\n%c:", devidx == 8 ? 'H' : ('0' + devidx));
+ statptr = host->status_ptr[devidx] - 10;
if ((signed int)statptr < 0)
- statptr += 16;
+ statptr += STATUS_BUFFER_SIZE;
- prev = status[devidx][statptr].when;
+ prev = host->status[devidx][statptr].when;
- for (; statptr != status_ptr[devidx]; statptr = (statptr + 1) & 15) {
- if (status[devidx][statptr].when) {
- p += sprintf (p, "%c%02X:%02X+%2ld",
- status[devidx][statptr].irq ? '-' : ' ',
- status[devidx][statptr].ph,
- status[devidx][statptr].ssr,
- (status[devidx][statptr].when - prev) < 100 ?
- (status[devidx][statptr].when - prev) : 99);
- prev = status[devidx][statptr].when;
+ for (; statptr != host->status_ptr[devidx]; statptr = (statptr + 1) & (STATUS_BUFFER_SIZE - 1)) {
+ if (host->status[devidx][statptr].when) {
+ p += sprintf(p, "%c%02X:%02X+%2ld",
+ host->status[devidx][statptr].irq ? '-' : ' ',
+ host->status[devidx][statptr].ph,
+ host->status[devidx][statptr].ssr,
+ (host->status[devidx][statptr].when - prev) < 100 ?
+ (host->status[devidx][statptr].when - prev) : 99);
+ prev = host->status[devidx][statptr].when;
}
}
}
- p += sprintf (p, "\nAttached devices:%s\n", instance->host_queue ? "" : " none");
+ p += sprintf(p, "\nAttached devices:%s\n", instance->host_queue ? "" : " none");
for (scd = instance->host_queue; scd; scd = scd->next) {
int len;
- proc_print_scsidevice (scd, p, &len, 0);
+ proc_print_scsidevice(scd, p, &len, 0);
p += len;
- p += sprintf (p, "Extensions: ");
+ p += sprintf(p, "Extensions: ");
if (scd->tagged_supported)
- p += sprintf (p, "TAG %sabled [%d] ",
+ p += sprintf(p, "TAG %sabled [%d] ",
scd->tagged_queue ? "en" : "dis", scd->current_tag);
- p += sprintf (p, "\nTransfers: ");
+ p += sprintf(p, "\nTransfers: ");
if (host->device[scd->id].sync_xfer & 15)
- p += sprintf (p, "sync, offset %d, %d ns\n",
+ p += sprintf(p, "sync, offset %d, %d ns\n",
host->device[scd->id].sync_xfer & 15,
- acornscsi_getperiod (host->device[scd->id].sync_xfer));
+ acornscsi_getperiod(host->device[scd->id].sync_xfer));
else
- p += sprintf (p, "async\n");
+ p += sprintf(p, "async\n");
pos = p - buffer;
if (pos + begin < offset) {
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/scsi/acornscsi.h linux.ac/drivers/acorn/scsi/acornscsi.h
--- linux.vanilla/drivers/acorn/scsi/acornscsi.h Sun Nov 8 15:08:18 1998
+++ linux.ac/drivers/acorn/scsi/acornscsi.h Sun Jan 24 23:54:37 1999
@@ -291,6 +291,27 @@
#include "queue.h"
#include "msgqueue.h"
+#define STATUS_BUFFER_SIZE 32
+/*
+ * This is used to dump the previous states of the SBIC
+ */
+struct status_entry {
+ unsigned long when;
+ unsigned char ssr;
+ unsigned char ph;
+ unsigned char irq;
+ unsigned char unused;
+};
+
+#define ADD_STATUS(_q,_ssr,_ph,_irq) \
+({ \
+ host->status[(_q)][host->status_ptr[(_q)]].when = jiffies; \
+ host->status[(_q)][host->status_ptr[(_q)]].ssr = (_ssr); \
+ host->status[(_q)][host->status_ptr[(_q)]].ph = (_ph); \
+ host->status[(_q)][host->status_ptr[(_q)]].irq = (_irq); \
+ host->status_ptr[(_q)] = (host->status_ptr[(_q)] + 1) & (STATUS_BUFFER_SIZE - 1); \
+})
+
/*
* AcornSCSI host specific data
*/
@@ -361,6 +382,7 @@
char *xfer_ptr; /* pointer to area */
unsigned char xfer_required:1; /* set if we need to transfer something */
unsigned char xfer_setup:1; /* set if DMA is setup */
+ unsigned char xfer_done:1; /* set if DMA reached end of BH list */
} dma;
/* card info */
@@ -370,6 +392,9 @@
unsigned int io_ram; /* base address of RAM access */
unsigned char page_reg; /* current setting of page reg */
} card;
+
+ unsigned char status_ptr[9];
+ struct status_entry status[9][STATUS_BUFFER_SIZE];
} AS_Host;
#endif /* ndef HOSTS_C */
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/scsi/cumana_2.c linux.ac/drivers/acorn/scsi/cumana_2.c
--- linux.vanilla/drivers/acorn/scsi/cumana_2.c Tue Dec 22 23:19:35 1998
+++ linux.ac/drivers/acorn/scsi/cumana_2.c Sun Jan 24 23:54:37 1999
@@ -4,12 +4,12 @@
* Copyright (C) 1997-1998 Russell King
*
* Changelog:
- * 30-08-1997 RMK 0.0.0 Created, READONLY version
- * 22-01-1998 RMK 0.0.1 Updated to 2.1.80
+ * 30-08-1997 RMK 0.0.0 Created, READONLY version.
+ * 22-01-1998 RMK 0.0.1 Updated to 2.1.80.
* 15-04-1998 RMK 0.0.1 Only do PIO if FAS216 will allow it.
- * 02-05-1998 RMK 0.0.2 Updated & added DMA support
+ * 02-05-1998 RMK 0.0.2 Updated & added DMA support.
* 27-06-1998 RMK Changed asm/delay.h to linux/delay.h
- * 18-08-1998 RMK 0.0.3 Fixed synchronous transfer depth
+ * 18-08-1998 RMK 0.0.3 Fixed synchronous transfer depth.
*/
#include
@@ -117,6 +117,8 @@
cumanascsi_2_irqenable,
cumanascsi_2_irqdisable,
NULL,
+ NULL,
+ NULL,
NULL
};
@@ -364,6 +366,7 @@
info->info.ifcfg.sync_max_depth = CUMANASCSI2_SYNC_DEPTH;
info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
info->info.ifcfg.disconnect_ok = 1;
+ info->info.ifcfg.wide_max_size = 0;
info->info.dma.setup = cumanascsi_2_dma_setup;
info->info.dma.pseudo = cumanascsi_2_dma_pseudo;
info->info.dma.stop = cumanascsi_2_dma_stop;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/scsi/eesox.c linux.ac/drivers/acorn/scsi/eesox.c
--- linux.vanilla/drivers/acorn/scsi/eesox.c Tue Dec 22 23:19:35 1998
+++ linux.ac/drivers/acorn/scsi/eesox.c Sun Jan 24 23:54:37 1999
@@ -123,6 +123,8 @@
eesoxscsi_irqenable,
eesoxscsi_irqdisable,
NULL,
+ NULL,
+ NULL,
NULL
};
@@ -379,6 +381,7 @@
info->info.ifcfg.sync_max_depth = EESOX_SYNC_DEPTH;
info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
info->info.ifcfg.disconnect_ok = 1;
+ info->info.ifcfg.wide_max_size = 0;
info->info.dma.setup = eesoxscsi_dma_setup;
info->info.dma.pseudo = eesoxscsi_dma_pseudo;
info->info.dma.stop = eesoxscsi_dma_stop;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/scsi/fas216.c linux.ac/drivers/acorn/scsi/fas216.c
--- linux.vanilla/drivers/acorn/scsi/fas216.c Mon Dec 28 23:09:41 1998
+++ linux.ac/drivers/acorn/scsi/fas216.c Sun Jan 24 23:54:37 1999
@@ -24,9 +24,9 @@
* 02-05-1998 RMK Added extra checks in fas216_reset
* 24-05-1998 RMK Fixed synchronous transfers with period >= 200ns
* 27-06-1998 RMK Changed asm/delay.h to linux/delay.h
+ * 26-08-1998 RMK Improved message support wrt MESSAGE_REJECT
*
* Todo:
- * - tighten up the MESSAGE_REJECT support.
* - allow individual devices to enable sync xfers.
*/
@@ -57,7 +57,7 @@
#define VER_MAJOR 0
#define VER_MINOR 0
-#define VER_PATCH 4
+#define VER_PATCH 5
#define SCSI2_TAG
@@ -86,6 +86,8 @@
*/
#define SCSI2_SYNC
+#define SCSI2_WIDE
+
#undef DEBUG_CONNECT
#undef DEBUG_BUSSERVICE
#undef DEBUG_FUNCTIONDONE
@@ -132,8 +134,8 @@
printk(" SCp={ ptr=%p this_residual=%X buffer=%p buffers_residual=%X }\n",
info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
info->scsi.SCp.buffer, info->scsi.SCp.buffers_residual);
- printk(" msgs async_stp=%X last_message=%X disconnectable=%d aborting=%d }\n",
- info->scsi.async_stp, info->scsi.last_message,
+ printk(" msgs async_stp=%X disconnectable=%d aborting=%d }\n",
+ info->scsi.async_stp,
info->scsi.disconnectable, info->scsi.aborting);
printk(" stats={ queues=%X removes=%X fins=%X reads=%X writes=%X miscs=%X\n"
" disconnects=%X aborts=%X resets=%X }\n",
@@ -144,10 +146,10 @@
info->ifcfg.clockrate, info->ifcfg.select_timeout,
info->ifcfg.asyncperiod, info->ifcfg.sync_max_depth);
for (i = 0; i < 8; i++) {
- printk(" busyluns[%d]=%X dev[%d]={ disconnect_ok=%d stp=%X sof=%X negstate=%X }\n",
+ printk(" busyluns[%d]=%X dev[%d]={ disconnect_ok=%d stp=%X sof=%X sync_state=%X }\n",
i, info->busyluns[i], i,
info->device[i].disconnect_ok, info->device[i].stp,
- info->device[i].sof, info->device[i].negstate);
+ info->device[i].sof, info->device[i].sync_state);
}
printk(" dma={ transfer_type=%X setup=%p pseudo=%p stop=%p }\n",
info->dma.transfer_type, info->dma.setup,
@@ -192,19 +194,19 @@
static const char *fas216_drv_phase(FAS216_Info *info)
{
switch (info->scsi.phase) {
- case PHASE_IDLE: return "idle";
- case PHASE_SELECTION: return "selection";
- case PHASE_MESSAGESENT: return "message sent";
- case PHASE_RECONNECTED: return "reconnected";
- case PHASE_DATAOUT: return "data out";
- case PHASE_DATAIN: return "data in";
- case PHASE_MSGOUT: return "message out";
- case PHASE_MSGIN: return "message in";
- case PHASE_AFTERMSGOUT: return "after message out";
- case PHASE_STATUS: return "status";
- case PHASE_DISCONNECT: return "disconnect";
- case PHASE_DONE: return "done";
- default: return "???";
+ case PHASE_IDLE: return "idle";
+ case PHASE_SELECTION: return "selection";
+ case PHASE_COMMAND: return "command";
+ case PHASE_RECONNECTED: return "reconnected";
+ case PHASE_DATAOUT: return "data out";
+ case PHASE_DATAIN: return "data in";
+ case PHASE_MSGIN: return "message in";
+ case PHASE_MSGIN_DISCONNECT: return "disconnect";
+ case PHASE_MSGOUT_EXPECT: return "expect message out";
+ case PHASE_MSGOUT: return "message out";
+ case PHASE_STATUS: return "status";
+ case PHASE_DONE: return "done";
+ default: return "???";
}
}
@@ -262,6 +264,37 @@
return clock;
}
+/* Function: unsigned short fas216_get_last_msg(FAS216_Info *info, int pos)
+ * Purpose : retrieve a last message from the list, using position in fifo
+ * Params : info - interface to search
+ * : pos - current fifo position
+ */
+static inline unsigned short
+fas216_get_last_msg(FAS216_Info *info, int pos)
+{
+ unsigned short packed_msg = NOP;
+ struct message *msg;
+ int msgnr = 0;
+
+ while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
+ if (pos >= msg->fifo)
+ break;
+ }
+
+ if (msg) {
+ if (msg->msg[0] == EXTENDED_MESSAGE)
+ packed_msg = EXTENDED_MESSAGE | msg->msg[2] << 8;
+ else
+ packed_msg = msg->msg[0];
+ }
+
+#ifdef DEBUG_MESSAGES
+ printk("Message: %04X found at position %02X\n",
+ packed_msg, pos);
+#endif
+ return packed_msg;
+}
+
/* Function: int fas216_syncperiod(FAS216_Info *info, int ns)
* Purpose : Calculate value to be loaded into the STP register
* for a given period in ns
@@ -303,6 +336,240 @@
outb(info->scsi.cfg[2], REG_CNTL3(info));
}
+/* Synchronous transfer support
+ *
+ * Note: The SCSI II r10 spec says (5.6.12):
+ *
+ * (2) Due to historical problems with early host adapters that could
+ * not accept an SDTR message, some targets may not initiate synchronous
+ * negotiation after a power cycle as required by this standard. Host
+ * adapters that support synchronous mode may avoid the ensuing failure
+ * modes when the target is independently power cycled by initiating a
+ * synchronous negotiation on each REQUEST SENSE and INQUIRY command.
+ * This approach increases the SCSI bus overhead and is not recommended
+ * for new implementations. The correct method is to respond to an
+ * SDTR message with a MESSAGE REJECT message if the either the
+ * initiator or target devices does not support synchronous transfers
+ * or does not want to negotiate for synchronous transfers at the time.
+ * Using the correct method assures compatibility with wide data
+ * transfers and future enhancements.
+ *
+ * We will always initiate a synchronous transfer negociation request on
+ * every INQUIRY or REQUEST SENSE message, unless the target itself has
+ * at some point performed a synchronous transfer negociation request, or
+ * we have synchronous transfers disabled for this device.
+ */
+
+/* Function: void fas216_handlesync(FAS216_Info *info, char *msg)
+ * Purpose : Handle a synchronous transfer message from the target
+ * Params : info - state structure for interface
+ * : msg - message from target
+ */
+static void
+fas216_handlesync(FAS216_Info *info, char *msg)
+{
+ struct fas216_device *dev = &info->device[info->SCpnt->target];
+ enum { sync, async, none, reject } res = none;
+
+#ifdef SCSI2_SYNC
+ switch (msg[0]) {
+ case MESSAGE_REJECT:
+ /* Synchronous transfer request failed.
+ * Note: SCSI II r10:
+ *
+ * SCSI devices that are capable of synchronous
+ * data transfers shall not respond to an SDTR
+ * message with a MESSAGE REJECT message.
+ *
+ * Hence, if we get this condition, we disable
+ * negociation for this device.
+ */
+ if (dev->sync_state == neg_inprogress) {
+ dev->sync_state = neg_invalid;
+ res = async;
+ }
+ break;
+
+ case EXTENDED_MESSAGE:
+ switch (dev->sync_state) {
+ /* We don't accept synchronous transfer requests.
+ * Respond with a MESSAGE_REJECT to prevent a
+ * synchronous transfer agreement from being reached.
+ */
+ case neg_invalid:
+ res = reject;
+ break;
+
+ /* We were not negociating a synchronous transfer,
+ * but the device sent us a negociation request.
+ * Honour the request by sending back a SDTR
+ * message containing our capability, limited by
+ * the targets capability.
+ */
+ default:
+ outb(CMD_SETATN, REG_CMD(info));
+ if (msg[4] > info->ifcfg.sync_max_depth)
+ msg[4] = info->ifcfg.sync_max_depth;
+ if (msg[3] < 1000 / info->ifcfg.clockrate)
+ msg[3] = 1000 / info->ifcfg.clockrate;
+
+ msgqueue_flush(&info->scsi.msgs);
+ msgqueue_addmsg(&info->scsi.msgs, 5,
+ EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
+ msg[3], msg[4]);
+ info->scsi.phase = PHASE_MSGOUT_EXPECT;
+
+ /* This is wrong. The agreement is not in effect
+ * until this message is accepted by the device
+ */
+ dev->sync_state = neg_targcomplete;
+ res = sync;
+ break;
+
+ /* We initiated the synchronous transfer negociation,
+ * and have successfully received a response from the
+ * target. The synchronous transfer agreement has been
+ * reached. Note: if the values returned are out of our
+ * bounds, we must reject the message.
+ */
+ case neg_inprogress:
+ res = reject;
+ if (msg[4] <= info->ifcfg.sync_max_depth &&
+ msg[3] >= 1000 / info->ifcfg.clockrate) {
+ dev->sync_state = neg_complete;
+ res = sync;
+ }
+ break;
+ }
+ }
+#else
+ res = reject;
+#endif
+
+ switch (res) {
+ case sync:
+ dev->period = msg[3];
+ dev->sof = msg[4];
+ dev->stp = fas216_syncperiod(info, msg[3] * 4);
+ fas216_set_sync(info, info->SCpnt->target);
+ break;
+
+ case reject:
+ outb(CMD_SETATN, REG_CMD(info));
+ msgqueue_flush(&info->scsi.msgs);
+ msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
+ info->scsi.phase = PHASE_MSGOUT_EXPECT;
+
+ case async:
+ dev->period = info->ifcfg.asyncperiod / 4;
+ dev->sof = 0;
+ dev->stp = info->scsi.async_stp;
+ fas216_set_sync(info, info->SCpnt->target);
+ break;
+
+ case none:
+ break;
+ }
+}
+
+/* Function: void fas216_handlewide(FAS216_Info *info, char *msg)
+ * Purpose : Handle a wide transfer message from the target
+ * Params : info - state structure for interface
+ * : msg - message from target
+ */
+static void
+fas216_handlewide(FAS216_Info *info, char *msg)
+{
+ struct fas216_device *dev = &info->device[info->SCpnt->target];
+ enum { wide, bit8, none, reject } res = none;
+
+#ifdef SCSI2_WIDE
+ switch (msg[0]) {
+ case MESSAGE_REJECT:
+ /* Wide transfer request failed.
+ * Note: SCSI II r10:
+ *
+ * SCSI devices that are capable of wide
+ * data transfers shall not respond to a
+ * WDTR message with a MESSAGE REJECT message.
+ *
+ * Hence, if we get this condition, we never
+ * reattempt negociation for this device.
+ */
+ if (dev->wide_state == neg_inprogress) {
+ dev->wide_state = neg_invalid;
+ res = bit8;
+ }
+ break;
+
+ case EXTENDED_MESSAGE:
+ switch (dev->wide_state) {
+ /* We don't accept wide data transfer requests.
+ * Respond with a MESSAGE REJECT to prevent a
+ * wide data transfer agreement from being reached.
+ */
+ case neg_invalid:
+ res = reject;
+ break;
+
+ /* We were not negociating a wide data transfer,
+ * but the device sent is a negociation request.
+ * Honour the request by sending back a WDTR
+ * message containing our capability, limited by
+ * the targets capability.
+ */
+ default:
+ outb(CMD_SETATN, REG_CMD(info));
+ if (msg[3] > info->ifcfg.wide_max_size)
+ msg[3] = info->ifcfg.wide_max_size;
+
+ msgqueue_flush(&info->scsi.msgs);
+ msgqueue_addmsg(&info->scsi.msgs, 4,
+ EXTENDED_MESSAGE, 2, EXTENDED_WDTR,
+ msg[3]);
+ info->scsi.phase = PHASE_MSGOUT_EXPECT;
+ res = wide;
+ break;
+
+ /* We initiated the wide data transfer negociation,
+ * and have successfully received a response from the
+ * target. The synchronous transfer agreement has been
+ * reached. Note: if the values returned are out of our
+ * bounds, we must reject the message.
+ */
+ case neg_inprogress:
+ res = reject;
+ if (msg[3] <= info->ifcfg.wide_max_size) {
+ dev->wide_state = neg_complete;
+ res = wide;
+ }
+ break;
+ }
+ }
+#else
+ res = reject;
+#endif
+
+ switch (res) {
+ case wide:
+ dev->wide_xfer = msg[3];
+ break;
+
+ case reject:
+ outb(CMD_SETATN, REG_CMD(info));
+ msgqueue_flush(&info->scsi.msgs);
+ msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
+ info->scsi.phase = PHASE_MSGOUT_EXPECT;
+
+ case bit8:
+ dev->wide_xfer = 0;
+ break;
+
+ case none:
+ break;
+ }
+}
+
/* Function: void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
* Purpose : update data pointers after transfer suspended/paused
* Params : info - interface's local pointer to update
@@ -338,6 +605,9 @@
residual -= bytes_transferred;
ptr += bytes_transferred;
+ if (residual == 0)
+ ptr = NULL;
+
info->scsi.SCp.ptr = ptr;
info->scsi.SCp.this_residual = residual;
}
@@ -353,7 +623,7 @@
{
unsigned int residual;
char *ptr;
- int correction;
+ int correction = 0;
fas216_checkmagic(info, "fas216_pio");
@@ -361,23 +631,24 @@
ptr = info->scsi.SCp.ptr;
if (direction == DMA_OUT) {
- while (residual > 0) {
- if ((inb(REG_CFIS(info)) & CFIS_CF) < 8) {
+// while (residual > 0) {
+// if ((inb(REG_CFIS(info)) & CFIS_CF) < 8) {
outb(*ptr++, REG_FF(info));
residual -= 1;
- } else if (inb(REG_STAT(info)) & STAT_INT)
- break;
- }
- correction = inb(REG_CFIS(info)) & CFIS_CF;
+// }
+// if (inb(REG_STAT(info)) & STAT_INT)
+// break;
+// }
+// correction = inb(REG_CFIS(info)) & CFIS_CF;
} else {
- while (residual > 0) {
- if ((inb(REG_CFIS(info)) & CFIS_CF) != 0) {
+// while (residual > 0) {
+// if ((inb(REG_CFIS(info)) & CFIS_CF) != 0) {
*ptr++ = inb(REG_FF(info));
residual -= 1;
- } else if (inb(REG_STAT(info)) & STAT_INT)
- break;
- }
- correction = 0;
+// }
+// if (inb(REG_STAT(info)) & STAT_INT)
+// break;
+// }
}
ptr -= correction;
@@ -549,10 +820,11 @@
switch (info->scsi.phase) {
case PHASE_SELECTION: /* while selecting - no target */
+ case PHASE_SELSTEPS:
fas216_done(info, DID_NO_CONNECT);
break;
- case PHASE_DISCONNECT: /* message in - disconnecting */
+ case PHASE_MSGIN_DISCONNECT: /* message in - disconnecting */
outb(CMD_ENABLESEL, REG_CMD(info));
info->scsi.disconnectable = 1;
info->scsi.reconnected.tag = 0;
@@ -564,8 +836,8 @@
fas216_done(info, DID_OK);
break;
- case PHASE_AFTERMSGOUT: /* message out - possible ABORT message */
- if (info->scsi.last_message == ABORT) {
+ case PHASE_MSGOUT: /* message out - possible ABORT message */
+ if (fas216_get_last_msg(info, info->scsi.msgin_fifo) == ABORT) {
info->scsi.aborting = 0;
fas216_done(info, DID_ABORT);
break;
@@ -592,14 +864,17 @@
fas216_checkmagic(info, "fas216_reselected_intr");
- if (info->scsi.phase == PHASE_SELECTION && info->SCpnt) {
+ if ((info->scsi.phase == PHASE_SELECTION ||
+ info->scsi.phase == PHASE_SELSTEPS) && info->SCpnt) {
Scsi_Cmnd *SCpnt = info->SCpnt;
info->origSCpnt = SCpnt;
info->SCpnt = NULL;
- if (info->device[SCpnt->target].negstate == syncneg_sent)
- info->device[SCpnt->target].negstate = syncneg_start;
+ if (info->device[SCpnt->target].wide_state == neg_inprogress)
+ info->device[SCpnt->target].wide_state = neg_wait;
+ if (info->device[SCpnt->target].sync_state == neg_inprogress)
+ info->device[SCpnt->target].sync_state = neg_wait;
}
#ifdef DEBUG_CONNECT
@@ -607,15 +882,14 @@
fas216_target(info), info->scsi.phase);
#endif
- msgqueue_flush(&info->scsi.msgs);
-
if ((inb(REG_CFIS(info)) & CFIS_CF) != 2) {
printk(KERN_ERR "scsi%d.H: incorrect number of bytes after reselect\n",
info->host->host_no);
outb(CMD_SETATN, REG_CMD(info));
- msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
- info->scsi.phase = PHASE_MSGOUT;
outb(CMD_MSGACCEPTED, REG_CMD(info));
+ msgqueue_flush(&info->scsi.msgs);
+ msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
+ info->scsi.phase = PHASE_MSGOUT_EXPECT;
return;
}
@@ -636,13 +910,14 @@
if (!ok) {
/*
- * Something went wrong - abort the command on
- * the target. Should this be INITIATOR_ERROR ?
+ * Something went wrong - send an initiator error to
+ * the target.
*/
outb(CMD_SETATN, REG_CMD(info));
- msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
- info->scsi.phase = PHASE_MSGOUT;
outb(CMD_MSGACCEPTED, REG_CMD(info));
+ msgqueue_flush(&info->scsi.msgs);
+ msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
+ info->scsi.phase = PHASE_MSGOUT_EXPECT;
return;
}
@@ -672,17 +947,20 @@
if (!ok && queue_probetgtlun(&info->queues.disconnected, target, identify_msg))
ok = 1;
+ msgqueue_flush(&info->scsi.msgs);
if (ok) {
info->scsi.phase = PHASE_RECONNECTED;
outb(target, REG_SDID(info));
} else {
/*
- * Our command structure not found - abort the command on the target
- * Should this be INITIATOR_ERROR ?
+ * Our command structure not found - abort the
+ * command on the target. Since we have no
+ * record of this command, we can't send
+ * an INITIATOR DETECTED ERROR message.
*/
outb(CMD_SETATN, REG_CMD(info));
msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
- info->scsi.phase = PHASE_MSGOUT;
+ info->scsi.phase = PHASE_MSGOUT_EXPECT;
}
outb(CMD_MSGACCEPTED, REG_CMD(info));
}
@@ -733,8 +1011,14 @@
}
if (!info->SCpnt) {
outb(CMD_SETATN, REG_CMD(info));
- msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
- info->scsi.phase = PHASE_MSGOUT;
+ msgqueue_flush(&info->scsi.msgs);
+#if 0
+ if (info->scsi.reconnected.tag)
+ msgqueue_addmsg(&info->scsi.msgs, 2, ABORT_TAG, info->scsi.reconnected.tag);
+ else
+#endif
+ msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
+ info->scsi.phase = PHASE_MSGOUT_EXPECT;
info->scsi.aborting = 1;
} else {
/*
@@ -751,6 +1035,28 @@
#endif
}
+static unsigned char fas216_get_msg_byte(FAS216_Info *info)
+{
+ int tout;
+
+ outb(CMD_MSGACCEPTED, REG_CMD(info));
+ for (tout = 1000000; tout; tout --)
+ if (inb(REG_STAT(info)) & STAT_INT)
+ break;
+
+ inb(REG_INST(info));
+
+ outb(CMD_TRANSFERINFO, REG_CMD(info));
+
+ for (tout = 1000000; tout; tout --)
+ if (inb(REG_STAT(info)) & STAT_INT)
+ break;
+
+ inb(REG_INST(info));
+
+ return inb(REG_FF(info));
+}
+
/* Function: void fas216_message(FAS216_Info *info)
* Purpose : handle a function done interrupt from FAS216 chip
* Params : info - interface which caused function done interrupt
@@ -765,34 +1071,10 @@
message[0] = inb(REG_FF(info));
if (message[0] == EXTENDED_MESSAGE) {
- int tout;
- outb(CMD_MSGACCEPTED, REG_CMD(info));
- for (tout = 1000000; tout; tout--)
- if (inb(REG_STAT(info)) & STAT_INT)
- break;
- inb(REG_INST(info));
- outb(CMD_TRANSFERINFO, REG_CMD(info));
- for (tout = 1000000; tout; tout--)
- if (inb(REG_STAT(info)) & STAT_INT)
- break;
- inb(REG_INST(info));
-
- message[1] = inb(REG_FF(info));
-
- for (msglen = 2; msglen < message[1] + 2; msglen++) {
- outb(CMD_MSGACCEPTED, REG_CMD(info));
- for (tout = 1000000; tout; tout--)
- if (inb(REG_STAT(info)) & STAT_INT)
- break;
- inb(REG_INST(info));
- outb(CMD_TRANSFERINFO, REG_CMD(info));
- for (tout = 1000000; tout; tout--)
- if (inb(REG_STAT(info)) & STAT_INT)
- break;
- inb(REG_INST(info));
+ message[1] = fas216_get_msg_byte(info);
- message[msglen] = inb(REG_FF(info));
- }
+ for (msglen = 2; msglen < message[1] + 2; msglen++)
+ message[msglen] = fas216_get_msg_byte(info);
}
#ifdef DEBUG_MESSAGES
@@ -806,6 +1088,7 @@
printk("\n");
}
#endif
+
if (info->scsi.phase == PHASE_RECONNECTED) {
if (message[0] == SIMPLE_QUEUE_TAG)
info->scsi.reconnected.tag = message[1];
@@ -815,14 +1098,22 @@
switch (message[0]) {
case COMMAND_COMPLETE:
- printk("fas216: command complete with no status in MESSAGE_IN?\n");
+ printk(KERN_ERR "scsi%d.%c: command complete with no "
+ "status in MESSAGE_IN?\n",
+ info->host->host_no, fas216_target(info));
break;
case SAVE_POINTERS:
/*
* Save current data pointer to SAVED data pointer
+ * SCSI II standard says that we must not acknowledge
+ * this until we have really saved pointers.
+ * NOTE: we DO NOT save the command nor status pointers
+ * as required by the SCSI II standard. These always
+ * point to the start of their respective areas.
*/
info->SCpnt->SCp = info->scsi.SCp;
+ info->SCpnt->SCp.sent_command = 0;
#if defined (DEBUG_MESSAGES) || defined (DEBUG_CONNECT)
printk("scsi%d.%c: save data pointers: [%p, %X]\n",
info->host->host_no, fas216_target(info),
@@ -843,13 +1134,27 @@
break;
case DISCONNECT:
- info->scsi.phase = PHASE_DISCONNECT;
+ info->scsi.phase = PHASE_MSGIN_DISCONNECT;
break;
case MESSAGE_REJECT:
- printk("scsi%d.%c: reject, last message %04X\n",
- info->host->host_no, fas216_target(info),
- info->scsi.last_message);
+ switch (fas216_get_last_msg(info, info->scsi.msgin_fifo)) {
+ case EXTENDED_MESSAGE | EXTENDED_SDTR << 8:
+ fas216_handlesync(info, message);
+ break;
+
+ case EXTENDED_MESSAGE | EXTENDED_WDTR << 8:
+ fas216_handlewide(info, message);
+ break;
+
+ default:
+ printk("scsi%d.%c: reject, last message %04X\n",
+ info->host->host_no, fas216_target(info),
+ fas216_get_last_msg(info, info->scsi.msgin_fifo));
+ }
+ break;
+
+ case NOP:
break;
case SIMPLE_QUEUE_TAG:
@@ -862,49 +1167,18 @@
case EXTENDED_MESSAGE:
switch (message[2]) {
case EXTENDED_SDTR: /* Sync transfer negociation request/reply */
- switch (info->device[info->SCpnt->target].negstate) {
- case syncneg_invalid:
- msgqueue_flush(&info->scsi.msgs);
- outb(CMD_SETATN, REG_CMD(info));
- msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
- info->scsi.phase = PHASE_MSGOUT;
- break;
-
- default:
- if (message[4] > info->ifcfg.sync_max_depth)
- message[4] = info->ifcfg.sync_max_depth;
- if (message[3] < 1000 / info->ifcfg.clockrate)
- message[3] = 1000 / info->ifcfg.clockrate;
-
- outb(CMD_SETATN, REG_CMD(info));
- msgqueue_addmsg(&info->scsi.msgs, 5,
- EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
- message[3], message[4]);
- info->scsi.phase = PHASE_MSGOUT;
- case syncneg_sent:
- info->device[info->SCpnt->target].negstate = syncneg_complete;
- info->device[info->SCpnt->target].period = message[3];
- info->device[info->SCpnt->target].sof = message[4];
- info->device[info->SCpnt->target].stp =
- fas216_syncperiod(info, message[3] * 4);
- printk(KERN_NOTICE "scsi%d.%c: using synchronous transfer, offset %d, %d ns\n",
- info->host->host_no, fas216_target(info), message[4], message[3] * 4);
- fas216_set_sync(info, info->SCpnt->target);
- break;
- }
+ fas216_handlesync(info, message);
break;
case EXTENDED_WDTR: /* Wide transfer negociation request/reply */
- /* We don't do wide transfers - reject message */
+ fas216_handlewide(info, message);
+ break;
+
default:
printk("scsi%d.%c: unrecognised extended message %02X, rejecting\n",
info->host->host_no, fas216_target(info),
message[2]);
- msgqueue_flush(&info->scsi.msgs);
- outb(CMD_SETATN, REG_CMD(info));
- msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
- info->scsi.phase = PHASE_MSGOUT;
- break;
+ goto reject_message;
}
break;
@@ -912,13 +1186,17 @@
printk("scsi%d.%c: unrecognised message %02X, rejecting\n",
info->host->host_no, fas216_target(info),
message[0]);
- msgqueue_flush(&info->scsi.msgs);
- outb(CMD_SETATN, REG_CMD(info));
- msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
- info->scsi.phase = PHASE_MSGOUT;
- break;
+ goto reject_message;
}
outb(CMD_MSGACCEPTED, REG_CMD(info));
+ return;
+
+reject_message:
+ outb(CMD_SETATN, REG_CMD(info));
+ outb(CMD_MSGACCEPTED, REG_CMD(info));
+ msgqueue_flush(&info->scsi.msgs);
+ msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
+ info->scsi.phase = PHASE_MSGOUT_EXPECT;
}
/* Function: void fas216_send_command(FAS216_Info *info)
@@ -935,201 +1213,46 @@
outb(CMD_FLUSHFIFO, REG_CMD(info));
/* load command */
- for (i = 0; i < info->SCpnt->cmd_len; i++)
+ for (i = info->scsi.SCp.sent_command; i < info->SCpnt->cmd_len; i++)
outb(info->SCpnt->cmnd[i], REG_FF(info));
outb(CMD_TRANSFERINFO, REG_CMD(info));
-}
-
-/* Function: int fas216_busservice_selection(FAS216_Info *info, unsigned int stat)
- * Purpose : handle bus service in selection phase
- * Params : info - interface which caused bus service
- * Returns : 0 if unable to service this interrupt
- */
-static int fas216_busservice_selection(FAS216_Info *info, unsigned int stat)
-{
- fas216_checkmagic(info, "fas216_busservice_selection");
-
- switch (stat & STAT_BUSMASK) {
- case STAT_DATAOUT: /* data out phase */
- fas216_starttransfer(info, DMA_OUT, 1);
- return 1;
-
- case STAT_DATAIN: /* data in phase */
- fas216_starttransfer(info, DMA_IN, 0);
- return 1;
-
- case STAT_STATUS: /* status phase */
- info->scsi.phase = PHASE_STATUS;
- outb(CMD_INITCMDCOMPLETE, REG_CMD(info));
- return 1;
- case STAT_MESGIN: /* message in phase */
- info->scsi.phase = PHASE_MSGIN;
- outb(CMD_TRANSFERINFO, REG_CMD(info));
- return 1;
-
- case STAT_MESGOUT:{ /* message out phase */
- char *msg;
- int start = 1, msglen;
-
- /* load message bytes, but don't forget to miss the first
- * byte!
- */
- while ((msg = msgqueue_getnextmsg(&info->scsi.msgs, &msglen)) != NULL) {
- int i;
-
- for (i = start; i < msglen; i++)
- outb(msg[i], REG_FF(info));
- start = 0;
- }
- outb(CMD_TRANSFERINFO, REG_CMD(info));
- info->scsi.phase = PHASE_MESSAGESENT;
- return 1;
- }
- default:
- return 0;
- }
+ info->scsi.phase = PHASE_COMMAND;
}
-/* Function: int fas216_busservice_messagesent(FAS216_Info *info, unsigned int stat)
- * Purpose : handle bus service after the IDENTIFY message has been sent
- * Params : info - interface which caused bus service
- * Returns : 0 if unable to service this interrupt
- */
-static int fas216_busservice_messagesent(FAS216_Info *info, unsigned int stat)
-{
- fas216_checkmagic(info, "fas216_busservice_messagesent");
-
- switch (stat & STAT_BUSMASK) {
- case STAT_MESGIN: /* message in phase */
- info->scsi.phase = PHASE_MSGIN;
- outb(CMD_FLUSHFIFO, REG_CMD(info));
- outb(CMD_TRANSFERINFO, REG_CMD(info));
- return 1;
-
- case STAT_COMMAND: /* command phase */
- fas216_send_command(info);
- return 1;
-
- default:
- return 0;
- }
-}
-
-/* Function: int fas216_busservice_dataphase(FAS216_Info *info, unsigned int stat)
- * Purpose : handle bus service in a data in/out phase.
- * Params : info - interface which caused bus service
- * Returns : 0 if unable to service this interrupt
- * Note : We do not allow the device to change the data direction!
- */
-static int fas216_busservice_dataphase(FAS216_Info *info, unsigned int stat)
-{
- fas216_checkmagic(info, "fas216_busservice_dataphase");
-
- switch (stat & STAT_BUSMASK) {
- case STAT_DATAIN: /* continue data in phase */
- if (info->scsi.phase == PHASE_DATAIN) {
- fas216_starttransfer(info, DMA_IN, 0);
- return 1;
- } else
- return 0;
-
- case STAT_DATAOUT: /* continue data out phase */
- if (info->scsi.phase == PHASE_DATAOUT) {
- fas216_starttransfer(info, DMA_OUT, 0);
- return 1;
- } else
- return 0;
-
- case STAT_STATUS: /* status in phase */
- fas216_stoptransfer(info);
- info->scsi.phase = PHASE_STATUS;
- outb(CMD_INITCMDCOMPLETE, REG_CMD(info));
- return 1;
-
- case STAT_MESGIN: /* message in phase */
- fas216_stoptransfer(info);
- info->scsi.phase = PHASE_MSGIN;
- outb(CMD_TRANSFERINFO, REG_CMD(info));
- return 1;
-
- default:
- return 0;
- }
-}
-
-/* Function: int fas216_busservice_reconnected(FAS216_Info *info, unsigned int stat)
- * Purpose : handle bus service in after a reconnection
+/* Function: void fas216_send_messageout(FAS216_Info *info, int start)
+ * Purpose : handle bus service to send a message
* Params : info - interface which caused bus service
- * Returns : 0 if unable to service this interrupt
* Note : We do not allow the device to change the data direction!
*/
-static int fas216_busservice_reconnected(FAS216_Info *info, unsigned int stat)
+static void fas216_send_messageout(FAS216_Info *info, int start)
{
- fas216_checkmagic(info, "fas216_busservice_reconnected");
-
- switch (stat & STAT_BUSMASK) {
- case STAT_MESGIN:
- outb(CMD_TRANSFERINFO, REG_CMD(info));
- return 1;
+ unsigned int tot_msglen = msgqueue_msglength(&info->scsi.msgs);
- case STAT_STATUS:
- fas216_finish_reconnect(info);
- info->scsi.phase = PHASE_STATUS;
- outb(CMD_INITCMDCOMPLETE, REG_CMD(info));
- return 1;
-
- case STAT_DATAOUT: /* data out phase */
- fas216_finish_reconnect(info);
- fas216_starttransfer(info, DMA_OUT, 1);
- return 1;
+ fas216_checkmagic(info, "fas216_send_messageout");
- case STAT_DATAIN: /* data in phase */
- fas216_finish_reconnect(info);
- fas216_starttransfer(info, DMA_IN, 0);
- return 1;
+ outb(CMD_FLUSHFIFO, REG_CMD(info));
- default:
- return 0;
- }
-}
+ if (tot_msglen) {
+ struct message *msg;
+ int msgnr = 0;
-/* Function: int fas216_busservice_messageout(FAS216_Info *info, unsigned int stat)
- * Purpose : handle bus service to send a message
- * Params : info - interface which caused bus service
- * Returns : 0 if unable to service this interrupt
- * Note : We do not allow the device to change the data direction!
- */
-static int fas216_busservice_messageout(FAS216_Info *info, unsigned int stat)
-{
- fas216_checkmagic(info, "fas216_busservice_messageout");
-
- if ((stat & STAT_BUSMASK) != STAT_MESGOUT) {
- printk("scsi%d.%c: didn't manage MESSAGE OUT phase\n",
- info->host->host_no, fas216_target(info));
- return 0;
- } else {
- unsigned int msglen = msgqueue_msglength(&info->scsi.msgs);
+ while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
+ int i;
- outb(CMD_FLUSHFIFO, REG_CMD(info));
+ for (i = start; i < msg->length; i++)
+ outb(msg->msg[i], REG_FF(info));
- if (msglen == 0)
- outb(NOP, REG_FF(info));
- else {
- char *msg;
+ msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF);
+ start = 0;
+ }
+ } else
+ outb(NOP, REG_FF(info));
- while ((msg = msgqueue_getnextmsg(&info->scsi.msgs, &msglen)) != NULL) {
- int i;
+ outb(CMD_TRANSFERINFO, REG_CMD(info));
- for (i = 0; i < msglen; i++)
- outb(msg[i], REG_FF(info));
- }
- }
- outb(CMD_TRANSFERINFO, REG_CMD(info));
- info->scsi.phase = PHASE_AFTERMSGOUT;
- return 1;
- }
+ info->scsi.phase = PHASE_MSGOUT;
}
/* Function: void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
@@ -1151,91 +1274,150 @@
case IS_COMPLETE: /* last action completed */
outb(CMD_NOP, REG_CMD(info));
- switch (info->scsi.phase) {
- case PHASE_SELECTION: /* while selecting - selected target */
- if (!fas216_busservice_selection(info, stat))
- printk("scsi%d.%c: bus phase %s after connect?\n",
- info->host->host_no, fas216_target(info),
- fas216_bus_phase(stat));
- break;
-
- case PHASE_MESSAGESENT:
- if (!fas216_busservice_messagesent(info, stat))
- printk("scsi%d.%c: bus phase %s after message sent?\n",
- info->host->host_no, fas216_target(info),
- fas216_bus_phase(stat));
- break;
+#define STATE(st,ph) ((ph) << 3 | (st))
+ /* This table describes the legal SCSI state transitions,
+ * as described by the SCSI II spec.
+ */
+ switch (STATE(stat & STAT_BUSMASK, info->scsi.phase)) {
+ /* Reselmsgin -> Data In */
+ case STATE(STAT_DATAIN, PHASE_RECONNECTED):
+ fas216_finish_reconnect(info);
+ case STATE(STAT_DATAIN, PHASE_SELSTEPS):/* Sel w/ steps -> Data In */
+ case STATE(STAT_DATAIN, PHASE_DATAIN): /* Data In -> Data In */
+ case STATE(STAT_DATAIN, PHASE_MSGOUT): /* Message Out -> Data In */
+ case STATE(STAT_DATAIN, PHASE_COMMAND): /* Command -> Data In */
+ case STATE(STAT_DATAIN, PHASE_MSGIN): /* Message In -> Data In */
+ fas216_starttransfer(info, DMA_IN, 0);
+ return;
- case PHASE_DATAIN: /* while transfering data in */
- case PHASE_DATAOUT: /* while transfering data out */
- if (!fas216_busservice_dataphase(info, stat))
- printk("scsi%d.%c: bus phase %s after %s?\n",
- info->host->host_no, fas216_target(info),
- fas216_bus_phase(stat), fas216_drv_phase(info));
- break;
+ case STATE(STAT_DATAOUT, PHASE_DATAOUT):/* Data Out -> Data Out */
+ fas216_starttransfer(info, DMA_OUT, 0);
+ return;
- case PHASE_RECONNECTED: /* newly reconnected device */
- /*
- * Command reconnected - if MESGIN, get message - it may be
- * the tag. If not, get command out of the disconnected queue
- */
- if (!fas216_busservice_reconnected(info, stat))
- printk("scsi%d.%c: bus phase %s after reconnect?\n",
- info->host->host_no, fas216_target(info),
- fas216_bus_phase(stat));
- break;
+ /* Reselmsgin -> Data Out */
+ case STATE(STAT_DATAOUT, PHASE_RECONNECTED):
+ fas216_finish_reconnect(info);
+ case STATE(STAT_DATAOUT, PHASE_SELSTEPS):/* Sel w/ steps-> Data Out */
+ case STATE(STAT_DATAOUT, PHASE_MSGOUT): /* Message Out -> Data Out */
+ case STATE(STAT_DATAOUT, PHASE_COMMAND):/* Command -> Data Out */
+ case STATE(STAT_DATAOUT, PHASE_MSGIN): /* Message In -> Data Out */
+ fas216_starttransfer(info, DMA_OUT, 1);
+ return;
+
+ /* Reselmsgin -> Status */
+ case STATE(STAT_STATUS, PHASE_RECONNECTED):
+ fas216_finish_reconnect(info);
+ goto status;
+ case STATE(STAT_STATUS, PHASE_DATAOUT): /* Data Out -> Status */
+ case STATE(STAT_STATUS, PHASE_DATAIN): /* Data In -> Status */
+ fas216_stoptransfer(info);
+ case STATE(STAT_STATUS, PHASE_SELSTEPS):/* Sel w/ steps -> Status */
+ case STATE(STAT_STATUS, PHASE_MSGOUT): /* Message Out -> Status */
+ case STATE(STAT_STATUS, PHASE_COMMAND): /* Command -> Status */
+ case STATE(STAT_STATUS, PHASE_MSGIN): /* Message In -> Status */
+ status:
+ outb(CMD_INITCMDCOMPLETE, REG_CMD(info));
+ info->scsi.phase = PHASE_STATUS;
+ return;
+
+ case STATE(STAT_MESGIN, PHASE_DATAOUT): /* Data Out -> Message In */
+ case STATE(STAT_MESGIN, PHASE_DATAIN): /* Data In -> Message In */
+ fas216_stoptransfer(info);
+ case STATE(STAT_MESGIN, PHASE_SELSTEPS):/* Sel w/ steps -> Message In */
+ case STATE(STAT_MESGIN, PHASE_MSGOUT): /* Message Out -> Message In */
+ info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
+ outb(CMD_TRANSFERINFO, REG_CMD(info));
+ info->scsi.phase = PHASE_MSGIN;
+ return;
- case PHASE_MSGIN:
- case PHASE_AFTERMSGOUT:
- switch (stat & STAT_BUSMASK) {
- case STAT_MESGIN:
- info->scsi.phase = PHASE_MSGIN;
- outb(CMD_TRANSFERINFO, REG_CMD(info));
- break;
+ /* Reselmsgin -> Message In */
+ case STATE(STAT_MESGIN, PHASE_RECONNECTED):
+ case STATE(STAT_MESGIN, PHASE_MSGIN):
+ info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
+ outb(CMD_TRANSFERINFO, REG_CMD(info));
+ return;
- case STAT_COMMAND: /* command phase */
- fas216_send_command(info);
- info->scsi.phase = PHASE_SELECTION;
- break;
+ /* Reselmsgin -> Command */
+ case STATE(STAT_COMMAND, PHASE_RECONNECTED):
+ fas216_finish_reconnect(info);
+ case STATE(STAT_COMMAND, PHASE_MSGOUT): /* Message Out -> Command */
+ case STATE(STAT_COMMAND, PHASE_MSGIN): /* Message In -> Command */
+ fas216_send_command(info);
+ info->scsi.phase = PHASE_COMMAND;
+ return;
+ /* Selection -> Message Out */
+ case STATE(STAT_MESGOUT, PHASE_SELECTION):
+ fas216_send_messageout(info, 1);
+ return;
+ /* Any -> Message Out */
+ case STATE(STAT_MESGOUT, PHASE_MSGOUT_EXPECT):
+ fas216_send_messageout(info, 0);
+ return;
+
+ /* Error recovery rules.
+ * These either attempt to abort or retry the operation.
+ * TODO: we need more of these
+ */
+ case STATE(STAT_COMMAND, PHASE_COMMAND):/* Command -> Command */
+ /* error - we've sent out all the command bytes
+ * we have.
+ * NOTE: we need SAVE DATA POINTERS/RESTORE DATA POINTERS
+ * to include the command bytes sent for this to work
+ * correctly.
+ */
+ printk(KERN_ERR "scsi%d.%c: "
+ "target trying to receive more command bytes\n",
+ info->host->host_no, fas216_target(info));
+ outb(CMD_SETATN, REG_CMD(info));
+ outb(15, REG_STCL(info));
+ outb(0, REG_STCM(info));
+ outb(0, REG_STCH(info));
+ outb(CMD_PADBYTES | CMD_WITHDMA, REG_CMD(info));
+ msgqueue_flush(&info->scsi.msgs);
+ msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
+ info->scsi.phase = PHASE_MSGOUT_EXPECT;
+ return;
- default:
- printk("scsi%d.%c: bus phase %s after %s?\n",
- info->host->host_no, fas216_target(info),
- fas216_bus_phase(stat),
- fas216_drv_phase(info));
- }
- break;
+ /* Selection -> Message Out */
+ case STATE(STAT_MESGOUT, PHASE_SELSTEPS):
+ case STATE(STAT_MESGOUT, PHASE_MSGOUT): /* Message Out -> Message Out */
+ /* If we get another message out phase, this
+ * usually means some parity error occurred.
+ * Resend complete set of messages. If we have
+ * more than 1 byte to send, we need to assert
+ * ATN again.
+ */
+ if (msgqueue_msglength(&info->scsi.msgs) > 1)
+ outb(CMD_SETATN, REG_CMD(info));
- case PHASE_MSGOUT:
- if (!fas216_busservice_messageout(info, stat))
- printk("scsi%d.%c: bus phase %s instead of message out?\n",
- info->host->host_no, fas216_target(info),
- fas216_bus_phase(stat));
- break;
+ fas216_send_messageout(info, 0);
+ return;
+ }
- case PHASE_DISCONNECT:
- printk("scsi%d.%c: disconnect message received, but bus service %s?\n",
+ if (info->scsi.phase == PHASE_MSGIN_DISCONNECT) {
+ printk(KERN_ERR "scsi%d.%c: disconnect message received, but bus service %s?\n",
info->host->host_no, fas216_target(info),
fas216_bus_phase(stat));
+ msgqueue_flush(&info->scsi.msgs);
outb(CMD_SETATN, REG_CMD(info));
msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
- info->scsi.phase = PHASE_MSGOUT;
+ info->scsi.phase = PHASE_MSGOUT_EXPECT;
info->scsi.aborting = 1;
outb(CMD_TRANSFERINFO, REG_CMD(info));
- break;
-
- default:
- printk("scsi%d.%c: internal phase %s for bus service?"
- " What do I do with this?\n",
- info->host->host_no, fas216_target(info),
- fas216_drv_phase(info));
+ return;
}
- break;
+ printk(KERN_ERR "scsi%d.%c: bus phase %s after %s?\n",
+ info->host->host_no, fas216_target(info),
+ fas216_bus_phase(stat),
+ fas216_drv_phase(info));
+ print_debug_list();
+ return;
default:
printk("scsi%d.%c: bus service at step %d?\n",
info->host->host_no, fas216_target(info),
ssr & IS_BITS);
+ print_debug_list();
}
}
@@ -1269,6 +1451,7 @@
case PHASE_MSGIN: /* message in phase */
case PHASE_RECONNECTED: /* reconnected command */
if ((stat & STAT_BUSMASK) == STAT_MESGIN) {
+ info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
fas216_message(info);
break;
}
@@ -1300,10 +1483,11 @@
if (stat & STAT_INT) {
if (isr & INST_BUSRESET)
- printk("scsi%d.H: fas216: bus reset detected\n", instance->host_no);
- else if (isr & INST_ILLEGALCMD)
+ printk("scsi%d.H: bus reset detected\n", instance->host_no);
+ else if (isr & INST_ILLEGALCMD) {
printk(KERN_CRIT "scsi%d.H: illegal command given\n", instance->host_no);
- else if (isr & INST_DISCONNECT)
+ fas216_dumpstate(info);
+ } else if (isr & INST_DISCONNECT)
fas216_disconnect_intr(info);
else if (isr & INST_RESELECTED) /* reselected */
fas216_reselected_intr(info);
@@ -1327,7 +1511,7 @@
static void fas216_kick(FAS216_Info *info)
{
Scsi_Cmnd *SCpnt;
- int i, msglen, from_queue = 0;
+ int tot_msglen, from_queue = 0;
fas216_checkmagic(info, "fas216_kick");
@@ -1380,7 +1564,8 @@
if (from_queue) {
#ifdef SCSI2_TAG
- if (SCpnt->device->tagged_queue && SCpnt->cmnd[0] != REQUEST_SENSE) {
+ if (SCpnt->device->tagged_queue && SCpnt->cmnd[0] != REQUEST_SENSE &&
+ SCpnt->cmnd[0] != INQUIRY) {
SCpnt->device->current_tag += 1;
if (SCpnt->device->current_tag == 0)
SCpnt->device->current_tag = 1;
@@ -1409,6 +1594,7 @@
/* build outgoing message bytes */
msgqueue_flush(&info->scsi.msgs);
+
if (info->device[SCpnt->target].disconnect_ok)
msgqueue_addmsg(&info->scsi.msgs, 1, IDENTIFY(1, SCpnt->lun));
else
@@ -1418,15 +1604,29 @@
if (SCpnt->tag)
msgqueue_addmsg(&info->scsi.msgs, 2, SIMPLE_QUEUE_TAG, SCpnt->tag);
- /* add synchronous negociation */
- if (SCpnt->cmnd[0] == REQUEST_SENSE &&
- info->device[SCpnt->target].negstate == syncneg_start) {
- info->device[SCpnt->target].negstate = syncneg_sent;
+#ifdef SCSI2_WIDE
+ if (info->device[SCpnt->target].wide_state == neg_wait) {
+ info->device[SCpnt->target].wide_state = neg_inprogress;
+ msgqueue_addmsg(&info->scsi.msgs, 4,
+ EXTENDED_MESSAGE, 2, EXTENDED_WDTR,
+ info->ifcfg.wide_max_size);
+ }
+#ifdef SCSI2_SYNC
+ else
+#endif
+#endif
+#ifdef SCSI2_SYNC
+ if ((info->device[SCpnt->target].sync_state == neg_wait ||
+ info->device[SCpnt->target].sync_state == neg_complete) &&
+ (SCpnt->cmnd[0] == REQUEST_SENSE ||
+ SCpnt->cmnd[0] == INQUIRY)) {
+ info->device[SCpnt->target].sync_state = neg_inprogress;
msgqueue_addmsg(&info->scsi.msgs, 5,
EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
1000 / info->ifcfg.clockrate,
info->ifcfg.sync_max_depth);
}
+#endif
/* following what the ESP driver says */
outb(0, REG_STCL(info));
@@ -1444,25 +1644,29 @@
/* synchronous transfers */
fas216_set_sync(info, SCpnt->target);
- msglen = msgqueue_msglength(&info->scsi.msgs);
+ tot_msglen = msgqueue_msglength(&info->scsi.msgs);
- if (msglen == 1 || msglen == 3) {
+ if (tot_msglen == 1 || tot_msglen == 3) {
/*
* We have an easy message length to send...
*/
- char *msg;
+ struct message *msg;
+ int msgnr = 0, i;
+
+ info->scsi.phase = PHASE_SELSTEPS;
/* load message bytes */
- while ((msg = msgqueue_getnextmsg(&info->scsi.msgs, &msglen)) != NULL) {
- for (i = 0; i < msglen; i++)
- outb(msg[i], REG_FF(info));
+ while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
+ for (i = 0; i < msg->length; i++)
+ outb(msg->msg[i], REG_FF(info));
+ msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF);
}
/* load command */
for (i = 0; i < SCpnt->cmd_len; i++)
outb(SCpnt->cmnd[i], REG_FF(info));
- if (msglen == 1)
+ if (tot_msglen == 1)
outb(CMD_SELECTATN, REG_CMD(info));
else
outb(CMD_SELECTATN3, REG_CMD(info));
@@ -1471,17 +1675,11 @@
* We have an unusual number of message bytes to send.
* Load first byte into fifo, and issue SELECT with ATN and
* stop steps.
- * Note: we only peek at t his message - we need the rest
- * later on!
*/
- int thismsg;
- char *msg = msgqueue_peeknextmsg(&info->scsi.msgs, &thismsg);
+ struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0);
- if (!msg || thismsg < 1)
- printk(KERN_CRIT "scsi%d.%c: no message to send, but %d bytes\n",
- info->host->host_no, fas216_target(info), msglen);
- else
- outb(msg[0], REG_FF(info));
+ outb(msg->msg[0], REG_FF(info));
+ msg->fifo = 1;
outb(CMD_SELECTATNSTOP, REG_CMD(info));
}
@@ -1525,11 +1723,15 @@
/*
* In theory, this should not happen, but just in case it does.
*/
- if (info->scsi.SCp.ptr && result == DID_OK) {
+ if (info->scsi.SCp.ptr &&
+ info->scsi.SCp.this_residual &&
+ result == DID_OK) {
switch (SCpnt->cmnd[0]) {
case INQUIRY:
case START_STOP:
case READ_CAPACITY:
+ case TEST_UNIT_READY:
+ case MODE_SENSE:
break;
default:
@@ -1819,7 +2021,7 @@
*/
static void fas216_reset_state(FAS216_Info *info)
{
- syncneg_t negstate;
+ neg_t sync_state, wide_state;
int i;
fas216_checkmagic(info, "fas216_reset_state");
@@ -1833,26 +2035,37 @@
info->scsi.reconnected.lun = 0;
info->scsi.reconnected.tag = 0;
info->scsi.disconnectable = 0;
- info->scsi.last_message = 0;
info->scsi.aborting = 0;
info->scsi.phase = PHASE_IDLE;
- info->scsi.async_stp = fas216_syncperiod(info, info->ifcfg.asyncperiod);
+ info->scsi.async_stp =
+ fas216_syncperiod(info, info->ifcfg.asyncperiod);
+
+ if (info->ifcfg.wide_max_size == 0)
+ wide_state = neg_invalid;
+ else
+#ifdef SCSI2_WIDE
+ wide_state = neg_wait;
+#else
+ wide_state = neg_invalid;
+#endif
if (info->host->dma_channel == NO_DMA || !info->dma.setup)
- negstate = syncneg_invalid;
+ sync_state = neg_invalid;
else
#ifdef SCSI2_SYNC
- negstate = syncneg_start;
+ sync_state = neg_wait;
#else
- negstate = syncneg_invalid;
+ sync_state = neg_invalid;
#endif
for (i = 0; i < 8; i++) {
- info->device[i].disconnect_ok = info->ifcfg.disconnect_ok;
- info->device[i].negstate = negstate;
- info->device[i].period = info->ifcfg.asyncperiod / 4;
- info->device[i].stp = info->scsi.async_stp;
- info->device[i].sof = 0;
+ info->device[i].disconnect_ok = info->ifcfg.disconnect_ok;
+ info->device[i].sync_state = sync_state;
+ info->device[i].wide_state = wide_state;
+ info->device[i].period = info->ifcfg.asyncperiod / 4;
+ info->device[i].stp = info->scsi.async_stp;
+ info->device[i].sof = 0;
+ info->device[i].wide_xfer = 0;
}
}
@@ -2083,6 +2296,49 @@
return 0;
}
+int fas216_print_stats(FAS216_Info *info, char *buffer)
+{
+ return sprintf(buffer,
+ "Queued commands: %-10u Issued commands: %-10u\n"
+ "Done commands : %-10u Reads : %-10u\n"
+ "Writes : %-10u Others : %-10u\n"
+ "Disconnects : %-10u Aborts : %-10u\n"
+ "Resets : %-10u\n",
+ info->stats.queues, info->stats.removes,
+ info->stats.fins, info->stats.reads,
+ info->stats.writes, info->stats.miscs,
+ info->stats.disconnects, info->stats.aborts,
+ info->stats.resets);
+}
+
+int fas216_print_device(FAS216_Info *info, Scsi_Device *scd, char *buffer)
+{
+ struct fas216_device *dev = &info->device[scd->id];
+ int len = 0;
+ char *p;
+
+ proc_print_scsidevice(scd, buffer, &len, 0);
+ p = buffer + len;
+
+ p += sprintf(p, " Extensions: ");
+
+ if (scd->tagged_supported)
+ p += sprintf(p, "TAG %sabled [%d] ",
+ scd->tagged_queue ? "en" : "dis",
+ scd->current_tag);
+
+ p += sprintf(p, "\n Transfers : %d-bit ",
+ 8 << dev->wide_xfer);
+
+ if (dev->sof)
+ p += sprintf(p, "sync offset %d, %d ns\n",
+ dev->sof, dev->period * 4);
+ else
+ p += sprintf(p, "async\n");
+
+ return p - buffer;
+}
+
EXPORT_SYMBOL(fas216_init);
EXPORT_SYMBOL(fas216_abort);
EXPORT_SYMBOL(fas216_reset);
@@ -2094,7 +2350,8 @@
EXPORT_SYMBOL(fas216_eh_device_reset);
EXPORT_SYMBOL(fas216_eh_bus_reset);
EXPORT_SYMBOL(fas216_eh_host_reset);
-
+EXPORT_SYMBOL(fas216_print_stats);
+EXPORT_SYMBOL(fas216_print_device);
#ifdef MODULE
int init_module(void)
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/scsi/fas216.h linux.ac/drivers/acorn/scsi/fas216.h
--- linux.vanilla/drivers/acorn/scsi/fas216.h Sun Nov 8 15:08:19 1998
+++ linux.ac/drivers/acorn/scsi/fas216.h Sun Jan 24 23:54:37 1999
@@ -40,6 +40,7 @@
#define CMD_TRANSFERINFO 0x10
#define CMD_INITCMDCOMPLETE 0x11
#define CMD_MSGACCEPTED 0x12
+#define CMD_PADBYTES 0x18
#define CMD_SETATN 0x1a
#define CMD_RSETATN 0x1b
@@ -171,15 +172,17 @@
typedef enum {
PHASE_IDLE, /* we're not planning on doing anything */
PHASE_SELECTION, /* selecting a device */
+ PHASE_SELSTEPS, /* selection with command steps */
+ PHASE_COMMAND, /* command sent */
PHASE_MESSAGESENT, /* selected, and we're sending cmd */
PHASE_RECONNECTED, /* reconnected */
PHASE_DATAOUT, /* data out to device */
PHASE_DATAIN, /* data in from device */
PHASE_MSGIN, /* message in from device */
- PHASE_MSGOUT, /* message out to device */
- PHASE_AFTERMSGOUT, /* after message out phase */
+ PHASE_MSGIN_DISCONNECT, /* disconnecting from bus */
+ PHASE_MSGOUT, /* after message out phase */
+ PHASE_MSGOUT_EXPECT, /* expecting message out */
PHASE_STATUS, /* status from device */
- PHASE_DISCONNECT, /* disconnecting from bus */
PHASE_DONE /* Command complete */
} phase_t;
@@ -197,13 +200,15 @@
} fasdmatype_t;
typedef enum {
- syncneg_start, /* Negociate with device for Sync xfers */
- syncneg_sent, /* Sync Xfer negociation sent */
- syncneg_complete, /* Sync Xfer complete */
- syncneg_invalid /* Sync Xfer not supported */
-} syncneg_t;
+ neg_wait, /* Negociate with device */
+ neg_inprogress, /* Negociation sent */
+ neg_complete, /* Negociation complete */
+ neg_targcomplete, /* Target completed negociation */
+ neg_invalid /* Negociation not supported */
+} neg_t;
#define MAGIC 0x441296bdUL
+#define NR_MSGS 8
typedef struct {
unsigned long magic_start;
@@ -231,7 +236,7 @@
MsgQueue_t msgs; /* message queue for connected device */
unsigned int async_stp; /* Async transfer STP value */
- unsigned short last_message; /* last message to be sent */
+ unsigned char msgin_fifo; /* bytes in fifo at time of message in */
unsigned char disconnectable:1; /* this command can be disconnected */
unsigned char aborting:1; /* aborting command */
@@ -255,6 +260,7 @@
unsigned char clockrate; /* clock rate of FAS device (MHz) */
unsigned char select_timeout; /* timeout (R5) */
unsigned char sync_max_depth; /* Synchronous xfer max fifo depth */
+ unsigned char wide_max_size; /* Maximum wide transfer size */
unsigned char cntl3; /* Control Reg 3 */
unsigned int asyncperiod; /* Async transfer period (ns) */
unsigned int disconnect_ok:1; /* Disconnects allowed? */
@@ -267,12 +273,14 @@
} queues;
/* per-device info */
- struct {
+ struct fas216_device {
unsigned char disconnect_ok:1; /* device can disconnect */
- unsigned int period; /* sync xfer period (*4ns) */
+ unsigned char period; /* sync xfer period in (*4ns) */
unsigned char stp; /* synchronous transfer period */
unsigned char sof; /* synchronous offset register */
- syncneg_t negstate; /* synchronous transfer mode */
+ unsigned char wide_xfer; /* currently negociated wide transfer */
+ neg_t sync_state; /* synchronous transfer mode */
+ neg_t wide_state; /* wide transfer mode */
} device[8];
unsigned char busyluns[8]; /* array of bits indicating LUNs busy */
@@ -339,6 +347,9 @@
* Returns : 0 on success
*/
extern int fas216_release (struct Scsi_Host *instance);
+
+extern int fas216_print_stats(FAS216_Info *info, char *buffer);
+extern int fas216_print_device(FAS216_Info *info, Scsi_Device *scd, char *buffer);
/* Function: int fas216_eh_abort(Scsi_Cmnd *SCpnt)
* Purpose : abort this command
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/scsi/msgqueue.c linux.ac/drivers/acorn/scsi/msgqueue.c
--- linux.vanilla/drivers/acorn/scsi/msgqueue.c Sun Nov 8 15:08:19 1998
+++ linux.ac/drivers/acorn/scsi/msgqueue.c Sun Jan 24 23:54:37 1999
@@ -83,45 +83,25 @@
int length = 0;
for (mq = msgq->qe; mq; mq = mq->next)
- length += mq->length;
+ length += mq->msg.length;
return length;
}
/*
- * Function: char *msgqueue_getnextmsg(MsgQueue_t *msgq, int *length)
- * Purpose : return a message & its length
+ * Function: struct message *msgqueue_getmsg(MsgQueue_t *msgq, int msgno)
+ * Purpose : return a message
* Params : msgq - queue to obtain message from
- * length - pointer to int for message length
+ * : msgno - message number
* Returns : pointer to message string, or NULL
*/
-char *msgqueue_getnextmsg(MsgQueue_t *msgq, int *length)
+struct message *msgqueue_getmsg(MsgQueue_t *msgq, int msgno)
{
struct msgqueue_entry *mq;
- if ((mq = msgq->qe) != NULL) {
- msgq->qe = mq->next;
- mqe_free(msgq, mq);
- *length = mq->length;
- }
-
- return mq ? mq->msg : NULL;
-}
-
-/*
- * Function: char *msgqueue_peeknextmsg(MsgQueue_t *msgq, int *length)
- * Purpose : return next message & length without removing it from the list
- * Params : msgq - queue to obtain message from
- * : length - pointer to int for message length
- * Returns : pointer to message string, or NULL
- */
-char *msgqueue_peeknextmsg(MsgQueue_t *msgq, int *length)
-{
- struct msgqueue_entry *mq = msgq->qe;
-
- *length = mq ? mq->length : 0;
+ for (mq = msgq->qe; mq && msgno; mq = mq->next, msgno--);
- return mq ? mq->msg : NULL;
+ return mq ? &mq->msg : NULL;
}
/*
@@ -143,10 +123,11 @@
va_start(ap, length);
for (i = 0; i < length; i++)
- mq->msg[i] = va_arg(ap, unsigned char);
+ mq->msg.msg[i] = va_arg(ap, unsigned char);
va_end(ap);
- mq->length = length;
+ mq->msg.length = length;
+ mq->msg.fifo = 0;
mq->next = NULL;
mqp = &msgq->qe;
@@ -178,8 +159,7 @@
EXPORT_SYMBOL(msgqueue_initialise);
EXPORT_SYMBOL(msgqueue_free);
EXPORT_SYMBOL(msgqueue_msglength);
-EXPORT_SYMBOL(msgqueue_getnextmsg);
-EXPORT_SYMBOL(msgqueue_peeknextmsg);
+EXPORT_SYMBOL(msgqueue_getmsg);
EXPORT_SYMBOL(msgqueue_addmsg);
EXPORT_SYMBOL(msgqueue_flush);
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/scsi/msgqueue.h linux.ac/drivers/acorn/scsi/msgqueue.h
--- linux.vanilla/drivers/acorn/scsi/msgqueue.h Sun Nov 8 15:08:19 1998
+++ linux.ac/drivers/acorn/scsi/msgqueue.h Sun Jan 24 23:54:37 1999
@@ -6,9 +6,14 @@
#ifndef MSGQUEUE_H
#define MSGQUEUE_H
-struct msgqueue_entry {
+struct message {
char msg[8];
int length;
+ int fifo;
+};
+
+struct msgqueue_entry {
+ struct message msg;
struct msgqueue_entry *next;
};
@@ -21,60 +26,51 @@
} MsgQueue_t;
/*
- * Function: void msgqueue_initialise (MsgQueue_t *msgq)
+ * Function: void msgqueue_initialise(MsgQueue_t *msgq)
* Purpose : initialise a message queue
* Params : msgq - queue to initialise
*/
-extern void msgqueue_initialise (MsgQueue_t *msgq);
+extern void msgqueue_initialise(MsgQueue_t *msgq);
/*
- * Function: void msgqueue_free (MsgQueue_t *msgq)
+ * Function: void msgqueue_free(MsgQueue_t *msgq)
* Purpose : free a queue
* Params : msgq - queue to free
*/
-extern void msgqueue_free (MsgQueue_t *msgq);
+extern void msgqueue_free(MsgQueue_t *msgq);
/*
- * Function: int msgqueue_msglength (MsgQueue_t *msgq)
+ * Function: int msgqueue_msglength(MsgQueue_t *msgq)
* Purpose : calculate the total length of all messages on the message queue
* Params : msgq - queue to examine
* Returns : number of bytes of messages in queue
*/
-extern int msgqueue_msglength (MsgQueue_t *msgq);
+extern int msgqueue_msglength(MsgQueue_t *msgq);
/*
- * Function: char *msgqueue_getnextmsg (MsgQueue_t *msgq, int *length)
+ * Function: struct message *msgqueue_getmsg(MsgQueue_t *msgq, int msgno)
* Purpose : return a message & its length
* Params : msgq - queue to obtain message from
- * length - pointer to int for message length
- * Returns : pointer to message string, or NULL
- */
-extern char *msgqueue_getnextmsg (MsgQueue_t *msgq, int *length);
-
-/*
- * Function: char *msgqueue_peeknextmsg(MsgQueue_t *msgq, int *length)
- * Purpose : return next message & length without removing it from the list
- * Params : msgq - queue to obtain message from
- * : length - pointer to int for message length
+ * : msgno - message number
* Returns : pointer to message string, or NULL
*/
-extern char *msgqueue_peeknextmsg(MsgQueue_t *msgq, int *length);
+extern struct message *msgqueue_getmsg(MsgQueue_t *msgq, int msgno);
/*
- * Function: int msgqueue_addmsg (MsgQueue_t *msgq, int length, ...)
+ * Function: int msgqueue_addmsg(MsgQueue_t *msgq, int length, ...)
* Purpose : add a message onto a message queue
* Params : msgq - queue to add message on
* length - length of message
* ... - message bytes
* Returns : != 0 if successful
*/
-extern int msgqueue_addmsg (MsgQueue_t *msgq, int length, ...);
+extern int msgqueue_addmsg(MsgQueue_t *msgq, int length, ...);
/*
- * Function: void msgqueue_flush (MsgQueue_t *msgq)
+ * Function: void msgqueue_flush(MsgQueue_t *msgq)
* Purpose : flush all messages from message queue
* Params : msgq - queue to flush
*/
-extern void msgqueue_flush (MsgQueue_t *msgq);
+extern void msgqueue_flush(MsgQueue_t *msgq);
#endif
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/scsi/powertec.c linux.ac/drivers/acorn/scsi/powertec.c
--- linux.vanilla/drivers/acorn/scsi/powertec.c Tue Dec 22 23:19:35 1998
+++ linux.ac/drivers/acorn/scsi/powertec.c Sun Jan 24 23:54:37 1999
@@ -114,6 +114,8 @@
powertecscsi_irqenable,
powertecscsi_irqdisable,
NULL,
+ NULL,
+ NULL,
NULL
};
@@ -271,8 +273,9 @@
info->info.ifcfg.select_timeout = 255;
info->info.ifcfg.asyncperiod = POWERTEC_ASYNC_PERIOD;
info->info.ifcfg.sync_max_depth = POWERTEC_SYNC_DEPTH;
- info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
+ info->info.ifcfg.cntl3 = /*CNTL3_BS8 |*/ CNTL3_FASTSCSI | CNTL3_FASTCLK;
info->info.ifcfg.disconnect_ok = 1;
+ info->info.ifcfg.wide_max_size = 0;
info->info.dma.setup = powertecscsi_dma_setup;
info->info.dma.pseudo = NULL;
info->info.dma.stop = powertecscsi_dma_stop;
@@ -443,31 +446,12 @@
host->io_port, host->irq, host->dma_channel,
info->info.scsi.type, info->control.terms ? "on" : "off");
- pos += sprintf(buffer+pos,
- "Queued commands: %-10u Issued commands: %-10u\n"
- "Done commands : %-10u Reads : %-10u\n"
- "Writes : %-10u Others : %-10u\n"
- "Disconnects : %-10u Aborts : %-10u\n"
- "Resets : %-10u\n",
- info->info.stats.queues, info->info.stats.removes,
- info->info.stats.fins, info->info.stats.reads,
- info->info.stats.writes, info->info.stats.miscs,
- info->info.stats.disconnects, info->info.stats.aborts,
- info->info.stats.resets);
+ pos += fas216_print_stats(&info->info, buffer + pos);
- pos += sprintf (buffer+pos, "\nAttached devices:%s\n", host->host_queue ? "" : " none");
+ pos += sprintf (buffer+pos, "\nAttached devices:\n");
for (scd = host->host_queue; scd; scd = scd->next) {
- int len;
-
- proc_print_scsidevice (scd, buffer, &len, pos);
- pos += len;
- pos += sprintf (buffer+pos, "Extensions: ");
- if (scd->tagged_supported)
- pos += sprintf (buffer+pos, "TAG %sabled [%d] ",
- scd->tagged_queue ? "en" : "dis",
- scd->current_tag);
- pos += sprintf (buffer+pos, "\n");
+ pos += fas216_print_device(&info->info, scd, buffer + pos);
if (pos + begin < offset) {
begin += pos;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/acorn/scsi/queue.c linux.ac/drivers/acorn/scsi/queue.c
--- linux.vanilla/drivers/acorn/scsi/queue.c Sun Nov 8 15:08:19 1998
+++ linux.ac/drivers/acorn/scsi/queue.c Sun Jan 24 23:54:37 1999
@@ -55,6 +55,7 @@
q->magic = QUEUE_MAGIC_FREE;
q->SCpnt = NULL;
}
+ q -= 1;
q->next = NULL;
}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/block/genhd.c linux.ac/drivers/block/genhd.c
--- linux.vanilla/drivers/block/genhd.c Thu Jan 14 01:25:21 1999
+++ linux.ac/drivers/block/genhd.c Tue Jan 26 23:52:31 1999
@@ -130,6 +130,14 @@
SYS_IND(p) == LINUX_EXTENDED_PARTITION);
}
+static int sec_fac(kdev_t dev) /* JSt */
+{
+ if (hardsect_size[MAJOR(dev)] != NULL)
+ return (hardsect_size[MAJOR(dev)][MINOR(dev)]/512);
+ else
+ return (1);
+}
+
static unsigned int get_ptable_blocksize(kdev_t dev)
{
int ret = 1024;
@@ -149,6 +157,7 @@
* the natural blocksize for the device so that we don't have to try
* and read partial sectors. Anything smaller should be just fine.
*/
+
switch( blksize_size[MAJOR(dev)][MINOR(dev)] )
{
case 2048:
@@ -196,6 +205,7 @@
struct partition *p;
unsigned long first_sector, first_size, this_sector, this_size;
int mask = (1 << hd->minor_shift) - 1;
+ int sector_size = sec_fac(dev);
int i;
first_sector = hd->part[MINOR(dev)].start_sect;
@@ -245,7 +255,7 @@
first_sector + first_size))
continue;
- add_partition(hd, current_minor, this_sector+START_SECT(p), NR_SECTS(p));
+ add_partition(hd, current_minor, this_sector+START_SECT(p)*sector_size, NR_SECTS(p)*sector_size);
current_minor++;
if ((current_minor & mask) == 0)
goto done;
@@ -267,9 +277,9 @@
if (i == 4)
goto done; /* nothing left to do */
- hd->part[current_minor].nr_sects = NR_SECTS(p);
- hd->part[current_minor].start_sect = first_sector + START_SECT(p);
- this_sector = first_sector + START_SECT(p);
+ hd->part[current_minor].nr_sects = NR_SECTS(p) * sector_size; /* JSt */
+ hd->part[current_minor].start_sect = first_sector + START_SECT(p) * sector_size;
+ this_sector = first_sector + START_SECT(p) * sector_size;
dev = MKDEV(hd->major, current_minor);
brelse(bh);
}
@@ -317,11 +327,13 @@
#endif
#ifdef CONFIG_BSD_DISKLABEL
-static void check_and_add_bsd_partition(struct gendisk *hd, struct bsd_partition *bsd_p)
+static void check_and_add_bsd_partition(struct gendisk *hd,
+ struct bsd_partition *bsd_p, kdev_t dev)
{
struct hd_struct *lin_p;
/* check relative position of partitions. */
- for (lin_p = hd->part + 1; lin_p - hd->part < current_minor; lin_p++) {
+ for (lin_p = hd->part + 1 + MINOR(dev);
+ lin_p - hd->part - MINOR(dev) < current_minor; lin_p++) {
/* no relationship -> try again */
if (lin_p->start_sect + lin_p->nr_sects <= bsd_p->p_offset
|| lin_p->start_sect >= bsd_p->p_offset + bsd_p->p_size)
@@ -383,7 +395,7 @@
break;
if (p->p_fstype != BSD_FS_UNUSED)
- check_and_add_bsd_partition(hd, p);
+ check_and_add_bsd_partition(hd, p, dev);
}
brelse(bh);
@@ -436,6 +448,7 @@
struct partition *p;
unsigned char *data;
int mask = (1 << hd->minor_shift) - 1;
+ int sector_size = sec_fac(dev);
#ifdef CONFIG_BSD_DISKLABEL
/* no bsd disklabel as a default */
kdev_t bsd_kdev = 0;
@@ -538,7 +551,7 @@
for (i=1 ; i<=4 ; minor++,i++,p++) {
if (!NR_SECTS(p))
continue;
- add_partition(hd, minor, first_sector+START_SECT(p), NR_SECTS(p));
+ add_partition(hd, minor, first_sector+START_SECT(p)*sector_size, NR_SECTS(p)*sector_size);
if (is_extended_partition(p)) {
printk(" <");
/*
@@ -790,7 +803,7 @@
struct sgi_partition *p;
#define SGI_LABEL_MAGIC 0x0be5a941
- if(!(bh = bread(dev, 0, 1024))) {
+ if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) {
printk("Dev %s: unable to read partition table\n", kdevname(dev));
return -1;
}
@@ -854,11 +867,18 @@
int blk;
int part, res;
+ /*
+ * Don't bother touching M/O 2K media.
+ */
+
+ if (get_ptable_blocksize(dev) != 1024)
+ return 0;
+
set_blocksize(dev,512);
res = 0;
for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
- if(!(bh = bread(dev,blk,512))) {
+ if(!(bh = bread(dev,blk,get_ptable_blocksize(dev)))) {
printk("Dev %s: unable to read RDB block %d\n",
kdevname(dev),blk);
goto rdb_done;
@@ -875,7 +895,7 @@
blk = htonl(rdb->rdb_PartitionList);
brelse(bh);
for (part = 1; blk > 0 && part <= 16; part++) {
- if (!(bh = bread(dev,blk,512))) {
+ if (!(bh = bread(dev,blk, get_ptable_blocksize(dev)))) {
printk("Dev %s: unable to read partition block %d\n",
kdevname(dev),blk);
goto rdb_done;
@@ -908,6 +928,10 @@
}
rdb_done:
+ /*
+ * FIXME: should restore the original size. Then we could clean
+ * up the M/O skip. Amiga people ?
+ */
set_blocksize(dev,BLOCK_SIZE);
return res;
}
@@ -1089,7 +1113,7 @@
partsect = extensect = pi->st;
while (1)
{
- xbh = bread (dev, partsect / 2, 1024);
+ xbh = bread (dev, partsect / 2, get_ptable_blocksize(dev));
if (!xbh)
{
printk (" block %ld read failed\n", partsect);
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/char/Makefile linux.ac/drivers/char/Makefile
--- linux.vanilla/drivers/char/Makefile Mon Dec 28 23:09:42 1998
+++ linux.ac/drivers/char/Makefile Thu Jan 14 06:27:08 1999
@@ -44,12 +44,17 @@
ifdef CONFIG_VT
L_OBJS += keyboard.o
endif
-ifneq ($(ARCH),m68k)
-L_OBJS += pc_keyb.o defkeymap.o
+ ifneq ($(ARCH),m68k)
+ L_OBJS += pc_keyb.o defkeymap.o
+ endif
+else
+ifdef CONFIG_PCI
+L_OBJS += defkeymap.o keyboard.o
endif
-ifdef CONFIG_MAGIC_SYSRQ
-L_OBJS += sysrq.o
endif
+
+ifdef CONFIG_MAGIC_SYSRQ
+LX_OBJS += sysrq.o
endif
ifeq ($(CONFIG_ATARI_DSP56K),y)
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/char/bttv.c linux.ac/drivers/char/bttv.c
--- linux.vanilla/drivers/char/bttv.c Tue Jan 26 09:44:20 1999
+++ linux.ac/drivers/char/bttv.c Wed Jan 27 00:23:07 1999
@@ -2907,8 +2907,8 @@
}
if(btv->type==BTTV_AVERMEDIA98)
{
- btv->pll.pll_ifreq=28636363;
- btv->pll.pll_crystal=BT848_IFORM_XT0;
+ btv->pll.pll_ifreq=28636363;
+ btv->pll.pll_crystal=BT848_IFORM_XT0;
}
if (btv->have_tuner && btv->tuner_type != -1)
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/char/bw-qcam.c linux.ac/drivers/char/bw-qcam.c
--- linux.vanilla/drivers/char/bw-qcam.c Sun Nov 8 15:10:11 1998
+++ linux.ac/drivers/char/bw-qcam.c Sun Jan 24 21:15:01 1999
@@ -5,6 +5,28 @@
*
* Video4Linux conversion work by Alan Cox.
* Parport compatibility by Phil Blundell.
+ * Busy loop avoidance by Mark Cooke.
+ *
+ * Module parameters:
+ *
+ * maxpoll=<1 - 5000>
+ *
+ * When polling the QuickCam for a response, busy-wait for a
+ * maximum of this many loops. The default of 250 gives little
+ * impact on interactive response.
+ *
+ * NOTE: If this parameter is set too high, the processor
+ * will busy wait until this loop times out, and then
+ * slowly poll for a further 5 seconds before failing
+ * the transaction. You have been warned.
+ *
+ * yieldlines=<1 - 250>
+ *
+ * When acquiring a frame from the camera, the data gathering
+ * loop will yield back to the scheduler after completing
+ * this many lines. The default of 4 provides a trade-off
+ * between increased frame acquisition time and impact on
+ * interactive response.
*/
/* qcam-lib.c -- Library for programming with the Connectix QuickCam.
@@ -58,6 +80,14 @@
#include "bw-qcam.h"
+#if LINUX_VERSION_CODE >= 0x020117
+MODULE_PARM(maxpoll,"i");
+MODULE_PARM(yieldlines,"i");
+#endif
+
+static unsigned int maxpoll=250; /* Maximum busy-loop count for qcam I/O */
+static unsigned int yieldlines=4; /* Yield after this many during capture */
+
extern __inline__ int read_lpstatus(struct qcam_device *q)
{
return parport_read_status(q->pport);
@@ -154,6 +184,7 @@
q->top = 1;
q->left = 14;
q->mode = -1;
+ q->status = QC_PARAM_CHANGE;
return q;
}
@@ -209,14 +240,17 @@
{
/* 1000 is enough spins on the I/O for all normal
cases, at that point we start to poll slowly
- until the camera wakes up */
+ until the camera wakes up. However, we are
+ busy blocked until the camera responds, so
+ setting it lower is much better for interactive
+ response. */
- if(runs++>1000)
+ if(runs++>maxpoll)
{
current->state=TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/10);
+ schedule_timeout(HZ/200);
}
- if(runs>1050)
+ if(runs>(maxpoll+1000)) /* 5 seconds */
return -1;
}
}
@@ -226,14 +260,17 @@
{
/* 1000 is enough spins on the I/O for all normal
cases, at that point we start to poll slowly
- until the camera wakes up */
+ until the camera wakes up. However, we are
+ busy blocked until the camera responds, so
+ setting it lower is much better for interactive
+ response. */
- if(runs++>1000)
+ if(runs++>maxpoll)
{
current->state=TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/10);
+ schedule_timeout(HZ/200);
}
- if(runs++>1050) /* 5 seconds */
+ if(runs++>(maxpoll+1000)) /* 5 seconds */
return -1;
}
}
@@ -256,14 +293,17 @@
status = read_lpdata(q);
/* 1000 is enough spins on the I/O for all normal
cases, at that point we start to poll slowly
- until the camera wakes up */
+ until the camera wakes up. However, we are
+ busy blocked until the camera responds, so
+ setting it lower is much better for interactive
+ response. */
- if(runs++>1000)
+ if(runs++>maxpoll)
{
current->state=TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/10);
+ schedule_timeout(HZ/200);
}
- if(runs++>1050) /* 5 seconds */
+ if(runs++>(maxpoll+1000)) /* 5 seconds */
return 0;
}
while ((status & 1) != val);
@@ -287,7 +327,7 @@
lastreg = reg = read_lpstatus(q) & 0xf0;
- for (i = 0; i < 300; i++)
+ for (i = 0; i < 500; i++)
{
reg = read_lpstatus(q) & 0xf0;
if (reg != lastreg)
@@ -296,9 +336,20 @@
mdelay(2);
}
- /* Be liberal in what you accept... */
- if (count > 30 && count < 200)
+#if 0
+ /* Force camera detection during testing. Sometimes the camera
+ won't be flashing these bits. Possibly unloading the module
+ in the middle of a grab? Or some timeout condition?
+ I've seen this parameter as low as 19 on my 450Mhz box - mpc */
+ printk("Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count);
+ return 1;
+#endif
+
+ /* Be (even more) liberal in what you accept... */
+
+/* if (count > 30 && count < 200) */
+ if (count > 20 && count < 300)
return 1; /* found */
else
return 0; /* not found */
@@ -352,6 +403,8 @@
static int qc_setscanmode(struct qcam_device *q)
{
+ int old_mode = q->mode;
+
switch (q->transfer_scale)
{
case 1:
@@ -383,6 +436,10 @@
case QC_UNIDIR:
break;
}
+
+ if (q->mode != old_mode)
+ q->status |= QC_PARAM_CHANGE;
+
return 0;
}
@@ -434,8 +491,11 @@
qc_command(q, q->contrast);
qc_command(q, 0x1f);
qc_command(q, q->whitebal);
-}
+ /* Clear flag that we must update the grabbing parameters on the camera
+ before we grab the next frame */
+ q->status &= (~QC_PARAM_CHANGE);
+}
/* Qc_readbytes reads some bytes from the QC and puts them in
the supplied buffer. It returns the number of bytes read,
@@ -539,7 +599,7 @@
long qc_capture(struct qcam_device * q, char *buf, unsigned long len)
{
- int i, j, k;
+ int i, j, k, yield;
int bytes;
int linestotrans, transperline;
int divisor;
@@ -575,7 +635,7 @@
q->transfer_scale;
transperline = (transperline + divisor - 1) / divisor;
- for (i = 0; i < linestotrans; i++)
+ for (i = 0, yield = yieldlines; i < linestotrans; i++)
{
for (pixels_read = j = 0; j < transperline; j++)
{
@@ -599,6 +659,18 @@
pixels_read += bytes;
}
(void) qc_readbytes(q, 0); /* reset state machine */
+
+ /* Grabbing an entire frame from the quickcam is a lengthy
+ process. We don't (usually) want to busy-block the
+ processor for the entire frame. yieldlines is a module
+ parameter. If we yield every line, the minimum frame
+ time will be 240 / 200 = 1.2 seconds. The compile-time
+ default is to yield every 4 lines. */
+ if (i >= yield) {
+ current->state=TASK_INTERRUPTIBLE;
+ schedule_timeout(HZ/200);
+ yield = i + yieldlines;
+ }
}
if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
@@ -745,9 +817,12 @@
qcam->bpp = p.depth;
qc_setscanmode(qcam);
- parport_claim_or_block(qcam->pdev);
+ qcam->status |= QC_PARAM_CHANGE;
+
+/* parport_claim_or_block(qcam->pdev);
qc_set(qcam);
parport_release(qcam->pdev);
+*/
return 0;
}
case VIDIOCSWIN:
@@ -779,6 +854,11 @@
qcam->transfer_scale = 1;
}
qc_setscanmode(qcam);
+
+ /* We must update the camera before we grab. We could
+ just have changed the grab size */
+ qcam->status |= QC_PARAM_CHANGE;
+
/* Ok we figured out what to use from our wide choice */
return 0;
}
@@ -824,11 +904,15 @@
parport_claim_or_block(qcam->pdev);
/* Probably should have a semaphore against multiple users */
qc_reset(qcam);
+
+ /* Update the camera parameters if we need to */
+ if (qcam->status & QC_PARAM_CHANGE)
+ qc_set(qcam);
+
len=qc_capture(qcam, buf,count);
parport_release(qcam->pdev);
return len;
}
-
static struct video_device qcam_template=
{
@@ -909,6 +993,17 @@
for (port = parport_enumerate(); port; port=port->next)
init_bwqcam(port);
+
+ /* Do some sanity checks on the module parameters. */
+ if (maxpoll > 5000) {
+ printk("Connectix Quickcam max-poll was above 5000. Using 5000.\n");
+ maxpoll = 5000;
+ }
+
+ if (yieldlines < 1) {
+ printk("Connectix Quickcam yieldlines was less than 1. Using 1.\n");
+ yieldlines = 1;
+ }
return (num_cams)?0:-ENODEV;
}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/char/bw-qcam.h linux.ac/drivers/char/bw-qcam.h
--- linux.vanilla/drivers/char/bw-qcam.h Sun Nov 8 15:07:44 1998
+++ linux.ac/drivers/char/bw-qcam.h Sun Jan 24 21:15:01 1999
@@ -48,6 +48,9 @@
#define MAX_HEIGHT 243
#define MAX_WIDTH 336
+/* Bit fields for status flags */
+#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */
+
struct qcam_device {
struct video_device vdev;
struct pardevice *pdev;
@@ -59,6 +62,6 @@
int port_mode;
int transfer_scale;
int top, left;
+ int status;
unsigned int saved_bits;
};
-
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/char/console.c linux.ac/drivers/char/console.c
--- linux.vanilla/drivers/char/console.c Sun Jan 24 19:55:33 1999
+++ linux.ac/drivers/char/console.c Wed Jan 27 18:58:10 1999
@@ -2778,7 +2778,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 --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/char/esp.c linux.ac/drivers/char/esp.c
--- linux.vanilla/drivers/char/esp.c Sun Nov 8 15:10:12 1998
+++ linux.ac/drivers/char/esp.c Sun Nov 8 14:58:21 1998
@@ -2186,7 +2186,7 @@
if (signal_pending(current))
break;
- if (timeout && ((orig_jiffies + timeout) < jiffies))
+ if (timeout && time_before(orig_jiffies + timeout, jiffies))
break;
serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/char/pc_keyb.h linux.ac/drivers/char/pc_keyb.h
--- linux.vanilla/drivers/char/pc_keyb.h Tue Jan 19 02:57:26 1999
+++ linux.ac/drivers/char/pc_keyb.h Tue Jan 19 03:05:18 1999
@@ -115,7 +115,10 @@
#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
#define AUX_RESET 0xFF /* Reset aux device */
-#define AUX_BUF_SIZE 2048
+#define AUX_BUF_SIZE 2048 /* This might be better divisible by
+ three to make overruns stay in sync
+ but then the read function would need
+ a lock etc - ick */
struct aux_queue {
unsigned long head;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/net/Config.in linux.ac/drivers/net/Config.in
--- linux.vanilla/drivers/net/Config.in Sun Jan 24 19:55:35 1999
+++ linux.ac/drivers/net/Config.in Tue Jan 26 11:47:13 1999
@@ -2,6 +2,9 @@
# Network device configuration
#
+mainmenu_option next_comment
+comment 'ARCnet devices'
+
tristate 'ARCnet support' CONFIG_ARCNET
if [ "$CONFIG_ARCNET" != "n" ]; then
bool ' Enable arc0e (ARCnet "Ether-Encap" packet format)' CONFIG_ARCNET_ETH
@@ -12,6 +15,8 @@
dep_tristate ' ARCnet COM20020 chipset driver' CONFIG_ARCNET_COM20020 $CONFIG_ARCNET
fi
+endmenu
+
tristate 'Dummy net driver support' CONFIG_DUMMY
tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
@@ -22,6 +27,10 @@
#
# Ethernet
#
+
+mainmenu_option next_comment
+comment 'Ethernet (10 or 100Mbit)'
+
bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET
if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
if [ "$CONFIG_ARM" = "y" ]; then
@@ -53,6 +62,7 @@
tristate '3c507 support' CONFIG_EL16
if [ "$CONFIG_MCA" = "y" ]; then
tristate '3c523 support' CONFIG_ELMC
+ #tristate '3c527 support' CONFIG_ELMC_II
fi
fi
tristate '3c509/3c579 support' CONFIG_EL3
@@ -81,11 +91,10 @@
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'RealTek 8129/8139 (not 8019/8029!) support' CONFIG_RTL8139
tristate 'Packet Engines Yellowfin Gigabit-NIC support' CONFIG_YELLOWFIN
- tristate 'Alteon AceNIC & 3Com 3C985 Gigabit support' CONFIG_ACENIC
fi
bool 'Other ISA cards' CONFIG_NET_ISA
if [ "$CONFIG_NET_ISA" = "y" ]; then
- tristate 'AT1700/1720 support' CONFIG_AT1700
+ tristate 'AT1700/1720 support (EXPERIMENTAL)' CONFIG_AT1700
tristate 'Cabletron E21xx support' CONFIG_E2100
tristate 'DEPCA, DE10x, DE200, DE201, DE202, DE422 support' CONFIG_DEPCA
tristate 'EtherWORKS 3 (DE203, DE204, DE205) support' CONFIG_EWRK3
@@ -113,6 +122,7 @@
if [ "$CONFIG_NET_EISA" = "y" ]; then
tristate 'AMD PCnet32 (VLB and PCI) support' CONFIG_PCNET32
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ tristate 'Alteon AceNIC & 3Com 3C985 Gigabit support' CONFIG_ACENIC
tristate 'Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200
fi
@@ -143,6 +153,8 @@
fi
fi
+endmenu
+
bool 'FDDI driver support' CONFIG_FDDI
if [ "$CONFIG_FDDI" = "y" ]; then
bool 'Digital DEFEA and DEFPA adapter support' CONFIG_DEFXX
@@ -151,7 +163,6 @@
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool 'HIPPI driver support (EXPERIMENTAL)' CONFIG_HIPPI
if [ "$CONFIG_HIPPI" = "y" ]; then
- bool 'CERN HIPPI PCI adapter support' CONFIG_CERN_HIPPI
bool 'Essential RoadRunner HIPPI PCI adapter support' CONFIG_ROADRUNNER
if [ "$CONFIG_ROADRUNNER" != "n" ]; then
bool ' Use large TX/RX rings' CONFIG_ROADRUNNER_LARGE_RINGS
@@ -159,16 +170,13 @@
fi
fi
-tristate 'Frame relay DLCI support' CONFIG_DLCI
-if [ "$CONFIG_DLCI" = "y" -o "$CONFIG_DLCI" = "m" ]; then
- int ' Max open DLCI' CONFIG_DLCI_COUNT 24
- int ' Max DLCI per device' CONFIG_DLCI_MAX 8
- dep_tristate ' SDLA (Sangoma S502/S508) support' CONFIG_SDLA $CONFIG_DLCI
-fi
-
#
# AppleTalk
#
+
+mainmenu_option next_comment
+comment 'Appletalk devices'
+
if [ "$CONFIG_ATALK" != "n" ]; then
dep_tristate 'Apple/Farallon LocalTalk PC support' CONFIG_LTPC $CONFIG_ATALK
dep_tristate 'COPS LocalTalk PC support' CONFIG_COPS $CONFIG_ATALK
@@ -183,6 +191,8 @@
fi
fi
+endmenu
+
if [ ! "$CONFIG_PARPORT" = "n" ]; then
dep_tristate 'PLIP (parallel port) support' CONFIG_PLIP $CONFIG_PARPORT
fi
@@ -201,10 +211,13 @@
bool 'Wireless LAN (non-hamradio)' CONFIG_NET_RADIO
if [ "$CONFIG_NET_RADIO" = "y" ]; then
- tristate 'STRIP (Metricom starmode radio IP)' CONFIG_STRIP
+ dep_tristate 'STRIP (Metricom starmode radio IP)' CONFIG_STRIP $CONFIG_INET
tristate 'AT&T WaveLAN & DEC RoamAbout DS support' CONFIG_WAVELAN
fi
+mainmenu_option next_comment
+comment 'Token ring devices'
+
bool 'Token Ring driver support' CONFIG_TR
if [ "$CONFIG_TR" = "y" ]; then
tristate 'IBM Tropic chipset based adaptor support' CONFIG_IBMTR
@@ -212,12 +225,21 @@
tristate 'SysKonnect adapter support' CONFIG_SKTR
fi
+endmenu
+
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ tristate 'Red Creek Hardware VPN (EXPERIMENTAL)' CONFIG_RCPCI
tristate 'Traffic Shaper (EXPERIMENTAL)' CONFIG_SHAPER
fi
+
#
# WAN drivers support
#
+
+mainmenu_option next_comment
+comment 'Wan interfaces'
+
+
# There is no way to detect a comtrol sv11 - force it modular for now.
#
dep_tristate 'Comtrol Hostess SV-11 support' CONFIG_HOSTESS_SV11 m
@@ -225,8 +247,19 @@
# The COSA/SRP driver has not been tested as non-modular yet.
#
dep_tristate 'COSA/SRP sync serial boards support' CONFIG_COSA m
-tristate 'Red Creek Hardware VPN (EXPERIMENTAL)' CONFIG_RCPCI
#
+
+tristate 'Frame relay DLCI support' CONFIG_DLCI
+if [ "$CONFIG_DLCI" != "n" ]; then
+ int ' Max open DLCI' CONFIG_DLCI_COUNT 24
+ int ' Max DLCI per device' CONFIG_DLCI_MAX 8
+ dep_tristate ' SDLA (Sangoma S502/S508) support' CONFIG_SDLA $CONFIG_DLCI
+fi
+
+#
+# Wan router core.
+#
+
if [ "$CONFIG_WAN_ROUTER" != "n" ]; then
bool 'WAN drivers' CONFIG_WAN_DRIVERS
if [ "$CONFIG_WAN_DRIVERS" = "y" ]; then
@@ -239,11 +272,14 @@
fi
fi
fi
+
+endmenu
+
#
# X.25 network drivers
#
if [ "$CONFIG_X25" != "n" ]; then
-if [ "$CONFIG_LAPB" != "n" ]; then
+if [ "$CONFIG_LAPB" = "y" -o "$CONFIG_LAPB" = "m" ]; then
dep_tristate 'LAPB over Ethernet driver' CONFIG_LAPBETHER $CONFIG_LAPB
dep_tristate 'X.25 async driver' CONFIG_X25_ASY $CONFIG_LAPB
fi
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/net/Makefile linux.ac/drivers/net/Makefile
--- linux.vanilla/drivers/net/Makefile Tue Jan 19 02:57:28 1999
+++ linux.ac/drivers/net/Makefile Wed Jan 27 19:06:11 1999
@@ -143,14 +143,6 @@
endif
endif
-ifeq ($(CONFIG_ETHERH),y)
-CONFIG_8390_BUILTIN = y
-else
- ifeq ($(CONFIG_ETHERH),m)
- CONFIG_8390_MODULE = y
- endif
-endif
-
ifeq ($(CONFIG_WD80x3),y)
L_OBJS += wd.o
CONFIG_8390_BUILTIN = y
@@ -171,14 +163,6 @@
endif
endif
-ifeq ($(CONFIG_ETHERH),y)
-CONFIG_8390_BUILTIN = y
-else
- ifeq ($(CONFIG_ETHERH),m)
- CONFIG_8390_MODULE = y
- endif
-endif
-
ifeq ($(CONFIG_NE2K_PCI),y)
L_OBJS += ne2k-pci.o
CONFIG_8390_BUILTIN = y
@@ -430,6 +414,14 @@
endif
endif
+ifeq ($(CONFIG_SUNBMAC),y)
+L_OBJS += sunbmac.o
+else
+ ifeq ($(CONFIG_SUNBMAC),m)
+ M_OBJS += sunbmac.o
+ endif
+endif
+
ifeq ($(CONFIG_MYRI_SBUS),y)
L_OBJS += myri_sbus.o
else
@@ -478,6 +470,14 @@
endif
endif
+ifeq ($(CONFIG_ELMC_II),y)
+L_OBJS += 3c527.o
+else
+ ifeq ($(CONFIG_ELMC_II),m)
+ M_OBJS += 3c527.o
+ endif
+endif
+
ifeq ($(CONFIG_EL3),y)
L_OBJS += 3c509.o
else
@@ -1046,6 +1046,7 @@
ifeq ($(CONFIG_IRDA),y)
SUB_DIRS += irda
+MOD_SUB_DIRS += irda
else
ifeq ($(CONFIG_IRDA),m)
MOD_SUB_DIRS += irda
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/net/Space.c linux.ac/drivers/net/Space.c
--- linux.vanilla/drivers/net/Space.c Tue Jan 19 02:57:28 1999
+++ linux.ac/drivers/net/Space.c Tue Jan 26 11:33:18 1999
@@ -518,7 +518,7 @@
&& dfx_probe(dev)
#endif
#ifdef CONFIG_APFDDI
- && apfddi_init(dev);
+ && apfddi_init(dev)
#endif
&& 1 ) {
return 1; /* -ENODEV or -EAGAIN would be more accurate. */
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/net/hamradio/baycom_epp.c linux.ac/drivers/net/hamradio/baycom_epp.c
--- linux.vanilla/drivers/net/hamradio/baycom_epp.c Thu Dec 3 13:48:35 1998
+++ linux.ac/drivers/net/hamradio/baycom_epp.c Wed Jan 27 19:08:52 1999
@@ -1075,6 +1075,7 @@
if (!(pp->modes & (PARPORT_MODE_PCECPEPP|PARPORT_MODE_PCEPP))) {
printk(KERN_ERR "%s: parport at 0x%lx does not support any EPP mode\n",
bc_drvname, pp->base);
+ parport_release(bc->pdev);
parport_unregister_device(bc->pdev);
return -EIO;
}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/net/ibmtr.c linux.ac/drivers/net/ibmtr.c
--- linux.vanilla/drivers/net/ibmtr.c Tue Jan 26 09:44:20 1999
+++ linux.ac/drivers/net/ibmtr.c Thu Jan 28 13:22:37 1999
@@ -1353,12 +1353,23 @@
static void tr_tx(struct device *dev)
{
struct tok_info *ti=(struct tok_info *) dev->priv;
- struct trh_hdr *trhdr=(struct trh_hdr *)ti->current_skb->data;
+ struct trh_hdr *trhdr;
unsigned int hdr_len;
__u32 dhb;
unsigned char xmit_command;
int i;
struct trllc *llc;
+
+ if(ti->current_skb==NULL)
+ {
+ printk(KERN_ERR "%s: tx request but no packet!\n",
+ dev->name);
+ dev->tbusy=0;
+ mark_bh(NET_BH);
+ return;
+ }
+
+ trhdr=(struct trh_hdr *)ti->current_skb->data;
if (readb(ti->asb + offsetof(struct asb_xmit_resp, ret_code))!=0xFF)
DPRINTK("ASB not free !!!\n");
@@ -1603,6 +1614,7 @@
writeb(XMIT_UI_FRAME, ti->srb + offsetof(struct srb_xmit, command));
writew(ti->exsap_station_id, ti->srb
+offsetof(struct srb_xmit, station_id));
+ wmb(); /* This must be written before the IRQ hits */
writeb(CMD_IN_SRB, (ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD));
dev->trans_start=jiffies;
}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/net/irda/irport.c linux.ac/drivers/net/irda/irport.c
--- linux.vanilla/drivers/net/irda/irport.c Tue Jan 26 09:44:20 1999
+++ linux.ac/drivers/net/irda/irport.c Wed Jan 27 19:06:11 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 --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/net/irda/pc87108.c linux.ac/drivers/net/irda/pc87108.c
--- linux.vanilla/drivers/net/irda/pc87108.c Sun Jan 24 19:55:35 1999
+++ linux.ac/drivers/net/irda/pc87108.c Wed Jan 27 19:06:11 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: Fri Jan 22 20:20:09 1999
* Modified by: Dag Brattli
*
* Copyright (c) 1998 Dag Brattli
@@ -100,7 +100,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);
@@ -250,6 +252,7 @@
return 0;
}
+#ifdef MODULE
/*
* Function pc87108_close (idev)
*
@@ -276,6 +279,7 @@
return 0;
}
+#endif /* MODULE */
/*
* Function pc87108_probe (iobase, board_addr, irq, dma)
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/net/myri_sbus.c linux.ac/drivers/net/myri_sbus.c
--- linux.vanilla/drivers/net/myri_sbus.c Sun Nov 8 15:07:29 1998
+++ linux.ac/drivers/net/myri_sbus.c Thu Jan 14 06:23:57 1999
@@ -278,7 +278,7 @@
mp->rx_skbs[i] = skb;
skb->dev = dev;
skb_put(skb, RX_ALLOC_SIZE);
- rxd[i].myri_scatters[0].addr = (u32) ((unsigned long)skb->data);
+ rxd[i].myri_scatters[0].addr = sbus_dvma_addr(skb->data);
rxd[i].myri_scatters[0].len = RX_ALLOC_SIZE;
rxd[i].ctx = i;
rxd[i].num_sg = 1;
@@ -340,12 +340,6 @@
dev_kfree_skb(skb);
mp->tx_skbs[entry] = NULL;
mp->enet_stats.tx_packets++;
-
-#ifdef NEED_DMA_SYNCHRONIZATION
- mmu_sync_dma(((u32)((unsigned long)skb->data)),
- skb->len, mp->myri_sbus_dev->my_bus);
-#endif
-
entry = NEXT_TX(entry);
}
mp->tx_old = entry;
@@ -437,8 +431,7 @@
drops++;
DRX(("DROP "));
mp->enet_stats.rx_dropped++;
- rxd->myri_scatters[0].addr =
- (u32) ((unsigned long)skb->data);
+ rxd->myri_scatters[0].addr = sbus_dvma_addr(skb->data);
rxd->myri_scatters[0].len = RX_ALLOC_SIZE;
rxd->ctx = index;
rxd->num_sg = 1;
@@ -447,7 +440,7 @@
}
#ifdef NEED_DMA_SYNCHRONIZATION
- mmu_sync_dma(((u32)((unsigned long)skb->data)),
+ mmu_sync_dma(sbus_dvma_addr(skb->data),
skb->len, mp->myri_sbus_dev->my_bus);
#endif
@@ -464,8 +457,7 @@
mp->rx_skbs[index] = new_skb;
new_skb->dev = dev;
skb_put(new_skb, RX_ALLOC_SIZE);
- rxd->myri_scatters[0].addr =
- (u32) ((unsigned long)new_skb->data);
+ rxd->myri_scatters[0].addr = sbus_dvma_addr(new_skb->data);
rxd->myri_scatters[0].len = RX_ALLOC_SIZE;
rxd->ctx = index;
rxd->num_sg = 1;
@@ -489,8 +481,7 @@
/* Reuse original ring buffer. */
DRX(("reuse "));
- rxd->myri_scatters[0].addr =
- (u32) ((unsigned long)skb->data);
+ rxd->myri_scatters[0].addr = sbus_dvma_addr(skb->data);
rxd->myri_scatters[0].len = RX_ALLOC_SIZE;
rxd->ctx = index;
rxd->num_sg = 1;
@@ -600,6 +591,12 @@
return 1;
}
+
+#ifdef NEED_DMA_SYNCHRONIZATION
+ mmu_sync_dma(sbus_dvma_addr(skb->data),
+ skb->len, mp->myri_sbus_dev->my_bus);
+#endif
+
/* This is just to prevent multiple PIO reads for TX_BUFFS_AVAIL. */
head = sq->head;
tail = sq->tail;
@@ -628,8 +625,7 @@
txd = &sq->myri_txd[entry];
mp->tx_skbs[entry] = skb;
- txd->myri_gathers[0].addr =
- (unsigned int) ((unsigned long)skb->data);
+ txd->myri_gathers[0].addr = sbus_dvma_addr(skb->data);
txd->myri_gathers[0].len = len;
txd->num_sg = 1;
txd->chan = KERNEL_CHANNEL;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/53c7,8xx.c linux.ac/drivers/scsi/53c7,8xx.c
--- linux.vanilla/drivers/scsi/53c7,8xx.c Sun Nov 8 15:07:50 1998
+++ linux.ac/drivers/scsi/53c7,8xx.c Sun Nov 8 14:35:40 1998
@@ -1901,7 +1901,8 @@
*/
timeout = jiffies + 5 * HZ / 10;
- while ((hostdata->test_completed == -1) && jiffies < timeout)
+ while ((hostdata->test_completed == -1) &&
+ time_before(jiffies,timeout))
barrier();
failed = 1;
@@ -1986,7 +1987,8 @@
restore_flags(flags);
timeout = jiffies + 5 * HZ; /* arbitrary */
- while ((hostdata->test_completed == -1) && jiffies < timeout)
+ while ((hostdata->test_completed == -1) &&
+ time_before(jiffies, timeout))
barrier();
NCR53c7x0_write32 (DSA_REG, 0);
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/53c7xx.c linux.ac/drivers/scsi/53c7xx.c
--- linux.vanilla/drivers/scsi/53c7xx.c Sun Nov 8 15:07:55 1998
+++ linux.ac/drivers/scsi/53c7xx.c Thu Dec 17 01:56:08 1998
@@ -298,6 +298,10 @@
*/
#undef inb
#undef outb
+#undef inw
+#undef outw
+#undef inl
+#undef outl
#define inb(x) 1
#define inw(x) 1
#define inl(x) 1
@@ -1612,7 +1616,8 @@
*/
timeout = jiffies + 5 * HZ / 10;
- while ((hostdata->test_completed == -1) && jiffies < timeout)
+ while ((hostdata->test_completed == -1) &&
+ time_before(jiffies, timeout))
barrier();
failed = 1;
@@ -1698,7 +1703,8 @@
restore_flags(flags);
timeout = jiffies + 5 * HZ; /* arbitrary */
- while ((hostdata->test_completed == -1) && jiffies < timeout)
+ while ((hostdata->test_completed == -1) &&
+ time_before(jiffies, timeout))
barrier();
NCR53c7x0_write32 (DSA_REG, 0);
@@ -1899,7 +1905,7 @@
if (left < 0)
printk("scsi%d: loop detected in ncr reconncect list\n",
host->host_no);
- else if (ncr_search)
+ else if (ncr_search) {
if (found)
printk("scsi%d: scsi %ld in ncr issue array and reconnect lists\n",
host->host_no, c->pid);
@@ -1910,6 +1916,7 @@
/* If we're at the tail end of the issue queue, update that pointer too. */
found = 1;
}
+ }
/*
* Traverse the host running list until we find this command or discover
@@ -2960,14 +2967,14 @@
NCR53c7x0_write8(DCNTL_REG, hostdata->saved_dcntl | DCNTL_SSM);
else
NCR53c7x0_write8(DCNTL_REG, hostdata->saved_dcntl);
-#if 0
- /* Following disables snooping - run with caches disabled at first */
+ /* Following disables snooping - snooping is not required, as non-
+ * cached pages are used for shared data, and appropriate use is
+ * made of cache_push/cache_clear. Indeed, for 68060
+ * enabling snooping causes disk corruption of ext2fs free block
+ * bitmaps and the like. If you have a 68060 with snooping hardwared
+ * on, then you need to enable CONFIG_060_WRITETHROUGH.
+ */
NCR53c7x0_write8(CTEST7_REG, CTEST7_10_TT1|CTEST7_STD);
-#else
- /* Setup CTEST7 for SC1=0, SC0=1 - sink/source data without invalidating
- * cache lines. */
- NCR53c7x0_write8(CTEST7_REG, CTEST7_10_TT1|CTEST7_STD|CTEST7_10_SC0);
-#endif
/* Actually burst of eight, according to my 53c710 databook */
NCR53c7x0_write8(hostdata->dmode, DMODE_10_BL_8 | DMODE_10_FC2);
NCR53c7x0_write8(SCID_REG, 1 << host->this_id);
@@ -5947,11 +5954,12 @@
}
}
}
- if (!(istat & (ISTAT_SIP|ISTAT_DIP)))
+ if (!(istat & (ISTAT_SIP|ISTAT_DIP))) {
if (stage == 0)
++stage;
else if (stage == 3)
break;
+ }
}
hostdata->state = STATE_HALTED;
restore_flags(flags);
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/Config.in linux.ac/drivers/scsi/Config.in
--- linux.vanilla/drivers/scsi/Config.in Sun Jan 3 03:52:01 1999
+++ linux.ac/drivers/scsi/Config.in Mon Jan 4 15:38:00 1999
@@ -76,6 +76,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 +118,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 --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/Makefile linux.ac/drivers/scsi/Makefile
--- linux.vanilla/drivers/scsi/Makefile Sun Jan 3 03:52:01 1999
+++ linux.ac/drivers/scsi/Makefile Mon Jan 4 15:38:00 1999
@@ -576,6 +576,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
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/amiga7xx.c linux.ac/drivers/scsi/amiga7xx.c
--- linux.vanilla/drivers/scsi/amiga7xx.c Sun Nov 8 15:07:55 1998
+++ linux.ac/drivers/scsi/amiga7xx.c Thu Dec 17 01:56:25 1998
@@ -15,6 +15,7 @@
#include
#include
+#include
#include
#include
#include
@@ -33,9 +34,9 @@
S_IFDIR | S_IRUGO | S_IXUGO, 2
};
-extern ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip,
- u32 base, int io_port, int irq, int dma,
- long long options, int clock);
+extern int ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip,
+ u32 base, int io_port, int irq, int dma,
+ long long options, int clock);
int amiga7xx_detect(Scsi_Host_Template *tpnt)
{
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/atari_NCR5380.c linux.ac/drivers/scsi/atari_NCR5380.c
--- linux.vanilla/drivers/scsi/atari_NCR5380.c Sun Nov 8 15:07:54 1998
+++ linux.ac/drivers/scsi/atari_NCR5380.c Sun Nov 8 14:35:42 1998
@@ -1459,9 +1459,9 @@
unsigned long timeout = jiffies + 2*NCR_TIMEOUT;
while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
- && jiffies < timeout && !hostdata->connected)
+ && time_before(jiffies, timeout) && !hostdata->connected)
;
- if (jiffies >= timeout)
+ if (time_after_eq(jiffies, timeout))
{
printk("scsi : arbitration timeout at %d\n", __LINE__);
NCR5380_write(MODE_REG, MR_BASE);
@@ -1616,7 +1616,7 @@
* only wait for BSY... (Famous german words: Der Klügere gibt nach :-)
*/
- while ((jiffies < timeout) && !(NCR5380_read(STATUS_REG) &
+ while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) &
(SR_BSY | SR_IO)));
if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) ==
@@ -1629,7 +1629,7 @@
return -1;
}
#else
- while ((jiffies < timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY));
+ while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY));
#endif
/*
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/atari_scsi.c linux.ac/drivers/scsi/atari_scsi.c
--- linux.vanilla/drivers/scsi/atari_scsi.c Sun Nov 8 15:07:50 1998
+++ linux.ac/drivers/scsi/atari_scsi.c Thu Dec 17 01:56:31 1998
@@ -132,51 +132,51 @@
} while(0)
#define SCSI_DMA_READ_P(elt) \
- (((unsigned long)tt_scsi_dma.elt##_hi << 24) | \
- ((unsigned long)tt_scsi_dma.elt##_hmd << 16) | \
- ((unsigned long)tt_scsi_dma.elt##_lmd << 8) | \
- (unsigned long)tt_scsi_dma.elt##_lo)
-
-
-#define SCSI_DMA_SETADR(adr) \
- do { \
- unsigned long __adr = (adr); \
- st_dma.dma_lo = (unsigned char)__adr; \
- MFPDELAY(); \
- __adr >>= 8; \
- st_dma.dma_md = (unsigned char)__adr; \
- MFPDELAY(); \
- __adr >>= 8; \
- st_dma.dma_hi = (unsigned char)__adr; \
- MFPDELAY(); \
- } while(0)
-
-#define SCSI_DMA_GETADR() ({ \
- unsigned long __adr; \
- __adr = st_dma.dma_lo; \
- MFPDELAY(); \
- __adr |= (st_dma.dma_md & 0xff) << 8; \
- MFPDELAY(); \
- __adr |= (st_dma.dma_hi & 0xff) << 16; \
- MFPDELAY(); \
- __adr; \
-})
-
-#define ENABLE_IRQ() \
- do { \
- if (IS_A_TT()) \
- atari_enable_irq( IRQ_TT_MFP_SCSI ); \
- else \
- atari_enable_irq( IRQ_MFP_FSCSI ); \
- } while(0)
-
-#define DISABLE_IRQ() \
- do { \
- if (IS_A_TT()) \
- atari_disable_irq( IRQ_TT_MFP_SCSI ); \
- else \
- atari_disable_irq( IRQ_MFP_FSCSI ); \
- } while(0)
+ (((((((unsigned long)tt_scsi_dma.elt##_hi << 8) | \
+ (unsigned long)tt_scsi_dma.elt##_hmd) << 8) | \
+ (unsigned long)tt_scsi_dma.elt##_lmd) << 8) | \
+ (unsigned long)tt_scsi_dma.elt##_lo)
+
+
+static inline void SCSI_DMA_SETADR(unsigned long adr)
+{
+ st_dma.dma_lo = (unsigned char)adr;
+ MFPDELAY();
+ adr >>= 8;
+ st_dma.dma_md = (unsigned char)adr;
+ MFPDELAY();
+ adr >>= 8;
+ st_dma.dma_hi = (unsigned char)adr;
+ MFPDELAY();
+}
+
+static inline unsigned long SCSI_DMA_GETADR(void)
+{
+ unsigned long adr;
+ adr = st_dma.dma_lo;
+ MFPDELAY();
+ adr |= (st_dma.dma_md & 0xff) << 8;
+ MFPDELAY();
+ adr |= (st_dma.dma_hi & 0xff) << 16;
+ MFPDELAY();
+ return adr;
+}
+
+static inline void ENABLE_IRQ(void)
+{
+ if (IS_A_TT())
+ atari_enable_irq(IRQ_TT_MFP_SCSI);
+ else
+ atari_enable_irq(IRQ_MFP_FSCSI);
+}
+
+static inline void DISABLE_IRQ(void)
+{
+ if (IS_A_TT())
+ atari_disable_irq(IRQ_TT_MFP_SCSI);
+ else
+ atari_disable_irq(IRQ_MFP_FSCSI);
+}
#define HOSTDATA_DMALEN (((struct NCR5380_hostdata *) \
@@ -480,16 +480,17 @@
/* fetch rest bytes in the DMA register */
dst = (char *)SCSI_DMA_READ_P( dma_addr );
- if ((nr = ((long)dst & 3))) {
+ nr = ((long)dst & 3);
+ if (nr) {
/* there are 'nr' bytes left for the last long address before the
DMA pointer */
- dst = (char *)( (unsigned long)dst & ~3 );
+ dst = (char *)((unsigned long)dst ^ nr);
DMA_PRINTK("SCSI DMA: there are %d rest bytes for phys addr 0x%08lx",
nr, (long)dst);
dst = (char *)PTOV(dst); /* The content of the DMA pointer
* is a physical address! */
DMA_PRINTK(" = virt addr 0x%08lx\n", (long)dst);
- for( src = (char *)&tt_scsi_dma.dma_restdata; nr > 0; --nr )
+ for (src = (char *)&tt_scsi_dma.dma_restdata; nr != 0; --nr)
*dst++ = *src++;
}
}
@@ -764,7 +765,7 @@
}
#endif
-__initfunc(void atari_scsi_setup( char *str, int *ints ))
+void __init atari_scsi_setup(char *str, int *ints)
{
/* Format of atascsi parameter is:
* atascsi=,,,,
@@ -772,23 +773,6 @@
* Negative values mean don't change.
*/
- /* Grmbl... the standard parameter parsing can't handle negative numbers
- * :-( So let's do it ourselves!
- */
-
- int i = ints[0]+1, fact;
-
- while( str && (isdigit(*str) || *str == '-') && i <= 10) {
- if (*str == '-')
- fact = -1, ++str;
- else
- fact = 1;
- ints[i++] = simple_strtoul( str, NULL, 0 ) * fact;
- if ((str = strchr( str, ',' )) != NULL)
- ++str;
- }
- ints[0] = i-1;
-
if (ints[0] < 1) {
printk( "atari_scsi_setup: no arguments!\n" );
return;
@@ -869,7 +853,7 @@
#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
-__initfunc(static void atari_scsi_reset_boot( void ))
+static void __init atari_scsi_reset_boot(void)
{
unsigned long end;
@@ -892,7 +876,7 @@
NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
NCR5380_read( RESET_PARITY_INTERRUPT_REG );
- for( end = jiffies + AFTER_RESET_DELAY; jiffies < end; )
+ for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies,end); )
barrier();
printk( " done\n" );
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/gdth_proc.c linux.ac/drivers/scsi/gdth_proc.c
--- linux.vanilla/drivers/scsi/gdth_proc.c Thu Jan 14 01:25:25 1999
+++ linux.ac/drivers/scsi/gdth_proc.c Sat Jan 16 21:35:28 1999
@@ -3,6 +3,7 @@
*/
#include "gdth_ioctl.h"
+#include
int gdth_proc_info(char *buffer,char **start,off_t offset,int length,
int hostno,int inout)
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/hosts.c linux.ac/drivers/scsi/hosts.c
--- linux.vanilla/drivers/scsi/hosts.c Tue Jan 19 02:57:31 1999
+++ linux.ac/drivers/scsi/hosts.c Tue Jan 19 03:08:49 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
@@ -466,6 +470,9 @@
#endif
#ifdef CONFIG_SCSI_NCR53C406A /* 53C406A should come before QLOGIC */
NCR53c406a,
+#endif
+#ifdef CONFIG_SCSI_SYM53C416
+ SYM53C416,
#endif
#ifdef CONFIG_SCSI_QLOGIC_FAS
QLOGICFAS,
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/megaraid.c linux.ac/drivers/scsi/megaraid.c
--- linux.vanilla/drivers/scsi/megaraid.c Thu Jan 14 01:25:25 1999
+++ linux.ac/drivers/scsi/megaraid.c Tue Jan 26 23:46:43 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.93
*
* Description: Linux device driver for AMI MegaRAID controller
*
+ * Supported controllers: MegaRAID 418, 428, 438, 466
+ *
+ * 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,34 @@
* 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.
+ *
*
* 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 +74,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 +97,7 @@
#include
#include
#include /* for kmalloc() */
+#include /* for CONFIG_PCI */
#if LINUX_VERSION_CODE < 0x20100
#include
#else
@@ -108,18 +113,21 @@
#include "megaraid.h"
-/*================================================================
- *
- * #Defines
- *
- *================================================================*/
+//================================================================
+//
+// #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);\
@@ -154,125 +162,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,
+//================================================================
+//
+// Function prototypes
+//
+//================================================================
+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);
/* 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 };
+//================================================================
+//
+// Global variables
+//
+//================================================================
+static int numCtlrs = 0;
+static mega_host_config *megaCtlrs[12] = {0};
/* Change this to 0 if you want to see the raw drives */
-static int use_raid = 1;
+static int use_raid = 1;
/* 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 +288,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);
}
/*-------------------------------------------------------------------------
@@ -297,82 +304,79 @@
*
*-------------------------------------------------------------------------*/
-/*================================================
- * Initialize SCB structures
- *================================================*/
-static void initSCB(mega_host_config *megaCfg)
+//================================================
+// Initialize SCB structures
+//================================================
+static void initSCB (mega_host_config * megaCfg)
{
int idx;
- for(idx=0; idxmax_cmds; idx++) {
- megaCfg->scbList[idx].idx = -1;
- megaCfg->scbList[idx].flag = 0;
+ for (idx = 0; idx < megaCfg->max_cmds; idx++) {
+ megaCfg->scbList[idx].idx = -1;
+ megaCfg->scbList[idx].flag = 0;
megaCfg->scbList[idx].sgList = NULL;
- megaCfg->scbList[idx].SCpnt = NULL;
+ megaCfg->scbList[idx].SCpnt = NULL;
}
}
-/*===========================
- * Allocate a SCB structure
- *===========================*/
-static mega_scb *allocateSCB(mega_host_config *megaCfg,Scsi_Cmnd *SCpnt)
+//===========================
+// Allocate a SCB structure
+//===========================
+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].flag = 0;
+ megaCfg->scbList[idx].idx = idx;
megaCfg->scbList[idx].SCpnt = SCpnt;
- megaCfg->scbList[idx].next = NULL;
- spin_unlock_irqrestore(&mega_lock,flags);
+ 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);
+ kmalloc (sizeof (mega_sglist) * MAX_SGLIST, GFP_ATOMIC | GFP_DMA);
}
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)
-{
- long flags;
-
- spin_lock_irqsave(&mega_lock,flags);
- scb->flag = 0;
- scb->idx = -1;
- scb->next = NULL;
+//=======================
+// Free a SCB structure
+//=======================
+static void freeSCB (mega_scb * scb)
+{
+ scb->flag = 0;
+ scb->idx = -1;
+ scb->next = NULL;
scb->SCpnt = NULL;
- spin_unlock_irqrestore(&mega_lock,flags);
}
/* 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;
+ long islogical;
- while(1) {
- DEQUEUE(SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
- if (SCpnt == NULL) return;
+ while (1) {
+ DEQUEUE (SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
+ if (SCpnt == NULL)
+ return;
- megaCfg = (mega_host_config *)SCpnt->host->hostdata;
+ 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
@@ -381,14 +385,15 @@
*/
islogical = (SCpnt->channel == megaCfg->host->max_channel) ? 1 : 0;
if (SCpnt->cmnd[0] == INQUIRY &&
- ((((u_char*)SCpnt->request_buffer)[0] & 0x1F) == TYPE_DISK) &&
+ ((((u_char *) SCpnt->request_buffer)[0] & 0x1F) == TYPE_DISK) &&
(islogical != use_raid)) {
- SCpnt->result = 0xF0;
+ 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 +405,20 @@
}
/* 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)
{
+ long flags;
+
pScb->SCpnt->result = status;
- ENQUEUE(pScb->SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
- freeSCB(pScb);
+ ENQUEUE (pScb->SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
+ spin_lock_irqsave (&mega_lock, flags);
+ freeSCB (pScb);
+ spin_unlock_irqrestore (&mega_lock, flags);
}
/*----------------------------------------------------
@@ -417,42 +426,42 @@
*
* 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;
+ 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 +475,20 @@
* 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;
+
+ if (SCpnt->cmnd[0] & 0x80) /* ioctl from megamgr */
+ return mega_ioctl (megaCfg, SCpnt);
/* We don't support multi-luns */
if (SCpnt->lun != 0) {
SCpnt->result = (DID_BAD_TARGET << 16);
- callDone(SCpnt);
+ callDone (SCpnt);
return NULL;
}
@@ -486,44 +498,44 @@
*
*-----------------------------------------------------*/
if (SCpnt->channel == megaCfg->host->max_channel) {
- switch(SCpnt->cmnd[0]) {
+ 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 = 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);
/* 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 +544,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));
+ memset (mbox, 0, sizeof (pScb->mboxData));
mbox->logdrv = SCpnt->target;
- mbox->cmd = (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == READ_10) ?
+ 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 +599,31 @@
*-----------------------------------------------------*/
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 = 0;
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 +631,163 @@
}
/*--------------------------------------------------------------------
+ * 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;
+
+ if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
+ SCpnt->result = (DID_ERROR << 16);
+ callDone (SCpnt);
+ return NULL;
+ }
+
+ mbox = (mega_ioctl_mbox *) & pScb->mboxData;
+ mailbox = (mega_mailbox *) & pScb->mboxData;
+ memset (mailbox, 0, sizeof (pScb->mboxData));
+
+ if (SCpnt->cmnd[0] == 0x83) { /* passthrough command */
+ char cdblen = SCpnt->cmnd[2];
+
+ pthru = &pScb->pthru;
+ memset (pthru, 0, sizeof (mega_passthru));
+ pthru->islogical = SCpnt->cmnd[cdblen + 3] & 0x80;
+ pthru->timeout = SCpnt->cmnd[cdblen + 3] & 0x07;
+ pthru->reqsenselen = 10; /* ? MAX_SENSE; */
+ pthru->ars = SCpnt->cmnd[cdblen + 3] & 0x08;
+ pthru->logdrv = SCpnt->cmnd[cdblen + 4];
+ pthru->channel = SCpnt->cmnd[cdblen + 5];
+ pthru->target = SCpnt->cmnd[cdblen + 6];
+ pthru->cdblen = cdblen;
+ memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmnd[2]);
+
+ 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);
+
+ return pScb;
+ }
+ /* else normal (nonpassthru) command */
+
+ mbox->cmd = SCpnt->cmnd[0] & 0x7F;
+ mbox->channel = SCpnt->cmnd[1];
+ mbox->param = SCpnt->cmnd[2];
+ mbox->pad[0] = SCpnt->cmnd[3];
+ mbox->logdrv = SCpnt->cmnd[4];
+
+ mbox->numsgelements = build_sglist (megaCfg, pScb,
+ (u_long *) & mbox->xferaddr,
+ (u_long *) & seg);
+
+ 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);
+ }
+ 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;
+
+ 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];
+ spin_unlock_irqrestore (&mega_lock, flags); /* megalock within cmd_done */
+ mega_cmd_done (megaCfg, &megaCfg->scbList[sIdx - 1], qStatus);
+ spin_lock_irqsave (&mega_lock, flags);
}
}
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,111 +796,128 @@
/*==================================================*/
/* 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 < 30000; counter++) {
+ udelay (100);
+ if (!mbox->busy)
+ return 0;
}
- return -1;
-}
-
-/*=====================================================
- * Post a command to the card
- *
- * Arguments:
- * mega_host_config *megaCfg - Controller structure
- * 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;
+ return -1; /* give up after 3 seconds */
+}
- mboxData[0x1] = (pScb ? pScb->idx+1 : 0x00); /* Set cmdid */
- mboxData[0xF] = 1; /* Set busy */
+//=====================================================
+// Post a command to the card
+//
+// Arguments:
+// mega_host_config *megaCfg - Controller structure
+// 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 */
+
+ spin_lock_irqsave(&mega_lock,flags);
/* 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
*/
+
if (megaCfg->flag & PENDING) {
+ spin_unlock_irqrestore(&mega_lock,flags);
return -1;
}
/* 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, sizeof (mega_mailbox));
+ 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 +927,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->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 +977,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 +1003,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 = 9; /* max logical drives + 1 */
+ 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 +1088,56 @@
/*----------------------------------------------------------
* 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;
#if LINUX_VERSION_CODE < 0x20100
- while(!pcibios_find_device(pciVendor, pciDev, pciIdx,&pciBus,&pciDevFun)) {
+ while (!pcibios_find_device (pciVendor, pciDev, pciIdx, &pciBus, &pciDevFun)) {
+ if (flag & BOARD_QUARTZ) {
+ u_int magic;
+ pcibios_read_config_dword (pciBus, pciDevFun,
+ PCI_CONF_AMISIG,
+ &magic);
+ if (magic != AMI_SIGNATURE) {
+ continue; /* not an AMI board */
+ }
+ }
#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 +1146,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,47 +1154,47 @@
}
/* 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);
+ initSCB (megaCfg);
}
return pciIdx;
@@ -1088,23 +1203,22 @@
/*---------------------------------------------------------
* 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,33 +1226,40 @@
/*---------------------------------------------------------------------
* 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];
+ int i;
- 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 */
+ for (i = 0; i < megaCfg->max_cmds; i++) {
+ if (megaCfg->scbList[i].sgList)
+ kfree (megaCfg->scbList[i].sgList); /* free sgList */
+ }
+ scsi_unregister (pSHost);
return 0;
}
@@ -1146,20 +1267,20 @@
/*----------------------------------------------
* 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 +1299,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 +1329,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 +1374,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 +1446,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 --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/megaraid.h linux.ac/drivers/scsi/megaraid.h
--- linux.vanilla/drivers/scsi/megaraid.h Tue Jan 26 09:44:21 1999
+++ linux.ac/drivers/scsi/megaraid.h Thu Jan 28 22:22:18 1999
@@ -1,7 +1,9 @@
#ifndef __MEGARAID_H__
#define __MEGARAID_H__
+#ifndef LINUX_VERSION_CODE
#include
+#endif
#define IN_ISR 0x80000000L
#define NO_INTR 0x40000000L
@@ -20,7 +22,7 @@
#define MEGA_CMD_TIMEOUT 10
-#define MAX_SGLIST 20
+#define MAX_SGLIST 17
#define MAX_COMMANDS 254
#define MAX_LOGICAL_DRIVES 8
@@ -96,6 +98,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 +117,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 +138,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: 254, /* 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 +149,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 --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/ncr53c8xx.c linux.ac/drivers/scsi/ncr53c8xx.c
--- linux.vanilla/drivers/scsi/ncr53c8xx.c Tue Jan 19 02:57:31 1999
+++ linux.ac/drivers/scsi/ncr53c8xx.c Tue Jan 19 03:09:19 1999
@@ -4996,7 +4996,7 @@
** Force ordered tag if necessary to avoid timeouts
** and to preserve interactivity.
*/
- if (lp && lp->tags_stime + (3*HZ) <= jiffies) {
+ if (lp && time_before_eq(lp->tags_stime + 3*HZ, jiffies)) {
if (lp->tags_smap) {
order = M_ORDERED_TAG;
if ((DEBUG_FLAGS & DEBUG_TAGS)||bootverbose>2){
@@ -9796,7 +9796,8 @@
/* PCI_CACHE_LINE_SIZE value is in 32-bit words. */
cache_line_size = 64 / sizeof(u_int32);
if (initverbose >= 2)
- printk("ncr53c8xx: setting PCI_CACHE_LINE_SIZE to %d (fixup)\n", cache_line_size);
+ printk("ncr53c8xx: setting PCI_CACHE_LINE_SIZE to %d (fixup)\n",
+ cache_line_size);
pcibios_write_config_byte(bus, device_fn,
PCI_CACHE_LINE_SIZE, cache_line_size);
pcibios_read_config_byte(bus, device_fn,
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/pci2000.c linux.ac/drivers/scsi/pci2000.c
--- linux.vanilla/drivers/scsi/pci2000.c Sun Nov 8 15:07:54 1998
+++ linux.ac/drivers/scsi/pci2000.c Mon Jan 4 16:04:59 1999
@@ -108,7 +108,7 @@
do {
if ( !inb_p (padapter->cmd) )
return FALSE;
- } while ( timer > jiffies ); // test for timeout
+ } while ( time_after(timer, jiffies) ); // test for timeout
return TRUE;
}
/****************************************************************
@@ -205,7 +205,7 @@
int bus;
int z;
- DEB(printk ("\npci2000 recieved interrupt "));
+ DEB(printk ("\npci2000 received interrupt "));
for ( z = 0; z < NumAdapters; z++ ) // scan for interrupt to process
{
if ( PsiHost[z]->irq == (UCHAR)(irq & 0xFF) )
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/pci2220i.c linux.ac/drivers/scsi/pci2220i.c
--- linux.vanilla/drivers/scsi/pci2220i.c Sun Nov 8 15:07:56 1998
+++ linux.ac/drivers/scsi/pci2220i.c Mon Jan 4 16:04:59 1999
@@ -152,7 +152,7 @@
outb_p (0x03, padapter->regDmaCmdStat); // kick the DMA engine in gear
return 0;
}
- } while ( timer > jiffies ); // test for timeout
+ } while ( time_after(timer, jiffies) ); // test for timeout
padapter->ide.ide.ides.cmd = 0; // null out the command byte
return 1;
@@ -192,7 +192,7 @@
return (WriteData (padapter));
return 0;
}
- } while ( timer > jiffies ); // test for timeout
+ } while ( time_after(timer, jiffies) ); // test for timeout
padapter->ide.ide.ides.cmd = 0; // null out the command byte
return status;
@@ -288,7 +288,7 @@
UCHAR status;
int z;
-// DEB(printk ("\npci2220i recieved interrupt\n"));
+// DEB(printk ("\npci2220i received interrupt\n"));
for ( z = 0; z < NumAdapters; z++ ) // scan for interrupt to process
{
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/psi240i.c linux.ac/drivers/scsi/psi240i.c
--- linux.vanilla/drivers/scsi/psi240i.c Sun Nov 8 15:07:56 1998
+++ linux.ac/drivers/scsi/psi240i.c Mon Jan 4 16:04:59 1999
@@ -129,7 +129,7 @@
outsw (pports[PORT_DATA], padapter->buffer, (USHORT)padapter->ide.ide.ide[2] * 256);
return 0;
}
- } while ( timer > jiffies ); // test for timeout
+ } while ( time_after(timer, jiffies) ); // test for timeout
padapter->ide.ide.ides.cmd = 0; // null out the command byte
return 1;
@@ -169,7 +169,7 @@
return 0;
}
- } while ( timer > jiffies ); // test for timeout
+ } while ( time_after(timer, jiffies) ); // test for timeout
padapter->ide.ide.ides.cmd = 0; // null out the command byte
return status;
@@ -264,7 +264,7 @@
UCHAR status;
int z;
- DEB(printk ("\npsi240i recieved interrupt\n"));
+ DEB(printk ("\npsi240i received interrupt\n"));
shost = PsiHost[irq - 10];
if ( !shost )
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/qlogicfas.c linux.ac/drivers/scsi/qlogicfas.c
--- linux.vanilla/drivers/scsi/qlogicfas.c Sun Nov 8 15:07:54 1998
+++ linux.ac/drivers/scsi/qlogicfas.c Sun Nov 8 14:35:43 1998
@@ -276,9 +276,9 @@
int i,k;
k = 0;
i = jiffies + WATCHDOG;
- while ( i > jiffies && !qabort && !((k = inb(qbase + 4)) & 0xe0))
+ while ( time_after(i, jiffies) && !qabort && !((k = inb(qbase + 4)) & 0xe0))
barrier();
- if (i <= jiffies)
+ if (time_before_eq(i, jiffies))
return (DID_TIME_OUT);
if (qabort)
return (qabort == 1 ? DID_ABORT : DID_RESET);
@@ -408,8 +408,8 @@
}
/*** Enter Status (and Message In) Phase ***/
k = jiffies + WATCHDOG;
- while ( k > jiffies && !qabort && !(inb(qbase + 4) & 6)); /* wait for status phase */
- if ( k <= jiffies ) {
+ while ( time_after(k, jiffies) && !qabort && !(inb(qbase + 4) & 6)); /* wait for status phase */
+ if ( time_before_eq(k, jiffies) ) {
ql_zap();
return (DID_TIME_OUT << 16);
}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/qlogicfc.c linux.ac/drivers/scsi/qlogicfc.c
--- linux.vanilla/drivers/scsi/qlogicfc.c Thu Jan 1 01:00:00 1970
+++ linux.ac/drivers/scsi/qlogicfc.c Wed Dec 23 19:37:14 1998
@@ -0,0 +1,1953 @@
+/*
+ * 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 1000000
+
+/* 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++) {
+ 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) {
+ 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;
+ 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) {
+ 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:
+ 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);
+
+ /* this is really gross */
+ if (host->can_queue < host->host_busy){
+ if (host->can_queue+2 < host->host_busy)
+ printk("1 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;
+ }
+ /* this command returns the status loop down and generates
+ an interupt when the loop comes up */
+ param[0] = MBOX_INIT_LIP;
+ isp2100_mbox_command(host, param);
+
+ 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->version = isp2100_read_nvram_word(host, 3) & 0xff;
+ control_block->firm_opts = isp2100_read_nvram_word(host, 4);
+ 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->retry_cnt = value & 0xff;
+ control_block->retry_delay = (value >> 8) & 0xff;
+ 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)
+{
+ int i;
+
+ 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 --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/qlogicfc.h linux.ac/drivers/scsi/qlogicfc.h
--- linux.vanilla/drivers/scsi/qlogicfc.h Thu Jan 1 01:00:00 1970
+++ linux.ac/drivers/scsi/qlogicfc.h Wed Dec 23 19:37:14 1998
@@ -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 --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/qlogicfc_asm.c linux.ac/drivers/scsi/qlogicfc_asm.c
--- linux.vanilla/drivers/scsi/qlogicfc_asm.c Thu Jan 1 01:00:00 1970
+++ linux.ac/drivers/scsi/qlogicfc_asm.c Tue Dec 22 17:09:51 1998
@@ -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 --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/scsi.c linux.ac/drivers/scsi/scsi.c
--- linux.vanilla/drivers/scsi/scsi.c Tue Jan 19 02:57:31 1999
+++ linux.ac/drivers/scsi/scsi.c Tue Jan 19 03:09:56 1999
@@ -280,8 +280,6 @@
{"YAMAHA","CDR100","1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
{"YAMAHA","CDR102","1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
{"iomega","jaz 1GB","J.86", BLIST_NOTQ | BLIST_NOLUN},
-{"IBM","DPES-","*", BLIST_NOTQ | BLIST_NOLUN},
-{"WDIGTL","WDE","*", BLIST_NOTQ | BLIST_NOLUN},
/*
* Must be at end of list...
*/
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/sd.c linux.ac/drivers/scsi/sd.c
--- linux.vanilla/drivers/scsi/sd.c Tue Jan 19 02:57:31 1999
+++ linux.ac/drivers/scsi/sd.c Tue Jan 26 19:40:49 1999
@@ -708,14 +708,14 @@
*/
if (rscsi_disks[dev].sector_size == 1024)
if((block & 1) || (SCpnt->request.nr_sectors & 1)) {
- printk("sd.c:Bad block number requested");
+ printk("sd.c:Bad block number/count requested");
SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
goto repeat;
}
if (rscsi_disks[dev].sector_size == 2048)
if((block & 3) || (SCpnt->request.nr_sectors & 3)) {
- printk("sd.c:Bad block number requested");
+ printk("sd.c:Bad block number/count requested");
SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
goto repeat;
}
@@ -1126,8 +1126,8 @@
unsigned char cmd[10];
char nbuff[6];
unsigned char *buffer;
- unsigned long spintime;
- int the_result, retries;
+ unsigned long spintime_value = 0;
+ int the_result, retries, spintime;
Scsi_Cmnd * SCpnt;
/*
@@ -1222,16 +1222,18 @@
SCpnt->request.sem = NULL;
}
- spintime = jiffies;
+ spintime = 1;
+ spintime_value = jiffies;
}
time1 = jiffies + HZ;
spin_unlock_irq(&io_request_lock);
- while(jiffies < time1); /* Wait 1 second for next try */
+ while(time_before(jiffies, time1)); /* Wait 1 second for next try */
printk( "." );
spin_lock_irq(&io_request_lock);
}
- } while(the_result && spintime && spintime+100*HZ > jiffies);
+ } while(the_result && spintime &&
+ time_after(spintime_value+100*HZ, jiffies));
if (spintime) {
if (the_result)
printk( "not responding...\n" );
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/sym53c416.c linux.ac/drivers/scsi/sym53c416.c
--- linux.vanilla/drivers/scsi/sym53c416.c Thu Jan 1 01:00:00 1970
+++ linux.ac/drivers/scsi/sym53c416.c Sat Jan 16 21:35:28 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 --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/scsi/sym53c416.h linux.ac/drivers/scsi/sym53c416.h
--- linux.vanilla/drivers/scsi/sym53c416.h Thu Jan 1 01:00:00 1970
+++ linux.ac/drivers/scsi/sym53c416.h Thu Jan 28 22:22:17 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 --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/midi_synth.c linux.ac/drivers/sound/midi_synth.c
--- linux.vanilla/drivers/sound/midi_synth.c Sun Nov 8 15:08:01 1998
+++ linux.ac/drivers/sound/midi_synth.c Tue Jan 26 23:48:33 1999
@@ -12,6 +12,7 @@
*/
/*
* Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ * Andrew Veliath : fixed running status in MIDI input state machine
*/
#include
@@ -196,13 +197,19 @@
inc->m_left = len_tab[(data >> 4) - 8];
inc->m_buf[0] = inc->m_prev_status = data;
}
- } else if (inc->m_prev_status & 0x80) /* Ignore if no previous status (yet) */
- { /* Data byte (use running status) */
- inc->m_state = MST_DATA;
+ } else if (inc->m_prev_status & 0x80) {
+ /* Data byte (use running status) */
inc->m_ptr = 2;
- inc->m_left = len_tab[(data >> 4) - 8] - 1;
- inc->m_buf[0] = inc->m_prev_status;
inc->m_buf[1] = data;
+ inc->m_buf[0] = inc->m_prev_status;
+ inc->m_left = len_tab[(inc->m_buf[0] >> 4) - 8] - 1;
+ if (inc->m_left > 0)
+ inc->m_state = MST_DATA; /* Not done yet */
+ else {
+ inc->m_state = MST_INIT;
+ do_midi_msg(dev, inc->m_buf, inc->m_ptr);
+ inc->m_ptr = 0;
+ }
}
break; /* MST_INIT */
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/sb_card.c linux.ac/drivers/sound/sb_card.c
--- linux.vanilla/drivers/sound/sb_card.c Thu Jan 28 22:00:14 1999
+++ linux.ac/drivers/sound/sb_card.c Tue Jan 26 10:05:10 1999
@@ -130,13 +130,13 @@
int io = -1;
int irq = -1;
int dma = -1;
-int dma16 = -1; /* Set this for modules that need it */
-int type = 0; /* Can set this to a specific card type */
-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 dma16 = -1; /* Set this for modules that need it */
+int type = 0; /* Can set this to a specific card type */
+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 sm_games = 0; /* Mixer - see sb_mixer.c */
-int acer = 0; /* Do acer notebook init */
+int acer = 0; /* Do acer notebook init */
MODULE_PARM(io, "i");
MODULE_PARM(irq, "i");
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/sb_ess.c linux.ac/drivers/sound/sb_ess.c
--- linux.vanilla/drivers/sound/sb_ess.c Tue Jan 26 09:44:21 1999
+++ linux.ac/drivers/sound/sb_ess.c Wed Jan 27 19:01:10 1999
@@ -156,9 +156,11 @@
* ES1946 yes This is a PCI chip; not handled by this driver
*/
+
#include "sound_config.h"
#include "sb_mixer.h"
#include "sb.h"
+#include
#include "sb_ess.h"
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/sound/sys_timer.c linux.ac/drivers/sound/sys_timer.c
--- linux.vanilla/drivers/sound/sys_timer.c Sun Nov 8 15:08:02 1998
+++ linux.ac/drivers/sound/sys_timer.c Tue Jan 26 23:48:33 1999
@@ -13,6 +13,7 @@
*/
/*
* Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ * Andrew Veliath : adapted tmr2ticks from level 1 sequencer (avoid overflow)
*/
#include
@@ -39,11 +40,17 @@
tmr2ticks(int tmr_value)
{
/*
- * Convert system timer ticks (HZ) to MIDI ticks
- * (divide # of MIDI ticks/minute by # of system ticks/minute).
+ * Convert timer ticks to MIDI ticks
*/
- return ((tmr_value * curr_tempo * curr_timebase) + (30 * 100)) / (60 * HZ);
+ unsigned long tmp;
+ unsigned long scale;
+
+ /* tmr_value (ticks per sec) *
+ 1000000 (usecs per sec) / HZ (ticks per sec) -=> usecs */
+ tmp = tmr_value * (1000000 / HZ);
+ scale = (60 * 1000000) / (curr_tempo * curr_timebase); /* usecs per MIDI tick */
+ return (tmp + scale / 2) / scale;
}
static void
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/video/Config.in linux.ac/drivers/video/Config.in
--- linux.vanilla/drivers/video/Config.in Sun Jan 24 19:55:36 1999
+++ linux.ac/drivers/video/Config.in Sun Jan 24 20:28:50 1999
@@ -37,7 +37,7 @@
fi
if [ "$CONFIG_ATARI" = "y" ]; then
bool 'Atari native chipset support' CONFIG_FB_ATARI
- bool 'ATI Mach64 display support' CONFIG_FB_ATY
+ bool 'ATI Mach64 display support' CONFIG_FB_ATARI_ATY
fi
if [ "$CONFIG_PPC" = "y" ]; then
bool 'Open Firmware frame buffer device support' CONFIG_FB_OF
@@ -45,7 +45,7 @@
bool 'Apple "control" display support' CONFIG_FB_CONTROL
bool 'Apple "platinum" display support' CONFIG_FB_PLATINUM
bool 'Apple "valkyrie" display support' CONFIG_FB_VALKYRIE
- bool 'ATI Mach64 display support' CONFIG_FB_ATY
+ bool 'ATI Mach64 display support' CONFIG_FB_OF_ATY
bool 'IMS Twin Turbo display support' CONFIG_FB_IMSTT
bool 'Chips 65550 display support' CONFIG_FB_CT65550
bool 'S3 Trio display support' CONFIG_FB_S3TRIO
@@ -73,7 +73,7 @@
bool ' G100/G200 support' CONFIG_FB_MATROX_G100
bool ' Multihead support' CONFIG_FB_MATROX_MULTIHEAD
fi
- bool 'ATI Mach64 display support' CONFIG_FB_ATY
+ bool 'ATI Mach64 display support' CONFIG_FB_PCI_ATY
fi
fi
if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
@@ -104,11 +104,27 @@
if [ "$CONFIG_PCI" != "n" ]; then
bool 'PCI framebuffers' CONFIG_FB_PCI
if [ "$CONFIG_FB_PCI" != "n" ]; then
- bool ' ATI Mach64 display support' CONFIG_FB_ATY
+ bool ' ATI Mach64 display support' CONFIG_FB_SPARC64_PCI_ATY
fi
fi
fi
tristate 'Virtual Frame Buffer support (ONLY FOR TESTING!)' CONFIG_FB_VIRTUAL
+
+ if [ "$CONFIG_FB_ATARI_ATY" = "y" \
+ -o "$CONFIG_FB_OF_ATY" = "y" \
+ -o "$CONFIG_FB_PCI_ATY" = "y" \
+ -o "$CONFIG_FB_SPARC64_PCI_ATY" = "y" ]; then
+ define_bool CONFIG_FB_ATY y
+ else
+ if [ "$CONFIG_FB_ATARI_ATY" = "m" \
+ -o "$CONFIG_FB_OF_ATY" = "m" \
+ -o "$CONFIG_FB_PCI_ATY" = "m" \
+ -o "$CONFIG_FB_SPARC64_PCI_ATY" = "m" ]; then
+ define_bool CONFIG_FB_ATY m
+ else
+ define_bool CONFIG_FB_ATY n
+ fi
+ fi
bool 'Advanced low level driver options' CONFIG_FBCON_ADVANCED
if [ "$CONFIG_FBCON_ADVANCED" = "y" ]; then
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/video/Makefile linux.ac/drivers/video/Makefile
--- linux.vanilla/drivers/video/Makefile Sun Jan 24 19:55:36 1999
+++ linux.ac/drivers/video/Makefile Tue Jan 26 23:43:49 1999
@@ -128,6 +128,14 @@
endif
endif
+ifeq ($(CONFIG_FB_CYBER2000),y)
+L_OBJS += cyber2000fb.o
+else
+ ifeq ($(CONFIG_FB_CYBER2000),m)
+ M_OBJS += cyber2000fb.o
+ endif
+endif
+
ifeq ($(CONFIG_FB_MAC),y)
L_OBJS += macfb.o
endif
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/video/cgsixfb.c linux.ac/drivers/video/cgsixfb.c
--- linux.vanilla/drivers/video/cgsixfb.c Tue Dec 22 23:19:55 1998
+++ linux.ac/drivers/video/cgsixfb.c Wed Jan 27 18:58:06 1999
@@ -352,8 +352,8 @@
do {
i = fbc->s;
} while (i & 0x10000000);
- fbc->fg = attr_fgcol(p,*s);
- fbc->bg = attr_bgcol(p,*s);
+ fbc->fg = attr_fgcol(p, scr_readw(s));
+ fbc->bg = attr_bgcol(p, scr_readw(s));
fbc->mode = 0x140000;
fbc->alu = 0xe880fc30;
fbc->pixelm = ~(0);
@@ -379,15 +379,15 @@
fbc->x1 = (x += 4 * fontwidth(p)) - 1;
fbc->y0 = y;
if (fontheightlog(p)) {
- fd1 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
- fd2 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
- fd3 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
- fd4 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
+ fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+ fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+ fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+ fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
} else {
- fd1 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
- fd2 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
- fd3 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
- fd4 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
+ fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+ fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+ fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+ fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
}
if (fontwidth(p) == 8) {
for (i = 0; i < fontheight(p); i++)
@@ -408,11 +408,11 @@
fbc->x1 = (x += 2 * fontwidth(p)) - 1;
fbc->y0 = y;
if (fontheightlog(p)) {
- fd1 = p->fontdata + ((*s++ & p->charmask) << (fontheightlog(p) + 1));
- fd2 = p->fontdata + ((*s++ & p->charmask) << (fontheightlog(p) + 1));
+ fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
+ fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
} else {
- fd1 = p->fontdata + (((*s++ & p->charmask) * fontheight(p)) << 1);
- fd2 = p->fontdata + (((*s++ & p->charmask) * fontheight(p)) << 1);
+ fd1 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
+ fd2 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
}
for (i = 0; i < fontheight(p); i++) {
fbc->font = ((((u32)*(u16 *)fd1) << fontwidth(p)) | ((u32)*(u16 *)fd2)) << (16 - fontwidth(p));
@@ -428,9 +428,9 @@
fbc->x1 = (x += fontwidth(p)) - 1;
fbc->y0 = y;
if (fontheightlog(p))
- i = ((*s++ & p->charmask) << fontheightlog(p));
+ i = ((scr_readw(s++) & p->charmask) << fontheightlog(p));
else
- i = ((*s++ & p->charmask) * fontheight(p));
+ i = ((scr_readw(s++) & p->charmask) * fontheight(p));
if (fontwidth(p) <= 8) {
fd1 = p->fontdata + i;
for (i = 0; i < fontheight(p); i++)
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/video/clgenfb.c linux.ac/drivers/video/clgenfb.c
--- linux.vanilla/drivers/video/clgenfb.c Sun Jan 24 19:55:37 1999
+++ linux.ac/drivers/video/clgenfb.c Wed Jan 27 18:59:21 1999
@@ -204,8 +204,8 @@
struct fb_info_gen *info);
static int clgen_blank(int blank_mode, struct fb_info_gen *info);
-static void clgen_set_dispsw(const void *par, struct display *disp,
- struct fb_info_gen *info);
+static void clgen_set_disp(const void *par, struct display *disp,
+ struct fb_info_gen *info);
/* function table of the above functions */
static struct fbgen_hwswitch clgen_hwswitch =
@@ -220,7 +220,7 @@
clgen_setcolreg,
clgen_pan_display,
clgen_blank,
- clgen_set_dispsw
+ clgen_set_disp
};
/* Text console acceleration */
@@ -1372,13 +1372,14 @@
}
}
-static void clgen_set_dispsw(const void *par, struct display *disp,
- struct fb_info_gen *info)
+static void clgen_set_disp(const void *par, struct display *disp,
+ struct fb_info_gen *info)
{
struct clgenfb_par *_par = (struct clgenfb_par*) par;
struct clgenfb_info *info2 = (struct clgenfb_info *)info;
- printk("clgen_get_dispsw(): ");
+ printk("clgen_set_disp(): ");
+ disp->screen_base = info2->fbmem;
switch (_par->var.bits_per_pixel)
{
#ifdef FBCON_HAS_MFB
@@ -1670,7 +1671,7 @@
int init_module(void)
{
printk("init_module()\n");
- clgenfb_init(0);
+ clgenfb_init();
return 0;
}
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/video/creatorfb.c linux.ac/drivers/video/creatorfb.c
--- linux.vanilla/drivers/video/creatorfb.c Sun Jan 24 19:55:38 1999
+++ linux.ac/drivers/video/creatorfb.c Wed Jan 27 18:58:06 1999
@@ -433,8 +433,8 @@
FFBWait(fbc);
FFBFifo(fbc, 2);
- fbc->fg = ((u32 *)p->dispsw_data)[attr_fgcol(p,*s)];
- fbc->bg = ((u32 *)p->dispsw_data)[attr_bgcol(p,*s)];
+ fbc->fg = ((u32 *)p->dispsw_data)[attr_fgcol(p,scr_readw(s))];
+ fbc->bg = ((u32 *)p->dispsw_data)[attr_bgcol(p,scr_readw(s))];
xy = fb->s.ffb.xy_margin;
if (fontwidthlog(p))
xy += (xx << fontwidthlog(p));
@@ -452,15 +452,15 @@
fbc->fontinc = 0x10000;
fbc->fontxy = xy;
if (fontheightlog(p)) {
- fd1 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
- fd2 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
- fd3 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
- fd4 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
+ fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+ fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+ fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+ fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
} else {
- fd1 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
- fd2 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
- fd3 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
- fd4 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
+ fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+ fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+ fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+ fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
}
FFBFifo(fbc, fontheight(p));
if (fontwidth(p) == 8) {
@@ -483,11 +483,11 @@
fbc->fontinc = 0x10000;
fbc->fontxy = xy;
if (fontheightlog(p)) {
- fd1 = p->fontdata + ((*s++ & p->charmask) << (fontheightlog(p) + 1));
- fd2 = p->fontdata + ((*s++ & p->charmask) << (fontheightlog(p) + 1));
+ fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
+ fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
} else {
- fd1 = p->fontdata + (((*s++ & p->charmask) * fontheight(p)) << 1);
- fd2 = p->fontdata + (((*s++ & p->charmask) * fontheight(p)) << 1);
+ fd1 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
+ fd2 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
}
FFBFifo(fbc, fontheight(p));
for (i = 0; i < fontheight(p); i++) {
@@ -504,9 +504,9 @@
fbc->fontinc = 0x10000;
fbc->fontxy = xy;
if (fontheightlog(p))
- i = ((*s++ & p->charmask) << fontheightlog(p));
+ i = ((scr_readw(s++) & p->charmask) << fontheightlog(p));
else
- i = ((*s++ & p->charmask) * fontheight(p));
+ i = ((scr_readw(s++) & p->charmask) * fontheight(p));
FFBFifo(fbc, fontheight(p));
if (fontwidth(p) <= 8) {
fd1 = p->fontdata + i;
diff -u --new-file --recursive --exclude-from ../exclude linux.vanilla/drivers/video/cyber2000fb.c linux.ac/drivers/video/cyber2000fb.c
--- linux.vanilla/drivers/video/cyber2000fb.c Thu Jan 1 01:00:00 1970
+++ linux.ac/drivers/video/cyber2000fb.c Tue Jan 26 23:43:49 1999
@@ -0,0 +1,1125 @@
+/*
+ * linux/drivers/video/cyber2000.c
+ *
+ * Integraphics Cyber2000 frame buffer device
+ *
+ * Based on cyberfb.c
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include